歡迎光臨
每天分享高質量文章

基於Web頁面驗證碼機制漏洞的檢測

*本文作者:SatanX,來自FreeBuf.COM

*宣告:本篇文章僅供滲透測試參考,嚴禁用於非法用途。

 

在當今網際網路上,每個使用者或多或少都在部分網站上註冊過一些帳號,當這些帳號涉及到金錢或者利益的時候,帳號的安全就是一個非常值得重視的問題,因此帳號的安全是各個廠商所非常關註的一個點。但是依然會存在一些廠商在身份驗證這一塊上存在著漏洞,並不是廠商不註重這個問題,只是在程式碼層的驗證過程中的邏輯出現了一些差異,往往這些邏輯漏洞利用起來比較容易。

一、不可靠的前端校驗

在現實環境中,會有許多的網站他們沒有嚴格進行身份校驗,他們往往是透過依靠帳號密碼傳送後回傳的狀態碼來判斷使用者身份是否正確,這就暴露出了很大的漏洞,這種漏洞利用起來就相當的容易,往往只需要一個安全界的神器 BURP 就可以完成身份驗證的繞過,在登入的時候輸入正確的賬戶以及隨意的密碼,將報文攔截下來,然後選擇 burp 裡面的攔截傳回包的功能,捕捉傳回的狀態碼。

 

 

將傳回包中的狀態碼修改為正常登入的狀態碼,當然這裡的狀態碼不一定都是 0 和 1 這種,各種狀態碼都有可能存在,那麼我們怎麼樣判斷正確的狀態碼是什麼呢?

 

這裡我們就需要自己手動註冊一個使用者,然後進行正常登入,並且抓取傳回的狀態碼,當你發現發回的報文中,僅僅只存在狀態碼,並沒有其他 set-cookie 或者 tocken 等資訊的時候,那麼這個登入介面就有極大的可能性存在這種漏洞。這是比較致命的一種漏洞,那麼你可能就會有其他的問題了,即使他存在了這種漏洞,但是我們不太可能擁有其他大量的帳號,這個漏洞的危害不就沒什麼用了碼?這就是我接下來要說的問題。

二、遍歷手機號

現在大多數的網站都存在著手機號註冊的這一個功能,一般來說同一個手機號只能註冊一個帳號,所以手機號也是能作為帳號,這就是能利用的一個點,當手機號能成為帳號的時候,那麼之前所存在的疑問就解決了一半,既然知道手機是可以用來登入的帳號,那麼如何來獲得這些手機號呢?這個問題其實是一個非常好的問題,對於手機號來說,一共有 11 位數,要想胡亂的猜測一個手機號是否在這個平臺上註冊過,一次性猜中的機率是微乎其微,但是有的網站的忘記密碼這一功能就存在利用的方法(不過這種漏洞廠商大多數是忽略的),但是我認為他的危害性還是有的。在我們忘記密碼的時候輸入手機號碼,傳送手機驗證碼的時候,部分網站都會先查詢這個手機號是否在這個網站上註冊過,要是沒有則會提示號碼不存在,存在則傳送簡訊。那麼可以使用這一個邏輯來進行使用者手機號遍歷。順帶提一下手機號碼可以使用手機號碼字典生成器來生成,然後用來遍歷。

如圖所示,使用者不存在則是另外的資訊。我們只需根據 length 長度來辨別,也可以自己寫 py 指令碼來遍歷儲存註冊使用者。這一個點可以獲取到大量的使用者手機號

三、可爆破的手機驗證碼

前面介紹了前端校驗繞過的方法以及使用者手機號獲取的方式,接下來來講解一下手機驗證碼的問題。我放一張思維導圖來供大家參考

 

手機驗證碼存在的位置可能有三個點:登入、註冊、密碼找回這三個點。其中註冊這個點的危害相對較小,除非找到一個可以批次註冊帳號的點。

 

那麼危害較大的就剩下登入和密碼找回了,實際這兩個點的原理是一樣的,只不過利用的環境有所不同。

 

目前登入時候使用手機驗證碼登入的網站數量不是佔很大的百分比,本文就以找回密碼這塊來說明。

 

我們在測試之前首先要進行判斷的時候他的手機簡訊驗證碼的長度、時效以及頁面是否存在有比較難的圖片驗證碼,也就是難以用 python 的庫直接識別的圖片驗證碼(識別率低於 50%)。這是我們首先要註意的,其次提交一次表單,抓包來看看,是否存在有前端加密,或者 sign 等。我以手機驗證碼長度為 4 位和 6 位來分類。

 

第一類:4 位手機驗證碼

 

當我們發現手機驗證碼長度為 4 位的時候,時效為 5 分鐘左右,並且沒有什麼複雜前端加密或者 sign 和複雜的圖片驗證碼的時候,那麼恭喜你,你可能找到了一個可以爆破出驗證碼的點,這種漏洞雖然是爆破,但是他利用所花費的時間確實非常低的,通常可以在很短的時間內重置或者登入一個手機號。這對廠商來說就是一個高危漏洞,相信他會給你不錯的報酬。

 

上面的這種屬於較為簡單的漏洞,筆者在前段時間測試的時候發現了帶有 sign 標記的 4 位驗證碼,這種的爆破的難度就有所提升了,他的 sign 是根據當前的時間戳以及手機號驗證碼等資訊進行加密後生成的,要想去破解這個加密演演算法,是不太現實的。於是筆者就使用了一種騷思路,可能各位安全界的大佬們也用過,那就是 python 的selenium 庫來模擬瀏覽器自動化點選測試,但是這個就需要自己去根據網站的實際情況以及視窗位置來編寫指令碼。關於 selenium 的提供一個學習連結

第二類:6 位手機驗證碼

 

通常來說 6 位的驗證碼,30 分鐘的時效是一個挺安全的設計,因為在 30 分鐘內想跑完 100W 條資料的難度還是挺大,並且網站通常會根據發包速率來進行限制,一旦你的發包速率突破設定,你將會被 403,也就是你的 IP 會被封禁一段時間,有這些設定的驗證碼是安全的,但是如果說時效在 1 小時甚至更長,並且不限制 IP 的發包速率了話,那麼利用也是可以利用的,只不過利用的成本過高,所以基本不考慮。因此在導圖中寫到基本不不去考慮。

四、現實環境下的漏洞案例思路以及分析

接下來給大家帶來一個真實的漏洞案例,也是我本人所挖掘到的一個高危漏洞

在登陸介面,由於圖片驗證碼長期有效,所以猜測可以爆破。

 

透過兩次提交發現圖片驗證碼在一定時間內是不會發生變化的,儘管已經經過了一次校驗。因為檢視 js 發現驗證碼是由手機驗證碼經過 sha256 後從第六位開始取 4 位收到的驗證碼,測試時候輸入的驗證碼為 1602

 

 

證明瞭這個加密演演算法,於是利用指令碼生成了 0000-9999 的加密後的字典用來爆破。在爆破過程中發現,驗證碼的時效 1 分鐘左右,並不足以完成爆破。於是就換了另外一種思路,既然透過爆破是沒有辦法完成驗證碼的限制,則想到了程式員在編寫程式碼的時候他會不會犯一種錯誤,猜想他是否會將過期後的驗證碼重置為一串特定的字元。既然有了這種猜想,那麼就肯定需要來進行一波驗證,首先根據他的加密演演算法發現他的是 sha256,也就是每一位驗證碼資料只會在 0-f 之間生成,於是生成了一個 0000-ffff 的字典,來進行了一波爆破,就如猜想的一樣,爆破出一個意外的數值,當然並不是在第一次爆破過程中發現的,第一次可能是一個意外,於是我便借用了別人的手機進行了幾次嘗試後,發現這個數值是固定的,那麼這個漏洞就證明成立的了。

 

 

這樣就挖掘出了一個任意登入帳號的漏洞,剛好這個網站又存在如之前所說的手機號遍歷的問題,於是結合這兩個點所產生的結果就是可以登入任意使用者。

 

當然關於挖掘到這方面的漏洞不止一個,但是礙於廠商修複尚未完成不宜公開其他漏洞

分析:對於這個漏洞點的發現其實是因為當時測試時候的突發奇想,本身這個漏洞前端 sha256 加密擷取 4 位這個演演算法不認真找都不容易發現,單單是這一個點就能攔住許多想爆破的人,驗證碼本身是為 0000-9999 的純數字,很難聯想到是從 sha256 中擷取的字串,但是當你繞過這個問題的時候,驗證碼的時效性就又成為了你的下一個問題,筆者在挖掘出這個特殊字串的時候也是有點吃驚的,畢竟這個想法是我在挖掘的時候的突發奇想,也就是腦子一熱冒出來的想法。所以當你在挖掘的時候被一個點困住的時候,不要死磕,可以發散一下思維說不定就能想到設計者在設計的時候所可能犯下的錯誤,4299 這個數字在爆破出來後我對原先加密演演算法的字典裡進行了一波搜尋,發現並不存在 4299 這個數值的,可能設計者當初在設計的時候認為 4299 並 2 不屬於任何 0000-9999 加密後的數值,以為這麼設計不會產生問題。其實漏洞挖掘本身就是一個三分實力七分運氣的事,本著常心肯定會挖掘出的。所以提升自己的能力、改善自己的心態將會成為你挖掘漏洞的時候的一大利器。

贊(0)

分享創造快樂