日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

DVWA--Command Injection(命令执行)--四个等级

發(fā)布時間:2023/12/31 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DVWA--Command Injection(命令执行)--四个等级 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Command Injection,也就是我們常說的命令執(zhí)行,DVWA共有四個等級

索引目錄:

Low

Medium

High

Impossible


命令執(zhí)行漏洞的原理: :在操作系統(tǒng)中, & 、&& 、| 、 || 都可以作為命令連接符使用,用戶通過瀏覽器提交執(zhí)行命令,由于服務(wù)器端沒有對執(zhí)行函數(shù)進行過濾,從而造成可以執(zhí)行危險命令

PHP的命令執(zhí)行函數(shù)主要有: :system、exec、passthru、shell_exec與’ '(這個并不是函數(shù),只是代表他可以執(zhí)行命令)

常用url編碼
%20 = 空格
%5c = \
%26 = &
%7c = |

command1 & command2 :不管command1執(zhí)行成功與否,都會執(zhí)行command2,也就是command1和command2都執(zhí)行
command1 && command2 :先執(zhí)行command1執(zhí)行成功后才會執(zhí)行command2 ,若command1執(zhí)行失敗,則不執(zhí)行command2
command1 | command2 :只執(zhí)行command2(將上一個命令的輸出作為下一個命令的輸入)
command1 || command2 :command1執(zhí)行失敗,再執(zhí)行command2(若command1執(zhí)行成功,就不再執(zhí)行command2)

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 -n 4 ' . $target );} // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

stristr(string,search,before_search) :搜索字符串在另一字符串中的第一次出現(xiàn),返回字符串的剩余部分(從匹配點),如果未找到所搜索的字符串,則返回 FALSE

string 必需。規(guī)定被搜索的字符串

search 必需。規(guī)定要搜索的字符串
如果該參數(shù)是數(shù)字,則搜索匹配該數(shù)字對應(yīng)的 ASCII 值的字符

before_search 可選。默認(rèn)值為 “false” 的布爾值
如果設(shè)置為 “true”,它將返回 search 參數(shù)第一次出現(xiàn)之前的字符串部分

注釋:該函數(shù)是二進制安全的
注釋:該函數(shù)是不區(qū)分大小寫的,如需進行區(qū)分大小寫的搜索,請使用 strstr() 函數(shù)
舉例:

<?php echo stristr("Hello world!","WORLD"); ?> /*結(jié)果 world! */

php_uname ($mode) :返回運行 PHP 的系統(tǒng)的有關(guān)信息,也就是返回運行 PHP 的操作系統(tǒng)的描述
$mode 是單個字符,用于定義要返回什么信息:
‘a(chǎn)’:此為默認(rèn)。包含序列 “s n r v m” 里的所有模式
‘s’:操作系統(tǒng)名稱。例如: FreeBSD
‘n’:主機名。例如:DESKTOP-XXXXXXX
‘r’:版本名稱,例如: 5.1.2-RELEASE
‘v’:版本信息。操作系統(tǒng)之間有很大的不同
‘m’:機器類型。例如:i386

shell_exec() :通過 shell 環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回。也就是說, PHP先運行一個shell環(huán)境, 然后讓shell進程運行你的命令, 并且把所有輸出已字符串形式返回, 如果程序執(zhí)行有錯誤或者程序沒有任何輸出, 則返回null

Low級別的代碼對提交的參數(shù)沒有進行過濾,僅僅使用使用stristr與php_uname判斷操作系統(tǒng)是否是Windows NT,因此我們可以使用命令連接符來實現(xiàn)命令執(zhí)行

滲透測試:

command1 && command2 :先執(zhí)行command1后執(zhí)行command2

command1 & command2 :先執(zhí)行command2后執(zhí)行command1

command1 | command2 :只執(zhí)行command2

command1 || command2 :command1執(zhí)行失敗,再執(zhí)行command2(若command1執(zhí)行成功,就不再執(zhí)行command2)


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 -n 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

