XXE從入門到放棄

Gcow安全團隊發表於2020-01-17

 

XXE從入門到放棄


一、認識XML和XXE


XXE全稱XML External Entity Injection,也就是XML外部實體注入攻擊,是對非安全的外部實體資料進行處理時引發的安全問題。要想搞懂XXE,肯定要先了解XML語法規則和外部實體的定義及呼叫形式。

XML基礎知識

XML用於標記電子檔案使其具有結構性的標記語言,可以用來標記資料、定義資料型別,是一種允許使用者對自己的標記語言進行定義的源語言。XML文件結構包括XML宣告、DTD文件型別定義(可選)、文件元素。

XML語法規則如下:

1. 所有的XML元素都必須有一個關閉標籤

2. XML標籤對大小寫敏感

3. XML必須正確巢狀

4. XML屬性值必須加引號””

5. 實體引用 (在標籤屬性,以及對應的位置值可能會出現<>符號,但是這些符號在對應的XML中都是有特殊含義的,這時候我們必須使用對應html的實體對應的表示,比如<傅好對應的實體就是lt,>符號對應的實體就是gt)

6. 在XML中,空格會被保留 (案例如:<p>a空格B</p>,這時候a和B之間的空格就會被保留)

XXE從入門到放棄XXE從入門到放棄

XML元素介紹

XML元素是指從(且包括)開始標籤直到(且包括)結束標籤的部分。

每個元素又有可以有對應的屬性。XML屬性必須加引號。

XXE從入門到放棄
 

注意:

(1) XML文件必須有一個根元素

(2) XML元素都必須有一個關閉標籤

(3) XML標籤對大小寫敏感

(4) XML元素必須被正確的巢狀

(5) XML屬性值必須加引號

XML DTD介紹

DTD文件型別定義,約束了xml文件的結構。擁有正確語法的XML被稱為“形式良好”的XML,透過DTD驗證約束XML是“合法”的XML。

XXE從入門到放棄XXE從入門到放棄

XXE從入門到放棄
 

DTD是什麼?

XML 文件有自己的一個格式規範,這個格式規範是由一個叫做 DTD文件型別定義(document type definition) 的東西控制的。

DTD用來描述xml文件的結構,一個DTD文件包含:  

元素的定義規則;元素之間的關係規則;屬性的定義規則。

DTD 可被成行地宣告於 XML 文件中,也可作為一個外部引用。

他就是長得下面這個樣子:

內部的 DOCTYPE 宣告

內部宣告DTD型別

內部宣告DTD型別宣告:<!DOCTYPE 根元素[子  元素宣告]>

XXE從入門到放棄

引用外部實體:

我們主要關注XML外部實體的定義和呼叫方式:

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

XXE從入門到放棄

 

DTD資料型別

PCDA他的意思是被解析的字元資料/

PCDA他的意思是被解析的字元資料,PCDATA是會被解析器解析的文字

CDA他的意思是字元資料

CDATA是不會被解析器解析的文字,在這些文字中的標籤不會被當作標記來對待,其中的實體也不會被展開。

DTD實體介紹

(實體定義)

實體是用於定義引用普通文字或者特殊字元的快捷方式的變數

    在DTD中的實體型別,一般分為:內部實體和外部實體,細分又分為一般實體和引數實體。除外部引數實體引用以字元(%)開始外,其它實體都以字元(&)開始,以字元(;)結束。

內部實體:

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

 XXE從入門到放棄
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

 外部實體:

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

XXE從入門到放棄

外部引數實體:

<!ENTITY % 實體名 "實體內容”>

XXE從入門到放棄


XML注入產生的原理

XXE漏洞全稱XML External Entity Injection即xml外部實體注入漏洞,XXE漏洞發生在應用程式解析XML輸入時,沒有禁止外部實體的載入,導致可載入惡意外部檔案,造成檔案讀取、命令執行、內網埠掃描、攻擊內網網站、發起dos攻擊等危害。xxe漏洞觸發的點往往是可以上傳xml檔案的位置,沒有對上傳的xml檔案進行過濾,導致可上傳惡意xml檔案。

xxe漏洞觸發的點往往是可以上傳XML檔案約位置,沒有對上傳的XML檔案進行過濾,導致可以上傳惡意的XML檔案。

怎麼判斷網站是否存在XXE漏洞

最直接的方法就是用burp抓包,然後,修改HTTP請求方法,修改Content-Type頭部欄位等等,檢視返回包的響應,看看應用程式是否解析了傳送的內容,一旦解析了,那麼有可能XXE攻擊漏洞,接下來,來看一個小小的展示:

這個是測試xxe的測試點:http://169.254.4.52/bWAPP/xxe-1.php

我們點選下面的Any bugs然後用burp抓包

XXE從入門到放棄
 

XXE從入門到放棄
 

我們隨便輸入下

XXE從入門到放棄
 

從上面我們可以看到,web應用正在解析xml的內容,接受使用者特定或者自定義的輸入,然後呈現給使用者。為了驗證,我們可以構造如下的輸入:

XXE從入門到放棄

