細說驗證碼安全 —— 測試思路大梳理


細說驗證碼安全 —— 測試思路大梳理

1 前言

在安全領域,驗證碼主要分為兩大類:操作驗證碼 和 身份驗證碼

雖然都是驗證碼,但是這兩者所承擔的職責卻完全不同。

操作驗證碼,比如登錄驗證碼,主要用來 區分人與機器 ,在某種程度上屬於圖靈測試

身份驗證碼,主要用來判斷賬號歸屬人,解決信任問題,所以更恰當的叫法是 認證碼

由於兩者的分工和定位不同,所衍生出的安全問題、所關注的安全點也有所不同。

本文將烏雲中所有驗證碼相關案例提煉、分析並匯總,得出一些可重用的方法和經驗。

希望本文能給讀者帶來一些微小的幫助,當你遇到驗證碼相關業務時,能有一個比較完整的測試和審計思路。

PS:在這一過程中,我居然發現,烏雲中的驗證碼的主要案例類型,與我平時所遇到的案例類型,基本是大致相同的(8大類和5大類)

原來各地的程序員犯的錯都是類似的呀 :)

2 操作驗證碼安全

操作驗證碼,主要是為了解決三個問題:

1、賬戶暴力破解

2、高頻次的接口訪問

3、敏感操作二次確認(CSRF)

實際上這三個問題,都屬於 人機區分問題,即 這個操作、請求到底是不是人為地、自願地發出的?

驗證碼安全,圍繞下面幾點展開:

1、驗證碼可重用 (特定賬戶暴力破解、CSRF)

2、驗證碼可識別 (特定賬戶暴力破解)

3、驗證碼在客戶端生成、顯示、校驗 (特定賬戶暴力破解、CSRF)

4、空驗證碼繞過 (特定賬戶暴力破解、CSRF)

5、驗證碼數量有限 (特定賬戶暴力破解)

6、是否校驗客戶端可控 (特定賬戶暴力破解、CSRF)

7、驗證碼可預測 (特定賬戶暴力破解)

8、錯誤超過一定次數才開啟驗證碼 (撞庫)

我將烏雲上所有的驗證碼案例匯總分析,共有63個相關案例,得到如下統計結果:

0x01 驗證碼可重用

這是驗證碼安全里最常見的一類安全問題,也是最容易遺漏的一類

一般來說,驗證碼是與Session綁定的,Session生成時,往往也伴隨着驗證碼的生成和綁定。

在訪問頁面時,接口的請求和驗證碼的生成通常是異步進行的,這使得兩個功能變得相對獨立。也就意味着我們如果僅請求接口,而不觸發驗證碼的生成,那么驗證碼就不會變化。

並且在考慮安全時,開發人員的關注點往往在 驗證碼校驗 是否通過,通過則進入業務流程,不通過則重新填寫,而忽視了 這個用戶是否按照既定的業務流程在走(接口訪問與驗證碼生成是否同時進行),驗證碼是否被多次使用了。

理論上來講,任何驗證碼只能使用一次或幾次,否則就可能導致安全問題

  • 案例1 (驗證碼輸入正確時,未銷毀重置)

當用戶輸入正確的驗證碼時,程序認為其通過了校驗,直接進入了業務流程,忽視了驗證碼銷毀重置的問題。

我們可以在輸入了正確驗證碼后,不斷重用這一驗證碼,這導致了 特定賬戶暴力破解的問題

WooYun這方面的案例有27個

http://www.anquan.us/static/bugs/wooyun-2015-0116594.html 驗證正確,未銷毀
http://www.anquan.us/static/bugs/wooyun-2016-0169672.html 正確,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-0164315.html 正確,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-0111128.html 正確,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-0110497.html 校驗正確后,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-0102697.html 校驗正確后,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-099708.html  校驗正確后,未銷毀
http://www.anquan.us/static/bugs/wooyun-2015-093065.html  校驗正確后,未銷毀
http://www.anquan.us/static/bugs/wooyun-2014-087890.html  錯誤,未銷毀,可爆破
http://www.anquan.us/static/bugs/wooyun-2014-085942.html  校驗正確后,未銷毀
http://www.anquan.us/static/bugs/wooyun-2014-084180.html  同上
http://www.anquan.us/static/bugs/wooyun-2014-083092.html  同上
http://www.anquan.us/static/bugs/wooyun-2014-083274.html  同上
http://www.anquan.us/static/bugs/wooyun-2014-082783.html  同上
http://www.anquan.us/static/bugs/wooyun-2014-074661.html
http://www.anquan.us/static/bugs/wooyun-2014-070959.html
http://www.anquan.us/static/bugs/wooyun-2014-056990.html  輸入錯誤時銷毀,正確時不銷毀
http://www.anquan.us/static/bugs/wooyun-2014-050862.html
http://www.anquan.us/static/bugs/wooyun-2014-049064.html
http://www.anquan.us/static/bugs/wooyun-2013-046547.html  異步機制請求驗證碼,未銷毀
http://www.anquan.us/static/bugs/wooyun-2013-028024.html  同上
http://www.anquan.us/static/bugs/wooyun-2013-025053.html  未銷毀
http://www.anquan.us/static/bugs/wooyun-2013-020460.html
http://www.anquan.us/static/bugs/wooyun-2012-013915.html  未銷毀
http://www.anquan.us/static/bugs/wooyun-2012-06226.html
http://www.anquan.us/static/bugs/wooyun-2011-03450.html
  • 案例2 (驗證碼輸入錯誤時,未銷毀)

