go top

來自外部的威脅 - XXE漏洞攻擊成因

技術文章 | 2018/06/15

於去年底公布的 OWASP 2017 Top 10 中,新加入的重大風險分別是:XML 外部實體注入的風險、不安全的反序列化及不充分的記錄及監控。上次的專欄介紹的是不安全的反序列化,這次我們針對 XML 外部實體注入做介紹。以下會先簡單介紹什麼是 XML,接著帶入 XXE 的成因,並以簡單的範例展現它會造成的危害。


What is XML

XXE Injection 的全名是 XML External Entity Injection,因此,在介紹 XXE 之前,先來簡單介紹一下什麼是 XML 和它的用途。

XML 是一個純文件型態的檔案格式,目的就是將 data 以簡單的格式儲存,方便 data 在不同平台間傳遞、儲存、共享等。

XML 檔案有兩個特徵:DTD 及 XML Schema,在此特別介紹所謂的 DTD,Document Type Definition,文件類型定義,用來宣告網頁的文件類型。舉例來說,HTML 有很多版本,如:HTML, HTML2.0, ... , XHTML, XHTML5 等,利用 <!DOCTYPE> 讓瀏覽器能正確顯示內容,如下圖:


 說明 XML 文件基本結構與 DTD(文件類型定義)的關係。圖中展示了如何透過 <!DOCTYPE> 宣告元素與實體(Entity),這是理解 XXE 注入攻擊如何利用外部實體定義來操縱 XML 解析器的基礎觀念。XML 基礎, DTD 宣告, XML 實體, 網頁開發安全, 雲力橘子技術專欄


DTD 還可以宣告以下四種:元素 (Elements)、屬性 (Attribute)、實體 (Entities)及註解 (Comments) 。其中的實體 (Entities)就是 XML External Entity Injection 中的 Entity,接下來就開始介紹 XXE Injection 吧。


What is XXE Injection

XXE Injection,全名 XML eXternal Entity Injection,XML 外部實體注入。會發生 XXE 主要是因為 parser 沒有禁止使用外部實體,意思是我們可以自行定義一個實體名稱,並在實體內容中定義要伺服器做的行為,因此注入點通常是可以輸入 XML 的位置。

假設一個簡單網站頁面,要求輸入一個暱稱,輸入後發現他是以 XML 格式傳遞資料:


 展示 XXE 注入攻擊流程。攻擊者在 XML 資料中注入惡意實體 SYSTEM 指令,誘使伺服器解析器讀取伺服器內部的敏感檔案(如 /etc/passwd),並將內容回傳給攻擊者,造成本地檔案包含(LFI)漏洞。XXE 攻擊原理, XML 外部實體注入, LFI 漏洞, 資訊安全威脅, 伺服器安全

那也許可以嘗試將 body 做出以下變化:

 XML 外部實體注入的惡意代碼(Payload)範例。透過自定義實體名稱並指向外部資源路徑,測試伺服器是否具有防禦機制。若解析器未禁止外部實體,將導致機密資料外洩或伺服器端請求偽造(SSRF)。XXE Payload, 滲透測試實務, 弱點掃描, 網站安全檢測, 雲力橘子資安服務

自己額外宣告一個實體 xxe,目的是輸出本機資料夾中的密碼檔,並將原本丟出暱稱的位置更改成實體名稱,沒有禁止解析外部實體的狀況下就會獲得:

防範 XXE 注入的安全設定建議,包括在程式碼中停用 XML 解析器的外部實體(External Entities)與參數實體(Parameter Entities)處理功能,是開發者落實資安合規與源碼安全的重要步驟。XXE 防禦, 停用 DTD, 安全開發週期, 源碼檢測, 資安合規

以上是一個最基本的 XXE Injection 範例。

然而,一個 XXE 風險,並不只有造成 Local File Inclusion 一個危害,讓我們來修改一下 payload:

說明 XML 文件基本結構與 DTD(文件類型定義)的關係。圖中展示了如何透過 <!DOCTYPE> 宣告元素與實體(Entity),這是理解 XXE 注入攻擊如何利用外部實體定義來操縱 XML 解析器的基礎觀念。XML 基礎, DTD 宣告, XML 實體, 網頁開發安全, 雲力橘子技術專欄

這樣就成功的使伺服器訪問指定的外部網站,表示也可以造成RCE (Remote Code Execute)。

同理,也可使伺服器訪問外網無法訪問的內部系統,便可達成 SSRF (Server-Side Request Forgery, 服務請求偽造)。

還有個利用 XXE 達成的攻擊手法 - Billion Laugh Attack,其 payload 如下:

展示 XXE 注入攻擊流程。攻擊者在 XML 資料中注入惡意實體 SYSTEM 指令,誘使伺服器解析器讀取伺服器內部的敏感檔案(如 /etc/passwd),並將內容回傳給攻擊者,造成本地檔案包含(LFI)漏洞。XXE 攻擊原理, XML 外部實體注入, LFI 漏洞, 資訊安全威脅, 伺服器安全

由伺服器的 CPU 得知,它造成的結果就是有名的 DoS (Denial-of-service)啦!

XML 外部實體注入的惡意代碼(Payload)範例。透過自定義實體名稱並指向外部資源路徑,測試伺服器是否具有防禦機制。若解析器未禁止外部實體,將導致機密資料外洩或伺服器端請求偽造(SSRF)。XXE Payload, 滲透測試實務, 弱點掃描, 網站安全檢測, 雲力橘子資安服務


結論

由上述可見,XXE Injection 並不是一個結果,可以說它是一個成因,因為網站含有 XXE 風險,會造成如洩漏敏感資訊、RCE、SSRF、DoS 等結果。

預防 XXE 其實並不難,完整的禁止使用外部實體,parser 就不會處理攻擊者自行宣告之 entity,即可防止 XXE Injection 的發生。以 PHP 為例,在程式碼中加入  libxml_disable_entity_loader(true);  即可防止 parser 處理外部實體。