DVWA--Command Injection

 

Low

命令注入Low级别的,我们先看一下源码

 

<?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() 函数搜索字符串在另一字符串中的第一次出现。

注释:该函数是二进制安全的。

注释:该函数是不区分大小写的。如需进行区分大小写的搜索,请使用 strstr() 函数。

 


使用语法

stristr(string,search,before_search)

string 必需。规定被搜索的字符串。

search 必需。规定要搜索的字符串。

如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符。

before_search 可选。默认值为 "false" 的布尔值。

如果设置为 "true",它将返回 search 参数第一次出现之前的字符串部分。

 

比如这样使用,返回world 以及之后的

 

 

 

 

这样该改成true,返回前面的字符串

 

 

 

php_uname

返回运行 PHP 的系统的有关信息

参数

mode 是单个字符,用于定义要返回什么信息:

'a':此为默认。包含序列 "s n r v m" 里的所有模式。

's':操作系统名称。例如: FreeBSD。

'n':主机名。例如: localhost.example.com。

'r':版本名称,例如: 5.1.2-RELEASE。

'v':版本信息。操作系统之间有很大的不同。

'm':机器类型。例如:i386。

 

使用php_uname 来判断操作系统来执行不同系统的ping 命令

 

 

可以看到对ip参数没有任何过滤,,直接就是post获取到输入内容,然后提交到shell执行,这样我们可以使用&&再后面跟上我们的命令

 

 

 

127.0.0.1 && whoami  ,可以看到成功执行

 

直接创建用户 

 

 

 

到了这一步已经是可以进行进一步提权了,剩下的操作就不用多说了吧。

 

 

 Medium

再来看看Medium的源码

<?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>";
}

?>

 

 可以看到他把 && 和; 分号做了过滤,仅此而已,我们还可以用 & | 这种来绕过

 

还可以根据他的过滤规则来构造绕过  比如 127.0.0.1 &;&net user 这样就相当于是 127.0.0.1 && net user

 

这里我们再看一下cmd 的特殊字符

“|”:表示管道命令

解释:将第一条命令的结果作为第二条命令的参数来使用

 

“&”:表示组合命令

解释:不管前面命令是否执行,都会执行后面的命令,相当于or

 

“&&”:表示组合命令

解释:前面命令能执行才执行后面命令,相当于and

 

“||”:表示组合命令

解释:如果前面命令不执行则执行后面的命令

 

 

 

 

 

 

High

看一下源码

<?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 |;| net user = 127.0.0.1 | net user

 

为什么这种payload能绕过,注意看代码,'| '='', 在| 后面有空格,也就是我们可以利用这点让他过滤掉;| 这样我们前面的| 成功逃逸

或者是127.0.0.1 |net user 也可以

 

impossible

<?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();

?>

 

可以看到使用了 stripslashes函数删除反斜杠 \ , 使用explode函数把输入字符串从"."开始分割开成4份,再用is_numeric一个个判断每个部分是不是数字或者数字字符串,并且对输入字符串限制了4字节.

很难对其利用进行命令执行了。

 

posted @ 2021-05-01 10:01  Erichas  阅读(88)  评论(0编辑  收藏  举报