當用戶輸入錯誤的驗證碼,而程序沒有將驗證碼重置時,也會存在安全隱患

不過驗證碼的爆破,有什么意義呢?我們本來就可以看到呀

當一個敏感操作的CSRF存在驗證碼防御,且驗證碼比較弱時,我們就可以用js寫腳本來爆破,繞過防御

0x02 驗證碼可識別

  • 案例 1(驗證碼過於簡單)

這個屬於最簡單的驗證碼,過於簡單、清晰、可識別性高,可以編寫程序進行識別,導致驗證碼防御體系失效

WooYun中共有7個類似案例:

http://www.anquan.us/static/bugs/wooyun-2016-0204186.html
http://www.anquan.us/static/bugs/wooyun-2016-0194576.html
http://www.anquan.us/static/bugs/wooyun-2016-0176919.html
http://www.anquan.us/static/bugs/wooyun-2015-0120388.html
http://www.anquan.us/static/bugs/wooyun-2012-012722.html
http://www.anquan.us/static/bugs/wooyun-2012-011765.html
http://www.anquan.us/static/bugs/wooyun-2012-010851.html

實際上,比這個更難識別,更復雜的驗證碼,也有一些准確率較高的識別方法,我們在測試時把握好效果與成本的平衡即可

0x03 客戶端生成/顯示/校驗

  • 案例1(客戶端生成驗證碼文本,然后在服務端請求對應的img)

程序在客戶端生成驗證碼文本,然后向服務端請求該文本對應的 img,導致我們在客戶端直接拿到驗證碼

程序在客戶端生成驗證碼文本,然后加圖層生成img

  • 案例2 (客戶端生成驗證碼,並且輸出到HTML標簽中)

程序在客戶端生成驗證碼,並且輸出到form表單里的html標簽中,可能是為了方便校驗?

WooYun中共有5個類似案例:

http://www.anquan.us/static/bugs/wooyun-2015-0161823.html
http://www.anquan.us/static/bugs/wooyun-2015-0146767.html
http://www.anquan.us/static/bugs/wooyun-2015-099909.html
http://www.anquan.us/static/bugs/wooyun-2012-06634.html
http://www.anquan.us/static/bugs/wooyun-2012-012829.html
https://xz.aliyun.com/t/4487
  • 案例3(服務端生成驗證碼,但將明文文本返回給了客戶端)

驗證碼生成之后,向客戶端返回了驗證碼文本(Cookie、body)

WooYun中共有6個類似案例:

http://www.anquan.us/static/bugs/wooyun-2013-023090.html
http://www.anquan.us/static/bugs/wooyun-2012-010524.html
http://www.anquan.us/static/bugs/wooyun-2012-05151.html
http://www.anquan.us/static/bugs/wooyun-2012-03967.html
http://www.anquan.us/static/bugs/wooyun-2014-075186.html
http://www.anquan.us/static/bugs/wooyun-2014-073811.html
https://xz.aliyun.com/t/4533

0x04 空驗證碼繞過

如果你的代碼是這樣寫的,那就會存在安全問題

if isset($_POST['captcha'])
{
    ....
}

login();

當驗證碼為空時,不進入驗證碼判斷流程,直接進入業務邏輯

WooYun中有6個類似案例:

http://www.anquan.us/static/bugs/wooyun-2015-0150406.html
http://www.anquan.us/static/bugs/wooyun-2013-028061.html
http://www.anquan.us/static/bugs/wooyun-2013-025065.html
http://www.anquan.us/static/bugs/wooyun-2012-014224.html
http://www.anquan.us/static/bugs/wooyun-2012-08287.html
http://www.anquan.us/static/bugs/wooyun-2014-049531.html

0x05 驗證碼數量有限

