DVWA Command Injection

前言

命令注入是未一些函数的参数做过滤或过滤不严导致的,可以执行系统或者应用指令(CMD命令或者bash命令)的一种注入攻击手段。>PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一。

管道符

利用命令注入,很多时候需要利用管道符,下面将分别介绍Windows和Linux的管道符;

Windows

  • ,直接执行后面的语句,例如:ping 127.0.0.1 | whoami
  • ||,如果前面的语句执行出错,则执行后面的语句;要执行后面的语句,前面的语句只能为假,例如:ping 2 || whoami
  • &,无论前面的语句的真假,都会执行两个语句,例如:ping 2 & whoami
  • &&,如果前面的语句为假则直接出错,也不执行后面的语句;要执行后面的语句,前面的语句只能为真,例如:ping 127.0.0.1 && whoami

Linux

  • ,执行完前面的语句再执行后面的,例如: ping 127.0.0.1;whoami
  • |,只显示后面语句的执行结果,例如:ping 127.0.0.1 | whoami
  • ||,当前面的语句执行出错时,执行后面的语句;要执行后面的语句,前面的语句只能为假,例如:ping 1|| whoami
  • &, 无论前面的语句的真假,都会执行两个语句,例如:ping 127.0.0.1 & whoami
  • &&,如果前面的语句为假则直接出错,也不执行后面的;要执行后面的语句,前面的语句只能为真,例如:ping 127.0.0.1 && whoami

LOW

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>

分析:

函数

  • stristr(string,search,before_search)

    stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE。

    • 参数string规定被搜索的字符串,
    • 参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符),
    • 可选参数before_true为布尔型,默认为“false” ,如果设置为 “true”,

    函数将返回 search 参数第一次出现之前的字符串部分。

  • php_uname(mode)

    这个函数会返回运行php的操作系统的相关描述,参数mode可取值

    • a (此为默认,包含序列”snrvm”里的所有模式)
    • s (返回操作系统名称)
    • n(返回主机名)
    • r(返回版本名称)
    • v(返回版本信息)
    • m(返回机器类型)

功能:

获取 IP 的值,直接传参使用 shell_exec 执行。

  • Windows 的话执行 ping 命令。
  • linux 的话,执行 ping -c 4 命令。

未对输入数据做过滤处理,可以使用管道添加其他命令,达到攻击的目的;

MEDIUM

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>

分析:

str_replace函数将&&,;替换为空字符,过滤了&&;,但是其他 的符号仍然可用;

HIGH

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 <?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>

分析:

黑名单看似过滤了所有的非法字符,但仔细观察到是把| (注意这里|后有一个空格)替换为空字符,于是|就有用了;

输入127.0.0.1|ifconfig执行后面的命令;

IMPOSSIBLE

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode( ".", $target );
// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>

分析:

加入了Anti-CSRF token,同时对参数ip进行了严格的限制,只有诸如“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。