滑塊驗證碼(滑動驗證碼)相比圖形驗證碼,破解難度如何?

rt,感覺沒什麼難度呀。

這是什麼鬼,怎麼突然就火了

簡單來說就計算出偏移值就破解了滑動驗證碼,識別起來比圖形驗證碼簡單很多,識別圖形驗證碼的代價是要花錢買打碼,讓人工識別,而滑塊就不需要人工了,機器就可以瞬間識別(尤其是html5支持canvas後,有瀏覽器就能方便識別)。

參看,易語言本地破解滑動驗證碼:【原創】滑塊驗證碼識別源碼

補充:

回復 肖元安,菜鳥才會用按鍵精靈去破解,作為黑客怎麼能夠不會使用curl和ajax呢


這個必須冒個泡,因為好一段時間裡我和公司的小夥伴都在研究關於各種驗證碼的破解,圖形和滑動驗證碼都有搞過,針對阿里的滑塊,極驗的幾代產品,和一些複雜的驗證碼都做過對應的繞過,這裡準備寫一個稍微長一點的答案給各位開導一下思路。

首先說下結論:在保證較好用戶體驗度的情況下,兩者都不安全,就破解成本而言,圖形驗證碼成本更高一些

接下來我從字元驗證碼到滑動驗證碼挨著跟大家說一下分別的破解方式

=======================驗證碼的分割線========================

圖形驗證碼

首先說說圖形驗證碼

1.從最簡單的驗證碼開始。

最簡單的圖形驗證碼莫過於四位數字或者四位數字+字母,且干擾較小的驗證碼了,這種驗證碼的破解基本不需要費什麼力,利用定製分割+python中的pytesseract模塊即可完成破解,因為很簡單,我就不做闡述了,有興趣可以去看csdn上相關博主的系列教程。

圖像驗證碼識別(三)--基本流程討論 - ysc6688的專欄 - CSDN博客

2.稍微複雜一點的驗證碼

這類驗證碼就可能涉及到降噪去除干擾一類的操作了,當然,這類操作也有很多人研究過了,圖像二值化+開閉運算+腐蝕膨脹,基本可以幹掉絕大多數的干擾,如果是純噪點,可以達到一個非常好的去噪效果。

比如這種驗證碼,經過一個二值化濾波後就達到了一個較好的去噪效果,而這個二值化濾波閾值需要根據實際情況修改

當然實際情況可能沒那麼理想,比如有的驗證碼光通過二值濾波是無法達到這麼好的效果的,這時候使用開閉運算基本也可以處理的較好,因為處理起來也較為簡單,這裡也不細說了。

3.干擾較為嚴重的驗證碼

這類驗證碼存在大量干擾,與字母混合在一起,有的甚至存在粘連,處理起來十分麻煩,需要用到的方式也相對複雜,這裡詳細給大家說一下。

此驗證碼是我們在研究一家安全公司的驗證碼時遇到的,確實複雜度比較強,大量的噪點和混雜的干擾線。

先給大家看看我們處理之後的效果

這個效果雖然說不上多好,但已經完全足夠識別,後來我們對演算法進行了一定的改進,已經可以達到比目前更好的去噪和缺失補償效果,但因為特殊原因不便公開,這裡就暫且分享一下做到這種程度所用到的方法。

驗證碼特徵觀察:這一步主要是觀察驗證碼本身和干擾點或線之間的差異,就我這張驗證碼,大家如果仔細觀察的話可以看出來,干擾線和驗證碼字母本身深度是存在差異的,我們將圖放到ps中,發現字元本身像素大概為140,而干擾線像素大概為124,因此,這就可以作為我們的初步過濾條件,設計一個小的過濾演算法即可進行過濾,效果大致如下

可以看到,干擾線的主體已被我們去掉,但存在的問題也出現了

(1)依然存在大量噪點和干擾塊

(2)驗證碼和干擾線之間的重疊的部分被幹掉,導致較大缺口

(3)並不是每個驗證碼都會有這種明顯的像素區分,遇到其它情況怎麼辦

首先解答第一個問題,處理剩下的噪點和干擾塊,這個很簡單,使用opencv中自帶的閉運算+腐蝕或者開運算+膨脹

kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(2,2))
kernel2=cv2.getStructuringElement(cv2.MORPH_CROSS,(2,2))
# # 閉運算+腐蝕
closed=cv2.morphologyEx(newImg,cv2.MORPH_CLOSE,kernel)
newImg=cv2.erode(closed,kernel2,iterations=1)

這裡的kernel是區域大小,建議大家在處理的時候設置兩個kernel,方便調整。

這是處理之後的效果,可以看到,通過這樣的處理基本消除了絕大部分的干擾,但距離我最上面達到的效果依然有一定距離,調整kernel的大小對最終的效果也會有一定的影響,這個大家可以在實際環境中自己調整。

那麼,上述圖像中存在的缺陷部分如何填補呢?就業是我們的第二個問題,我們使用的是八點掃描法,即對圖像中的每個像素點逐一掃描,比如一個一個像素位置(x,y),分別尋找周圍(x+2,y)(x-2,y)(x,y+2)(x,y-2)(x+2,y+2)(x-2,y+2)(x+2,y-2)(x-2,y-2)這些點的像素值,若周圍八個點的像素存在4點或5點大於某個閾值,則將其置為黑色0,這樣下來,就將部分缺失的像素補充回原圖,達到這個效果。

當然,如果想要達到更好效果,就需要對補償演算法做進一步的改進了,至於怎麼改進大家可以順著這個思路去想

好了,回答第三個問題,如果像素值不像我這個驗證碼和干擾線一樣為兩個固定的值怎麼辦?

這種時候我們可以通過橫向和縱向掃描的方式繪製像素亮度分布直方圖(PS也可以實現類似功能),大概是這個樣子

然後根據直方圖通過將像素範圍設定在某一閾值範圍內來過濾干擾,這種方式針對存在背景圖像的驗證碼,比如在圖像中找字這種驗證碼的過濾效果較好。

再解決一些大家在破解圖像驗證碼中可能遇到的問題:

遇到字元粘連怎麼辦?

通常遇到這種情況,我們會採用骨架演算法,顧名思義,也就是提取圖片最基本的一個框架,關於這個演算法,網上也已經有大量的文章討論,我這裡就不造輪子了