當程序使用靜態的圖片,而不是動態生成驗證碼時,圖片的數量將是有限的。

我們可以將其全部取回並計算md5,以此繞過驗證碼機制。

WooYun中有2個類似案例,之前的12306也屬於這種情況

http://www.anquan.us/static/bugs/wooyun-2015-0102178.html
http://www.anquan.us/static/bugs/wooyun-2012-07413.html

0x06 是否校驗可控

天才才能寫出來的驗證碼校驗機制,請求中存在一個字段,來決定是否進行校驗,修改為 false(0) 即可

WooYun中有5個類似案例

http://www.anquan.us/static/bugs/wooyun-2014-071289.html
http://www.anquan.us/static/bugs/wooyun-2013-034367.html
http://www.anquan.us/static/bugs/wooyun-2013-026219.html
http://www.anquan.us/static/bugs/wooyun-2012-014563.html
http://www.anquan.us/static/bugs/wooyun-2014-082981.html

0x07 超過次數才開啟驗證碼

接口在登錄錯誤超過一定次數后才會開啟驗證碼,這種機制要么是基於ip判斷,要么就是基於session判斷,要么是基於賬號判斷

  • 案例1 (基於session)

如果是基於Session判斷,我們清空session即可繞過。

WooYun中有1個類似案例

http://www.anquan.us/static/bugs/wooyun-2015-0114450.html
  • 案例2 (基於ip)

如果是基於ip判斷,我們可以嘗試ip是否可以偽造,或者使用代理池

WooYun中有1個類似案例

http://www.anquan.us/static/bugs/wooyun-2014-080327.html
  • 案例3 (基於賬號)

服務端的限制僅針對於特定賬號,比如某賬戶錯誤5次以上開啟驗證碼。

這種情況下雖然無法暴力破解特定賬戶,但是仍然可以實施撞庫攻擊

WooYun中有2個類似案例

http://www.anquan.us/static/bugs/wooyun-2015-0149748.html
http://www.anquan.us/static/bugs/wooyun-2016-0193985.html

0x08 驗證碼可預測

當驗證碼與時間戳等因素強相關時,就不再具有隨機性的屬性,導致驗證碼形同虛設。

WooYun中有1個類似案例

http://www.anquan.us/static/bugs/wooyun-2015-0115041.html

3 身份驗證碼安全

身份驗證碼主要是為了驗證操作人身份,然后進行 密碼修改、賬戶變更、重要操作等功能。

而這類驗證碼主要牽扯到5類安全問題:

1、驗證碼返回給客戶端

2、業務流程缺陷

3、驗證碼無時間間隔限制

4、驗證碼可爆破

5、驗證碼在客戶端生成

將烏雲中的案例去重、去無關案例后,有41個身份驗證碼的案例,分布如下:

0x01 驗證碼返回客戶端

服務器將驗證碼明文返回給客戶端,本來覺得這種錯誤比較低級,沒想到這樣的案例還挺多。

大致有三種可能,一種是驗證碼校驗在客戶端進行,這種錯誤太低級了,可能性不大。

另一種情況:

1、客戶點擊獲取驗證碼

2、程序生成一個隨機驗證碼,將參數拼接之后,提交給短信API

3、客戶端需要判斷是否發送成功,所以程序將短信API返回的內容交給了客戶端

作為一個短信API,很有可能會在response中包含了發送的短信內容,導致驗證碼的泄露

最后一種情況,開發寫API的時候,為了方便調試,返回了這些信息,后來忘刪了...

  • 案例

WooYun中有15個類似案例

http://www.anquan.us/static/bugs/wooyun-2016-0179467.html
http://www.anquan.us/static/bugs/wooyun-2016-0172266.html
http://www.anquan.us/static/bugs/wooyun-2015-0139468.html
http://www.anquan.us/static/bugs/wooyun-2014-085124.html
http://www.anquan.us/static/bugs/wooyun-2014-082114.html
http://www.anquan.us/static/bugs/wooyun-2014-078687.html
http://www.anquan.us/static/bugs/wooyun-2014-066510.html
http://www.anquan.us/static/bugs/wooyun-2014-049813.html
http://www.anquan.us/static/bugs/wooyun-2014-049547.html
http://www.anquan.us/static/bugs/wooyun-2013-042464.html
http://www.anquan.us/static/bugs/wooyun-2013-024195.html
http://www.anquan.us/static/bugs/wooyun-2013-022009.html
http://www.anquan.us/static/bugs/wooyun-2013-019668.html
http://www.anquan.us/static/bugs/wooyun-2014-085124.html
http://www.anquan.us/static/bugs/wooyun-2014-082114.html

