目录
原理
命令执行
web应用提供调取外部应用、执行系统命令功能。用户利用这些功能执行系统命令,从而读取敏感信息、拿到系统权限。
代码执行
应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval(),eval可以将字符串当做函数进行执行)时,没有考虑用户是否控制这个字符串,将造成代码执行漏洞。一般很难通过黑盒查找漏洞,大部分都是根据源代码判断代码执行漏洞。
利用条件以及危害
条件:
1用户可以控制函数输入。
2存在可以执行代码的危险函数
危害
1 继承web服务程序的权限去执行系统命令或者读写文件。
2 反弹shell。
3 控制整个网站甚至控制服务器。
4 进一步的内网渗透
利用方式与常规绕过
危险函数
命令执行:system()、exec()、shell_exec()、passthru()
代码执行:eval()、assert()、call_user_func()、preg_replace()
使用方法
代码执行
1.函数:eval() 使用方法<?php @eval($_POST[777]); ?>
eval函数将输入的字符串参数当作php代码来进行执行
2函数:preg_relpace()使用方法:正则匹配函数 php7中已经不再支持,改用preg_replace_callback(); php5.4及下正常使用php5.5提示已被弃用
<?php $cmd=$_POST[777]; preg_replace("/a-z/e",$cmd,ajest) ?>
3函数:call_user_func() 使用方法:把第一个参数作为回调函数调用
<?php call_user_func($_GET['a'],$ GET['b']); ?> xxx.php?a=assert&b=phpinfo();
4.函数:assert()使用方法:<?PHP assert($_GET[777]);?>
判断一个表达式是否成立
5.函数:create_function()使用方法: 创建匿名函数执行代码执行命令和上传文件参考eval函数(必须加分号)。
<?php $func =create_function('' ,$_POST['cmd']); $func(); ?>
6.函数:array_map() 使用方法: 将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致
<?php $func=$_GET['func']; $cmd=$_POST['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); echo $new_array; ?>
7.函数:call_user_func_array()使用方法: 将传入的参数作为数组的第一个值传递给assert函数
<?php $cmd=$_POST['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array); ?>
命令执行
函数system()使用方法:system($_GET['cmd']);
可以执行系统命令并将其输出
函数:exec()使用方法:echo exec($_GET['cmd'])
执行一个外部的应用程序,以数组形式保存结果,回显需要echo
函数:passthru()使用方法:<?php @passthru($_GET[" cmd"]);?>
将字符串作为OS命令执行,不需要输出执行结果,且输出全部的内容
函数:shell_exec()使用方法:echo shell_exec($_POST[" cmd"])
管道符
Windows
“|” :前面为真时,直接执行后面的语句。 “||” :前面语句执行出错,则执行后面的语句,前面语句只能为假
“&” :前面语句为假则直接执行后面的语句,前面语句可真可假 “&&” :前面语句执行出错,则直接出错,前面语句只能为真
Linux
“|” :直接执行后面的语句 “||” :前面语句执行出错,则执行后面的语句,前面语句只能为假。
“&” :前面语句为假则直接执行后面的语句,前面语句可真可假。 “&&” :前面语句执行出错,则直接出错,前面语句只能为真
“;” :执行完前面的语句再执行后面的。在windwos下无法使用
绕过
Windows
1、大小写绕过:通过windows大小写不敏感的特性绕过 2、双引号绕过:通过加入双引号混淆命令绕过 3、管道符绕过:通过管道符来绕过
Linux
1、变量拼接绕过:通过;符号来绕过 2、反引号加base编码绕过:通过base64加密绕过 3、反引号加混淆绕过:通过加入无意义的字符来绕过 4、$1 、$@ $* 混淆绕过:linux中 $1 $@ $* 等不会影响命令的正常执行 5、换行符绕过:linux中换行不影响执行
防御方式
1、尽量不要执行外部命令
2、使用自定义函数来替代外部命令功能
3、使用escapeshellarg来处理命令参数。Escapeshellarg函数会将任何引起参数或命令结束的字符进行转义,如单引号"'"会被转义为"\’" ,双引号“””会被转义为""" ,分号" ; "会被转义为"\; " ,这样escapeshellarg会将参数内容限制在一对单引号或双引号里面,转义参数中所包含的单引号或双引号,使其无法对当前执行进行截断,实现防范命令注入攻击的目的。
4、使用safe_mode_exec_dir执行可执行的文件路径将php.ini文件中的safe_mode设置为On,然后将允许执行的文件放入一个目录中,并使用safe_mode_exec_dir指定这个可执行的文件路径。这样,在需要执行相应的外部程序时,程序必须在safe_mode_exec_dir指定的目录中才会允许执行,否则执行将失败
案例
Struts2-009远程代码执行漏洞 shiro cve-2016-4437 框架漏洞