1. 程式人生 > >php命令註入函數及dvwa命令註入實踐

php命令註入函數及dvwa命令註入實踐

net c89 linux命令 不知道 cte 若是 狀態 知識擴展 當前

命令註入漏洞

註:命令註入漏洞的分析,及含有命令註入漏洞的函數解析

含有命令註入漏洞的函數:system()、exec()、passthru()、shell_exec()、``(與shell_exec()功能相同)

一、 基於DVWA環境的命令註入漏洞(shell_exec)

1、 函數用法
String shell_exec(string command)
command 要執行的命令
2、 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>";
}

?>

源碼分析:
函數首先判斷環境下的系統,如果是win則執行第一個命令,若是linux執行的命令加上-c選項,以為linux中ping命令是一直執行的。只有加了-c指定發送的跳數才能停止。
可以看到在接收用戶輸入的地方,對用戶的輸入沒有做任何的處理。不難看出這就是一個典型的命令註入漏洞。而且孩子是最輕易。
我們正常測試一下:
技術分享圖片
可以看到,正常返回的是ping返回的數據。
我們通過這個命令執行漏洞進行測試一下:
構造我們的語句:10.39.1.4 | net user
解釋: | 的意思是前面命令的輸出結果作為後面命令的輸入。
net user 查看當前系統中存在哪些用戶
測試:
技術分享圖片
可以看到當前系統中存在三個用戶。如果作為×××去利用的話就可以使用命令去創建一個用戶。就不在演示

漏洞分析:不處理用戶的任何輸入就直接執行函數中的命令。

知識擴展:
; - 分號在linux命令執行的時候,可以直接執行幾條命令,命令與命令之間用分號隔開。
& 前面的命令執行後接著執行候命的命令
&& 前面的命令執行成功後才可以執行下面的命令
| 前面的命令輸出結果最為後面命令輸入的內容
|| 前面的命令執行失敗後才會執行後面的命令

3、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>";
}

?>

源碼分析:
Str_replace()函數,以其他字符替換字符串中的一些字符(區分大小寫)。
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );將用戶輸入的內容,含有&&或;的替換為空。
其他的部分基本和low相差不大。
這裏的源碼對用戶的輸入進行了初步的過濾,過濾掉了一些能夠同時執行命令的符號,但是我們知道,擁有同樣作用的符號不止&&和;。所以依然可以進行命令註入。
命令註入測試:
構造語句: 10.39.1.4 & net user
& 前面命令執行後接著執行後面的命令
測試:
技術分享圖片
依然獲得了執行的結果

漏洞分析:此級別下的源碼雖然對用戶的輸入設置了過濾,但是沒有將特殊符號過濾完全,僅僅設置黑名單是不夠的,你不知道用戶會輸入什麽,造成有心者亦可以利用此漏洞。

4、 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>";

}

?>

源碼分析:
這個級別的源碼和medium級別的源碼相差不大,只是將更多的符號加入黑名單。
通過這樣的確實能夠有效的防禦之前的諸多思路。
測試:
輸入10.39.1.4 | net user
技術分享圖片
已經不能用那些方法了。具體的利用我也沒有找到合適的方法。

漏洞分析:只是做黑名單的話,總是不夠安全的,只要黑名單不夠完整,就不是很安全。即使你認為名單已經很完整了。可能還有你不知道的存在可以利用。

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

源碼分析:
Explode()函數,將字符串變為數組。這裏就是將我們輸入的ip,變成數組
然後判斷數組的前四組數是否為數字,並且數組中有四個對象。不滿足就會報錯提醒。也就是說這裏只允許你輸入四組數字。
若果判斷為true的話,就會再將這四組數通過點連接起來再就行ping命令。
就不測試了,這樣的源碼已經杜絕了你的所有命令註入×××。

二、eval()函數造成的命令註入漏洞

1、函數用法
eval(phpcode)
Phpcode 規定要計算的php代碼。通常用分號結束每句代碼的執行。
2、環境源碼

<?php
$var = "var";
if(isset($_GET["name"])){
    $arg = $_GET["name"];
    eval("\$var=$arg;");
    echo "\$var = ".$var;
}

?>

構造語句:

name=phpinfo()

測試效果:
技術分享圖片
3、 ctf題目實例
題目地址bugku中的本地包含:http://120.24.86.145:8003/
題目解析:
源碼:

<?php 
    include "flag.php"; 
    $a = @$_REQUEST[‘hello‘]; 
    eval( "var_dump($a);"); 
    show_source(__FILE__); 
?>

構造語句:
Hello = file(‘flag.php’)
解析,當參數接收到的構造的語句的時候,代碼就會變為
Eval(var_dump(file(‘flag.php’)))
Eval函數,執行函數體沒的php代碼;file()函數把整個文件讀到一個數組中。Var_dump()函數 輸出。
所以執行結果就是將flag.php中的內容以數組的形式輸出出來。
技術分享圖片
得到flag

三、system()函數造成的漏洞

1、函數用法:
System(string command,int &return_var)
Command 要執行的命令
Return_var 存放命令的執行後的狀態值
2、環境源碼:

<?php
$cmd = $_GET[‘cmd‘];
if(isset($cmd)){
    echo system("dir".$cmd);
}
?>

構造語句:
Cmd=| net user

測試:
技術分享圖片
通過漏洞我們獲得了系統中存在哪些用戶,同樣的我們也可以通過這樣的方法在系統中創建我們自己的用戶。並可以加入到管理員組中。這裏就不在說了。

四、shell_exec()函數造成的漏洞

1、函數用法:
shell_exec(string command)
command 要執行的命令
2、環境源碼:

<?php
$cmd = $_GET[‘cmd‘];
if(isset($cmd)){
    echo "<h3>";
    echo shell_exec("dir".$cmd);
    echo "<h3>";
}
?>

4、 測試:
構造語句: | net user

技術分享圖片
實現方法和上一個函數是一樣的。同樣的函數還有exec()和符號

五、passthru()函數造成的漏洞
1、函數用法:
void passthru (string command, int &return_var)
command 要執行的命令
return_var 存放執行命令後的狀態值

同 exec() 函數類似, passthru() 函數 也是用來執行外部命令(command)的。 當所執行的 Unix 命令輸出二進制數據, 並且需要直接傳送到瀏覽器的時候, 需要用此函數來替代 exec() 或 system() 函數。
2、環境源碼:

<?php
$cmd = $_GET[‘cmd‘];
if(isset($cmd)){

    echo passthru($cmd);
}
?>

3、測試
構造語句 cmd=net user
技術分享圖片
獲得用戶列表

六、總結

        總結以上所有函數漏洞造成的命令註入漏洞,每一個例子都是因為沒有對用戶的輸入進行處理。在防禦漏洞的時候,一定明白一個道理,所有用戶的輸入都是有害的。所有的輸入都是不值得相信的。

php命令註入函數及dvwa命令註入實踐