淺談Web登錄認證類漏洞
0x0 前言
做滲透測試也有一段時間了,每次對目標站點進行滲透的時候都發現登錄方面的問題特別多,針對Web登錄認證這塊,我一直想要寫個帖子進行全面點的總結,耐于目前處于實習階段,工作也較多,所以推遲到了如今,話不多說,下面開始進行對Web登錄認證類漏洞的安全驗證設計機制進行探討。
一、用戶登錄
當我們打開瀏覽器進行瀏覽網頁的時候,或多或少會遇到一些用戶后臺界面,
而這些界面并非任意用戶能訪問,舉個例子吧,就如同我們下班回家,需要進入家里,這時候家門就是一道認證,而我們手里的鑰匙就是進去的憑證,但這道認證確并不安全,為什么呢,請往下看
存在的漏洞

1.用戶枚舉
這種漏洞在web用戶登錄時最為常見,當輸入錯誤的用戶名提示賬號不存在,輸正確的用戶名提示密碼錯誤,從而枚舉用戶名,如下圖:

利用思路:使用工具進行暴力破解,如:BurpSuite、Hydra,當枚舉出用戶賬號時,然后針對指定用戶進行密碼爆破,如果存在賬號鎖定這一策略,那么可制造腳本構造批量的惡意登錄,導致大部分用戶被鎖(如管理員)無法正常登錄后臺業務

修復方案:
1.使用模糊的錯誤提示,如用戶名或密碼不正確
2.采用有效的驗證碼機制 (添加驗證碼也不一定能防止,下文詳說)
2.賬號鎖定
說明:后端登錄機制采取用戶登錄錯誤次數過多鎖定賬號
利用思路:寫個腳本批量登錄或利用bp爆破用戶賬號導致大部分用戶被鎖,致使業務系統不能正常運轉

修復方案:
1.使用有效驗證碼方式防爆破
2.盡量不要使用登錄次數太多鎖定的方式,或者設置短時鎖定
3.賬號密碼暴力破解
這里簡述一下暴力破解
所謂暴力枚舉,就是對密碼字典中的密碼逐個試,直到將用戶名和密碼試出來,但這種方法完全取決于字典是否包含密碼,但是從理論上講,只要我的數據字典足夠大,就沒有枚舉不了的字符形式的密碼,注意,我說的是字符形式,所以,現在出現了生物學密碼,比如指紋識別,虹膜識別等。但最終,生物學密碼也是會以數據的形式存入數據庫
同理,我再舉一個例子,當有一天我回家了,就如同往常一樣,掏出手里的鑰匙去開門,但這時候我手里的鑰匙比較多,暫時分不清哪把鑰匙是能開這個門的,面對這種情況,既然我分不清哪把是能開門的鑰匙,而且我拿鑰匙去開門又沒有次數限制,那么我直接拿鑰匙逐個的去開門嘗試一下不就能得出結果了嗎?這時候只要我手里包含著能開門的鑰匙,那么我就能進去;同理,在我們進行web登錄時,后臺程序如果對我們登錄錯誤的次數不做限制,且沒有驗證碼等防御機制的情況下,那么此時的我們就可以利用字典(就如同剛剛例子手里所有的鑰匙)針對該登錄機制進行暴力破解了,這時候只要我們的字典包含著該站點的賬號密碼,那么我們即可成功進入后臺,這因為站點對我們的非法登錄錯誤次數不做限制,從而導致我們成功利用該漏洞,漏洞效果如下圖:

