zoukankan      html  css  js  c++  java
  • DVWA-对Command Injection(命令注入)的简单演示与分析

    1. 前言

    上一篇文章中,对命令注入进行了简单的分析,有兴趣的可以去看一看,文章地址 https://www.cnblogs.com/lxfweb/p/12828754.html,今天这篇文章以DVWA的Command Injection(命令注入)模块为例进行演示与分析,本地搭建DVWA程序可以看这篇文章 https://www.cnblogs.com/lxfweb/p/12678463.html,通过对DVWA不同等级的代码分析,看看它是如何做的防御。

    漏洞利用与分析

    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(),php_uname(),函数,这是用来判断当前的系统是否是Windows,因为Windows和Linux下的ping命令执行参数是不同的。接下来是用shell_exec函数来执行ping命令,并将结果输出。我们发现low级别的代码,对用户的输入没有做任何的过滤。存在很大的安全隐患。例如使用管道符“|”查看当前端口,输入下列内容

    127.0.0.1|netstat -ano

    结果如下图

     这里不止可以使用“|”,在DOS下允许同时执行多条命令的符号主要有以下几个

    1. & 连接符  执行完第一个命令,执行第二个命令
    2. && 只有上一个执行成功,才执行下一个命令
    3. |  管道符  让前一命令的输出当做后一命令的输入,就是说前面命令的结果当做一个参数传递给后面命令处理 
    4. ||    只有上一个执行失败,才执行下一个命令

    可以用连接符直接接net user zhangsan 123/add 创建用户 接着连接提权命令 net localgroup administrators zhangsan /add 拿下整个服务器

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

    我们发现,中级的代码,对参数做了一点过滤,把&&和;删除,相当于黑名单的形式,在Linux中;也可以起连接作用,依次执行多个命令。我们可以尝试|  ||  & &;& ,这里以||举例,||前面报错,后面执行咱们构造的命令,结果如下图

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

    高级别的代码对黑名单进行了进一步完善,好像过滤了所有危险字符,仔细观察黑名单里“|”管道符,后面有一个空格“| ” 这样可以尝试“ |” 发现成功绕过,结果如下图

     Impossible(无漏洞)

    查看核心代码

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

    通过查看Impossible级别的代码加入了Anti-CSRF token,并且采用白名单的方式,对参数ip进行了严格的限制,只接受X.X.X.X(X只能为数字),因此不存在命令执行漏洞。

  • 相关阅读:
    repadmin example.
    在 Windows 2000 和 Windows XP 中重置计算机帐户
    管理活动目录
    使用AdsiEdit工具查看GC数据
    mms链接media player 9.0无法打开
    活动目录的复制之细节
    使用Repadmin.exe 对活动目录复制排错
    Difference among Domain Local Group and Global Group and Universal Group
    使用 ADSI Edit 编辑 Active Directory 属性
    xp的密码工具
  • 原文地址:https://www.cnblogs.com/lxfweb/p/12831417.html
Copyright © 2011-2022 走看看