2、DVWA——命令注入

一、命令注入

1.1 概述

  命令注入的目标是通过易受攻击的应用程序在主机操作系统上执行任意命令。当应用程序将不安全的用户提供的数据(表单、cookie、HTTP 标头等)传递到系统 shell 时,可能会发生命令注入攻击。在这种攻击中,攻击者提供的操作系统命令通常以易受攻击的应用程序的权限执行。命令注入攻击的可能性很大程度上是由于输入验证不足。

  此攻击与代码注入不同,代码注入允许攻击者添加自己的代码,然后由应用程序执行。

1.2 判断命令注入流程

  • 是否调用系统命令
  • 函数或函数的参数是否可控
  • 是否拼接注入命令

二、low

2.1 通关思路

(1)输入127.0.0.1,看看是否有回显。

在这里插入图片描述
(2)尝试用命令连接符拼接命令,payloa:127.0.0.1 && whoami
在这里插入图片描述

  原理:由于在操作系统中,“&”、“&&”、“|”、“||”都可以作为命令连接符使用,由于网页没有对参数进行任何过滤,因此可以用连接符后面接上其他指令来执行。

常见的命令连接符:

  • a && b :代表首先执行前者命令a再执行后命令b,但是前提条件是命令a执行正确才会执行命令b,在a执行失败的情况下不会执行b命令。所以又被称为短路运算符。
    前面的命令执行成功后,它后面的命令才被执行

  • a & b:代表首先执行命令a再执行命令b,如果a执行失败,还是会继续执行命令b。也就是说命令b的执行不会受到命令a的干扰。
    表示简单的拼接,A命令语句和B命令语句没有制约关系

  • a || b:代表首先执行a命令再执行b命令,如果a命令执行成功,就不会执行b命令,相反,如果a命令执行不成功,就会执行b命令。
    前面的命令执行失败,它后面的命令才被执行

  • a | b:代表首先执行a命令,再执行b命令,不管a命令成功与否,都会去执行b命令。
    当第一条命令失败时,它仍然会执行第二条命令,表示A命令语句的输出,作为B命令语句的输入执行。

2.2.源码分析

  通过数据包,可以看到客户端以POST方式进行请求。

在这里插入图片描述

<?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():搜索字符串在另一字符串中的第一次出现。
  • php_uname():返回运行 PHP 的系统的有关信息。

  分析:php_uname(mode) 函数会返回运行php的操作系统的相关描述,当参数是 “s” 时,返回操作系统名称。stristr() 函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),未找到所搜索的字符串返回 FALSE。使用该函数的目的是为了区分 DVWA 搭建在什么系统上。不过,对于最重要的传入的 ping 命令的参数 target,并没有进行任何过滤。

三、Medium

3.1 通关思路

  直接输入127.0.0.1 & whoami,发现仍然可以执行命令。

在这里插入图片描述

3.2 源码分析

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

  几个函数

  • array_keys():返回包含数组中所有键名的一个新数组。
  • str_replace():替换字符串中的一些字符(区分大小写)。语法:str_replace(find,replace,string,count)

  分析:medium 级别的代码加入了对“&&”和“;”的过滤。

四、high

4.1 通关思路

payload:127.0.0.1|ifconfig

在这里插入图片描述

4.2 源码分析

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

  分析:虽然是把所有的连接符都过滤了,但是开发者在| 后面加了个空格,因此我们还是能够用 | 连接符进行绕过。

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

  分析:

  • 使用token防止CSRF攻击;
  • 对参数 ip 进行了严格的限制,只有“数字.数字.数字.数字”的输入才会被接收执行;

六、总结

  一些 Web 程序中需要调用一些执行系统命令的函数,例如 PHP 的systemexecshell_exec函数等。当攻击者能够直接操作命令执行的参数,并且没有代码对传入的参数进行过滤时,攻击者就能将用于搞破坏的系统命令夹带进来让系统执行。
在 Windows 系统和 Linux 系统中都有一些管道符,这些管道符可以被用来拼接攻击指令:

  • &&:前面的语句正确执行时,才执行后面的语句;
  • &:前面的语句执行出错时,执行后面的语句;
  • |:将前面的语句运行的结果,当做后面语句的输入,显示后面语句的执行结果;
  • ||:前面的语句出错时,执行后面的语句。

  对于指令注入漏洞,比较好的防御方式是尽可能别用命令执行函数,对于输入的参数要做好黑名单过滤或者白名单验证。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值