1. 程式人生 > >防止XXE注入攻擊

防止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資料裡禁止引用外部實體。


文中涉及到的程式碼和技術細節,只限用於技術交流,切勿用於非法用途。歡迎探討交流,行文倉促,不足之處,敬請不吝批評指正。


【參考】