這是之前復測遇到的一個站點,該站點對用戶登錄密碼錯誤次數沒有限制,且登錄界面存在用戶名枚舉,這可導致攻擊者枚舉出指定用戶,接著針對指定用戶進行密碼爆破,從而進入后臺進行惡意操作
該站點傳輸使用了Base64加密,根據其特性,可把密碼字典進行Base64加密后針對性的進行爆破破解,Base64加密的信息都是可以解密的,面對客戶這些掩耳盜鈴的修復方式也是很無奈
修復方案:
針對該漏洞,我們可以在登錄認證時添加有效驗證碼機制,且服務端第一優先級先驗證驗證碼的存在性和正確性,一個驗證碼使用一次后銷毀,驗證用戶名和認證因子的匹配性、最后再觸發相關功能,重要請求中要帶有驗證碼機制,對不存在或者不正確的賬號采用模糊的報錯提示信息
4.xss
登錄框存在xss,這種情況除了在ctf和靶場遇到外,實戰我還沒遇到過,此外本文只針對登錄認證做探討,想深入了解xss的同學可以自行網上找資料。
對此漏洞我們可以使用以下修補方案:
1.開啟Http Only避免攻擊者利用XSS攻擊盜取用戶cookie
2.對輸出進行html編碼,就是通過函數,將用戶的輸入的數據進行html編碼,使其不能作為腳本運行,對所有的過濾、檢測、限制等策略,建議在Web Server那一端去完成,而不是使用客戶端的JavaScript或者VBScript去做簡單的檢查。因為真正的攻擊者可以繞過你精心設計制作的客戶端進行過濾、檢測或限制手段
5.sql注入
用戶名字段或者密碼字段存在sql注入,比較典型的是萬能密碼登錄(大家都知道)
利用方式:登錄數據傳輸多采用post,這時候我們用bp改包找尋注入點或者丟sqlmap進行探測即可

修復方案:
1.使用參數化查詢,檢查變量數據類型和格式
2.采用sq語句預編譯和綁定變量
二、用戶注冊
注冊功能在網站中并不少見,同樣的,這個功能點也存在眾多問題
常見漏洞有下面幾個:

1、用戶枚舉
注冊時系統提示用戶名已注冊或用戶未注冊,這可導致通過爆破方式來批量枚舉用戶
賬號存在時:

賬號不存在時:

利用思路:
1.先枚舉出用戶名,然后針對該用戶進行密碼爆破,可利用社工庫根據手機號等用戶習慣生成字典進行爆破,這樣成功率會提高不少
2.單個手機號獲取短信無上限,可通過腳本不斷向驗證手機號或者郵箱發送短信或者郵件,導致接收方接受大量垃圾信息
3.登錄認證存在賬號鎖定,寫個腳本批量鎖賬號
修復方案:
1.短信發送設置時間間隔
2.短信發送設置發送次數限制
3.短信發送設置圖形驗證碼,每次發送都要驗證一次圖形驗證碼
2、任意用戶注冊
注冊功能的圖形驗證碼失效,并且手機驗證碼無失效時間并且為4位數,因此可以通過爆破手機驗證碼可以使用任意手機號碼進行注冊
當短信驗證碼為錯誤時:

為正確時:

利用思路:
1.通過爆破手機驗證碼可以使用任意手機號碼進行注冊
2.枚舉已有用戶
修復方案:
1.設置有效及復雜的驗證碼
2.短信驗證碼位數設定為6,能增加爆破難度
3.設定錯誤注冊限制,當用戶短信驗證碼輸錯次數超過一定次數,該驗證碼便失效
3、sql注入
常見的有二次注入
舉一個實戰栗子:
該漏洞位于注冊界面,攻擊者可利用用戶注冊+修改密碼重置admin密碼,這里我注冊一個admin’#的賬號,登陸該賬號后可以進行對admin密碼修改;造成該漏洞的原因是,雖在第一次進行數據庫插入數據的時候,僅僅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 對其中的特殊字符進行了轉義,但在寫入數據庫的時候還是保留了原來的數據,但是數據本身還是臟數據,在將數據存入到了數據庫中之后,開發者就認為數據是可信的,在下一次需要進行查詢的時候,直接從數據庫中取出了臟數據,沒有進行進一步的檢驗和處理,這樣就會造成SQL的二次注入。比如在第一次插入數據的時候,數據中帶有單引號,直接插入到了數據庫中;然后在下一次使用中在拼湊的過程中’會被還原,這就形成了二次注入從而造成admin密碼被重置