提取圖像的骨架(Skeleton)演算法 - 第二不及的專欄 - CSDN博客

我知道各位比較懶,所以告訴各位python的擴展包里也是帶了這個演算法的,模塊自己去安裝吧

from skimage import morphology
sk=morphology.skeletonize(img)

實現的效果大致就是這個樣子,基本上有粘連的絕大多數驗證碼都能分割開,至於那些重疊很緊的暫時也沒有特別好的辦法

如何來分割驗證碼?

那種位置固定直接按寬度切割的就不說了,說說那些變化的

分割驗證碼網上也有不少的方法,比如

圖像驗證碼識別(七)--字元分割 - ysc6688的專欄 - CSDN博客

這位博主就提到了泛水填充法和x像素投影法,而這裡我說說另一種連通域提取法,所謂的連通域提取,即在圖像中找到像素連通的區域並把它們分割出來,如下圖所示

這是一張我處理之後的驗證碼,在連通域劃分之前

連通域劃分之後

在python中的具體實現

img為原圖
new=img.copy()
mser=cv2.MSER_create()
regions=mser.detectRegions(img)
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions[0]]
cv2.polylines(new, hulls, 1, (0, 255, 0))
cv2.imshow("Image",new)
cv2.waitKey(0)

detectRegions返回兩個參數,regions[0]為被切割後的圖像,regions[1]為一個boxes矩陣(包含被分割後形成的多個分割框,每一行返回了x,y,w,h),需要注意的是返回的box中可能有很多個框,需要篩選。

通過這種方式,即可提取出每一個元素

如何識別驗證碼?

做到我上述效果之後,基本pytesseract都能識別了,當然不可能每張圖片都處理到這個效果,所以還是要通過別的識別途徑,應用最廣泛的就是機器學習了。

使用svm演算法,將樣本集和結果集加入訓練生成模型用以識別處理之後的驗證碼,經我測試準確度大概可以到95%以上,如果是簡單的驗證碼基本可以達到百分之百。

當然,如果祭出深度學習,使用多層CNN進行訓練,調好參,那準確率直逼百分之百,一朋友對普通干擾驗證碼圖片不做任何處理和切割,直接使用tensorflow暴力學習,大概十多萬的樣本集,loss高的可怕,最後準確度竟然達到了驚人的百分之九十七。

現在的大型打碼平台基本也進入了深度學習時代,對於干擾較低的圖形驗證碼基本是秒殺,所以圖形驗證碼已經過時,除非犧牲用戶體驗,將驗證碼混淆的爹媽都認不出來,但這樣顯然就有違了初衷。

圖形驗證碼就先說到這,各位如果有什麼問題可以在評論區說出來,我看到了再補充進文章里,至於為什麼我說滑動驗證碼也不安全,在後續會繼續寫,今天先搬磚,不然工頭要辭退我了。

晚上上來一看網易居然已經被打臉,一樓的兄弟速度真是快,那我明天就具體給大家講講破解滑動驗證碼的一些方法。

=====================滑動驗證碼的分割線=========================

滑動驗證碼

今天繼續如約說一下滑動驗證碼,看到評論區有朋友讓我說說xxx廠商的驗證碼,這個我只能說抱歉,為了規避法律影響,我只說繞過方式,不針對具體廠商,具體怎麼搞你們自己去試吧:)

以四種方式來談一下滑動驗證碼的破解:

1.系統層工具使用

系統層工具,即第三方工具通過調用系統層api進行各類操作,這類工具基本完全模擬人的行為,無法通過js指紋收集直接檢測其是否為工具,這類工具中比較出名的有sikuli、按鍵精靈、大漠插件(遊戲外掛應用較多)等,這裡為大家介紹一下sikuli,搞自動化測試的朋友應該比較熟悉,真正的圖形腳本語言

圖形腳本語言sikuli - 蟲師 - 博客園

看看IDE先:

那段示例代碼如下:

作用就是雙擊打開360瀏覽器,睡3秒然後輸入iphone8點擊搜索,怎麼樣,這種編程是不是很愉快,其中

這個東西就是你們想要的,具體用法我就不說了,我不會告訴你百度搜索「sikuli實現拖拽」第一個鏈接就是,好吧知道你們懶:

圖形化編程軟體 sikuli dragDrop()函數使用拖動 滑動條slider 的一個 demo

其它類似的軟體就不說了,你們自己去摸索

2.selenium webdriver

這個恐怕是搞驗證碼破解用的最多的的一個工具了,這個工具的作用呢就是驅動瀏覽器工作,並向瀏覽器嵌入代碼從而實現對瀏覽器的操控,功能非常強大,只有你想不到的,沒有它做不到的。

給出一個別人做的demo

滑動驗證碼破解:Python Selenium 2.0 應用

然後再給出一段我破解某大型廠商滑動驗證碼的demo

#coding:utf-8

from selenium import webdriver
from selenium.webdriver import ActionChains
import time

driver = webdriver.Firefox()
driver.get("http://xxxxx.com/xxxx/")
driver.delete_all_cookies()

time.sleep(2)
fuck=driver.find_element_by_xpath("//*[@id="nc_1_n1z"]")
action =ActionChains(driver)
action.click_and_hold(fuck)
action.move_by_offset(260,0)
action.release().perform()

使用了最基礎的拖動即完成破解,複雜的我會在後面說到

3.圖像匹配技術

這個其實是一個找坐標的問題,即使用python、java這類的原生代碼進行圖像匹配定位實現拖動,涉及的知識點也很多,大概包括:屏幕截圖、圖像匹配識別、坐標定位、圖像拖動,真正做過原生代碼驗證碼拖動的朋友應該能理解我上述說的,這裡僅介紹一下思路:

  • 屏幕截圖、使用原生代碼對當前窗口截圖
  • 圖像識別,通過驗證碼圖像與截圖中圖像相似度匹配找到驗證碼所在位置
  • 做差找到驗證碼實際在瀏覽器中位置
  • 使用代碼api實現拖動

實現以上幾步,基本完成。

4.逆向前端js

如果說機器學習對滑動驗證碼的幫助,無非就是收集一大堆前端信息,如:滑鼠軌跡、滑動條拖動速度、瀏覽器指紋、XFF、頁面刷新頻率等信息,然後回傳到後端進行分析,而在這之前,廠商需要預先建立一套模型,來對各種收集到的信息進行處理,那麼,如果滿足了條件,就可以完成破解。

