命令執行漏洞(Commnd Execution)總結

前言:
   這周來學習下命令執行漏洞;命令執行漏洞是用戶通過瀏覽器在遠程服務器上執行任意系統命令,與代碼執行漏洞沒有太大的區別,不過我們在學習時還是要區分不同的概念。關於代碼執行漏洞會在下篇博客中詳述。


一、什麼是命令執行漏洞

應用 有時需要調用一些執行系統命令的函數,如PHP中的systemexecshell_execpassthrupopenproc_popen等,當用戶能控制這些函數中的參數時,就可以將惡意系統命令拼接到正常命令中,從而造成命令執行攻擊,這就是命令執行漏洞。

二、命令執行漏洞產生原因

  • 開發人員沒有對特殊函數入口做過濾,導致用戶可以提交惡意代碼並提交服務端執行。
  • Web服務器沒有過濾危險函數導致命令執行漏洞攻擊成功。

三、PHP中的危險函數

system:成功則返回命令輸出的最後一行,失敗則返回FALSE。
exec:命令執行結果的最後一行內容。
shell_exec:命令執行的輸出。如果執行過程中發生錯誤或者進程不產生輸出,則返回NULL。
passthru:執行外部程序並且顯示原始輸出。
eval:將輸入的字符串參數當做PHP程序代碼來執行。
assert
preg_replace
call_user_func

四、命令執行漏洞的危害

  • 任意執行系統命令
  • 惡意木馬被種植
  • 掛馬、釣魚
  • 敏感信息泄露

常用的命令連接符

在windows和linux都支持,如果程序沒有進行過濾,那麼我們可以通過連接符來執行多條命令。

A&&B   先執行A,執行成功後執行B,否則不執行B
A|B    只執行B
A&B    先執行A,不管是否成功,都會執行B
A;B    先執行A,再執行B
A&B    簡單拼接,A B之間無制約關係

瞭解了這些知識後,下面就在本地搭建的DVWA中練習下。

DVWA—Command Injection(命令注入)

在這裏插入圖片描述
先從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>";
}
?>

可以看到,low級別的代碼接收了用戶輸入的ip,服務器通過判斷操作系統執行不同ping命令。但是這裏對用戶輸入的ip並沒有進行任何的過濾,所以存在可利用的命令執行漏洞。

&&來執行多條命令,構造payload:127.0.0.1&&net user
在這裏插入圖片描述
執行成功;(如果存在亂碼問題,把DVWA\dvwa\includes目錄下的dvwaPage.inc.php文件中所有的”charset=utf-8”,全部替換修改爲”charset=gb2312”即可)

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

可以看到,medium級別相較於low級別的代碼 只增加了對 &&的過濾,繞過也很簡單,不用 && ,直接用 &不就好起來了嗎!

&&&的區別在於&&是執行完前面的命令然後執行後面的命令,&是不管前面的命令是否值執行,後面的都執行。

構造poyload:127.0.0.1&ipconfig

在這裏插入圖片描述
繞過執行成功!

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等級的黑名單更完善了,但是由我們可以看出來他只是過濾掉了“| ”,如果用|後不跟空格就可以繞過過濾。
構造payload:127.0.0.1|dir
在這裏插入圖片描述
繞過成功。

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

瞭解下幾個函數:
stripslashes(string) : 該函數會刪除字符串string中的反斜槓,返回已剝離反斜槓的字符串。

explode(separator,string,limit): 該函數把字符串打散爲數組,返回字符串的數組。參數separator規定在哪裏分割字符串,參數string是要分割的字符串,可選參數limit規定所返回的數組元素的數目。

is_numeric(string): 該檢測string是否爲數字或數字字符串,如果是返回TRUE,否則返回FALSE。

可以看到 Impossible級別的代碼加入了Anti-CSRF token,至於什麼是Anti-CSRF token請點擊 鏈接 查看;同時對參數ip進行了嚴格的限制,只有諸如“數字.數字.數字.數字”的輸入纔會被接收執行,因此不存在命令注入漏洞。
好了,關於命令執行漏洞這次就先總結到這,下篇會更代碼執行漏洞的知識。(●’◡’●)

參考博客:
https://blog.csdn.net/qq_36119192/article/details/82917250
https://blog.csdn.net/jpygx123/article/details/83276533

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章