array() :用于創(chuàng)建數(shù)組
在 PHP 中,有三種類型的數(shù)組:
索引數(shù)組 - 帶有數(shù)字索引的數(shù)組
關(guān)聯(lián)數(shù)組 - 帶有指定的鍵的數(shù)組
多維數(shù)組 - 包含一個或多個數(shù)組的數(shù)組
說明:
array() 創(chuàng)建數(shù)組,帶有鍵和值。如果在規(guī)定數(shù)組時省略了鍵,則生成一個整數(shù)鍵,這個 key 從 0 開始,然后以 1 進行遞增

要用 array() 創(chuàng)建一個關(guān)聯(lián)數(shù)組,可使用 => 來分隔鍵和值

要創(chuàng)建一個空數(shù)組,則不傳遞參數(shù)給 array():
$new = array();
關(guān)聯(lián)數(shù)組舉例:

<?php $age=array("Bill"=>"1","Steve"=>"2","Mark"=>"3"); echo "Bill is " . $age['Bill'] . " years old."; ?> /*結(jié)果: Bill is 1 years old. */

str_replace(find,replace,string,count) :以其他字符替換字符串中的一些字符(區(qū)分大小寫)
find 必需。規(guī)定要查找的值
replace 必需。規(guī)定替換 find 中的值的值
string 必需。規(guī)定被搜索的字符串
count 可選。對替換數(shù)進行計數(shù)的變量

該函數(shù)必須遵循下列規(guī)則:
如果搜索的字符串是數(shù)組,那么它將返回數(shù)組
如果搜索的字符串是數(shù)組,那么它將對數(shù)組中的每個元素進行查找和替換
如果同時需要對數(shù)組進行查找和替換,并且需要執(zhí)行替換的元素少于查找到的元素的數(shù)量,那么多余元素將用空字符串進行替換
如果查找的是數(shù)組,而替換的是字符串,那么替代字符串將對所有查找到的值起作用
注釋:該函數(shù)區(qū)分大小寫。請使用 str_ireplace() 函數(shù)執(zhí)行不區(qū)分大小寫的搜索
注釋:該函數(shù)是二進制安全的
舉例:

<?php echo str_replace("world","Shanghai","Hello world!"); ?> /*結(jié)果: Hello Shanghai! */

array_keys(array,value,strict) :返回包含數(shù)組中所有鍵名的一個新數(shù)組
array 必需。規(guī)定數(shù)組
value 可選。您可以指定鍵值,然后只有該鍵值對應(yīng)的鍵名會被返回

strict 可選。與 value 參數(shù)一起使用。可能的值:
true - 返回帶有指定鍵值的鍵名。依賴類型,數(shù)字 5 與字符串 “5” 是不同的
false - 默認(rèn)值。不依賴類型,數(shù)字 5 與字符串 “5” 是相同的

如果提供了第二個參數(shù),則只返回鍵值為該值的鍵名
如果 strict 參數(shù)指定為 true,則 PHP 會使用全等比較 (===) 來嚴(yán)格檢查鍵值的數(shù)據(jù)類型
舉例:

<?php $a=array("x"=>"A","y"=>"B","z"=>"C"); print_r(array_keys($a)); ?> /*結(jié)果: Array ( [0] => x [1] => y [2] => z ) */

過濾核心代碼理解:

array_keys( $substitutions )Array ( [0] => && [1] => ; ) ,也就是arry(&& , ;) $substitutions$substitutions = array( '&&' => '', ';' => '', )&&;是鍵,''為鍵值,轉(zhuǎn)換一下也就是array( [0] => '', [1] => '', ),再轉(zhuǎn)化一下就是arry('','') 假設(shè)$target=127.0.0.1 && ipconfig解釋1$target = str_replace( arry(&& , ;), arry( '&&' => '', ';' => '', ), "127.0.0.1 && ipconfig" );搜索"127.0.0.1 && ipconfig"中的&&; 替換成數(shù)組arry( '&&' => '', ';' => '', )&&;對應(yīng)的值 那么str_replace()函數(shù)會將$target中的&&;替換為''解釋2$target = str_replace( arry(&& , ;), arry('',''), "127.0.0.1 && ipconfig" );搜索"127.0.0.1 && ipconfig"中的&&; 替換成''注:這里的解釋1和解釋2只是為了幫助理解

