XXE漏洞原理、演示與防御


目錄:

  • 前言
  • 漏洞原理
  • Demo演示
  • 如何發現XXE漏洞
  • XXE其他危害
  • 案例-微信支付的XXE
  • 修復建議

 

前言

什么是XXE漏洞? 

XXE全稱是——XML External Entity

簡單來說,XXE就是XML外部實體注入。當應用程序允許引用外部實體時,通過構造惡意內容,就可以導致任意文件讀取、系統命令執行、內網端口探測、攻擊內網網站等危害。

什么是XML,如需詳細了解,可參考XML菜鳥教程

一、漏洞原理

1、DTD

文檔類型定義(DTD)可定義合法的XML文檔構建模塊。它使用一系列合法的元素來定義文檔的結構。DTD 可被成行地聲明於 XML 文檔中,也可作為一個外部引用。

什么是DTD,如需詳細了解,可參考DTD菜鳥教程

1.1、內部的 DOCTYPE 聲明:

<!DOCTYPE 根元素 [元素聲明]>

 

1.2、外部的 DOCTYPE 聲明:

<!DOCTYPE 根元素 SYSTEM "文件名">

 

這是包含 DTD 的 "note.dtd" 文件

 

 1.3、DTD實體

 實體是用於定義引用普通文本或特殊字符的快捷方式的變量。

  • 實體引用是對實體的引用。

  • 實體可在內部或外部進行聲明。

DTD內部實體聲明:

<!ENTITY 實體名稱 "實體的值">

 

DTD外部實體聲明:

<!ENTITY 實體名稱 SYSTEM "URI/URL">

 

 

2、XML外部實體

XML,可拓展的標記語言,(eXtensible Markup Language),用於傳輸和存儲數據。

XML文檔實例:

 

XML“外部實體”實例:

 

可以在DOCTYPE頭部標簽中通過SYSTEM關鍵字定義“實體”,這些“實體”可以訪問本地或遠程的內容。SYSTEM告訴XML解釋器,從URI中讀取實體的內容。攻擊者可以通過實體將自定義的值發送給應用程序,然后讓應用程序去呈現,比如上面就是把實體定義為passwd文件,讓XML解釋器去讀取文件。

二、Demo 演示

2.1、新建一個外部實體的XML文檔,讀取本地的某個文件。

<?xml version="1.0"?>
<!DOCTYPE note [
        <!ENTITY myentity  SYSTEM  "file:///C:/XXE.txt">
        ]>
<note>
    <to>Tove</to>
    <from>&myentity;</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend</body>
</note>

2.2、創建DOM解釋器解析上面的XML文件

package Eleven;


import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;

public class Test  {
    public static void main(String[] args) throws Exception{
        /**
         *創建DOM解釋器解析XML文件
         */
        // 把要解析的 XML 文檔轉化為輸入流,以便 DOM 解析器解析它
        InputStream is = new FileInputStream("D:\\2-code\\Eleven\\src\\main\\resources\\templates\\note2.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //創建DOM模式的解析器工廠
        DocumentBuilder builder = factory.newDocumentBuilder();  //調用工廠的方法得到DOM解析器對象
        Document doc = builder.parse(is);//調用 DOM 解析器對象的 parse() 方法解析 XML 文檔,得到代表整個文檔的 Document 對象
        NodeList nodeList = doc.getElementsByTagName("from");//根據元素名稱獲取元素值
        System.out.println(nodeList.item(0).getTextContent());
    }

}

2.3、執行后的結果

 

 三、如何發現XXE漏洞

3.1、尋找XML輸入點

比如Content-Type:text/xml, post的數據包含XML格式,如:

<forgot><username>admin</username></forgot>

請求頭中添加Content-Type:text/xml,或Content-type:application/xml

同時,POST中添加payload

 

3.2 通過關鍵字,在代碼中查找XML解釋器,確認解釋器是否針對此漏洞做了安全限制(禁用外部實體、過濾關鍵字等)

關鍵字:DocumentBuilderFactory等

四、XXE其他危害

4.1、任意文件讀取(如上)

 

通過提交自動以URI,可以讀取任意文件(本地或遠程)。

還可以通過DTD文檔引入外部DTD文檔,再引入外部實體聲明,如下:

 

以上輸入有回顯的情況,/etc/passwd可以直接被顯示出來,無回顯的情況,需要把文件外發至遠程服務器,具體如下:

 

 

4.2、拒絕服務攻擊

原理為:構造惡意的XML實體文件耗盡可用內存,因為許多XML解析器在解析XML文檔時傾向於將它的整個結構保留在內存中,解析非常慢,造成了拒絕服務器攻擊。

 

 

4.3、測試后端服務器的開放端口

 

通過返回的“Connection refused”可以知道該81端口是closed的,而80端口是open的。

4.4、后端WEB漏洞如果可以通過URL加以利用,可造成WEB漏洞攻擊

 

4.5、命令執行

 

PHP要開啟PECL上的Expect擴展。

五、案例-微信支付的XXE

漏洞描述:

微信支付提供了一個 api 接口,供商家接收異步支付結果,微信支付所用的java sdk在處理結果時可能觸發一個XXE漏洞,攻擊者可以向這個接口發送構造惡意payloads,獲取商家服務器上的任何信息,一旦攻擊者獲得了敏感的數據 (md5-key and merchant-Id etc.),他可能通過發送偽造的信息不用花錢就購買商家任意物品

如圖所示:

 

上述類中實現了xmltoMap和maptoXml這兩個方法,而這次的微信支付的xxe漏洞爆發點就在xmltoMap方法中,當構建了 documentBuilder 以后就直接對傳進來的 strXML 解析了,而不巧的是 strXML 是一處攻擊者可控的參數,於是就出現了 XXE 漏洞。

六、修復建議

1、配置XML處理器使用禁用DTD、禁止外部實體解析

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);  
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

2、通過黑名單過濾用戶提交的XML數據

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

 


免責聲明!

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



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