介绍
命令执行漏洞是值应用有时需要调用一些执行系统命令的函数,如:system()、shell_exec()、eval()、passthru(),代码未对用户可控参数做过滤,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击。
分类
1、代码层过滤不严
商业应用的一些核心代码封装在二进制文件中,在web应用中通过system函数调用:
system("/bin/program --arg $arg");
2、系统的漏洞造成命令注入
bash破壳漏洞(CVE-2014-6271)
3、调用的第三方组件存在代码执行漏洞
wordpress中用来处理图片的ImageMagick组件;
JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等);
ThinkPHP命令执行;
利用条件
1、应用调用执行命令的函数
2、将用户输入作为系统命令的参数拼接到命令中
3、没有对用户输入过滤或过滤不严格
常见拼接符
命令A ;命令B | 先执行命令A,在执行命令B |
命令A && 命令B | 命令A执行成功,才会执行命令B |
命令A & 命令B | 简单拼接,命令A、B之间没有制约关系 |
命令A | 命令B | 显示命令B的执行结果 |
命令A || 命令B | 命令A执行失败,才会执行命令B |
PHP中的危险函数
system(): 成功则返回命令输出的最后一行,失败则返回 FALSE。
exec(): 命令执行结果的最后一行内容
shell_exec(): 命令执行的输出。如果执行过程中发生错误或者进程不产生输出,则返回NUL。
passthru(): 执行外部程序并且显示原始输出。
eval(): 将输入的字符串参数当做PHP程序代码来执行。
命令执行常见可控位置情况
system("$sag"); //可控点直接是待执行的程序
stem("/bin/prog $arg") //可控点是传入程序的整个参数
system("/bin/prog -p $arg"); //可控点是传入程序的某个参数的值(无引号包裹)
system("/bin/prog -p="$arg""); //可控点是传入程序的某个参数的值(有双引号包裹)
system("/bin/prog -p='$arg'"); //可控点是传入程序的某个参数的值(有单引号包裹)
利用方式
方式一:常见拼接符利用
1、&&拼接符
2、&拼接符
3、||拼接符
4、|拼接符
方式二:添加用户
创建用户a
查看用户是否创建成功
将用户a添加管理员组
使用创建的用户进行远程登录
方式三:执行函数,信息泄露
执行函数,phpinfo();
方式四:写入文件,反弹shell
在目标/tmp目录下写入反弹shell脚本
使用命令执行漏洞,执行写入的脚本
nc监听端口,得到目标服务器shell
命令执行漏洞危害
- 继承WEB服务程序的权限去执行系统命令或读写文件
- 反弹shell
- 控制整个网站甚至服务器
- 进一步内网渗透
命令执行漏洞防御方式
- 尽量少用执行命令的函数或直接禁用
- 参数值尽量使用引号包括,并在拼接前调用addslashes函数进行转义
- 在使用动态函数之前,确保使用的函数是指定的函数之一
- 在进入执行命令的函数方法之前,对参数进行过滤,对敏感字符进行转义
- 对于可控点是程序参数的情况下,使用escapeshellcmd函数进行过滤