CSRF漏洞的原理
如果提到的哪個專業術語我沒有做通俗的解釋,請在下方回復。
如果覺得長,想要直入主題的話可以直接找到 ---重要內容分割線---,看那部分其實是這套驗證碼最核心的安全機制。
目前web前端的驗證碼主要分幾類:
1 看到圖形,肉眼識別後輸入字符;
2 根據界面圖形,進行鼠標、手指(移動端)交互操作;
3 短信、電話、郵箱驗證。
其中第3條,很多時候往往會與第1條相結合起來,以防止CSRF漏洞造成的短信炸彈攻擊。
包括用戶無感知的人機檢驗方式(簡單地如前端token+referrer判斷,這個待會兒再講)在內,
以上所說的所有手段,終究目的是壹個,那就是檢查當前訪問者究竟是壹個“人”,還是壹臺“機器”。
這在計算機研究領域被稱為圖靈測試,圖靈是壹位計算機科學家,他提出對於“人工智能”的定義是:如果把壹臺電腦放在壹個與外界隔絕的房間裏,同時把壹個人放在壹個壹模壹樣的房間裏,同時對人和電腦進行各種各樣的提問、測試,如果兩者做出的反應基本壹致(總會有差異,哪怕人與人之間也會有不同),那麽認為這臺電腦的算法水平已經達到了“人工智能”的級別。
說了這麽多,想表達的還是壹點,對於“讓機器模擬人的行為”或者說“把自己偽裝成壹個人”,這樣的事情在專業領域是有很多研究的。現在網絡上存在著諸多驗證碼、安全校驗等等東西,很多人不理解,認為這種東西增加了人們對於軟件的正常使用的成本。其實這些安全手段,都是為了防止黑客以各種各樣的技術手段,偽造網絡請求,假冒真實用戶的身份去“刷”網站的各個接口。
下面回到主題,來談壹談題主所提到的這個騰訊的驗證碼頁面的技術實現。
粗略地翻了壹下這個頁面的源代碼(對於web領域,頁面程序的源代碼是完全裸奔的,這壹點與客戶端程序不同,所以如果想要研究對方的代碼,對於web開發者來說是壹件比較容易的事情,換句話說web前端代碼裏邊是沒有太多秘密可言的,因此web的安全性也相對差壹些),這個頁面在我見過的壹些驗證碼系統中是很常見的壹種,就是前面提到的那第1種,看圖識別輸入字符的驗證碼形式。下面上代碼:
先來看看在UI層面,就是最常見的,通過javascript在DOM上綁定的監聽事件觸發回調,如圖所示,如果我把右邊紅圈中的click監聽remove掉,點擊按鈕之後就什麽反應都沒有了,所以基本確定它驗證碼的邏輯都卸載了這個CT_btn_trigger的回調函數中。然後看看點擊後彈出的layer:
全都是用DOM實現的,我在代碼中沒有發現任何flash object的痕跡(為什麽提flash,這個也放在後邊說),輸入驗證碼之後監聽網絡數據包,找到了發送驗證碼的那個接口:
服務端的接受驗證碼的接口為/cap_union_verify_new 而我們剛剛輸入的壹條驗證碼,query字段名稱是ans。這裏的這壹條網絡請求是https協議傳輸的,包括整個qq安全中心的頁面也都是上了https的,https協議與我們熟知的http協議最大的不同就是,通過加密手段規避掉了網絡中間層對數據包的截獲,這壹點對於這套驗證碼來說還是值得肯定的,目前的很多驗證碼系統對於傳輸驗證碼的網絡請求都沒有上https。
昨晚看的倉促,剛剛又翻了壹下發現了這壹套驗證碼系統的核心部分,其實就是上面截圖中的collect字段,感謝 @李默然 的提醒,這部分其實也就是我在前文中所提到的那個token,從collect這個字段命名不難猜出這個token是壹個前端拼裝起來的東西。具體如何拼裝,在這裏我就不壹壹扒代碼了,考慮到畢竟是壹個安全中心的頁面,把技術細節在這裏講的太透了,普通用戶也不那麽關心,反倒是替別有用心的人省了點兒事。所以就不給騰訊的前端同學找麻煩了,在這裏簡單述說說吧。
collect參數,在用戶點擊這個按鈕的那壹刻,就會從服務端傳過來壹個collect參數,這時的collect參數中做了壹些組裝和軟加密處理,拿到的是密文,明文中的內容不難猜測壹定包裹了驗證碼所需的那張圖片的url。
當輸入驗證碼完成後,從客戶端發往服務器的那條請求中,雖然ans字段中的驗證碼是明文,但是還依然帶了壹個collect字段,而這時的collect字段和上壹個collect字段內容是不同的,顯然也是壹個加密後的結果,推測可知這個collect字段在服務端解密後拿到的明文中,至少也要包含用戶本地操作的壹些數據,這數據中就包括,他輸入的那段驗證碼所對應的圖片究竟是哪張。也許存了圖片的url,也許是服務端記錄圖片的某壹組key值,但這個對應關系是壹定要有的。
以上提到的collect字段,其實是整個這套驗證碼系統最為關鍵的壹點,黑客如果要破譯這層csrf防禦,首先需要搞明白兩處collect字段是如何加密的。如果放在其他系統客戶端的角度來說,破譯這層加密的難度不小,但是由於web客戶端的代碼是裸奔的,這個天然的劣勢導致,黑客不壹定要以數學的方法去解出這套加密機制,而是可以直接翻看源代碼,看明白collect字段是怎麽拼裝的,然後只要結合起圖片識別模塊就可以對這個接口進行強刷了。由於驗證碼本身是最簡單的圖片6位驗證碼,所以圖像處理方面識別難度不是很大。
總的來講,這壹套驗證碼體系屬於中規中矩,可能因為並不涉及到金額安全問題,所以也並沒有十分重視。
如何優雅地屏蔽百度廣告推廣
下面簡單講講剛才翻源碼過程中遇到的幾個技術細節,值得了解壹下:
1 這樣的驗證碼安全嗎?
很遺憾,我是個喜歡講實話的人。這樣的驗證碼,不是絕對安全的。
2 什麽是CSRF漏洞?
CSRF簡單地說就是偽造的網絡請求,黑客以這種手段,用腳本寫出壹些自動化程序,非正常地使用正常用戶在訪問網頁時調用的http接口,從而達到其他目的(盜號,刷接口,甚至將服務器拖庫)。這也正是網頁加入驗證碼的根本原因,提高了黑客去做CSRF攻擊的成本,因為他的自動化腳本可以發送任何用戶相關的數據,但卻很難猜出每次都隨機出現的圖形驗證碼中的字符。
3 這樣的驗證碼存在哪些安全隱患?
簡單地圖形驗證碼現在已經不算是安全的了,因為以如今的圖像識別技術,黑客可以構造壹套自動化腳本,首先獲取驗證碼的那張圖片,然後把圖片交由專門做圖像識別的程序模塊進行識別處理,返回壹個識別結果,再把識別的結果像正常用戶填寫驗證碼壹樣回填到http請求的參數中去。我們看到,他在http請求的參數中,是直接把驗證碼的字符放在裏邊,而沒有對字符做任何md5、AES壹類的處理,所以黑客可以很容易的知道這個參數是什麽,並構造上述的壹個自動化滲透工具。來對服務器進行攻擊。他的圖像識別算法的能力不需要達到90% 80%這麽高,哪怕有10%的精度,黑客可以把這樣的壹套腳本攻擊程序分布式地放在各個機房的機器上,對服務器造成壹定的攻擊。對於妳所看到的這個qq安全中心的頁面是否安全的問題,真的沒有是和否的區別,只有值得與否的區別。畢竟構造壹套上述的自動化攻擊程序以目前的技術,成本還是很高的。但不是不可能。這也解釋了,為什麽春節搶票期間,12306出臺了那麽壹套變態的驗證碼,就是因為搶票的這個利益太大了,如果有人能夠破譯它的驗證碼系統,損失是鐵路部門無法接受的,所以寧可讓驗證碼把普通用戶難到罵娘,也絕對不能給黑客的自動化攻擊程序留下可乘之機。
4 為什麽我要提到flash?
flash作為軟件行業中被諸多安全漏洞纏身的壹項技術,在web領域,某種意義上卻能算是銀彈了,至少我是這樣認為的。為什麽這麽說?就像我剛才說的,軟件行業,客戶端代碼其實都是沒有什麽秘密可言的,妳真的想把壹些安全級別非常高的代碼邏輯保護起來,那只有放到服務端裏才可靠,這就是為什麽大家申請網銀卡的時候都會配給壹塊U盾,因為軟件客戶端永遠是不安全的,或者說相對於這樣大額度交易的利益來講,在黑客們面前他不夠安全。所以要依靠U盾的硬件加密手段,把壹些重要的加密邏輯焊死在芯片中進行固化保護。那麽話說回來,為什麽又要說flash在web領域是安全的呢?因為web太不安全了,作為壹個客戶端來說,它的壹切代碼都是裸奔的,任何打包、編譯都沒有,(有人可能要提到如今的webpack等打包工具,但那些東西實際意義並不在於打包而在於模塊化),通俗的解釋就是,任何壹個懂前端js代碼的工程師,都可以很低的成本,讀懂其他網站前端代碼中做了壹些什麽事情,這相比其他平臺的客戶端開發來說是非常可怕的。
真是因此,很多web網站都會把壹些不希望別人“輕易偷走”的數據,寫到壹個flash客戶端中,然後再把flash編譯後打包的swf作為壹個靜態資源加載到頁面中(因為現代瀏覽器都是支持flash的),讓flash和用戶交互。想要把flash反匯編出來,搞懂他裏邊做了什麽,對於同樣從事flash的AS開發工作的工程師與從事web前端開發工作的工程師,這本身從實現成本上就比web前端的html和javascript代碼要高很多。
另外,如今的絕大多數web工程師,都不太熟悉flash代碼,所以把flash作為web系統某些安全隱患上面的銀彈,還是有壹定道理的。這裏我可以舉壹個目前線上的例子,酷狗音樂就是通過flash播放器,解碼壹種acc格式(特殊的音頻格式,普通瀏覽器和播放器無法直接播放)的音頻文件,來實現音樂歌曲的防盜版。因為妳前端就算把他音頻文件的url拿到了,下載下來,妳也不好直接播放。
對於這部分,就不再扯遠了。