DVWA通关之命令注入(command injection)

DVWA通关之命令注入(command injection)

难度等级:low

过关思路

  1. 我们先将其难度设置为low,看到其界面如下:

image-20210128141119846

  1. 通过分析得知,该功能是输入一个IP地址,然后通过ping进行测试,先输入127.0.0.1www.baidu.com测试如下:

127.0.0.1

image-20210128141414768

www.baidu.com

image-20210128141609752

  1. 可以看到,IP地址和域名都是能够ping通的,接下来就是使用命令拼接测试了,

输入127.0.0.1 | whoami

image-20210128142225176

命令注入成功。

  1. 命令汇总,经过测试,以下命令均可注入成功。

127.0.0.1|whoami

127.0.0.1&whoami

127.0.0.1000 || whoami

127.0.0.1 && whoami

  1. 注意:有空格和无空格有时会有意想不到的效果

  2. 做完了当然得看一下源码:

image-20210128143009680

  可以看到,该代码没有对用户的输入做任何的过滤,直接使用shell_exec函数执行用户输入,这是非常危险的。

难度等级:medium

过关思路

  1. 这里过关思路和low一致,也没啥可说的,我们主要看一下源码就行。
  2. 源代码如下:

image-20210128143630947

  通过分析,可以看出,medium关卡比low关卡多了一个黑名单。其通过数组的方式将&&;进行了过滤,即将其替换为。但是,这种过滤基本上还是跟没有过滤差不多,因为黑名单里的过滤太少了,黑名单也不安全。

难度等级:high

过关思路

  1. 上手先测试几个前面的payload,发下好多都被过滤了,但是还有几个可以用:

127.0.0.1 || whoami

127.0.0.1|whoami

127.0.0.1000||whoami

image-20210128154801468

  1. 我们直接看源代码:

image-20210128154709468

  可以看到,这次的黑名单过滤明显的多了起来,但是也发现(可能是故意给我们漏出来的😂),其在过滤的时候,没有过滤|而是过滤了|+空格,所以,该代码只是遇到单单一个|,不会进行过滤。

难度等级:impossible

过关思路

  1. 这关基本上是不存在安全风险的,之所以放在这里,当作一个关卡,应该也是为了让我们学习一下怎么进行过滤,我们还是直接看源代码吧。
  2. 源代码如下:
<?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();

?>

  一波代码审计,我们发现,这次的过滤和前面的两关没有任何相似之处,而是直接换了一种思路,也就是我们所说的白名单。其控制了用户的输入,不在控制用户的输入哪些不能用,而是控制用户的输入哪些能用。

  1. 我们还是慢慢从函数入手分析:
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); 

  这段代码是控制了用户身份信息,在每次和服务器交互之时,服务器会随机给用户分配一个ID,用作用户的身份凭证,这样也就断绝了假冒用户的事件发生。

    $target = stripslashes( $target ); 

  stripslashes函数用于删除输入中的反斜杠。

$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 ))

  而这段代码是控制了用户只能输入IP地址,无法使用域名。且在用户输入IP地址后,使用explode函数.为分割,将IP地址分割为数组,最后判断数组的个数是否为4。可以说,过滤确实很绝,但是也有一个不好之处就是屏蔽掉了域名。

总结

  1. 掌握有关命令执行的知识 windows 或 linux 下:

命令执行漏洞(| || & && 称为管道符)

command1 && command2 先执行 command1,如果为真,再执行 command2

command1 | command2 只执行 command2

command1 & command2 先执行 command2 后执行 command1

command1 || command2 先执行 command1,如果为假,再执行 command2

windows:(1)|(2)||(3)&(4)&&

linux:(1)|(2)||(3);(4)&&

  1. 命令注入的相关系统函数:

① system()

② exec()

③ shell_exec()

④ passthru()

⑤ popen()

⑥ ``(反引号)

posted @ 2021-01-28 16:29  ruoli-s  阅读(359)  评论(0编辑  收藏  举报