zoukankan      html  css  js  c++  java
  • DVWA全级别通关笔记(二)-- Command Injection(命令注入)

    引言

    结合DVWA提供的命令注入模块,对命令注入漏洞进行学习总结。命令注入(Command Injection)是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。

    在一些web应用中,某些功能可能会调用一些命令执行函数,比如php中的system、exec、shell_exec等。如果对用户输入的淑数据过滤不充分的话,很容易造成命令执行漏洞。

    环境

    phpstudy(搭建DVWA)

    Command Injection

    low

    我们先分析一下漏洞源码:

     <?php
    
    if( isset( $_POST[ 'submit' ] ) ) {
        $target = $_REQUEST[ 'ip' ];
    // Determine OS and execute the ping command. if (stristr(php_uname('s'), 'Windows NT')) { $cmd = shell_exec( 'ping ' . $target ); echo '<pre>'.$cmd.'</pre>'; } else { $cmd = shell_exec( 'ping -c 3 ' . $target ); echo '<pre>'.$cmd.'</pre>'; } } ?>

      stritr函数主要用来查找字符串,并返回。php_uname返回运行PHP的操作系统描述。如果是windows系统则执行 “ping + $target” ,如果是linux系统,执行“ping -c 3 + target”, 并没有对用户输入的变量ip进行过滤,而是直接执行ping + target中的内容,所以存在命令执行漏洞,管道运算符使用的会比较多。

    A && B: 先执行A,如果成功,执行B;

    A || B :先执行A,如果失败,执行B;

    A | B:管道,先执行A后,将A的结果作为B的输入,打印的是B的结果;

    A & B:先执行A,然后不管成功与否,执行B;

     可以使用以下payload,注入成功。

    127.0.0.1;ifconfig
    127.0.0.1&ifconfig
    127.0.0.1&&ifconfig
    127.0.0.1|ifconfig
    x||ifconfig
    

     medium

    先分析一下源码:

     <?php
    
    if( isset( $_POST[ 'submit'] ) ) {
    
        $target = $_REQUEST[ 'ip' ];
    
        // Remove any of the charactars in the array (blacklist).
        $substitutions = array(
            '&&' => '',
            ';' => '',
        );
    
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
        
        // Determine OS and execute the ping command.
        if (stristr(php_uname('s'), 'Windows NT')) { 
        
            $cmd = shell_exec( 'ping  ' . $target );
            echo '<pre>'.$cmd.'</pre>';
            
        } else { 
        
            $cmd = shell_exec( 'ping  -c 3 ' . $target );
            echo '<pre>'.$cmd.'</pre>';
            
        }
    }
    
    ?> 
    

      这里创建了一个黑名单substitutions,对用户输入数据的 ‘ && ’ 和 ‘ ; ’进行了过滤。但是并没有对所有的管道运算符进行过滤,我们依然可以使用以下payload达到命令执行目的。

    1270.0.1999||ls -l
    127.0.0.1&ls -l
    127.0.0.1|ls -l

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

      high级别的源码对黑名单进行了扩充,过滤了更多可能造成命令执行的运算符,包括 ‘&’ 、‘;’ 、‘| ’ 、‘-’ 、‘$’ 、‘(’ 、‘)’ 、‘`’ 、‘||’ ,这里过滤的‘| ’中间有个空格,所以我们使用 ‘|’ 就可以绕过黑名单了。

    127.0.0.1|ls

    impossiable

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

      explode函数

     explode函数将用户输入的ip以 ‘.’ 为分隔符,分为四个字符,将这四个字符放入数组中,并判断这四个元素是否为数字或者数字字符串,如果不是则不执行命令。

    命令注入的防御措施

    1、采用白名单,或使用正则表达式进行过滤。

    2、不要让用户可以直接控制eval()、system、exec、shell_exec等函数的参数。

    3、在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。

    参考

    《WEB漏洞》

  • 相关阅读:
    codeforces C. Cows and Sequence 解题报告
    codeforces A. Point on Spiral 解题报告
    codeforces C. New Year Ratings Change 解题报告
    codeforces A. Fox and Box Accumulation 解题报告
    codeforces B. Multitasking 解题报告
    git命令使用
    shell简单使用
    知识束缚
    php 调用系统命令
    数据传输方式(前端与后台 ,后台与后台)
  • 原文地址:https://www.cnblogs.com/s1awwhy/p/13972885.html
Copyright © 2011-2022 走看看