淺談ASP.NET的Padding Oracle攻擊
網(wǎng)絡(luò)犯罪和黑客攻擊已經(jīng)越來越受到人們的重視。之前,我們在《2010年揚(yáng)名的十大WEB黑客技術(shù)》一文中了解到:2010年,排名第一的是在線網(wǎng)上銀行交易威脅,而其中黑客所鐘愛的攻擊技術(shù)便是Padding Oracle,這也是在過去一年中最為流行的黑客攻擊技術(shù)。那么下面,我們就引用一位網(wǎng)友的博客內(nèi)容,了解一下ASP.NET和Padding Oracle Attack相關(guān)內(nèi)容。
什么是Padding和Oracle
要談這個問題,先要了解什么是Padding Oracle Attack。有些文章把Padding和Oracle,與CSS樣式表或是那個收購了Sun的甲骨文公司聯(lián)系起來,這就驢唇不對馬嘴了。
Padding在這里的含義是“填充”,因?yàn)閷τ诩用芩惴▉碚f,它們是基于等長的“數(shù)據(jù)塊”進(jìn)行操作的(如對于RC2,DES或TripleDES算法來說這個長度是8字節(jié),而對于Rijndael算法來說則是16、24或32字節(jié))。但是,我們的輸入數(shù)據(jù)長度是不規(guī)則的,因此必然需要進(jìn)行“填充”才能形成完整的“塊”。“填充”時比較常用的是PKCS #5規(guī)則,簡單地說,便是根據(jù)最后一個數(shù)據(jù)塊所缺少的長度來選擇填充的內(nèi)容。
例如,數(shù)據(jù)塊長度要求是8字節(jié),如果輸入的最后一個數(shù)據(jù)塊只有5個字節(jié)的數(shù)據(jù),那么則在最后補(bǔ)充三個字節(jié)的0x3。如果輸入的最后一個數(shù)據(jù)塊正好為8字節(jié)長,則在最后補(bǔ)充一個完整的長為8字節(jié)的數(shù)據(jù)塊,每個字節(jié)填0x8。使用這個規(guī)則,我們便可以根據(jù)填充的內(nèi)容來得知填充的長度,以便在解密后去除填充的字節(jié)。
在解密時,如果算法發(fā)現(xiàn)解密后得到的結(jié)果,它的填充方式不符合規(guī)則,那么表示輸入數(shù)據(jù)有問題,對于解密的類庫來說,往往便會拋出一個異常,提示Padding不正確。Oracle在這里便是“提示”的意思,和甲骨文公司沒有任何關(guān)系。
如何進(jìn)行Padding Oracle Attack
剛才已經(jīng)提到,如果輸入的密文不合法,類庫則會拋出異常,這便是一種提示。攻擊者可以不斷地提供密文,讓解密程序給出提示,不斷修正,最終得到的所需要的結(jié)果。這里的一個關(guān)鍵在于,攻擊者所需要的提示僅僅是“解密成功與否”這樣一個二元信息,例如它在一個Web程序中可能只是“200 - OK”及“500 - Internal Server Error”這樣的表現(xiàn)形式,而不需要其他任何詳細(xì)信息。
例如,現(xiàn)代流行的Web框架大都是開源的,因此它的加密方式完全透明(當(dāng)然這點(diǎn)其實(shí)并不是必須的,只是大有幫助而已),對于攻擊者來說唯一不知道的便是密鑰。于是攻擊者便可以根據(jù)這個加密方式設(shè)計(jì)有針對性的密文,最終得到密鑰(及IV等信息)。在很多時候,一個網(wǎng)站都會使用同樣的密鑰和IV,于是只需從一個漏洞,便可以在網(wǎng)站的其他方面進(jìn)行破壞,或解密信息,或繞開驗(yàn)證。
在具體操作上還可以有許多方式進(jìn)行輔助,在Juliano Rizzo和Thai Duong的《Practical Padding Oracle Attacks》(及此)論文(下文稱PPOA)中便提到了很多方式,例如使用Google搜索異常的關(guān)鍵字(這說明許多站點(diǎn)都把異常信息輸出在頁面上),檢查代碼,從外表檢查一些BASE64形式的字符串,猜測常見的分割符,如“--”,“|”或是“:”等等。PPOA認(rèn)為,如今Padding Oracle漏洞與SQL注入,腳本注入等漏洞一樣無處不在,論文中還詳細(xì)討論了利用這個漏洞來攻擊eBay拉丁美洲站點(diǎn),CAPTCHA等應(yīng)用,以及在JSF(包括Apache MyFaces和Sun Mojarra實(shí)現(xiàn)),Ruby on Rails等Web框架中的漏洞——奇怪的是其中反而沒有提到ASP.NET。
關(guān)于Padding Oracle Attack的具體細(xì)節(jié),您可以從《Automated Padding Oracle Attacks with PadBuster》及《Padding Oracle Attacks on CBC-mode Encryption with Secret and Random IVs》兩篇文章中得到更詳細(xì)的信息,它們似乎并不像表面那樣高深莫測,尤其是前者,有機(jī)會我也打算將它翻譯一下。
針對ASP.NET的攻擊及其危害
那么,這次又是如何對ASP.NET站點(diǎn)進(jìn)行攻擊的呢?方式有不少,例如攻擊者可以為一個需要認(rèn)證的請求發(fā)送自定義的cookie值,如果沒有通過認(rèn)證,則會得到一個轉(zhuǎn)向登陸頁面的302跳轉(zhuǎn)。一個更為直觀和通用的作法來自于PPOA論文的作者所提供的一段視頻,其中使用了WebResources.axd?d=xyz進(jìn)行探測工作。WebResource.axd有一個特點(diǎn),便是會對錯誤的密文(即d=xyz中的xyz)產(chǎn)生500錯誤,而對正確的密文產(chǎn)生404錯誤,這便形成了足夠的提示。
好,那么假設(shè)攻擊者已經(jīng)得到了站點(diǎn)的Machine Key,也就是網(wǎng)站所使用的密鑰,那么它又能造成什么危害呢?
一些危害是很容易理解的,例如解密(或注入)ViewState,或是如視頻里那樣設(shè)置一個管理員的cookie。在ScottGu等文章中描述這個漏洞的危害時還提到,這個漏洞可以用來下載web.config等私密文件,這又是如何辦到的呢?要知道web.config文件的下載是被IIS和ASP.NET所禁止的,它似乎和加密解密或是Machine Key無關(guān)。不過您是否意識到,在ASP.NET 3.5 SP1以后,我們可以利用ScriptManager來打包輸出本地的腳本文件?例如:
- <asp:ScriptManager ID="sm" runat="server">
- <CompositeScript>
- <Scripts>
- <asp:ScriptReference Path="~/scripts/core.js" />
- <asp:ScriptReference Path="~/scripts/lib.js" />
- </Scripts>
- </CompositeScript>
- </asp:ScriptManager>
這段內(nèi)容會在頁面上放置一段ScriptResource.axd的引用,它的Query String便包含了需要輸出的文件路徑,它是與ScriptManager等組件完全獨(dú)立的。那么,如果攻擊者告訴它輸出“~/web.config”的時候……#p#
有趣的是,PPOA論文作者同時還在今年兩月和六月分別提供了攻擊CAPTCHA和攻擊Apache MyFaces的視頻,同時也提供了一個針對JSF的自動攻擊工具,不過它們并沒有形成微軟對ASP.NET的漏洞那樣強(qiáng)烈反應(yīng)。
防止攻擊
目前ScottGu給出了多個workaround,歸根結(jié)底便是消除“Oracle”,也就是提示信息。例如他強(qiáng)調(diào)要為404和500錯誤提供完全相同的反饋——不止是輸出的錯誤頁面,也包括所有的頭信息(如Server Time等自然除外),這種做法會讓攻擊者無法得到提示信息,自然也就無法解密了。此外,ScottGu的一些代碼同時讓錯誤頁面Sleep一小段時間,這也是種常用的混淆手段,讓攻擊者無法從響應(yīng)時間長短上來了解這個請求“性質(zhì)”如何。
從上面的分析中我們可以知道,這種統(tǒng)一錯誤信息的作法似乎是針對WebResource.axd和ScriptResource.axd的。由于我們知道了攻擊的手段,便也可以采取其他作法。例如對于不需要這兩個Handler的站點(diǎn),就把它們從ASP.NET或IIS里直接摘除吧。還有,如果在日志中發(fā)現(xiàn)太多CryptographicException異常,便要關(guān)注站點(diǎn)是否遭受的攻擊。
但是,Padding Oracle Attack的危害之處在于它所需要的信息實(shí)在太少,攻擊者只需分辨兩種狀態(tài)便可以進(jìn)行攻擊,即便WebResource.axd的攻擊被您防止了,那么之前提到的用戶認(rèn)證所帶來的302跳轉(zhuǎn)又如何?對于我們獨(dú)立編寫的應(yīng)用程序來說,要繞開這個問題可以使用各種技巧。但對于微軟來說可能就不容易了,因?yàn)锳SP.NET作為一個框架,它提供的是一種統(tǒng)一的,普適的機(jī)制,這也是為什么這個漏洞會影響幾乎所有微軟ASP.NET產(chǎn)品的緣故。
此外還有一些做法也是可取的。例如:
避免在ViewState和Cookie中存放敏感數(shù)據(jù)。
不要過度依賴Machine Key。
在認(rèn)證cookie里保存的不只是用戶名,而是外界無法得知的ID,或是同時保存checksum等額外的驗(yàn)證信息。
為ScriptResource.axd寫一個Wrapper,只讓它輸出擴(kuò)展名為js的內(nèi)容。
這些做法的目的是:即使攻擊者得到了Machine Key,也無法對站點(diǎn)造成破壞。
總結(jié)
安全性漏洞總是不令人愉快的,但是在遇到這種狀況的同時,我們也要努力得知問題的真實(shí)情況。在如今信息爆炸的時代,產(chǎn)生和獲取一條沒有多大價值甚至是錯誤的信息,可謂是非常容易的。排除干擾尋求真相,即便只是種態(tài)度和意愿,也是一名技術(shù)人員的基本素質(zhì)。因此在這個問題上,我最反感的便是“微軟的產(chǎn)品就是不安全”,“反正我不會被攻擊”這樣的態(tài)度。
原文鏈接:http://blog.zhaojie.me/2010/09/things-about-padding-oracle-vulnerability-in-asp-net.html
【編輯推薦】