Web應(yīng)用程序攻防實(shí)戰(zhàn)
原創(chuàng)【51CTO.com獨(dú)家翻譯】想親自擊敗黑客嗎?OK,沒(méi)問(wèn)題,首先你要了解黑客是如何查找安全漏洞的,其次就是要了解黑客是如何利用Web應(yīng)用程序漏洞的,最后就是了解他們是如何組織進(jìn)攻的。本文將以一個(gè)漏洞百出的程序Jarlsberg為例,為大家講解Web應(yīng)用程序的攻防手段,全面解剖黑客的行徑和應(yīng)對(duì)辦法。Jarlsberg是用Python編寫(xiě)的,因此略懂Python會(huì)幫助理解本文,但即使不懂也無(wú)所謂,因?yàn)槁┒春托迯?fù)漏洞的方法基本上是與語(yǔ)言無(wú)關(guān)的。另外我們會(huì)涉及到黑盒黑客和白盒黑客,所謂黑盒黑客就是通過(guò)操縱輸入字段或URL參數(shù),觀察Web應(yīng)用程序的響應(yīng)和變化,嘗試找出讓它出錯(cuò)的一種攻擊手段,這里我們通常會(huì)查看HTTP/HTTPS請(qǐng)求和響應(yīng),推薦兩款很棒的輔助工具Burp和WebScarab;所謂白盒黑客就是分析Web應(yīng)用程序源代碼,嘗試找出bug并進(jìn)行攻擊的手段。
你完全可以根據(jù)本文介紹的內(nèi)容搭建一個(gè)滲透測(cè)試環(huán)境,自己做做練習(xí),以提升自己的技能,當(dāng)然最重要的是通過(guò)學(xué)習(xí)達(dá)到舉一反三,以后自己也能發(fā)現(xiàn)和修復(fù)漏洞,Jarlsberg的下載地址是http://jarlsberg.appspot.com/jarlsberg-code.zip,你也可以直接訪問(wèn)http://jarlsberg.appspot.com/start,AppEngine會(huì)自動(dòng)為你創(chuàng)建一個(gè)新的Jarlsberg實(shí)例,每個(gè)實(shí)例都運(yùn)行在獨(dú)立的沙盒中,用唯一的ID進(jìn)行標(biāo)識(shí),你可以隨意展開(kāi)攻擊,你也可以將你唯一的URL分享給其它人進(jìn)行攻擊研究。
如果想在本地運(yùn)行Jarlsberg,需要先安裝Python 2.5,其它版本可能不行,執(zhí)行Jarlsberg安裝的命令如下:
            
  | 
        
用localhost:8008替換所有文件中的jarlsberg.appspot.com,并用分配給你的唯一ID替換默認(rèn)ID 123。
如果是直接在AppEngine上創(chuàng)建的Jarlsberg實(shí)例,它有諸多限制,如不能訪問(wèn)和干擾其它Jarlsberg實(shí)例,資源使用也是有限制的,如果你搗鼓得Jarlsberg實(shí)例無(wú)法運(yùn)行時(shí),可以通過(guò)下面的URL進(jìn)行重置,不過(guò)要注意的是所有歷史數(shù)據(jù)都將被清除掉。
            http://jarlsberg.appspot.com/resetbutton/123  | 
        
注意用你自己的ID替換這里的123。
Jarlsberg各個(gè)源文件介紹:
◆jarlsberg.py是Jarlsberg Web服務(wù)器
◆jdata.py在數(shù)據(jù)庫(kù)中存儲(chǔ)默認(rèn)數(shù)據(jù),有一個(gè)管理員賬號(hào)和兩個(gè)默認(rèn)用戶(hù)
◆jtl.py是Jarlsberg模板語(yǔ)言
◆jsanitize.py是Jarlsberg保護(hù)自身HTML免受攻擊的模塊
◆resources/...目錄下存放了所有模板,圖片和CSS等文件
跨站腳本(XSS)
跨站腳本(XSS)指的是黑客通過(guò)網(wǎng)站漏洞在不受自己控制的網(wǎng)站內(nèi)容(通常是HTML或JavaScript)中植入代碼,當(dāng)受害者瀏覽這樣的網(wǎng)頁(yè)時(shí),植入的代碼就會(huì)在受害者瀏覽器中執(zhí)行,這樣就可以順理成章地竊取受害者與網(wǎng)站請(qǐng)求相關(guān)的個(gè)人信息。
在一個(gè)反射式XSS攻擊中,攻擊通常是嵌入在請(qǐng)求URL中,受害者瀏覽黑客構(gòu)造的惡意URL時(shí)就被攻擊了。在存儲(chǔ)式XSS攻擊中,攻擊者將攻擊代碼保存在應(yīng)用程序內(nèi),受害者瀏覽到這樣的網(wǎng)頁(yè)時(shí)就觸發(fā)攻擊代碼的執(zhí)行。
假設(shè)http://www.google.com/search?q=flowers這個(gè)URL返回的頁(yè)面包含以下HTML片段:
            
  | 
        
查詢(xún)參數(shù)q的值被嵌入到Google返回的頁(yè)面中,如果www.google.com不做任何驗(yàn)證或忽略q,攻擊者就可以構(gòu)造一個(gè)類(lèi)似下面這樣的鏈接進(jìn)行攻擊嘗試:
            http://www.google.com/search?q=flowers+%3Cscript%3Eevil_script()%3C/script%3E  | 
        
接下來(lái)就是欺騙受害者點(diǎn)擊這個(gè)鏈接,當(dāng)受害者點(diǎn)擊這個(gè)鏈接后,他的瀏覽器就會(huì)解析下面的代碼:
            
  | 
        
瀏覽器就會(huì)執(zhí)行evil_script(),于是受害者的瀏覽器狀態(tài)和所有該域名對(duì)應(yīng)的cookies都全部暴露出來(lái)了。
有時(shí)即使受害者不直接地點(diǎn)擊惡意鏈接也會(huì)遭受攻擊,例如,假設(shè)攻擊者擁有www.evil.example.com域名,在頁(yè)面中用
XSS挑戰(zhàn)
一般說(shuō)來(lái),當(dāng)其他用戶(hù)瀏覽一個(gè)網(wǎng)頁(yè)時(shí),你可以讓一段JavaScript代碼在這個(gè)網(wǎng)頁(yè)上執(zhí)行,就說(shuō)明它有XSS漏洞,一個(gè)簡(jiǎn)單有效的JavaScript函數(shù)是alert(),它會(huì)彈出一個(gè)窗口。
你可能認(rèn)為插入一個(gè)alert消息不會(huì)有任何危險(xiǎn),但如果你能夠插入alert(1),那么插入其它惡意代碼,如eval(String.fromCharCode(...))也就沒(méi)有問(wèn)題了。
我們的挑戰(zhàn)是發(fā)現(xiàn)Jarlsberg中的XSS漏洞,在哪些地方去找這個(gè)漏洞呢?一個(gè)是URL,另一個(gè)是存儲(chǔ)的數(shù)據(jù)。因?yàn)閄SS漏洞通常包含在那些不能正確處理非受信用戶(hù)數(shù)據(jù)的應(yīng)用程序中,發(fā)現(xiàn)XSS漏洞的方法通常是在輸入字段中輸入任意文字,再看響應(yīng)的HTML代碼變化。我們先來(lái)做一個(gè)簡(jiǎn)單的嘗試。
文件上傳XSS
任務(wù):你能上傳一個(gè)文件,讓你在jarlsberg.appspot.com域名上執(zhí)行任意腳本嗎?
暗示:你可以上傳一個(gè)包含腳本的HTML文件。
攻擊:上傳一個(gè).html文件,包含以下腳本
| 
             | 
        
修復(fù):在一個(gè)獨(dú)立的域名上托管內(nèi)容,這樣腳本就不能訪問(wèn)你域名上的任何內(nèi)容了,也就是說(shuō),我們應(yīng)該用username.usercontent.example.com或username.example-usercontent.com這樣的域名代替example.com/username托管用戶(hù)的內(nèi)容,另外還要注意不要讓用戶(hù)可以注冊(cè)注入wwww等容易引起釣魚(yú)攻擊的用戶(hù)名。
反射式XSS
有趣的是,有些瀏覽器內(nèi)置了防反射式XSS攻擊,如IE和Chrome,另外也有一些瀏覽器擴(kuò)展,如NoScript也能提供這樣的保護(hù),為了解決這個(gè)問(wèn)題,Jarlsberg特意在每個(gè)HTTP響應(yīng)頭中加入了X-XSS-Protection: 0,讓IE可以識(shí)別,如果是Chrome,你可以通過(guò)disable-xss-auditor啟動(dòng)參數(shù)禁用反射式XSS保護(hù)。
如果你使用的是Firefox,并安裝了NoScript擴(kuò)展,請(qǐng)將jarlsberg.appspot.com列入允許列表,如果還不行,最好換個(gè)其它瀏覽器。
也許你認(rèn)為既然瀏覽器有了保護(hù)能力,為什么還需要擔(dān)心這種攻擊呢?其實(shí)瀏覽器并不能完全準(zhǔn)確地實(shí)施保護(hù),因?yàn)樗涣私饽愕膽?yīng)用程序,聰明的黑客是可以繞過(guò)這層保護(hù)機(jī)制的,真正的保護(hù)是從應(yīng)用程序源頭杜絕XSS漏洞。
任務(wù):找出一個(gè)反射式漏洞,我們希望通過(guò)點(diǎn)擊一個(gè)URL執(zhí)行一個(gè)腳本。
提示1:這個(gè)URL是什么呢?
            http://jarlsberg.appspot.com/123/invalid  | 
        
提示2:在URL中最危險(xiǎn)的字符是<和>,嘗試輸入下面的URL:
以上的URL是通過(guò)不同語(yǔ)言風(fēng)格構(gòu)造的<和>,直接在瀏覽器地址欄輸入<和>是一樣的,瀏覽器會(huì)自動(dòng)編碼,然后查看返回的HTML代碼,研究服務(wù)器對(duì)這些URL的響應(yīng)。
攻擊:創(chuàng)建下面這樣一個(gè)URL,讓受害者點(diǎn)擊它
            
  | 
修復(fù):在jsanitize.py文件_SanitizeTag部分中,將onmouseover添加到disallowed_attributes列表中,可以預(yù)防片段1的攻擊。
但這種修復(fù)方法不徹底,因?yàn)闄z查不允許的屬性時(shí)是區(qū)分大小寫(xiě)的,而HTML則不區(qū)分大小寫(xiě),正確的做法是:
1、將輸入解析為一個(gè)中間DOM結(jié)構(gòu),然后以良好的格式輸出;
2、為允許的標(biāo)記和屬性使用嚴(yán)謹(jǐn)?shù)陌酌麊危?/p>
3、對(duì)允許的URL和CSS屬性采用嚴(yán)格的凈化處理。
在條件允許的情況下,最好使用一個(gè)HTML凈化器。
通過(guò)HTML屬性進(jìn)行存儲(chǔ)式XSS
任務(wù):你也可以在HTML屬性上注入值來(lái)實(shí)施XSS,如通過(guò)設(shè)置配置文件中的顏色值植入一段腳本。
提示1:顏色是使用style='color:color'渲染的,試試在顏色名中包含一個(gè)單引號(hào)字符的效果。
提示2:你可以插入一個(gè)HTML屬性執(zhí)行一個(gè)腳本。
攻擊:使用的下面的代碼設(shè)置顏色
            red' onload='alert(1)' onmouseover='alert(2)  | 
        
當(dāng)你鼠標(biāo)移到它上面時(shí)就觸發(fā)了攻擊。
修復(fù):我們需要一個(gè)正確的文字轉(zhuǎn)義程序,有效地規(guī)避單引號(hào)和雙引號(hào),將下面的函數(shù)增加到j(luò)tl.py,用它替代cgi.escape。
| 
             def _EscapeTextToHtml(var): """Escape HTML metacharacters. This function escapes characters that are dangerous to insert into HTML. It prevents XSS via quotes or script injected in attribute values. It is safer than cgi.escape, which escapes only <, >, & by default. cgi.escape can be told to escape double quotes, but it will never escape single quotes. """ meta_chars = { '"': '"', '\'': ''', # Not ' '&': '&', '<': '<',< '>': '>', } escaped_var = "" for i in var: if i in meta_chars: escaped_var = escaped_var + meta_chars[i] else: escaped_var = escaped_var + i return escaped_var  | 
        
但這種修復(fù)方法仍然不完美,顏色值仍然存在漏洞。
提示1:有些瀏覽器允許你在樣式表中包含腳本。
提示2:最容易遭到利用的瀏覽器是IE,因?yàn)樗С謩?dòng)態(tài)CSS屬性(也叫做CSS表達(dá)式)。
攻擊方法:使用下面的代碼替換顏色值
            expression(alert(1))  | 
        
雖然其它瀏覽器不支持動(dòng)態(tài)CSS屬性,但一樣存在其它危險(xiǎn)的CSS屬性,如Mozilla的-moz-binding。
修復(fù)辦法:我們需要將顏色值凈化為一個(gè)真正的顏色值,最好的辦法是增加一個(gè)新的輸出凈化格式給jtl,例如,我們可能會(huì)書(shū)寫(xiě){{foo:color}}確保foo被安全地用作一個(gè)顏色,下面這個(gè)函數(shù)可以用來(lái)凈化。
            
  | 
        
你可以為字體大小,字體,URL等做類(lèi)似的凈化,它對(duì)輸入驗(yàn)證也很有幫助,如果有人輸入了一個(gè)無(wú)效值,你可以立即提醒或是拒絕他,但光做輸入驗(yàn)證還不夠,如果你的驗(yàn)證代碼本身也有漏洞,或是瀏覽器暴出新的攻擊向量,你不得不返回重新清洗之前全部輸入的值,或是增加輸出驗(yàn)證。#p#
通過(guò)Ajax進(jìn)行存儲(chǔ)式XSS
任務(wù):使用Jarlsberg Ajax代碼中的bug找出一個(gè)XSS攻擊點(diǎn),當(dāng)你點(diǎn)擊頁(yè)面刷新鏈接時(shí)觸發(fā)攻擊。
提示1:在http://jarlsberg.appspot.com/123/feed.jtl上運(yùn)行curl查看結(jié)果,或者在瀏覽器中輸入這個(gè)URL,查看返回結(jié)果的HTML源代碼,你會(huì)看到每個(gè)用戶(hù)的第一個(gè)微博包含在響應(yīng)包中,然后整個(gè)響應(yīng)包在客戶(hù)端接受評(píng)估,最后將微博內(nèi)容插入到文檔中,你能夠在微博內(nèi)容中加入點(diǎn)什么使其與預(yù)期的結(jié)果有所不同嗎?
提示2:在你的微博內(nèi)容中添加一個(gè)雙引號(hào)試試。
利用方法:將下面的代碼插入到你的微博內(nèi)容中。
            
  | 
        
JSON看起來(lái)應(yīng)該象
            
_feed(({..., "Mallory": "snippet", ...}))
             | 
        
代替后看起來(lái)象
            
  | 
        
注意,每個(gè)下劃線(xiàn)部分都是一個(gè)獨(dú)立的表達(dá)式,這個(gè)攻擊是不可見(jiàn)的,因?yàn)槭褂昧?span style=display:none>,即使刷新后也是不可見(jiàn)的,因?yàn)樗徊迦肓艘粋€(gè)空字符串,存在這種可利用的漏洞表明服務(wù)器端和客戶(hù)端都有bug。
修復(fù)辦法:首先,在服務(wù)器端,原文在JSON響應(yīng)中呈現(xiàn)時(shí)轉(zhuǎn)義就不正確,雖然模板聲明了{(lán){snippet.0:html}},但仍然不夠,原文將被插入到DOM節(jié)點(diǎn)的內(nèi)部HTML中,因此HTML必須進(jìn)行凈化,但凈化后的原文將被插入到JavaScript中,單引號(hào)和雙引號(hào)將被轉(zhuǎn)義,給jtl增加{{...:js}}支持是不夠的,我們也需要支持{{...:html:js}}。
如果要轉(zhuǎn)義單引號(hào)和雙引號(hào),分別使用\x27和\x22,用和"替代它們是不正確的,因?yàn)镴avaScript是不能識(shí)別和"的。
其次,在瀏覽器中,Jarlsberg使用JavaScript的eval轉(zhuǎn)換JSON,通常情況下,使用eval非常危險(xiǎn),我們應(yīng)該使用JSON解析器確保字符串不包括任何不安全的內(nèi)容,json.org就提供了JSON解析器下載。
通過(guò)Ajax實(shí)施反射式XSS
任務(wù):使用Jarlsberg的Ajax功能,找出一個(gè)URL,點(diǎn)擊它就執(zhí)行一個(gè)腳本。
提示1:Jarlsberg刷新用戶(hù)的微博頁(yè)面時(shí),使用了:
            http://jarlsberg.appspot.com/123/feed.jtl?uid=value  | 
        
結(jié)果是腳本
            _feed((["user", "snippet1", ... ]))  | 
        
提示2:這里使用了不同的漏洞,但和前面的反射式XSS利用方法是類(lèi)似的。
攻擊方法:創(chuàng)建類(lèi)似下面這樣的URL,誘使受害者點(diǎn)擊它
| 
             | 
        
這個(gè)bug讓Jarlsberg返回了所有文件類(lèi)型為text/html的jtl文件。
修復(fù)辦法:需要確保JSON內(nèi)容不會(huì)當(dāng)作HTML解析,需要修改{{...:js}},用JavaScript轉(zhuǎn)移字符\x3c和\x3e進(jìn)行替換,在JavaScript中用\x3c和\x3e分別替換<和>總是安全的,注意,用HTML轉(zhuǎn)移字符<和>也是不正確的。
同時(shí),你還應(yīng)該設(shè)置響應(yīng)的內(nèi)容類(lèi)型,這里我們使用application/javascript。
此外,Jarlsberg也未設(shè)置內(nèi)容編碼,瀏覽器會(huì)嘗試根據(jù)文檔內(nèi)容進(jìn)行猜測(cè),攻擊者也可以利用這個(gè)漏洞欺騙瀏覽器,如攻擊者使用UTF-7編碼欺騙瀏覽器,于是就可以嵌入+ADw-script+AD4-腳本標(biāo)記,在UTF-7中,+ADw-和+AD4-分別代表<和>,因此不僅要設(shè)置正確的內(nèi)容類(lèi)型,編碼也要設(shè)置,設(shè)置方法和HTML類(lèi)似,如:
            Content-Type: text/html; charset=utf-8  | 
        
雖然沒(méi)有一種萬(wàn)能的方法來(lái)防御XSS漏洞,但仍然有一些重要的原則應(yīng)該遵守。
1、首先確保你弄明白了問(wèn)題;
2、盡可能通過(guò)模板功能凈化,盡量不要直接在代碼中使用轉(zhuǎn)義字符進(jìn)行凈化;
3、實(shí)施XSS相關(guān)的測(cè)試;
4、不要試圖自己寫(xiě)模板庫(kù)。 #p#
客戶(hù)端狀態(tài)操縱
用戶(hù)與Web應(yīng)用程序交互是通過(guò)瀏覽器進(jìn)行的,點(diǎn)擊一個(gè)按鈕或是提交一個(gè)表單,瀏覽器都會(huì)將請(qǐng)求發(fā)送給Web服務(wù)器,因?yàn)闉g覽器很容易被黑客控制,因此Web服務(wù)器不應(yīng)該相信任何瀏覽器發(fā)來(lái)的數(shù)據(jù)。
寫(xiě)一個(gè)Web應(yīng)用程序也不相信任何數(shù)據(jù)似乎不太可能,也沒(méi)那個(gè)必要,如用戶(hù)提交一個(gè)表單表示他想購(gòu)買(mǎi)的商品列表,這時(shí)信任它也無(wú)妨,但如果提交的表單也包含價(jià)格信息,那就應(yīng)該謹(jǐn)慎了。
特權(quán)提升
任務(wù):將你的帳戶(hù)升級(jí)成管理員
提示:一般用戶(hù)和管理員都使用editprofile.jtl編輯自己的配置信息,如果你不是管理員,這個(gè)頁(yè)面看起來(lái)會(huì)有所不同。
攻擊方法:使用下面任意一個(gè)URL都可以將你的普通帳戶(hù)轉(zhuǎn)換成管理員
            
  | 
        
第二個(gè)URL可以通過(guò)替換username將任何一個(gè)普通用戶(hù)升級(jí)成管理員。
由于Cookie的問(wèn)題,你可能看到帳戶(hù)狀態(tài)不是立即顯示為管理員,只要你注銷(xiāo)重新登錄就可以了。
修復(fù)辦法:這里的bug是服務(wù)器端代碼缺少身份驗(yàn)證引起的,正確的做法是在服務(wù)器端檢查授權(quán)。
Cookie操縱
因?yàn)镠TTP協(xié)議是無(wú)狀態(tài)的,Web無(wú)法知道某兩個(gè)請(qǐng)求來(lái)自同一個(gè)用戶(hù),就是在這種背景下,Cookie誕生了,當(dāng)一個(gè)網(wǎng)站在HTTP響應(yīng)中引入Cookie后,瀏覽器在下一次請(qǐng)求時(shí)就會(huì)自動(dòng)發(fā)送Cookie,網(wǎng)站可以使用Cookie保存會(huì)話(huà)狀態(tài),Jarlsberg使用Cookie記住登錄用戶(hù)的身份,因?yàn)镃ookie是保存在客戶(hù)端的,因此很容易受到操縱,Jarlsberg為了保護(hù)Cookie專(zhuān)門(mén)增加了一個(gè)散列,遺憾的是,實(shí)施攻擊不一定需要破壞散列。
任務(wù):讓Jarlsberg為你生成其它用戶(hù)的Cookie。
提示:Jarlsberg的Cookie格式如下
            hash|username|admin|author  | 
        
當(dāng)你登錄時(shí)Jarlsberg為你生成一個(gè)Cookie。
攻擊方法:使用“foo|admin|author”作為用戶(hù)名創(chuàng)建一個(gè)新用戶(hù),然后用它登錄,Jarlsberg產(chǎn)生“hash|foo|admin|author||author”Cookie,于是foo成為管理員,因此這也算是一種特權(quán)提升攻擊。
修復(fù)辦法:由于系統(tǒng)對(duì)用戶(hù)名沒(méi)有任何字符限制才導(dǎo)致攻擊可以得逞,因此在構(gòu)造Cookie時(shí)要對(duì)用戶(hù)名進(jìn)行轉(zhuǎn)義,如果與預(yù)期的模式不能匹配,就拒絕為其產(chǎn)生Cookie。
跨站請(qǐng)求偽造(XSRF)
前面我們?cè)岬?,如果用?hù)提交的表單僅僅表示他希望購(gòu)買(mǎi)的商鋪列表,那信任這些數(shù)據(jù)也無(wú)妨,只要確保是這個(gè)用戶(hù)提交的數(shù)據(jù)即可,如果你的網(wǎng)站有XSS漏洞,即使你已經(jīng)實(shí)施了XSS保護(hù),但還有另一種攻擊需要保護(hù),那就是跨站請(qǐng)求偽造。
瀏覽器向網(wǎng)站發(fā)送請(qǐng)求時(shí),它也會(huì)將該網(wǎng)站的Cookie一并發(fā)送,Web服務(wù)器不會(huì)區(qū)分請(qǐng)求是否有用戶(hù)行為(如用戶(hù)點(diǎn)擊提交按鈕,或是頁(yè)面中嵌入的一個(gè)圖片),因此,當(dāng)網(wǎng)站接收到一個(gè)請(qǐng)求要執(zhí)行一些動(dòng)作時(shí)(如刪除郵件,修改聯(lián)系人信息等),Web服務(wù)器不知道這些行為是否是用戶(hù)真正的本意,即使請(qǐng)求中包含了Cookie也證明不了,攻擊者可以利用這個(gè)漏洞欺騙服務(wù)器,執(zhí)行非用戶(hù)本意想要執(zhí)行的動(dòng)作。
例如,假設(shè)Blogger有XSRF漏洞,在頁(yè)面上有一個(gè)刪除按鈕,其對(duì)于的URL是:
            http://www.blogger.com/deleteblog.do?blogId=BLOGID  | 
        
攻擊者Bob在他自己的網(wǎng)頁(yè)http://www.evil.example.com中嵌入下面的HTML代碼:
| 
             | 
        
如果受害者Alice登錄到www.blogger.com,當(dāng)她瀏覽上面的頁(yè)面時(shí),會(huì)發(fā)生:
◆她的瀏覽器從http://www.evil.example.com載入頁(yè)面,之后瀏覽器嘗試載入頁(yè)面中嵌入的所有對(duì)象,包括這里的img對(duì)象;
◆Blogger驗(yàn)證Cookie是一個(gè)有效的會(huì)話(huà)Cookie,然后驗(yàn)證alice's-blog-id對(duì)應(yīng)的博客是否屬于Alice,如果是就刪除該博客;
◆Alice不知道是什么原因造成自己的博客就沒(méi)有了。
在這個(gè)攻擊示例中,因?yàn)槊總€(gè)用戶(hù)有他們自己的博客id,攻擊目標(biāo)是單個(gè)用戶(hù),但在很多時(shí)候,類(lèi)似這樣的攻擊可以針對(duì)批量用戶(hù),批量數(shù)據(jù)。
XSRF挑戰(zhàn)
這里的目標(biāo)是找到一個(gè)方法代表登錄Jarlsberg的用戶(hù)執(zhí)行賬號(hào)修改行為,但真正的用戶(hù)并不知情,假設(shè)你可以正常訪問(wèn)一個(gè)網(wǎng)頁(yè)。
任務(wù):找到一個(gè)方法讓某個(gè)人刪除他們的Jarlsberg微博內(nèi)容。
提示:刪除一個(gè)微博內(nèi)容用到的URL是什么?
攻擊方法:誘使用戶(hù)訪問(wèn)產(chǎn)生下列請(qǐng)求的頁(yè)面
            http://jarlsberg.appspot.com/123/deletesnippet?index=0  | 
        
為了達(dá)到更好的迷惑性,我們將Jarlsberg圖標(biāo)加在這個(gè)URL上。
修復(fù)辦法:我們首先應(yīng)該修改/deletesnippet通過(guò)POST請(qǐng)求工作,因?yàn)檫@是一個(gè)狀態(tài)改變行為,按照HTML形式,將method='get'修改為method='post'。在服務(wù)器端,GET和POST請(qǐng)求除了調(diào)用不同的處理程序外,它們都一樣,例如,Jarlsberg使用Python的BaseHTTPServer為GET請(qǐng)求調(diào)用do_GET,為POST請(qǐng)求調(diào)用do_POST。
但僅僅修改為POST并是完美的修復(fù)方法,只能說(shuō)使用POST是正確的做法,因?yàn)镚ET請(qǐng)求是可以重新發(fā)出的,而POST請(qǐng)求是不能重新發(fā)出的,我們需要傳遞一個(gè)唯一的,不可預(yù)知的認(rèn)證令牌action_token給用戶(hù),可以使用用戶(hù)Cookie和當(dāng)前時(shí)間戳的哈希值,在所有改變狀態(tài)的HTTP請(qǐng)求中作為一個(gè)附加HTTP參數(shù)包含這個(gè)令牌,使用時(shí)間戳的目的是可以讓過(guò)期的令牌失效,即使它被泄露出去,因時(shí)效性問(wèn)題,引起的影響也會(huì)很小。
在處理一個(gè)請(qǐng)求時(shí),Jarlsberg應(yīng)該重新生成令牌,與請(qǐng)求提供的令牌進(jìn)行比較,如果相同就執(zhí)行行為,否則就拒絕它,生成和驗(yàn)證令牌的函數(shù)如下:
            
  | 
        
很遺憾,這個(gè)函數(shù)仍然有問(wèn)題。
因?yàn)榱钆浦邪瑫r(shí)間,我們必須防止它永久有效,如果攻擊者獲得一個(gè)令牌的拷貝,他可以在24小時(shí)內(nèi)反復(fù)使用它就麻煩了,令牌的過(guò)期時(shí)間應(yīng)盡可能設(shè)得短一點(diǎn),即使請(qǐng)求被攻擊者攔截,也只能攻擊一次,攻擊者不能反復(fù)利用這個(gè)請(qǐng)求,令牌應(yīng)該和特定的狀態(tài)改變行為聯(lián)系起來(lái),如一個(gè)頁(yè)面的URL,對(duì)于非常長(zhǎng)的行為,如編輯一個(gè)微博,頁(yè)面上的腳本可以查詢(xún)服務(wù)器更新令牌。
XSRF漏洞的存在讓攻擊者可以輕易構(gòu)造一系列請(qǐng)求,為了阻止這種攻擊,需要引入一些不可預(yù)知的值,讓攻擊者不是那么容易構(gòu)造偽造的請(qǐng)求,有些應(yīng)用程序框架內(nèi)置了XSRF保護(hù),它們會(huì)在每個(gè)響應(yīng)中包含一個(gè)唯一的令牌,并且會(huì)驗(yàn)證每個(gè)POST請(qǐng)求。#p#
跨站腳本置入(XSSI)
瀏覽器可以阻止一個(gè)域名下的網(wǎng)頁(yè)讀取另一個(gè)域名下的網(wǎng)頁(yè),但它不能阻止一個(gè)域名下的網(wǎng)頁(yè)引用另一個(gè)域名下的資源,特別是它們?cè)试S引用另一個(gè)域名下的圖片,執(zhí)行另一個(gè)域名下的腳步,引用的腳本無(wú)自己的安全上下文,它完全依賴(lài)引用它的頁(yè)面的安全上下文,例如,如果www.evil.example.com包含了一個(gè)托管在www.google.com上的腳本,這個(gè)腳本就運(yùn)行在evil上下文而不是google上下文中,因此這個(gè)腳本中包含的任何用戶(hù)數(shù)據(jù)都可能被泄露。
XSSI挑戰(zhàn)
任務(wù):使用XSSI找到一個(gè)閱讀他人私有微博的方法。
在另一個(gè)網(wǎng)站上創(chuàng)建一個(gè)網(wǎng)頁(yè),在這個(gè)網(wǎng)頁(yè)中插入一些代碼,使其可以訪問(wèn)你的私有微博內(nèi)容。
提示1:將下面的代碼添加到你的HTML頁(yè)面,你可以從另一個(gè)域名運(yùn)行腳本
| 
             | 














