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