XXE攻防

一、XML基礎知識


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

 

 

DTD(文檔類型定義)的作用是定義 XML 文檔的合法構建模塊。DTD 可以在 XML 文檔內聲明,也可以外部引用。


內部聲明DTD


<!DOCTYPE 根元素 [元素聲明]>


引用外部DTD


<!DOCTYPE 根元素 SYSTEM "文件名">


或者


<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">

 
 

DTD實體是用於定義引用普通文本或特殊字符的快捷方式的變量,可以內部聲明或外部引用。


內部聲明實體


<!ENTITY 實體名稱 "實體的值">


引用外部實體


<!ENTITY 實體名稱 SYSTEM "URI">


或者


<!ENTITY 實體名稱 PUBLIC "public_ID" "URI">

 

二、XML外部實體注入(XML External Entity)


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

 

引入外部實體方式有多種,比如:


惡意引入外部實體方式1:

XML內容:
 

 

 

惡意引入外部實體方式2:

XML內容:
 

 

DTD文件(evil.dtd)內容:
 

 

惡意引入外部實體方式3:

XML內容:
 

 

DTD文件(evil.dtd)內容:
 

 

另外,不同程序支持的協議不一樣,
 

 

上圖是默認支持協議,還可以支持其他,如PHP支持的擴展協議有
 


 

 

以下舉例說明XXE危害,當然XXE不止這些危害。
 

XXE危害1:讀取任意文件
 


 

 


 

 

該CASE是讀取/etc/passwd,有些XML解析庫支持列目錄,攻擊者通過列目錄、讀文件,獲取帳號密碼後進一步攻擊,如讀取tomcat-users.xml得到帳號密碼後登錄tomcat的manager部署webshell。
 

另外,數據不回顯就沒有問題了嗎?如下圖,
 



 

不,可以把數據發送到遠程服務器,
 



 

遠程evil.dtd文件內容如下:
 


 


觸發XXE攻擊後,服務器會把文件內容發送到攻擊者網站
 


 


 

 

XXE危害2:執行系統命令
 


 

 


 


該CASE是在安裝expect擴展的PHP環境裏執行系統命令,其他協議也有可能可以執行系統命令。

 

XXE危害3:探測內網端口
 


 

 


 


該CASE是探測192.168.1.1的80、81端口,通過返回的「Connection refused」可以知道該81端口是closed的,而80端口是open的。

 

XXE危害4:攻擊內網網站
 


 

 


 

該CASE是攻擊內網struts2網站,遠程執行系統命令。

 

三、客戶端XXE案例


日前,某office文檔轉換軟件被爆存在XXE漏洞(PS:感謝TSRC平臺白帽子Titans`報告漏洞),某一應用場景爲:Web程序調用該office軟件來獲取office文檔內容後提供在線預覽。由於該軟件在處理office文檔時,讀取xml文件且允許引用外部實體,當用戶上傳惡意文檔並預覽時觸發XXE攻擊。詳情如下:


新建一個正常文檔,內容爲Hi TSRC,
 


 

使用該軟件轉換後可以得到文本格式的文檔內容,
 


 


 

當往該docx的xml文件注入惡意代碼(引用外部實體)時,可進行XXE攻擊。
 


 


 

 

 

四、防禦XXE攻擊


方案一、使用開發語言提供的禁用外部實體的方法


PHP:

libxml_disable_entity_loader(true);


JAVA:

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

dbf.setExpandEntityReferences(false);


Python:

from lxml import etree

xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

 

方案二、過濾用戶提交的XML數據

      
關鍵詞:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。

 


【最後】


無論是WEB程序,還是PC程序,只要處理用戶可控的XML都可能存在危害極大的XXE漏洞,開發人員在處理XML時需謹慎,在用戶可控的XML數據裏禁止引用外部實體。

 

 

附:

 

 
  1. To crash the server / Cause denial of service:

  2.  
  3. <?xml version="1.0"?>

  4. <!DOCTYPE lolz [

  5. <!ENTITY lol "lol">

  6. <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">

  7. <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">

  8. <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">

  9. <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">

  10. <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">

  11. <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">

  12. <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">

  13. <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">

  14. ]>

  15. <lolz>&lol9;</lolz>


上述代碼就是著名的’billion laughs’(https://en.wikipedia.org/wiki/Billion_laughs)攻擊,該攻擊通過創建一項遞歸的 XML 定義,在內存中生成十億個」Ha!」字符串,從而導致 DDoS 攻擊。原理爲:構造惡意的XML實體文件耗盡可用內存,因爲許多XML解析器在解析XML文檔時傾向於將它的整個結構保留在內存中,解析非常慢,造成了拒絕服務器攻擊。

 

 

原文轉載自:https://security.tencent.com/index.php/blog/msg/69

附加部分轉載自:http://www.freebuf.com/articles/web/126788.html