當前位置:
首頁 > 新聞 > 中文點選驗證碼之自動識別

中文點選驗證碼之自動識別

某次測試中遇到了漢字點選的驗證碼,看著很簡單,嘗試了一下發現有兩種簡單的識別方法,終於有空給重新整理一下,分享出來。


0x01 驗證碼的獲取


首先獲取驗證碼。由於網站比較特殊,就不以他們的為例,自己生成驗證碼吧。這個不是重點,這裡直接貼代碼了。




運行後生成這樣兩張圖片。


ap_XXXXX.png



mp_XXXXX.png



ap_XXXXX.png是說明需要點擊的文字,mp_XXXXX.png是需要點擊的圖片。


0x02 驗證碼識別


對於這種簡單的點選驗證碼,可以有兩種很容易的識別方式(機器學習算麻煩的,這裡就不列出了。嗯,對,我也不會)。一種是opencv的圖像模板匹配,另外一種是OCR識別。


1. opencv的圖像模板匹配


第一種方式,使用opencv的圖像模板匹配。模板匹配是一種在較大圖像中搜索和查找模板圖像位置的方法,opencv2和opencv3中提供了一個專門用於模板匹配的函數matchTemplate()。它是在輸入圖像上滑動模板圖像(如在2D卷積中),並比較模板圖像下的輸入圖像的模板和補丁。在OpenCV中實現了六種比較方法(這裡用到的是cv2.TM_CCOEFF_NORMED),它返回一個灰度圖像,其中每個像素表示該像素的鄰域與模板匹配的程度。


獲得結果後,可以使用cv.minMaxLoc()函數查找最大/最小值的位置。將其作為矩形的左上角,並將(w,h)作為矩形的寬度和高度,那個矩形就是模板區域。


我們進行使用模板匹配來識別這種驗證碼時,首先先將「模板」找出來,這裡我們需要匹配的是「獵」、「戶」、「室」這三個字。將這三個字所在的圖片進行截取,然後使用matchTemplate()函數在mp中進行匹配。


首先截取第一個字「獵」。



截取之後,就可以在mp中進行匹配。

這裡得到了最大和最小位置。我們使用最大位置,然後將最大值作為閾值。獲取模板的尺寸,然後在 mp 中用矩形(紅色區域)畫出匹配的區域。如下所示。


同理,用黃色和藍色矩形將「戶」、「室」所在的區域畫出來。



點選時發送所選區域中間的坐標即可,這裡就不再給出實例了。這種方法雖然簡單,但是對於字體不一的就不能很正確的標記出來。


修改生成圖片的代碼,將mp中的文字的字體設置為隨機。修改的代碼如下:



ap生成的結果還是和之前一樣, mp 的圖片如下:



使用同樣的代碼來匹配。


此時匹配的結果就有些慘不忍睹了。所以就換另外一種識別方式-ocr 識別。

2.OCR識別


這裡採用的是騰訊雲的OCR-通用印刷體識別(https://cloud.tencent.com/document/product/866/17600)。


參考文檔。輸入mp圖片,返回的是json。


查看json內容,發現包含了圖片中的文字、位置和大小等。


同理ap中內容也可以獲取。



此時匹配的時候直接就是匹配文字了。首先獲取ap中後三個文字,然後與mp中返回的內容匹配,獲取其位置和大小,然後再畫矩形即可。


由於比較簡單,這裡直接貼結果。


匹配相當完美。

0X03 總結


本文用了兩種方法來自動識別漢字點選驗證碼,第一種採用的是opencv的模板匹配,這種方法雖然也可以匹配到,但這種方法缺點就是對於字體形狀差異較大的驗證碼識別率較低。而第二種方法就比較快捷方便了,而且識別度高,比較推薦第二種方法。


當然這兩種方法對於簡單、「正規」的驗證碼可以,遇到複雜的、「扭曲的」驗證碼就不行了。這時候就要用到機器學習了,而本文只是簡單的「識別」,將機器學慣用到這裡,就有些大材小用了。


相關代碼:


https://github.com/fupinglee/MyPython/tree/master/captcha/Pointselection


0x04 參考



[1]http://bluewhale.cc/2017-09-22/use-python-opencv-for-image-template-matching-match-template.html


[2]https://cloud.tencent.com/document/product/866/17600


*本文作者:江南天安獵戶攻防實驗室,轉載請註明來自FreeBuf.COM


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

EvilOSX:一款功能強大的macOS遠程管理工具(RAT)

TAG:FreeBuf |