0x02 業務流程缺陷

涉及到驗證碼的業務,通常都分為多步進行,比如 修改手機號功能:認證原手機號 -> 填寫新手機號

當下一步的業務,沒有校驗上一步的認證是否成功時,就會存在邏輯缺陷繞過。

  • 案例1 (修改response繞過)

填寫手機驗證碼時填任意值,然后修改請求的response包中的標識字段,將其修改為true,即可繞過

實際上這種問題,本質上也是業務流程的邏輯缺陷問題。

雖然驗證碼的校驗在服務端進行,但是下一步的業務,並沒有校驗上一步的認證是否成功,兩者之間是獨立的

這就導致我們可以修改response,讓客戶端直接跳入下一次邏輯,我們也可以審計源碼,直接找出下一步的url

WooYun中有5個類似案例

http://www.anquan.us/static/bugs/wooyun-2015-0151201.html
http://www.anquan.us/static/bugs/wooyun-2015-0120951.html
http://www.anquan.us/static/bugs/wooyun-2015-0119252.html
http://www.anquan.us/static/bugs/wooyun-2015-0104509.html
http://www.anquan.us/static/bugs/wooyun-2015-090379.html
  • 案例2 (手機號合法性)

在驗證碼校驗過程中,程序應嚴格檢查對應關系,即 接收驗證碼的手機號,是否是該賬戶對應的手機號

如果不存在這處對應關系校驗,則會衍生出各種邏輯問題,比如用自己的手機通過驗證,然后修改其它人的信息

其實這種情況下,也是存在業務流程缺陷的問題。下一步的業務,並沒有校驗上一步業務中,手機號是否是屬於該賬戶的

http://www.anquan.us/static/bugs/wooyun-2015-0102205.html
http://www.anquan.us/static/bugs/wooyun-2011-03099.html
http://www.anquan.us/static/bugs/wooyun-2014-080315.html

0x03 驗證碼無時間間隔限制

服務端對用戶請求短信的頻次沒有時間間隔限制,或者是在客戶端限制,可導致短信資源濫用

沒有基於session、ip、賬戶的限制,屬於完全無限制的情況

http://www.anquan.us/static/bugs/wooyun-2012-010102.html
http://www.anquan.us/static/bugs/wooyun-2012-010556.html
http://www.anquan.us/static/bugs/wooyun-2012-04876.html
http://www.anquan.us/static/bugs/wooyun-2012-04771.html
http://www.anquan.us/static/bugs/wooyun-2012-04166.html
http://www.anquan.us/static/bugs/wooyun-2012-04022.html
http://www.anquan.us/static/bugs/wooyun-2011-01188.html
http://www.anquan.us/static/bugs/wooyun-2011-03485.html

0x04 驗證碼可爆破

  • 案例1 (完全無限制)

當驗證碼太弱(4-6位數字),且服務器沒有錯誤次數限制時,則會存在可爆破的問題

WooYun中有7個類似案例

http://www.anquan.us/static/bugs/wooyun-2015-0155994.html
http://www.anquan.us/static/bugs/wooyun-2013-017242.html
http://www.anquan.us/static/bugs/wooyun-2013-016896.html
http://www.anquan.us/static/bugs/wooyun-2012-016179.html
http://www.anquan.us/static/bugs/wooyun-2013-031605.html
http://www.anquan.us/static/bugs/wooyun-2013-040908.html
http://www.anquan.us/static/bugs/wooyun-2012-012377.html
  • 案例2 (限制覆蓋不全)

以重置密碼業務為例:用戶輸入手機驗證碼 -> 用戶提交新密碼

為了解決業務流程綁定的問題,通常兩個步驟的參數中都會帶有驗證碼。

開發人員往往只注意到第一個接口,而忽視了第二個接口。此時,在第一個頁面中使用自己的手機號通過驗證,第二個頁面中修改為他人手機號並爆破

WooYun中有1個類似案例:

http://www.anquan.us/static/bugs/wooyun-2015-0133289.html

0x05 驗證碼在客戶端生成

這種情況下,客戶端生成一個驗證碼發送給服務端,服務端將這個驗證碼拼接,然后請求短信API發送短信

天才才能想出來的辦法

WooYun中有2個類似案例

http://www.anquan.us/static/bugs/wooyun-2014-086716.html
http://www.anquan.us/static/bugs/wooyun-2013-022378.html

4 參考

幾乎所有漏洞案例都來自烏雲、個別案例來自先知 :)

 pdf版本鏈接https://xzfile.aliyuncs.com/upload/affix/20190815235348-def019d4-bf74-1.pdf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM