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

命令注入漏洞

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

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

1、 基於DVWA環境的命令注入漏洞(shell_exec)

一、 函數用法
String shell_exec(string command)
command 要執行的命令
二、 low級別
源碼:shell

<?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指定發送的跳數才能中止。
能夠看到在接收用戶輸入的地方,對用戶的輸入沒有作任何的處理。不難看出這就是一個典型的命令注入漏洞。並且孩子是最輕易。
咱們正常測試一下:
php命令注入函數及dvwa命令注入實踐
能夠看到,正常返回的是ping返回的數據。
咱們經過這個命令執行漏洞進行測試一下:
構造咱們的語句:10.39.1.4 | net user
解釋: | 的意思是前面命令的輸出結果做爲後面命令的輸入。
net user 查看當前系統中存在哪些用戶
測試:
php命令注入函數及dvwa命令注入實踐
能夠看到當前系統中存在三個用戶。若是做爲×××去利用的話就可使用命令去建立一個用戶。就不在演示
漏洞分析:不處理用戶的任何輸入就直接執行函數中的命令。數組

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

三、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
& 前面命令執行後接着執行後面的命令
測試:
php命令注入函數及dvwa命令注入實踐
依然得到了執行的結果session

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

四、 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
php命令注入函數及dvwa命令注入實踐
已經不能用那些方法了。具體的利用我也沒有找到合適的方法。

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

五、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命令。
就不測試了,這樣的源碼已經杜絕了你的全部命令注入×××。

2、eval()函數形成的命令注入漏洞

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

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

?>

構造語句:

name=phpinfo()

測試效果:
php命令注入函數及dvwa命令注入實踐
三、 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中的內容以數組的形式輸出出來。
php命令注入函數及dvwa命令注入實踐
獲得flag

3、system()函數形成的漏洞

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

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

構造語句:
Cmd=| net user

測試:
php命令注入函數及dvwa命令注入實踐
經過漏洞咱們得到了系統中存在哪些用戶,一樣的咱們也能夠經過這樣的方法在系統中建立咱們本身的用戶。並能夠加入到管理員組中。這裏就不在說了。

4、shell_exec()函數形成的漏洞

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

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

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

php命令注入函數及dvwa命令注入實踐
實現方法和上一個函數是同樣的。一樣的函數還有exec()和符號

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

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

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

    echo passthru($cmd);
}
?>

三、測試
構造語句 cmd=net user
php命令注入函數及dvwa命令注入實踐
得到用戶列表

6、總結

總結以上全部函數漏洞形成的命令注入漏洞,每個例子都是由於沒有對用戶的輸入進行處理。在防護漏洞的時候,必定明白一個道理,全部用戶的輸入都是有害的。全部的輸入都是不值得相信的。
相關文章
相關標籤/搜索