因為不太懂逆向,但看別人玩過,所以只說說思路。這種方式基本就是hook前端函數,在處理或者發送指紋信息的時候對其進行篡改,使得前端回傳的數據包由機器學習判別結果為正常從而達到繞過效果,但這種繞過方式通常是最難的,因為前端對抗已經持續了很多年,各種混淆加密已很成熟,一般人去調跟代碼跟到懷疑人生,但依然有高玩可以逆出來,一朋友就成功逆向了谷歌的前端虛擬機我會亂說?

好,方法說完,接下來解答幾個問題

1.面對擁有機器學習的滑動驗證碼要怎麼辦?

很多朋友之所以使用webdriver拖動失敗的原因在於他們直接通過拖動api將滑動驗證碼一股腦從左拖到右,那麼快的速度是肯定會被檢測出來。

建議使用循環或者sleep這類函數減緩拖動速度,你也可以使用點擊事件先在網頁四處點擊兩下,再來拖動。甚至拖動時也可不用直線拖動,可以向上或者向下也拖動幾個像素,使得行為更加接近人的自然操作來規避檢測,這樣基本能搞定絕大多數滑動驗證碼了。

當然也會有有心的廠商對webdriver驅動瀏覽器這樣的方式進行了檢測,導致代碼執行出錯,這個其實很好辦:

我換一種瀏覽器驅動行不行?

我自己編譯chrome改源碼行不行?

我用sikuli行不行?

當然以上都是被測試過可行的,sikuli這種前端無法檢測,所以只要稍稍模擬人的行為(四處點擊,拉斜線等),就可以繞過機器學習檢測了。

2.為什麼說破解圖形驗證碼成本更高?

你看我上面寫的東西,破解滑動驗證碼,除了逆向前端,其餘幾種是不是都很簡單?但是如果我們破解圖形驗證碼要怎麼辦呢?

降噪去噪、提取字元、訓練數據,其中訓練數據就是個大工程,給樣本打標籤打到你吐血。

3.應對簡訊驗證碼、語音驗證碼怎麼辦?

如果是簡訊驗證碼,可以嘗試暴力破解或尋找漏洞,但如果不存在漏洞且位數較高有時間限制的話也就沒辦法了,不過這種驗證碼由於其極不友好的用戶體驗,通常應用於資金交易等重要的環境下。試想如果大面積應用這種驗證碼我不帶手機豈不是都無法登錄賬戶了?

4.驗證碼未來的發展趨勢

從極驗三代其實可以看出來,滑動驗證碼其實也已被放棄

這種機器學習檢測+圖像識別+邏輯的驗證碼將會得到越來越廣泛的應用,但這種驗證碼依然是可以被識別的。

雖然下面的網易雲被打臉,但是它有句話還是很中肯的:攻與防技術都是在對抗中不斷升級的,無解的驗證碼還不存在,但防的一方可以不斷提升破解成本。

好了,答題完畢,寫了這麼多,你們看了都不點贊的?


謝邀請。對本問題下面高票的 「網易雲」官方賬號的回答,我有一些話想說一下。

關於網易驗證碼到底安不安全這個問題,先擺出觀點:

不安全,因為已經被老夫擼出來了

畢竟網易還是大廠商,就不對目前網易線上的那個產品進行直接處理了,別因此結下了梁子,後面不能去網易找工作了。

本文僅僅是為了拋磚引玉的工作,對網易圖片變大前的那種形式進行分析,網易變大後的形式我就不專門針對了,畢竟我也只是學習學習。

產品介紹

先來介紹一下網易的這個驗證碼產品,屬於網易易盾眾多旗下產品中的一個小分支。但是目前看其官網介紹好像已經有不少大型網站系統在使用了。

網易畢竟是大廠商啊,推進進來還是蠻迅速的。

產品官網:http://dun.163.com

滑動式

體驗地址:http://dun.163.com/trial/jigsaw

關於滑動式的驗證形式,大家是不是都相當眼熟啊,其實在網易之前已經有N家廠商提供過類似的這樣的形式的驗證了,網易估計覺得這個主意好,就直接搬過來了吧。

後面我再試試拿下這個驗證,看它到底水平如何,畢竟網易大廠,工資發那麼高,招的人想必也非常牛吧,即使是copy to 163,也應該會有點水平吧。當年,我是那麼想進網易,但是水平太差了,別人看不上哦。

點擊式

體驗地址:http://dun.163.com/trial/picture-click

關於點擊漢字的驗證形式,其實作為用戶來說,真的感覺眼要瞎了,體驗已經相當差了,不過既然能夠作為網易特色的主打產品,想必是在體驗性上對安全性做出了極大的讓步吧。不過,這個也並沒有什麼鳥用,哈哈。

見證奇蹟

這兩種驗證碼看起來蠻唬人的,但是真正對抗起來呢?讓老納來試試,當然我不是 NO CAN 但是還瞎BB的那種人,直接上乾貨。用劉謙的話來說:下面是見證奇蹟的時刻。

滑動式驗證

先寫個腳本下載個200張圖片:

圖片的規格大概是這個樣子:

對數據做下標記工作:

標註數據確實是個體力活,不過還好找了樓下的一個網吧,找了幾個在網吧打LOL沒錢的嗷嗷待哺的小學生做了會兼職,標記了2千張圖片,給了個上網費,他好我也好。

然後再用個流行的機器學習框架花大概1個晚上擼了個模型,花了大概20分鐘訓練出個模型,跑起來感覺還不錯,在網易官網上下載了5千張新圖片,大概對位置的識別率為81.3%。

基本是拿到圖片,就能返回位置了。至此,網易滑動圖像部分已經拿下了

然後再研究前端部分。在分析它的通訊過程和表單的時候,看到它的一些參數 ,還是蠻唬人的,看到下面這一大坨東西,你害怕不害怕?反正我是怕了。

不過,並沒有啥用處,因為直接用一個前端的JS模型器,直接按照它的通訊過程,把原始參數喂進去全部解決。沒辦法,以前剛畢業參加了1年的前端培訓的底子還在。

然後我隨便擼了條軌跡,而且也沒有去做隨機,居然就可以一直驗證通過。瞬間感覺好失落,因為自己的智商並沒有得到好的體現啊。