因此,從Medium的源代碼可以看出,它在Low代碼層面上增加了對上傳參數(shù)的過濾,將上傳參數(shù)的&&和;轉(zhuǎn)化為空,但是它僅僅只能過濾&&和;,我們可以使用&繼續(xù)進行命令執(zhí)行

滲透測試:


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 -n 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?>

High的代碼也就是在Medium的代碼上面進行了一次升級,增加了過濾的黑名單,但是,我們仔細(xì)看源代碼會發(fā)現(xiàn),本來可以過濾一個|,就可以過濾所有|、||、|||等等,可是你仔細(xì)觀察一下,會發(fā)現(xiàn)過濾的|后面有一個空格,也就表示,它過濾的是|空格,并沒有過濾|,所以我們可以利用|進行繞過

滲透測試:

繞過方法一:

看了上面一幅圖,大家也許就會有疑惑了,明明源代碼里有過濾||,為什么還能執(zhí)行呢?
我們仔細(xì)看一下它的黑名單:

從上面可以看出,它確實有過濾||,但是,你注意到了順序嗎!!它是由上到下依次查找轉(zhuǎn)義,它首先轉(zhuǎn)義|空格
所以127.0.0.1 || ipconfig經(jīng)過過濾后就是127.0.0.1 |ipconfig,這里的|是原命令語句(127.0.0.1 || ipconfig)左邊的,因此,最后的執(zhí)行命令便成了127.0.0.1 |ipconfig

如果我們把黑名單過濾的順序修改一下會怎樣呢?如下圖:

執(zhí)行結(jié)果:

此時我們會發(fā)現(xiàn)無法執(zhí)行,因為它首先過濾了||

繞過方法二:


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 -n 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(separator,string,limit) :把字符串打散為數(shù)組

參數(shù)描述
separator必需。規(guī)定在哪里分割字符串
string必需。要分割的字符串
limit可選。規(guī)定所返回的數(shù)組元素的數(shù)目。可能的值:(1)大于 0 - 返回包含最多 limit 個元素的數(shù)組;(2)小于 0 - 返回包含除了最后的 -limit 個元素以外的所有元素的數(shù)組;(3)0 - 返回包含一個元素的數(shù)組

舉例:

<?php $str = "Hello world. I love Shanghai!"; print_r (explode(" ",$str)); ?> /*結(jié)果 Array ( [0] => Hello [1] => world. [2] => I [3] => love [4] => Shanghai! ) */

is_numeric($var) :用于檢測變量是否為數(shù)字或數(shù)字字符串
$var要檢測的變量
如果指定的變量是數(shù)字和數(shù)字字符串則返回TRUE,否則返回FALSE

sizeof(array,mode) :計算數(shù)組中的單元數(shù)目或?qū)ο笾械膶傩詡€數(shù)
array 必需。規(guī)定數(shù)組
mode 可選。規(guī)定模式。可能的值:
0 - 默認(rèn)。不計數(shù)多維數(shù)組中的所有元素
1 - 遞歸地計數(shù)數(shù)組中元素的數(shù)目(計算多維數(shù)組中的所有元素)

當(dāng)變量未被設(shè)置,或是變量包含一個空的數(shù)組,該函數(shù)會返回 0。可使用 isset() 變量來測試變量是否被設(shè)置
舉例:

<?php $cars=array("Volvo","BMW","Toyota"); echo sizeof($cars); ?> /*結(jié)果 3 */

Impossible級別的代碼加入了Anti-CSRF token,并對提交的參數(shù)進行嚴(yán)格的過濾,不僅過濾了反斜杠;也使用is_numeric檢測變量是否為數(shù)字字符串或數(shù)字,使得非數(shù)字字符串或數(shù)字的全部“封殺”,從而達到阻止危險的命令執(zhí)行

注:這所有源代碼中的的ping -c 4 ip現(xiàn)在已經(jīng)不適用了,現(xiàn)在windows的版本應(yīng)該是ping - n 4 ip了,我都已經(jīng)在源代碼中修改了

總結(jié)

以上是生活随笔為你收集整理的DVWA--Command Injection(命令执行)--四个等级的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。