中文點選驗證碼之自動識別
某次測試中遇到了漢字點選的驗證碼,看著很簡單,嘗試了一下發現有兩種簡單的識別方法,終於有空給重新整理一下,分享出來。
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


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