PHP代码审计学习(5)——代码执行漏洞
代码执行
代码执行是指应用程序本身过滤不严,当应用在调用一些字符串函数的时候用户可以通过请求将代码注入到应用中执行。
存在于eval()、assert()、preg_replace()、call_user_func()、array_map()以及动态函数中,很难通过黑盒测试查找。
挖掘思路
1:用户能够控制函数输入
2:存在可执行的危险函数
常见危险函数
1、eval和assert
这俩两个函数原本作用就是动态执行代码,所以他们的参数直接就是PHP代码
<?php if(isset($_REQUEST['cmd'])){ $cmd = ($_REQUEST["cmd"]); system($cmd);//eval($cmd); echo "</pre>$cmd<pre>"; die; } ?>
因为对传入没有过滤,所以直接传入PHP代码
?cmd=phpinfo();
2、preg_replace函数
对字符串进行正则处理,一般挖掘的时候是都是绕过正则的
<?php preg_replace("/\[(.*)\]/e",'\\1',$_GET['str']); ?>
第一组是匹配中括号的的内容,\\1作为第一组的结果填充,这里是直接执行代码,所以
?str=[phpinfo()]
就能直接执行phpinfo()
3、回调函数
call_user_func()和array_map()等都有调用其他函数的功能,过滤不严且传入参数可控,就可以调用函数来执行代码
<?php $b="phpinfo()"; call_user_func($_GET['a'],$b); ?>
当传入assert函数的时候,就可以执行phpinf()
?a=assert
4、动态函数执行(重点)
因为PHP的特性,PHP函数可以由字符串拼接,我们可以用一个变量名去代替一个函数
<?php $_GET['a']{$_GET['b']}; ?>
接受a的参数作为函数,b的为函数的参数,所以传入
?a=assert&b=phpinfo()
就会打印PHP的信息
修复
1、尽量不要执行外部的应用程序或命令
2、使用自定义函数或函数库来替代外部应用程序或命令的功能
3、使用escappeshellarg函数来处理命令的参数
4、使用sare_mode_exec_dir来指定可执行的文件路径
5、将执行的参数做白名单限制,在代码或配置文件中限制某些参数