所以最後的非常順利,2天就拿下了這個驗證碼了

點擊式驗證

這個點擊式好像有一點難啊,因為有可能你看到的圖片是這樣的:

說實話,我已經懷疑我是不是要去醫院檢查一下我的視力了。不過作為一個碼蟻來說,這點苦和累還是能承受的。

然後默默的到樓下網吧抽了幾包煙,蹲點了幾天,俘獲了幾位失足少年,幫我完成了數據的標註工作,然後他們又滿血回到LOL戰場,我也回到我的戰場。深夜,我點起了一支煙,打開電腦,開始了我的戰鬥。

老規矩,先分析圖片:

1. 圖片中一般是4~5~6,7個漢字

2. 有背景干擾

3. 圖片規格 320×100

我感覺研究這個東西,自己要準備好幾瓶小四代言的滴眼液才能補回來啊。

擼了個模型,先做定位,再做漢字的分類:

請依次點擊 議,數,輕 完成驗證

看來目標檢測的定位還是蠻成功的啊,但是也有一些小問題,最右邊的一個坨黑色的東西,居然也被識別出來了,但是無所謂,再看漢字分類的結果:

根據可能性的排序,明顯這個題目的 議,數,輕 三個漢字都在預測的裡面,而且和位置完全吻合。

當然,程序也有瞎的時候,比如下面的這張圖:

識別結果如下:

那個 字沒有識別出來哦,但是3個字裡面能識出2個,還有一個在剩下的幾個漢字裡面瞎猜一個,也有33或者50%的可能性猜對吧,所以,這個也不差。

最後在5千張圖片上面做了下系統實驗,綜合的識圖成功率為97%。

所以雖然過程曲折 ,但是還好結果還是蠻讓人欣慰的:圖片成功拿下。

然後下面就是學習點擊式驗證的前端數據採集過程,果然不出所料:除了圖片之外 沒有任何別的安全策略了。於是,將這些工具集成了一下,形成了完整的工具流,在網易產品的官網上試了幾張圖,基本上15ms一張吧,感覺效率還是蠻高, 當然成功率大概95%以上了。

最後:漢字點擊式驗證成功拿下

簡訊上行

這個好像網易把它當成是大殺器啊。但是仔細一年,其實背景圖那麼多,切片一下就把關鍵信息識別出來了。

當然,這個驗證還是最安全的,最NB的,因為它需要用戶去花掉自己的錢去給一個陌生的號碼發送簡訊。那麼問題來了:

1. 這年頭我微信都只發語音,你讓我手機發簡訊,懶了哦。

2. 我咋知道發這簡訊發了之後,我的話費是不是會被扣完啊。或者被訂閱了某特殊聲訊信息。

所以,我又懶,膽子又小,最後我就放棄了使用這個服務了吧,所以這個驗證碼就成功的阻止了一個人去通過它了。

實在是高明!!!這應該是未來的驗證碼的終極形態吧。建議網易把這個提升到戰略的高度重點發展,發力。

最後的免責聲明:只做學習交流之用,禁止傳播和非法使用。


之前我試過模擬行為的破解,這裡以極驗為例,拋磚引玉說一下它的識別過程吧,思路需要開闊一下,另外需要多多嘗試,破解起來是比較簡單噠。

以下內容摘自我的 GitBook,所以一些圖片名稱之類的先不改啦,原鏈接為:8.2-極驗滑動驗證碼識別 · Python3網路爬蟲實戰,禁止轉載,謝謝。

簡單的圖形驗證碼我們可以直接利用 Tesserocr 來識別,但是近幾年又出現了一些新型驗證碼,如滑動驗證碼,比較有代表性的就是極驗驗證碼,它需要拖動拼合滑塊才可以完成驗證,相對圖形驗證碼來說識別難度上升了幾個等級,這裡我們看下下極驗驗證碼的識別過程。

1. 本節目標

本節我們的目標是用程序來識別並通過極驗驗證碼的驗證,其步驟有分析識別思路、識別缺口位置、生成滑塊拖動路徑,最後模擬實現滑塊拼合通過驗證。

2. 準備工作

本次我們使用的 Python 庫是 Selenium,使用的瀏覽器為 Chrome,在此之前請確保已經正確安裝好了 Selenium 庫、Chrome瀏覽器並配置好了 ChromeDriver,相關流程可以參考第一章的說明。

3. 了解極驗驗證碼

極驗驗證碼其官網為:http://www.geetest.com/,它是一個專註於提供驗證安全的系統,主要驗證方式是拖動滑塊拼合圖像,若圖像完全拼合,則驗證成功,即可以成功提交表單,否則需要重新驗證,樣例如圖8-5 和 8-6 所示:

圖 8-5 驗證碼示例

圖 8-6 驗證碼示例

現在極驗驗證碼已經更新到了 3.0 版本,截至 2017 年 7 月全球已有十六萬家企業正在使用極驗,每天服務響應超過四億次,廣泛應用於直播視頻、金融服務、電子商務、遊戲娛樂、政府企業等各大類型網站,下面是鬥魚、魅族的登錄頁面,可以看到其都對接了極驗驗證碼,如圖 8-7 和 8-8 所示:

圖 8-7 鬥魚登錄頁面

圖 8-8 魅族登錄頁面

4. 極驗驗證碼的特點

這種驗證碼相較於圖形驗證碼來說識別難度更大,極驗驗證碼首先需要在前台驗證通過,對於極驗 3.0,我們首先需要點擊按鈕進行智能驗證,如果驗證不通過,則會彈出滑動驗證的窗口,隨後需要拖動滑塊拼合圖像進行驗證,驗證之後會生成三個加密參數,參數隨後通過表單提交到後台,後台還會進行一次驗證。

另外極驗還增加了機器學習的方法來識別拖動軌跡,官方網站的安全防護說明如下:

  • 三角防護之防模擬

惡意程序模仿人類行為軌跡對驗證碼進行識別。針對模擬,極驗擁有超過 4000 萬人機行為樣本的海量數據。利用機器學習和神經網路構建線上線下的多重靜態、動態防禦模型。識別模擬軌跡,界定人機邊界。

  • 三角防護之防偽造

惡意程序通過偽造設備瀏覽器環境對驗證碼進行識別。針對偽造,極驗利用設備基因技術。深度分析瀏覽器的實際性能來辨識偽造信息。同時根據偽造事件不斷更新黑名單,大幅提高防偽造能力。

  • 三角防護之防暴力

惡意程序短時間內進行密集的攻擊,對驗證碼進行暴力識別 針對暴力,極驗擁有多種驗證形態,每一種驗證形態都有利用神經網路生成的海量圖庫儲備,每一張圖片都是獨一無二的,且圖庫不斷更新,極大程度提高了暴力識別的成本。

另外極驗的驗證相對於普通驗證方式更加方便,體驗更加友好,其官方網站說明如下:

  • 點擊一下,驗證只需要 0.4 秒

極驗始終專註於去驗證化實踐,讓驗證環節不再打斷產品本身的交互流程,最終達到優化用戶體驗和提高用戶轉化率的效果。

  • 全平台兼容,適用各種交互場景

極驗兼容所有主流瀏覽器甚至古老的IE6,也可以輕鬆應用在iOS和Android移動端平台,滿足各種業務需求,保護網站資源不被濫用和盜取。

  • 面向未來,懂科技,更懂人性

極驗在保障安全同時不斷致力於提升用戶體驗,精雕細琢的驗證面板,流暢順滑的驗證動畫效果,讓驗證過程不再枯燥乏味。

因此,相較於一般驗證碼,極驗的驗證安全性和易用性有了非常大的提高。

5. 識別思路

但是對於應用了極驗驗證碼的網站,識別並不是沒有辦法的。如果我們直接模擬表單提交的話,加密參數的構造是個問題,參數構造有問題服務端就會校驗失敗,所以在這裡我們採用直接模擬瀏覽器動作的方式來完成驗證,在 Python 中我們就可以使用 Selenium 來通過完全模擬人的行為的方式來完成驗證,此驗證成本相對於直接去識別加密演算法容易不少。

首先我們找到一個帶有極驗驗證的網站,最合適的當然為極驗官方後台了,鏈接為:https://account.geetest.com/login,首先可以看到在登錄按鈕上方有一個極驗驗證按鈕,如圖 8-9 所示:

圖 8-9 驗證按鈕

此按鈕為智能驗證按鈕,點擊一下即可智能驗證,一般來說如果是同一個 Session,一小段時間內第二次登錄便會直接通過驗證,如果智能識別不通過,則會彈出滑動驗證窗口,我們便需要拖動滑塊來拼合圖像完成二步驗證,如圖 8-10 所示:

圖 8-10 拖動示例

驗證成功後驗證按鈕便會變成如下狀態,如圖 8-11 所示:

圖 8-11 驗證成功結果

接下來我們便可以進行表單提交了。

所以在這裡我們要識別驗證需要做的有三步:

  • 模擬點擊驗證按鈕
  • 識別滑動缺口的位置
  • 模擬拖動滑塊

第一步操作是最簡單的,我們可以直接用 Selenium 模擬點擊按鈕即可。

第二步操作識別缺口的位置比較關鍵,需要用到圖像的相關處理方法,那缺口怎麼找呢?首先來觀察一下缺口的樣子,如圖 8-12 和 8-13 所示:

圖 8-12 缺口示例

圖 8-13 缺口示例

可以看到缺口的四周邊緣有明顯的斷裂邊緣,而且邊緣和邊緣周圍有明顯的區別,我們可以實現一個邊緣檢測演算法來找出缺口的位置。對於極驗來說,我們可以利用和原圖對比檢測的方式來識別缺口的位置,因為在沒有滑動滑塊之前,缺口其實是沒有呈現的,如圖 8-14 所示:

圖 8-14 初始狀態

所以我們可以同時獲取兩張圖片,設定一個對比閾值,然後遍歷兩張圖片找出相同位置像素 RGB 差距超過此閾值的像素點位置,那麼此位置就是缺口的位置。

第三步操作看似簡單,但是其中的坑比較多,極驗驗證碼增加了機器軌跡識別,勻速移動、隨機速度移動等方法都是不行的,只有完全模擬人的移動軌跡才可以通過驗證,而人的移動軌跡一般是先加速後減速的,這又涉及到物理學中加速度的相關問題,我們需要模擬這個過程才能成功。

有了基本的思路之後就讓我們用程序來實現一下它的識別過程吧。

6. 初始化

首先這次我們選定的鏈接為:https://account.geetest.com/login,也就是極驗的管理後台登錄頁面,在這裡我們首先初始化一些配置,如 Selenium 對象的初始化及一些參數的配置:

EMAIL = "test@test.com"
PASSWORD = "123456"

class CrackGeetest():
def __init__(self):
self.url = "https://account.geetest.com/login"
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser, 20)
self.email = EMAIL
self.password = PASSWORD

其中 EMAIL 和 PASSWORD 就是登錄極驗需要的用戶名和密碼,如果沒有的話可以先註冊一下。

7. 模擬點擊

隨後我們需要實現第一步的操作,也就是模擬點擊初始的驗證按鈕,所以我們定義一個方法來獲取這個按鈕,利用顯式等待的方法來實現:

def get_geetest_button(self):
"""
獲取初始驗證按鈕
:return: 按鈕對象
"""
button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "geetest_radar_tip")))
return button

獲取之後就會獲取一個 WebElement 對象,調用它的 click() 方法即可模擬點擊,代碼如下:

# 點擊驗證按鈕
button = self.get_geetest_button()
button.click()

到這裡我們第一步的工作就完成了。

8. 識別缺口

接下來我們需要識別缺口的位置,首先我們需要將前後的兩張比對圖片獲取下來,然後比對二者的不一致的地方即為缺口。首先我們需要獲取不帶缺口的圖片,利用 Selenium 選取圖片元素,然後得到其所在位置和寬高,隨後獲取整個網頁的截圖,再從截圖中裁切出來即可,代碼實現如下:

def get_position(self):
"""
獲取驗證碼位置
:return: 驗證碼位置元組
"""
img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, "geetest_canvas_img")))
time.sleep(2)
location = img.location
size = img.size
top, bottom, left, right = location["y"], location["y"] + size["height"], location["x"], location["x"] + size[
"width"]
return (top, bottom, left, right)

def get_geetest_image(self, name="captcha.png"):
"""
獲取驗證碼圖片
:return: 圖片對象
"""
top, bottom, left, right = self.get_position()
print("驗證碼位置", top, bottom, left, right)
screenshot = self.get_screenshot()
captcha = screenshot.crop((left, top, right, bottom))
return captcha

在這裡 get_position() 函數首先獲取了圖片對象,然後獲取了它的位置和寬高,隨後返回了其左上角和右下角的坐標。而 get_geetest_image() 方法則是獲取了網頁截圖,然後調用了 crop() 方法將圖片再裁切出來,返回的是 Image 對象。

隨後我們需要獲取第二張圖片,也就是帶缺口的圖片,要使得圖片出現缺口,我們只需要點擊一下下方的滑塊即可,觸發這個動作之後,圖片中的缺口就會顯現,實現如下:

def get_slider(self):
"""
獲取滑塊
:return: 滑塊對象
"""
slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "geetest_slider_button")))
return slider

利用 get_slider() 方法獲取滑塊對象,接下來調用其 click() 方法即可觸發點擊,缺口圖片即可呈現:

# 點按呼出缺口
slider = self.get_slider()
slider.click()

隨後還是調用 get_geetest_image() 方法將第二張圖片獲取下來即可。

到現在我們就已經得到了兩張圖片對象了,分別賦值給變數 image1 和 image2,接下來對比圖片獲取缺口即可。要對比圖片的不同之處,我們在這裡遍歷圖片的每個坐標點,獲取兩張圖片對應像素點的 RGB 數據,然後判斷二者的 RGB 數據差異,如果差距超過在一定範圍內,那就代表兩個像素相同,繼續比對下一個像素點,如果差距超過一定範圍,則判斷像素點不同,當前位置即為缺口位置,代碼實現如下:

def is_pixel_equal(self, image1, image2, x, y):
"""
判斷兩個像素是否相同
:param image1: 圖片1
:param image2: 圖片2
:param x: 位置x
:param y: 位置y
:return: 像素是否相同
"""
# 取兩個圖片的像素點
pixel1 = image1.load()[x, y]
pixel2 = image2.load()[x, y]
threshold = 60
if abs(pixel1[0] - pixel2[0]) &< threshold and abs(pixel1[1] - pixel2[1]) &< threshold and abs( pixel1[2] - pixel2[2]) &< threshold: return True else: return False def get_gap(self, image1, image2): """ 獲取缺口偏移量 :param image1: 不帶缺口圖片 :param image2: 帶缺口圖片 :return: """ left = 60 for i in range(left, image1.size[0]): for j in range(image1.size[1]): if not self.is_pixel_equal(image1, image2, i, j): left = i return left return left

get_gap() 方法即為獲取缺口位置的方法,此方法的參數為兩張圖片,一張為帶缺口圖片,另一張為不帶缺口圖片,在這裡遍歷兩張圖片的每個像素,然後利用 is_pixel_equal() 方法判斷兩張圖片同一位置的像素是否相同,比對的時候比較了兩張圖 RGB 的絕對值是否均小於定義的閾值 threshold,如果均在閾值之內,則像素點相同,繼續遍歷,否則遇到不相同的像素點就是缺口的位置。

在這裡比如兩張對比圖片如下,如圖 8-15 和 8-16 所示:

圖 8-15 初始狀態

圖 8-16 後續狀態

兩張圖片其實有兩處明顯不同的地方,一個就是待拼合的滑塊,一個就是缺口,但是滑塊的位置會出現在左邊位置,缺口會出現在與滑塊同一水平線的位置,所以缺口一般會在滑塊的右側,所以要尋找缺口的話,我們直接從滑塊右側尋找即可,所以在遍歷的時候我們直接設置了遍歷的起始橫坐標為 60,也就是在滑塊的右側開始識別,這樣識別出的結果就是缺口的位置了。

到現在為止,我們就可以獲取缺口的位置了,剩下最後一步模擬拖動就可以完成驗證了。

9. 模擬拖動

模擬拖動的這個過程說複雜並不複雜,只是其中的坑比較多。現在我們已經獲取到了缺口的位置,接下來只需要調用拖動的相關函數將滑塊拖動到對應位置不就好了嗎?然而事實很殘酷,如果勻速拖動,極驗必然會識別出來這是程序的操作,因為人是無法做到完全勻速拖動的,極驗利用機器學習模型篩選出此類數據,歸類為機器操作,驗證碼識別失敗。

隨後我又嘗試了分段模擬,將拖動過程劃分幾段,每段設置一個平均速度,同時速度圍繞該平均速度小幅度隨機抖動,同樣無法完成驗證。

最後嘗試了完全模擬加速減速的過程通過了驗證,在前段滑塊需要做勻加速運動,後面需要做勻減速運動,在這裡利用物理學的加速度公式即可完成。

設滑塊滑動的加速度用 a 來表示,當前速度用 v 表示,初速度用 v0 表示,位移用 x 表示,所需時間用 t 表示,則它們之間滿足如下關係:

x = v0 * t + 0.5 * a * t * t
v = v0 + a * t

接下來我們利用兩個公式可以構造一個軌跡移動演算法,計算出先加速後減速的運動軌跡,代碼實現如下:

def get_track(self, distance):
"""
根據偏移量獲取移動軌跡
:param distance: 偏移量
:return: 移動軌跡
"""
# 移動軌跡
track = []
# 當前位移
current = 0
# 減速閾值
mid = distance * 4 / 5
# 計算間隔
t = 0.2
# 初速度
v = 0

while current &< distance: if current &< mid: # 加速度為正2 a = 2 else: # 加速度為負3 a = -3 # 初速度v0 v0 = v # 當前速度v = v0 + at v = v0 + a * t # 移動距離x = v0t + 1/2 * a * t^2 move = v0 * t + 1 / 2 * a * t * t # 當前位移 current += move # 加入軌跡 track.append(round(move)) return track

在這裡我們定義了 get_track() 方法,傳入的參數為移動的總距離,返回的是運動軌跡,用 track 表示,它是一個列表,列表的每個元素代表每次移動多少距離。

首先定義了一個變數 mid,即減速的閾值,也就是加速到什麼位置就開始減速,在這裡定義為 4/5,即模擬前 4/5 路程是加速過程,後 1/5 是減速過程。

隨後定義了當前位移的距離變數 current,初始為 0,隨後進入 while 循環,循環的條件是當前位移小於總距離。在循環里我們分段定義了加速度,其中加速過程加速度定義為2,減速過程加速度定義為 -3,隨後再套用位移公式計算出某個時間段內的位移,同時將當前位移更新並記錄到軌跡里即可。

這樣直到運動軌跡達到總距離時即終止循環,最後得到的 track 即記錄了每個時間間隔移動了多少位移,這樣滑塊的運動軌跡就得到了。

最後我們只需要按照該運動軌跡拖動滑塊即可,方法實現如下:

def move_to_gap(self, slider, tracks):
"""
拖動滑塊到缺口處
:param slider: 滑塊
:param tracks: 軌跡
:return:
"""
ActionChains(self.browser).click_and_hold(slider).perform()
for x in tracks:
ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.5)
ActionChains(self.browser).release().perform()

在這裡傳入的參數為滑塊對象和運動軌跡,首先調用ActionChains 的 click_and_hold() 方法按住拖動底部滑塊,隨後遍歷運動軌跡獲取每小段位移距離,調用 move_by_offset() 方法移動此位移,最後移動完成之後調用 release() 方法鬆開滑鼠即可。

這樣再經過測試,驗證就通過了,識別完成,效果圖 8-17 所示:

圖 8-17 識別成功結果

最後,我們只需要將表單完善,模擬點擊登錄按鈕即可完成登錄,成功登錄後即跳轉到後台。

至此,極驗驗證碼的識別工作即全部完成,此識別方法同樣適用於其他使用極驗3.0的網站,原理都是相同的。

10. 本節代碼

本節代碼地址為:https://github.com/Python3WebSpider/CrackGeetest。


谷歌在相當一段時間以前推出了一種新驗證碼,很多國外網站都在用,「看起來」比滑動驗證碼還容易破解得多:它直接就是一句「I"m not a robot」前面一個複選框,只要像點擊同意用戶協議之類的複選框一樣點一下它就可以。

但是它背後是整個網站對用戶大量滑鼠行為的收集和分析,進而對比用戶移動滑鼠去點那個複選框的過程是否是人類操作滑鼠做出的。要騙過這個驗證碼的難度遠遠大於那些人類盯著看好一會兒才認得出來的驗證碼。

滑動驗證碼同理,背後是大量的滑動軌跡分析和對比,如果能用按鍵精靈直接拖滑塊到位就通過驗證,那個滑動驗證碼很明顯是不合格的,很可能就是寫了個簡單的拖動拼圖意思一下。


首先給出觀點:前沿的基於機器學習建模、多維判斷的拖動滑塊驗證,不是簡單計算滑塊偏移量和按鍵精靈所能應付的,而圖形驗證碼在當前不斷發展的OCR、神經網路面前卻越來越容易失守。

圖形驗證碼的原理和識別,在三四年前就已經有深刻的分析,利用機器學習和機器視覺,把驗證碼的文字和背景分離,去除干擾線,分割字元,扭曲還原,機器就可以做到自動識別。K-Means、SVM(支持向量機)的分類效果就不錯,對於扭曲,神經網路方法更是提供了很高的成功率。不過那時候節點多的大型網路,運算是比較慢的。但現在,數據量積累越來越豐富,深度神經網路模型越來越好,計算能力越來越強,最重要的是機器學習演算法的從業者越來越多,不管是重疊粘連的字元,或者是物體識別,識別率的提升是自然的。

參考:

常見驗證碼的弱點與驗證碼識別

http://blog.csdn.net/problc/article/details/22796971

機器自動識別驗證碼的原理是怎麼樣的?

https://www.zhihu.com/question/22479139

據說,有了深度學習,傳統字元型驗證碼被破解的最大概率已經達到98%。

參考:

網易雲安全(易盾)推"新一代行為式驗證碼"

http://news.yesky.com/hotnews/205/115428705.shtml

拖動滑塊分兩種情況。其餘答案說的前端拼接,就不用說了,確實不容易防不住有心人。新的滑塊驗證碼方案,驗證碼後台針對用戶產生的行為軌跡數據進行機器學習建模,結合訪問頻率、地理位置、歷史記錄等多個維度信息,快速、準確的返回人機判定結果。針對這種方式,單純分析調用JS是破解無效的。原因如同

@閆先森

所說,深度學習判別策略是黑盒。當然,理論上行為軌跡也可以用深度學習破解,不過還是要積累足夠多的訓練樣本,和足夠多的訓練時間。

題外話,攻與防技術都是在對抗中不斷升級的,無解的驗證碼還不存在,但防的一方可以不斷提升破解成本。應用選擇滑塊驗證,也有部分因素是因為競爭激烈的互聯網很看重用戶體驗,拖動畢竟是趣味性交互且容易完成,而圖形驗證碼既容易被黑客攻破,對用戶也並沒有那麼友好——肉眼識別無趣(可能還很艱難),鍵盤手動輸入更浪費時間,體驗比較大。

這裡分享網易雲安全(易盾)的驗證碼方案:

參考網址:雲安全(網易易盾)_內容安全_業務安全_網路安全雲服務-網易雲

易盾驗證碼拋棄了傳統字元型驗證碼展示-填寫字元-比對答案的流程,採用驗證碼展示-採集用戶行為-分析用戶行為流程,用戶只需要產生指定的行為軌跡,不需要鍵盤手動輸入,極大優化了傳統驗證碼用戶體驗不佳的問題;

同時驗證碼後台針對用戶產生的行為軌跡數據進行機器學習建模,結合訪問頻率、地理位置、歷史記錄等多個維度信息,快速、準確的返回人機判定結果,優化了傳統驗證碼基於單一字元維度容易被暴力破解的問題。後台會檢測破解攻擊,如果有破解的情況,會自動切換到更高難度的點選式驗證碼;除此之外網易雲還提供終極驗證上行簡訊驗證,確保驗證碼的安全性。


滑塊驗證碼,這玩意,根本就不是為了提高安全性而做出來的。相反,他是為了在不明顯降低安全性的前提下,讓驗證碼對人類更加友好。

實際上,他的安全性比傳統(良好設計和實現的)字元式驗證碼更低。那為什麼它會給人一種似乎還挺安全的錯覺呢?

因為他是新東西,所以對他的研究還不是太多。不像字元識別,其實是比滑塊更難以解決的問題,但是AI界研究多年,相對來說有一些還可以的成果,甚至是開源的實現。所以讓人覺得 「字元驗證碼已經有辦法破解了」。

這玩意,真的流行起來了之後,那麼對他的破解研究自然也會多起來,到時候只會比字元驗證碼死得更快更徹底。

總結一下,這個方案就是某個並未深刻理解驗證碼對抗本質的,但是還有點小聰明的人,靈光一現所發明的玩意,然後因為他看起來簡單好玩似乎還挺安全,於是在一定範圍內流行了起來的偽安全方案

做安全防禦,是很考驗哲學思維的,需要想的深,想的透,提前把一切可能的攻擊、繞過的花招都預料到,然後提前化解,才能得到真正有效的防禦方案。而類似滑塊驗證碼這種靈光一現的小機靈,只能是一時熱鬧而已


hmm...

在這個問題上 我來說兩句 少一點套路 直接上重點吧

這個問題關鍵在於圖形驗證碼可以人肉破解,滑動驗證碼基於行為,靠人肉不行 有很大的延時

機器如何識別?

滑動圖片驗證方式類似於拼圖,通過滑鼠拖動使滑塊圖片與背景圖的缺口部分重合,形成一幅完整的圖片,從而完成了滑動驗證的過程。

這就構建起了滑動驗證行為式驗證的「行為沙盒」,而用戶使用滑鼠拖動滑塊的動作就是滑動行為式驗證在這個「行為沙盒」中所要偵測的具體的行為。

後記:

看過很多關於破解滑動驗證碼的答案,有的夸夸其談,紙上談兵,有的一知半解,冒充極客,竟然還有用按鍵精靈做的demo版來騙贊,本人義憤填膺,表示相當的不服,決定開發一個牛掰的軟體,根據行為式驗證和神經網路演算法做了一個服務介面,已經能成功繞過「200多個行為判別特徵,堅若磐石的多維驗證防禦體系」 目前已正確率在95%左右(大寫的服 有沒有),大家如果有興趣可以訪問聰明力-驗證碼解析,一起交流學習!


接著樓上的說,現在工商總局也已經用上滑動驗證了,滑動驗證的核心並不是簡單的拼接成功就可以過,所以也不是簡單的算一下偏移量就能破解。滑動驗證做的好的是通過採集你的滑動過程軌跡與伺服器端的海量樣本進行對比,區分人還是機器,用到了很多深度學習的技術,當然市面上也有一些滑動驗證只是前端拼接就能過,大家還是要多多研究一下


簡單地說,滑塊驗證碼跟圖形驗證碼最大的區別是它面向的其實是過程而不是結果。傳統圖形驗證碼只關心你給出的答案對不對,而不關心這個答案是人做出來的還是機器做出來的。而滑塊驗證碼實際上關心的並不是你能不能將滑塊拖到正確的位置,而是你在拖動滑塊的這一過程中表現得像不像一個人。


之前在做一個項目的時候順帶研究了滑動驗證碼的原理,理論和樓主講的差不多。

思路大概分兩種:

  1. 機器的角度,需要分析滑動驗證碼的 ajax 請求,然後偽造網路請求,但難度極大
  2. 模擬人的角度,藉助 phantomjs 或者其他虛擬瀏覽器模擬人的操作,截取滑動驗證碼滑動之前和之後的圖片,然後用圖片處理的包(比如 Pillow)計算滑塊的偏移量,然後模擬人拖動到想應位置,上面也有提到過滑動軌跡驗證的問題,思路也很簡單就是人怎麼做代碼就怎麼做。

Python 版本實現:iYgnohZ/crack-geetest(僅供學習)

效果圖如下:


有一段時間研究過拼圖驗證。

1、沒有後端判斷的,這種就是搞笑來的,直接繞過就好了。

2、後端判斷位置的,這種其實也是來搞笑的,你識別個框在哪個位置還不簡單嗎?

3、後端判斷行為的,這種還是搞笑來的。行為識別聽起來好高大上,實際還是數據而已,拿一個合法的數據樣本加上若干隨機處理,直接繞過前端發送數據就破了。

驗證碼要不被機器識別而且容易被人識別,只有加入機器無法分離而人可以輕易分離的干擾。所以,玩一個簡單的拼圖遊戲就不錯。一個不怕機器識別的圖形驗證碼方案 - xuanbg的專欄 - CSDN博客

這個方案的要點:

1、位置很容易識別,但位置對應的圖片不容易識別

2、空白處的圖片和備選的圖片不是相同的圖片,大小、顏色都不同,機器不經過學習無法識別,但人很容易識別哪個是空白處的圖片

3、每次拼圖都不一樣,機器學習退散

唯一的問題,流量有點大。。。


在保證較好用戶體驗度的情況下,兩者都不安全,就破解成本而言,圖形驗證碼成本更高一些


簡單的滑動驗證是結果比較,也就是常見的拼圖,只要滑動結果在某區間範圍,則為通過。

這種以結果為參照的驗證碼,跟傳統的輸入框驗證碼差不多,都需要人有一個識別的過程,為了減去這種識別過程,牛逼團隊想方設法,想出識別行為的方式,如阿里的滑塊驗證,谷歌的點擊驗證,甚至某些團隊也在調研生物識別,你在輸入用戶名的時候就已經識別出人機。

相比傳統輸入的方式,給一張圖片,加躁之類的,其實難度也就在圖片的識別演算法,這些在現有的圖像分析團隊來說,並不是非常難。

然而,如果採用的是行為過程的採集,這種破解難度不是一般的高,機器始終是機器。


說個題外話,這種驗證方式是一個直系師兄做的,最早是用在珞珈山水上,當時他本科畢業留在國重工作,我們本科班主任帶的他,12年辭職出來專心做這個,還拉了一個華科的,大三的時候班主任讓他過來做創業經驗分享,至今影響深刻


推薦閱讀:

如何看待從Django 2.0開始不再提供對Python2的支持?
JS的基本數據類型的臨時包裝類型對象的觸發條件和生命周期是多久?下面代碼為何結果迥異?
0基礎如何在5天之內完成一個選戶系統?
如何看待前端培訓公司智能社亦庄總部疑似面臨倒閉?
花兩萬的錢去培訓一個自己本身不喜歡的web前端,好不好?

TAG:Web開發 | 網路安全 | 驗證碼 | 計算機圖形學 |