修復方案:
1.使用參數化查詢,檢查變量數據類型和格式
2.采用sq語句預編譯和綁定變量
驗證碼
- 1.圖片驗證碼
- 2.短信驗證碼
- 3.郵箱驗證碼
三、圖片驗證碼
- 1.驗證碼復用,有條件不生效
- 2.驗證碼易識別
現如今前端開發使用最多的驗證碼非圖片驗證碼莫屬了,這種驗證碼在一定程度上,可以很好的規避攻擊者針對登錄認證漏洞的利用,但前提是這種驗證碼是有效,在我做滲透測試時,遇到太多由于開發不規范所引起的驗證碼安全問題,話不多說,下面開始探討
1.驗證碼復用,有條件不生效
下面這個案例就比較有意思了
這是我剛剛進公司接到的第一個站,至今記憶猶新;
這個站的驗證碼機制存在的問題是:當同一個http請求到服務端以后最優先驗證了賬號密碼的準確性,隨后才對驗證碼做驗證,這時,驗證碼不是最優先驗證的,并且當賬號密碼為錯誤時,并不會刷新驗證碼,且這時候的驗證碼為有效的;驗證碼有條件不刷新,在驗證碼未遇到正確的賬號密碼時,驗證碼永遠不會刷新,且這時候的驗證碼一直有效,這開發神奇的腦洞很巧妙的導致驗證碼能復用,不說了,看下圖:
1.在密碼正確前未對驗證碼的一次性做驗證

2.只有當同一http請求內所有觸發因子都為正確時,驗證碼的一次性效驗才生效,且下一次驗證碼銷毀

驗證碼失效

這里說到底還是開發的邏輯思維有問題,首先,驗證碼正常情況下,是只能使用一次的,但是,由于數據提交到服務端時,驗證碼的優先級為低,這導致同一個http請求到服務端以后驗證碼不是最先驗證的,從而導致了驗證碼具有復用性,而這時候攻擊者就可以根據這一邏輯漏洞,針對登錄認證這方面做攻擊了,面對開發的這種腦洞,我也是很無奈,好好的一個驗證碼硬是給搞崩了
2.驗證碼易識別
分享一個我之前實戰的一個案例;這個站點的圖片驗證碼易識別,驗證碼雜點太少或者沒有雜點導致可以用程序識別出驗證碼的內容,這可導致攻擊者可根據越權得到的賬號信息,針對指定用戶進行密碼爆破,然后可利用越權漏洞更改指定用戶密碼
1.驗證碼為純數字,且驗證碼易識別

2.審查源碼發現加密方式為前端base64加密

3.密碼傳輸使用Base64加密,根據其特性,寫個py腳本對密碼字典進行Base64加密后針對性的進行爆破破解

4.直接使用Pkav HTTP Fuzzer 進行爆破

由于驗證碼使用不規范,導致攻擊者可進行對站點登錄認證漏洞的利用
安全的認證機制建設
一、圖片驗證碼
1.驗證碼必須要在服務端生成添加雜點干擾項并足夠扭曲以圖片格式返回前端且服務端應第一優先級先驗證驗證碼的存在性、正確性、一次性,其次可對參數進行正則格式驗證、之后對不能驗證參數進行過濾編碼、驗證用戶名和認證因子的匹配性、最后再觸發相關功能
二、登錄數據傳輸
1.采取HTTPS加密通道進行數據傳輸
2.采取有效的加密算法對敏感數據傳輸進行加密
三、手機和郵箱驗證碼
1.驗證碼要有一定的復雜度,至少6位,驗證碼不能返回前端
2.基于客戶端session進行次數限制,制定合適的鎖定策略
3.進行敏感數據操作時對比賬號和綁定的手機郵箱是否匹配,做多次驗證
除此之外,一個安全的認證機制的建設還應包含以下規則:
1.用戶提交敏感數據時,應把驗證碼和注冊/登錄信息在同一http請求中提交,且服務端應優先驗證驗證碼是否正確,最后再觸發相關功能
2.永遠不要相信用戶在數據交互點的輸入數據,面對用戶數據輸入,應做好相對應的參數過濾,針對sql注入,可采取參數綁定或預編譯查詢數據庫避免產生注入,而對于xss,可利用正則判斷部分字段,對用戶輸入的惡意代碼進行過濾,在不影響業務進行的情況下,可對參數進行過濾轉碼,使之不能作為正常的腳本運行