可以看到應用程式確實是直接解析了xml,那麼如果xml文件中有一個引數是用來呼叫遠端伺服器的內容?這個引數是可控的,我們可以做什麼?

XXE漏洞-檔案讀取

PHP中測試POC

File:///path/to/file.ext

http://url/file.ext

PHP://filter/read=convert.base64-encode/resource=/home/bee/test.php

讀取文件

有回顯的xxe利用

Payload:

XXE從入門到放棄

XXE從入門到放棄
 

讀取php檔案

直接讀取php檔案會報錯,因為php檔案裡面有<>//等特殊字元,xml解析時候會當成xml語法來解析。這時候就分不清處哪個是真正的xml語句了,

直接利用file協議讀取PHP檔案,就會產生報錯。那麼需要base64編碼來讀取,

Payload:

XXE從入門到放棄XXE從入門到放棄

XXE從入門到放棄
 

進行解密後得到對應內容

XXE從入門到放棄
 

本地測試無回顯注入讀取檔案

 但是,在實際情況中,大多數情況下伺服器上的 XML 並不是輸出用的,所以就少了輸出這一環節,這樣的話,即使漏洞存在,我們的payload的也被解析了,但是由於沒有輸出,我們也不知道解析得到的內容是什麼,因此我們想要現實中利用這個漏洞就必須找到一個不依靠其回顯的方法——外帶資料

      先看一下漏洞示例:

XXE從入門到放棄

相較於前面有回顯的漏洞程式碼,我們去掉了內容輸出的一部分。這樣,用之前的payload就沒有作用了:

XXE從入門到放棄

Payload的構造:

      有了前面使用外部DTD檔案來拼接內部DTD的引數實體的經驗,我們可以知道,透過外部DTD的方式可以將內部引數實體的內容與外部DTD宣告的實體的內容拼接起來,那麼我們就可以有這樣的設想:

(1) 客戶端傳送payload 1給web伺服器

(2) web伺服器向vps獲取惡意DTD,並執行檔案讀取payload2

(3) web伺服器帶著回顯結果訪問VPS上特定的FTP或者HTTP

(4) 透過VPS獲得回顯(nc監聽埠)

      首先,我們使用ncat監聽一個埠:

XXE從入門到放棄

也可以用python建立一個建議的http服務。

python -m SimpleHTTPServer 埠

  然後,我們構造payload:

      我們選擇使用外部DTD,在我們自己所能掌控(或是自己搭建)的主機上編寫一個dtd檔案:

XXE從入門到放棄


我們注意到,第一個引數實體的宣告中使用到了php的base64編碼,這樣是為了儘量避免由於檔案內容的特殊性,產生xml解析器錯誤。

      Payload如下:

XXE從入門到放棄


    如圖,我們先宣告一個外部的DTD引用,然後再xml文件內容中引用外部DTD中的一般實體。

      開始攻擊:

XXE從入門到放棄

  然後檢視我們的埠監聽情況,會發現我們收到了一個連線請求,問號後面的內容就是我們讀取到的檔案內容經過編碼後的字串:

 Ps:

      有時候也會出現報錯的情況(這是我們在漏洞的程式碼中沒有遮蔽錯誤和警告),比如我們這裡的payload沒有選用php的base64編碼,這裡報錯了,但是同時也將所讀取的內容爆了出來,只是特殊字元經過了HTML實體編碼。

XXE從入門到放棄

內網探測

xxe 由於可以訪問外部 url,也就有類似 ssrf 的攻擊效果,同樣的,也可以利用 xxe 來進行內網探測。

可以先透過 file 協議讀取一些配置檔案來判斷內網的配置以及規模,以便於編寫指令碼來探測內網。

一個 python 指令碼例項:

XXE從入門到放棄XXE從入門到放棄

執行起來大概是這樣

XXE從入門到放棄
 

DDOS攻擊

XXE從入門到放棄XXE從入門到放棄

該攻擊透過建立一項遞迴的 XML 定義,在記憶體中生成十億個”abc”字串,從而導致 DDoS 攻擊。原理為:構造惡意的XML實體檔案耗盡可用記憶體,因為許多XML解析器在解析XML文件時傾向於將它的整個結構保留在記憶體中,解析非常慢,造成了拒絕伺服器攻擊。

影響:

此漏洞非常危險, 因為此漏洞會造成伺服器上敏感資料的洩露,和潛在的伺服器拒絕服務攻擊。

防禦方法:

1. 禁用外部實體

2. 過濾和驗證使用者提交的XML資料

3. 不允許XML中含有任何自己宣告的DTD

4. 有效的措施:配置XML parser只能使用靜態DTD,禁止外來引入;對於Java來說,直接設定相應的屬性值為false即可

參考文章如下:

https://www.cnblogs.com/backlion/p/9302528.html

https://www.freebuf.com/vuls/175451.htmls

https://mp.weixin.qq.com/s/VWofHp5lJLYnbw01copnkw

https://www.freebuf.com/articles/web/97833.html

https://www.freebuf.com/articles/web/86007.html

相關文章