Web登錄認(rèn)證類漏洞分析防御總結(jié)和安全驗(yàn)證機(jī)制設(shè)計(jì)探討
做滲透測(cè)試有一段時(shí)間了,發(fā)現(xiàn)登錄方面的問(wèn)題特別多,想做個(gè)比較全面點(diǎn)的總結(jié),我盡量寫(xiě)的全面點(diǎn)又適合新人,這篇文章可能需要點(diǎn)想象力,因?yàn)閱?wèn)題比較多我不可能去海找各種例子舉出來(lái),不過(guò)好在會(huì)上網(wǎng)就遇到過(guò)各種登錄框,所以大家都比較了解
web登錄認(rèn)證方面,從子功能上可以劃分為登錄框登錄、忘記密碼(密碼重置)、修改密碼、驗(yàn)證碼、發(fā)送手機(jī)驗(yàn)證碼、發(fā)送郵箱驗(yàn)證碼、注冊(cè)賬號(hào)、登錄信息錯(cuò)誤提示、賬號(hào)鎖定等等小功能組成(單點(diǎn)登錄還要講原理,本文暫不涉及),每個(gè)web站點(diǎn)的登錄大約由上面小功能的全部或者一部分組成(這里漏洞缺陷以這些小功能做劃分,更有針對(duì)性覆蓋也全面一點(diǎn),但還是避免不了交叉)。
先從最基礎(chǔ)最常見(jiàn)的開(kāi)始列舉列:
登錄框
登錄框賬號(hào)密碼服務(wù)端持久化:當(dāng)你打開(kāi)登錄頁(yè)面發(fā)現(xiàn)賬號(hào)密碼已經(jīng)填好了,點(diǎn)擊登錄直接進(jìn)后臺(tái)哈哈
- 修復(fù)方案:保存賬號(hào)密碼處理的邏輯針對(duì)本地,session及時(shí)銷毀
- 信息泄露:登錄框提供個(gè)示例用戶名,比如示例郵箱、手機(jī)、用戶名規(guī)則導(dǎo)致黑客掌握規(guī)律生成字典
- 修復(fù)方案:不顯示示例用戶名
- sql注入:用戶名字段或者密碼字段存在sql注入,比較典型的是萬(wàn)能密碼登錄(大家都知道)
- 修復(fù)方案:使用參數(shù)綁定方式查詢和預(yù)編譯語(yǔ)句,如果使用各種框架按照框架安全開(kāi)發(fā)的要求編程
- XSS:用戶名或密碼字段存在XSS,比較典型的是反射XSS打自己
- 修復(fù)方案:使用各種XSS過(guò)濾庫(kù)編碼庫(kù),詳細(xì)請(qǐng)百度,本文不是XSS專題
- 賬號(hào)密碼暴力破解:黑客通過(guò)工具或者腳本加載賬號(hào)密碼字典不斷嘗試登錄
- 修復(fù)方案:添加驗(yàn)證碼(添加驗(yàn)證碼不對(duì)可能導(dǎo)致繞過(guò)等,不一定能防止,下文詳說(shuō))
- 用戶枚舉:輸入不對(duì)的用戶名提示密碼不存在,輸入對(duì)的用戶名提示密碼錯(cuò)誤,從而枚舉用戶名
- 修復(fù)方案:使用模糊的錯(cuò)誤提示,如用戶名或密碼不正確
- 賬號(hào)鎖定:用戶爆破的時(shí)候錯(cuò)誤次數(shù)過(guò)多鎖定賬號(hào),然后黑客批量嘗試用戶名導(dǎo)致大部分用戶名被鎖
- 賬號(hào)詳情泄露:提交合法用戶名,服務(wù)器返回關(guān)于用戶名相關(guān)的賬號(hào)、身份、密碼等詳細(xì)信息
- 修復(fù)方案:使用驗(yàn)證碼方式防爆破,盡量不要使用登錄次數(shù)太多鎖定的方式,或者設(shè)置短時(shí)鎖定
- 低頻撞庫(kù)爆破:利用腳本以慢頻率持久爆破,針對(duì)限制頻率數(shù)字比較大的防御策略
- 修復(fù)方案:使用驗(yàn)證碼機(jī)制
圖片驗(yàn)證碼
- 易識(shí)別:驗(yàn)證碼雜點(diǎn)太少或者沒(méi)有雜點(diǎn)導(dǎo)致可以用程序識(shí)別出驗(yàn)證碼的內(nèi)容
- 驗(yàn)證碼前端生成:驗(yàn)證碼是用js做的,用js生成點(diǎn)隨機(jī)字符填充到前端dom
- 單獨(dú)驗(yàn)證:驗(yàn)證碼和需要驗(yàn)證的參數(shù)不在同一個(gè)http請(qǐng)求,導(dǎo)致驗(yàn)證碼認(rèn)證成功后進(jìn)行攻擊,比如驗(yàn)證碼成功后抓到正在的用戶名密碼的請(qǐng)求進(jìn)行暴力破解
- 置空:當(dāng)驗(yàn)證碼的值或者參數(shù)置空的時(shí)候,可以直接認(rèn)證,這是服務(wù)端邏輯判斷少了一個(gè)驗(yàn)證碼為空的判斷
- 驗(yàn)證碼復(fù)用:同一個(gè)驗(yàn)證碼可以不限次數(shù)的使用,或者驗(yàn)證碼用完沒(méi)銷毀,導(dǎo)致可以爆破或者任意注冊(cè)
- 前端顯示:服務(wù)端生成的驗(yàn)證碼不是圖片,而是字符串直接返回到前端
- 任意值:攔截到http請(qǐng)求,對(duì)驗(yàn)證碼的值設(shè)置任意值都能通過(guò)驗(yàn)證碼驗(yàn)證
- 優(yōu)先級(jí)低:同一個(gè)http請(qǐng)求到服務(wù)端以后驗(yàn)證碼不是最先驗(yàn)證的,比如先驗(yàn)證用戶名,導(dǎo)致用戶枚舉
- 打碼平臺(tái):使用打碼平臺(tái)調(diào)用驗(yàn)證碼接口獲取驗(yàn)證碼進(jìn)行識(shí)別,返回驗(yàn)證碼
- 修復(fù)方案:驗(yàn)證碼必須要在服務(wù)端生成添加雜點(diǎn)干擾項(xiàng)并足夠扭曲以圖片格式返回前端,前端帶驗(yàn)證碼和需要驗(yàn)證參數(shù)在一個(gè)請(qǐng)求里發(fā)送到服務(wù)端,服務(wù)端第一優(yōu)先級(jí)先驗(yàn)證驗(yàn)證碼的存在性和正確性,一個(gè)驗(yàn)證碼使用一次后銷毀
手機(jī)和郵箱驗(yàn)證碼
- 前端顯示:服務(wù)器生成的驗(yàn)證碼返回到頁(yè)面前端,導(dǎo)致前端可以看到產(chǎn)生驗(yàn)證信息泄露
- 復(fù)雜度低:由4位數(shù)字組成的驗(yàn)證碼,如果服務(wù)端沒(méi)次數(shù)限制可以枚舉出來(lái)進(jìn)行登錄或者注冊(cè)
- zha_蛋:通過(guò)腳本不斷向驗(yàn)證手機(jī)號(hào)或者郵箱發(fā)送短信或者郵件,導(dǎo)致接收方接受大量垃圾信息
- 賬號(hào)鎖定:?jiǎn)蝹€(gè)手機(jī)或郵箱一定時(shí)間超過(guò)某次數(shù)鎖定一定時(shí)間,自動(dòng)化批量鎖定賬號(hào)
- 不匹配:比如同請(qǐng)求用戶名和手機(jī)不匹配但依舊發(fā)送驗(yàn)證碼,導(dǎo)致可以向任意號(hào)碼發(fā)短信
- 資費(fèi)消耗:有單個(gè)手機(jī)號(hào)次數(shù)限制,使用大量不同手機(jī)號(hào)短時(shí)間內(nèi)發(fā)送數(shù)萬(wàn)級(jí)短信
- 修復(fù)方案:驗(yàn)證碼要有一定的復(fù)雜度,至少6位,不能返回前端,基于基于客戶端session進(jìn)行次數(shù)限制,制定合適的鎖定策略,對(duì)比賬號(hào)和綁定的手機(jī)郵箱是否匹配
忘記密碼
- 賬號(hào)枚舉:你輸入用戶名提交以后系統(tǒng)提示用戶不存在等
- 認(rèn)證方式篡改:輸入合法用戶名以后輸入其他郵箱或者手機(jī)可以接受到驗(yàn)證碼
密碼重置
- 驗(yàn)證碼繞過(guò):圖片驗(yàn)證碼或手機(jī)驗(yàn)證碼和被重置的賬號(hào)不在同一請(qǐng)求或者利用文中技術(shù)繞過(guò)
- 用戶枚舉:通過(guò)重置接口判斷用戶是否存在,獲取用戶名
- 任意賬號(hào)重置:系統(tǒng)通過(guò)用戶名和密碼倆參數(shù)進(jìn)行密碼重置,導(dǎo)致任意賬號(hào)密碼都能重置
- 認(rèn)證方式篡改:輸入合法用戶名,使用黑客的郵箱或者手機(jī)接收到系統(tǒng)重置的密碼
- 修復(fù)方案:判斷賬號(hào)和綁定驗(yàn)證方式的合法關(guān)系,重要請(qǐng)求中要帶有驗(yàn)證碼機(jī)制,對(duì)不存在或者不正確的賬號(hào)采用模糊的報(bào)錯(cuò)提示信息
任意注冊(cè)
- 用戶枚舉:注冊(cè)時(shí)系統(tǒng)提示用戶名已注冊(cè),批量枚舉用戶
- 驗(yàn)證碼繞過(guò):使用正確的圖像驗(yàn)證碼或者手機(jī)郵箱驗(yàn)證碼后,再提交注冊(cè)信息,其他繞過(guò)方式見(jiàn)上文
- sql注入:注冊(cè)字段沒(méi)有預(yù)編譯參數(shù)綁定,導(dǎo)致注入
- 手機(jī)驗(yàn)證碼爆破:手機(jī)或者郵箱的驗(yàn)證碼太短,不強(qiáng)壯被暴力破解
- 修復(fù)方案:把驗(yàn)證碼和注冊(cè)信息在同一請(qǐng)求提交,服務(wù)端優(yōu)先驗(yàn)證驗(yàn)證碼是否正確,驗(yàn)證碼機(jī)制見(jiàn)上文
組合繞過(guò)
通過(guò)上文各種安全繞過(guò)技術(shù),我們可以嘗試一種或多種手段繞過(guò)驗(yàn)證碼、手機(jī)驗(yàn)證等等,總會(huì)有各種各樣的小漏洞被組合繞過(guò)進(jìn)而進(jìn)行攻擊,具體的看認(rèn)證機(jī)制使用了哪些防御措施,比如是否使用圖片驗(yàn)證碼、手機(jī)驗(yàn)證碼、用戶枚舉、等等吧
安全的認(rèn)證機(jī)制
上文中,關(guān)于認(rèn)證的攻擊繞過(guò)那么多,那么樣的認(rèn)證機(jī)制是安全的?上面重放攻擊那么多,什么是對(duì)抗重放攻擊最有效的手段?
對(duì)于可以使用腳本或者程序自動(dòng)化攻擊的,最有效的防御手段就是驗(yàn)證碼!!
防御手段有哪些關(guān)鍵點(diǎn)呢?
如何盡可能的避免各種邏輯繞過(guò)的漏洞?最好減少人造石步驟,甚至把需要認(rèn)證的參數(shù)全放一個(gè)http請(qǐng)求中!
- 對(duì)于參數(shù)過(guò)濾,可以使用正則匹配就使用正則,比如郵箱、手機(jī)、***使用正則驗(yàn)證,完全可以避免sql注入XSS這些
- 對(duì)于不能使用正則匹配的,對(duì)參數(shù)使用owasp等組織開(kāi)源的過(guò)濾庫(kù)防止XSS
- 對(duì)于同一個(gè)http請(qǐng)求的參數(shù),驗(yàn)證碼擁有最高優(yōu)先級(jí)驗(yàn)證,驗(yàn)證碼驗(yàn)證時(shí)要驗(yàn)證其存在性、參數(shù)的存在性、一次性
- 盡量不要使用接口,因?yàn)榻涌谝话悴荒苁褂抿?yàn)證碼
- 往前端返回信息,使用最小信息原則,只返回必要的信息
一個(gè)安全的認(rèn)證機(jī)制的設(shè)計(jì)
- 登錄功能:把用戶名密碼和其他需要的字段(如驗(yàn)證碼,驗(yàn)證碼只有一次,并足夠雜點(diǎn)和復(fù)雜度)放前端讓客戶一起填寫(xiě),然后放到同一個(gè)http請(qǐng)求提交給后端,后端判斷是否有驗(yàn)證碼參數(shù),然后判斷驗(yàn)證碼是否正確,再然后正則判斷部分字段,不能正則的對(duì)參數(shù)進(jìn)行過(guò)濾轉(zhuǎn)碼,然后使用參數(shù)綁定和預(yù)編譯查詢數(shù)據(jù)庫(kù),出錯(cuò)或者不存在的提示前端用戶名或者密碼錯(cuò)誤,這樣就防止了自動(dòng)化攻擊和SQL注入信息泄露等等
- 密碼重置功能:把驗(yàn)證碼、用戶名、認(rèn)證因子(郵箱、手機(jī)等)放到同一個(gè)http請(qǐng)求中,優(yōu)先驗(yàn)證驗(yàn)證碼的存在性、正確性、一次性,其次對(duì)參數(shù)進(jìn)行正則格式驗(yàn)證、之后對(duì)不能驗(yàn)證參數(shù)進(jìn)行過(guò)濾編碼、驗(yàn)證用戶名和認(rèn)證因子的匹配性、最后再觸發(fā)相關(guān)功能
上面兩種情況,即使攻擊者想撞庫(kù)、鎖定賬號(hào)、批量重置等操作,也會(huì)因?yàn)轵?yàn)證碼而只能影響個(gè)位數(shù)的賬號(hào),對(duì)系統(tǒng)整體影響不大。
其他功能同理,要結(jié)合實(shí)際的場(chǎng)景進(jìn)行設(shè)計(jì),即可把風(fēng)險(xiǎn)控制到最小!