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漏洞》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM