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