天天看點

Bypass Preventing CSRF

CSRF在過去的n年(n>2)一直都火,在bh/defcon/owasp等會議上多次探讨CSRF的攻防[具體你可以看看以往的那些pp].前

段時間PLAYHACK.net上發表了一個總結性的pp:Preventing

CSRF,然而CSRF是很難徹底防止的,這個也是我說CSRF卑鄙無恥的一個原因,下面我的一些Bypass Preventing

CSRF的tips:

0x01.HTTP Referer

其實國内的CSRF攻擊由來已久了,比如n年前的各大下載下傳網站防止盜鍊,n前dvbbs的一個xss利用了csrf提升權限等等.在下載下傳網站防止盜鍊的過程中很多就使用了通過判斷HTTP

Referer來限制,但是這樣的Prevent很容易就被繞過了.

0x01a.Attack From Inside

很多人都忽律了從site‘内部‘的攻擊.

1.很多的web

app都支援link/img等标簽,然而通過這些标簽通路的url的Referer都是本站的,是以攻擊者隻要在你的bbs

或者blog等上通過那些标簽發一個你構造好的url,然後就是引誘admin了 :)

2.ie有很多特點如:txt/圖檔等裡面的html/js會被執行,當年你可以通過上傳你的構造的代碼...[注意這裡txt裡js執行的domain和txt是同一個]

   0x01b.僞造http header

1.用戶端腳本:

    a.js

XMLhttp.setRequestHeader()

但是xmlhttp不可以跨區域[當然你可以利用0x01a.2裡的方式上傳],是以一般的是要結合xss.

     b.as

     *

XML.addRequestHeader()

LoadVars.addRequestHeader() as裡直接設定Header是有一些限制的,比如

.addRequestHeader("Refere", "AAA"); 這樣是不行的.Rapid7在06年釋出了一個可以繞過的巧妙方法:

.addRequestHeader("Referer:\r\nX-foo",

"bar"); 直接放到第1個參數. 這個bug已經被Adobe

fix了,但是在htm調用swf時swf可以使用任意字尾,我們同樣可以利用類似0x01a.2裡的方法一樣把swf上傳[具體可以參考

《Discuz!/phpwind flash标簽的xss》]

2.服務端腳本:

基本上所有的服務端語言都有發http包的功能,如php的fsockopen(),asp的xmlhttp等等,是以可以通過外面服務端腳本來僞造一個

Referer[其實就是類似于nc]

這個一般隻對于單純的限制Referer而且沒有身份驗證的[因為你cookie沒辦法傳遞],是以這個基本可以YY的.

0x02.Hidden

value

之是以用‘Hidden value‘做标題,是因為PLAYHACK文中寫 ‘0x03a: Cookies

Hashing‘ 和‘0x04: One-Time Tokens‘裡産生的hash都是通過hidden

value來傳遞.但是我們一樣可以通過一些手段得到這個hash.

0x02a.利用xss執行js-xmlhttp在xmlhttp.responseText裡得到hash:

xmlhttp.open("GET",

siteurl+"admincp.php?action=members", false);

xmlhttp.send();

var echo = xmlhttp.responseText;

var reg = /\<input

type=\"hidden\" name=\"formhash\" value=\"([\w\d]+)\">/i;

var

arr=reg.exec(echo);

var formhash=arr[1];

0x02b.利用as裡的xml.onData/LoadVars等得到hash:

import RegExp;

xml:XML = new XML();

xml.onData = function(s) {

     tb1.text = getFirstMatch(new

RegExp("<input type=\"hidden\" name=\"formhash\" id=\"formhash\"

value=\"(\\w+)\">", "ig"), s, 1);

}

xml.load(url+"post.htm");

function getFirstMatch(re, s, i) {

     var m = null;

     if ((m = re.exec(s)) != null) {

         return m[i];

     }

得到hash後,如果原來app裡用的‘Request變量‘那麼我們可以直接通過xml.load等get送出我們構造的變量,如果是post我們可以通過LoadVars等送出:

var _l3 = new LoadVars();  

_l3.decode(unescape("formhash="+hash));

_l3.send(url, "",

"POST");

但是需要加載crossdomain.xml[而且隻可以送出到crossdomain.xml裡設定的domain].如果沒有

crossdomain.xml或者crossdomain.xml裡設定不符合我們的要求,我們可以把crossdomain.xml改為任意字尾然後

通過System.security.loadPolicyFile()來加載.

0x03.CAPTCHA

Image

也就是我們經常看到的圖檔驗證碼,如果抛開使用者感覺等不談,就安全上應該是比較安全的防止crsf的方法,目前還沒有什麼通用的破解方法,現在有很多通過分析圖檔格式來得到驗證碼的,但是這些都是基于gui的,沒辦法利用到crsf上來.

要突破CAPTCHA

Image隻有具體問題具體分析了,通過分析原代碼找到app的一些邏輯錯誤/算法問題來想辦法繞過.比如有的圖檔驗證碼是根據cookie來計算判斷

的,那麼我可以通過xss得到cookie來‘算‘出這個驗證碼,又如驗證碼儲存到session沒有清空,可以暴力這個驗證碼[詳細見lake2的文

章:輕輕繞過你的驗證碼]等等.

小結:

在上面的文字裡,其實主要介紹的一個思路是通過http的請求來僞造送出的資料,然後通過分析這個資料得到你要的東西.按這個思路你可以不須拘泥于js/as等腳本,還有很多腳本/語言可以實作如java/jvm?

:)

[最後,感謝那些和我一起交流探讨的人們.]  

參考:

0.Preventing CSRF:

1.XMLHttp參考手冊:

2.Flash Lite 2.x ActionScript 語言參考:

3.HTTP Header Injection Vulnerabilities in the Flash Player

Plugin:

4.Discuz!/phpwind flash标簽的xss :

5.Request變量與csrf :

6.輕輕繞過你的驗證碼 :