C# - 破解網頁的圖片驗證碼

最近限量收到額外任務要對一個投票網頁進行灌票,但這投票的前提是要先註冊,所以限量就要寫一個破解程式來自動化快速註冊與投票,而註冊時需要的資訊可以用隨機字串產生,麻煩的是表單中有圖片驗證碼這搞死人的東西,因為這就涉及到圖形辨識,為了圖形辨識,限量找了許多資源與做法,但大部分的程式都苦於辨識的樣本Code(圖形的Binary樣本),經過一翻搜尋後發現有一群好心人們開發了一套Open Source的圖形辨識Library Tessnet,限量就感激的直接拿來應用了,所以這篇文章主要重點放在利用這套圖形辨識Library Tessnet,進行網頁上圖片驗證碼的辨識。


Tessnet2是一套Open Source的圖形辨識Library,目前版本到2.04.0,他提供.Net DLL讓開發者使用,但DLL只能以.Net Framework 2.0環境執行,這就是限量在使用時遇到的難題,因為撰寫的程式大多用.Net Framework 4.5版本,2.0相較之下比較舊了。但解決方法還是有的,以下就來看看如何用C#使用Tessnet2。
要辨識文字驗證碼有幾個步驟:(1)從指定網頁載入要破解的驗證碼圖片;(2)將驗證碼圖片灰階化以提高辨識的準確性;(3)使用Tessnet Library辨識驗證碼;(4)取得驗證結果並填入網頁驗證碼欄位

使用Tessnet時有幾點要注意:
(1) 到Tessnet2 - Pixel Technology取得Tessnet2的DLL與相關樣本資料。
(2) 在專案裡加入Tessnet2 DLL參考。



(3) 將樣本資料夾放置到執行路徑(bin資料夾下)。
(4) 調整平台建置設定(因為限量這裡是用tessnet2_x64的DLL,所以必須要在專案建置設定裡將平台目標改為x64)



(5) 在App.config裡面的<startup> Tag裡加上useLegacyV2RuntimeActivationPolicy="true"
因為tessnet2的DLL是運行在.Net Framework 2.0上,所以加上這個屬性就可以指定應用程式執行.Net Framework 2.0。

接著下面是進行辨識處理的步驟:

(1) 從指定網頁載入要破解的驗證碼圖片

為了將取得網頁上的驗證碼圖片,限量利用WinForm裡的WebBrowser元件取得網頁的DOM資訊,再取出驗證碼圖片轉換成.Net物件進行處理。



為了在網頁DOM裡取出HTML元件,要在WebBrowser的DocumentCompleted事件裡撰寫取得HTML元件的Code(注意:因為要等整個HTML Document全部載入後才能抓到HTML元件,否則會發生錯誤)


webBrowser1.DocumentCompleted += ( s, e ) =>
{
    var forms = webBrowser1.Document.GetElementsByTagName( "form" );
    // 取得整個網頁的DOM
    var doc = webBrowser1.Document.DomDocument as HTMLDocument;
    var body = doc.body as HTMLBody;
    IHTMLControlRange range = body.createControlRange();
    // 取得驗證碼圖片
    var imgEle = ( forms[0].GetElementsByTagName( "img" ) )[0].DomElement as IHTMLControlElement;
    range.add( imgEle );
    range.execCommand( "copy", false, Type.Missing );
    // 將圖片轉換成.Net物件
    Image img = Clipboard.GetImage();
    Clipboard.Clear();
    pictureBox1.Image = img;
}

(2) 將驗證碼圖片灰階化以提高辨識的準確性
接下來將.Net圖片物件轉換成灰階


private Image convert2GrayScale( Image img )
{
    Bitmap bitmap = new Bitmap( img );

    for ( int i = 0 ; i < bitmap.Width ; i++ )
    {
        for ( int j = 0 ; j < bitmap.Height ; j++ )
        {
            Color pixelColor = bitmap.GetPixel( i, j );
     byte r = pixelColor.R;
     byte g = pixelColor.G;
     byte b = pixelColor.B;

     byte gray = (byte)( 0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b );
     r = g = b = gray;
     pixelColor = Color.FromArgb( r, g, b );

     bitmap.SetPixel( i, j, pixelColor );
 }
    }

    Image grayImage = Image.FromHbitmap( bitmap.GetHbitmap() );
    bitmap.Dispose();
    return grayImage;
}

(3) 使用Tessnet Library辨識驗證碼


private string parseCaptchaStr( Image image )
{
    var sb = new StringBuilder();
    using ( var ocr = new Tesseract() )
    {
        // 設定辨識的相關設定(以下設定為辨識數字)
        ocr.SetVariable( "tessedit_char_whitelist", "0123456789" );
        // 樣本資料夾位置
        var path = string.Concat( Application.StartupPath, @"\tessdata" );
        ocr.Init( path, "eng", true );
        var result = ocr.DoOCR( new Bitmap( image ), Rectangle.Empty );
        // 將辨識結果轉換成字串
        result.ForEach( c =>
        {
            sb.Append( c.Text );
        } );
    }
    return sb.ToString();
}

(4) 取得驗證結果並填入網頁驗證碼欄位



有了破解驗證碼這個大絕招後,看來網路上一些邪惡的工作就可以自動完成了,在這裡限量還是要提醒一下,法網恢恢,疏而不漏,切勿以身試法。



參考來源:
How to use Tessnet2 library
.Net蛤什麼? - [ASP.NET] 圖形驗證碼破解-以簡單圖形為例

留言

  1. 試過用辨試軟體 效果不佳

    回覆刪除
  2. 請問如果說圖片的有辦法破解嗎?
    不知道有沒有在接Case 哈

    回覆刪除
    回覆
    1. 圖片的話目前無法,但國外有強人用Google以圖搜圖的方式有破解,但是正確性不高而且花費較多時間。

      刪除

張貼留言