來自外部的威脅 - XXE漏洞攻擊成因
於去年底公布的 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> 讓瀏覽器能正確顯示內容,如下圖:
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 格式傳遞資料:
那也許可以嘗試將 body 做出以下變化:
自己額外宣告一個實體 xxe,目的是輸出本機資料夾中的密碼檔,並將原本丟出暱稱的位置更改成實體名稱,沒有禁止解析外部實體的狀況下就會獲得:
以上是一個最基本的 XXE Injection 範例。
然而,一個 XXE 風險,並不只有造成 Local File Inclusion 一個危害,讓我們來修改一下 payload:
這樣就成功的使伺服器訪問指定的外部網站,表示也可以造成RCE (Remote Code Execute)。
同理,也可使伺服器訪問外網無法訪問的內部系統,便可達成 SSRF (Server-Side Request Forgery, 服務請求偽造)。
還有個利用 XXE 達成的攻擊手法 - Billion Laugh Attack,其 payload 如下:
由伺服器的 CPU 得知,它造成的結果就是有名的 DoS (Denial-of-service)啦!
結論
由上述可見,XXE Injection 並不是一個結果,可以說它是一個成因,因為網站含有 XXE 風險,會造成如洩漏敏感資訊、RCE、SSRF、DoS 等結果。
預防 XXE 其實並不難,完整的禁止使用外部實體,parser 就不會處理攻擊者自行宣告之 entity,即可防止 XXE Injection 的發生。以 PHP 為例,在程式碼中加入 libxml_disable_entity_loader(true); 即可防止 parser 處理外部實體。