TensorFlow自動識別驗證碼(二)

2021-12-25 阿里雲應急響應
0X000 前言

在 使用tensorflow自動識別驗證碼(一) 這篇文章中,對使用tensorflow自動識別驗證碼的過程做了簡單的了解和編寫。
那麼今天這篇文章將對上篇文章中代碼進行修改用於實現對主流的CMS進行驗證碼的破解。

0x001 破解步驟

先回顧一下 tensorflow 的自動識別驗證碼的步驟

由於後面三步基本都是tensorflow自動完成
我們主要的工作是前兩步。所以步驟以以下幾步為主:

尋找開源系統中的驗證碼模塊

修改和測試驗證碼模塊

驗證碼模塊適配採樣代碼

修改識別 模型參數

0x002 尋找開源系統中的驗證碼模塊

先尋找你想要破解的cms(開不開源沒關係,最主要是你有源碼)。
這裡用的是XXXCMS(=。= 屏蔽掉了關鍵字 自行想像)
我們先登陸一下管理員,OK,果然是有驗證碼的。

打開編輯器 尋找到生成驗證碼的類 checkcode.class.php

<?php/** * 生成驗證碼 * @author chenzhouyu * 類用法 * $checkcode = new checkcode(); * $checkcode->doimage(); * //取得驗證 * $_SESSION['code']=$checkcode->get_code(); */class checkcode {    //驗證碼的寬度    public $width=130;    //驗證碼的高    public $height=50;    //設置字體的地址    private $font;    //設置字體色    public $font_color;    //設置隨機生成因子    public $charset = 'abcdefghkmnprstuvwyzABCDEFGHKLMNPRSTUVWYZ23456789';    //設置背景色    public $background = '#EDF7FF';    //生成驗證碼字符數    public $code_len = 4;    //字體大小    public $font_size = 20;    //驗證碼    private $code;    //圖片內存    private $img;    //文字X軸開始的地方    private $x_start;    function __construct() {        $rand = rand(0,1);        if($rand==0) {            $this->font = PC_PATH.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'font'.DIRECTORY_SEPARATOR.'elephant.ttf';        } else {            $this->font = PC_PATH.'libs'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'font'.DIRECTORY_SEPARATOR.'Vineta.ttf';        }    }    /**     * 生成隨機驗證碼。     */    protected function creat_code() {        $code = '';        $charset_len = strlen($this->charset)-1;        for ($i=0; $i<$this->code_len; $i++) {            $code .= $this->charset[rand(1, $charset_len)];        }        $this->code = $code;    }    /**     * 獲取驗證碼     */    public function get_code() {        return strtolower($this->code);    }    /**     * 生成圖片     */    public function doimage() {        $code = $this->creat_code();        $this->img = imagecreatetruecolor($this->width, $this->height);        if (!$this->font_color) {            $this->font_color = imagecolorallocate($this->img, rand(0,156), rand(0,156), rand(0,156));        } else {            $this->font_color = imagecolorallocate($this->img, hexdec(substr($this->font_color, 1,2)), hexdec(substr($this->font_color, 3,2)), hexdec(substr($this->font_color, 5,2)));        }        //設置背景色        $background = imagecolorallocate($this->img,hexdec(substr($this->background, 1,2)),hexdec(substr($this->background, 3,2)),hexdec(substr($this->background, 5,2)));        //畫一個櫃形,設置背景顏色。        imagefilledrectangle($this->img,0, $this->height, $this->width, 0, $background);        $this->creat_font();        $this->creat_line();        $this->output();    }    /**     * 生成文字     */    private function creat_font() {        $x = $this->width/$this->code_len;        for ($i=0; $i<$this->code_len; $i++) {            imagettftext($this->img, $this->font_size, rand(-30,30), $x*$i+rand(0,5), $this->height/1.4, $this->font_color, $this->font, $this->code[$i]);            if($i==0)$this->x_start=$x*$i+5;        }    }    /**     * 畫線     */    private function creat_line() {        imagesetthickness($this->img, 3);        $xpos   = ($this->font_size * 2) + rand(-5, 5);        $width  = $this->width / 2.66 + rand(3, 10);        $height = $this->font_size * 2.14;        if ( rand(0,100) % 2 == 0 ) {          $start = rand(0,66);          $ypos  = $this->height / 2 - rand(10, 30);          $xpos += rand(5, 15);        } else {          $start = rand(180, 246);          $ypos  = $this->height / 2 + rand(10, 30);        }        $end = $start + rand(75, 110);        imagearc($this->img, $xpos, $ypos, $width, $height, $start, $end, $this->font_color);        if ( rand(1,75) % 2 == 0 ) {          $start = rand(45, 111);          $ypos  = $this->height / 2 - rand(10, 30);          $xpos += rand(5, 15);        } else {          $start = rand(200, 250);          $ypos  = $this->height / 2 + rand(10, 30);        }        $end = $start + rand(75, 100);        imagearc($this->img, $this->width * .75, $ypos, $width, $height, $start, $end, $this->font_color);    }    /**     * 輸出圖片     */    private function output() {        header("content-type:image/png\r\n");        imagepng($this->img);        imagedestroy($this->img);    }}

前期準備工作基本完成。接下來是修改和測試驗證碼模塊

0x003 修改和測試驗證碼模塊

由於系統的驗證碼都是隨機生成且不可控
我們需要把上面的代碼改造成 形如
create_img.php?code=XXXX 的形式
這樣子我們就可以通過上次的py的代碼隨機生成參數
來控制驗證碼的生成從而達到生成樣本的目的。
值得注意的是 這個系統用了兩種字體去生成它的驗證碼
我們這為了減輕識別的負擔,把其中一個去掉 。

改造後 保存為 create_img.php

<?phpclass checkcode{    //驗證碼的寬度    public $width = 130;    //驗證碼的高    public $height = 50;    //設置字體的地址    private $font;    //設置字體色    public $font_color;    //設置隨機生成因子    public $charset = 'abcdefghkmnprstuvwyzABCDEFGHKLMNPRSTUVWYZ23456789';    //設置背景色    public $background = '#EDF7FF';    //生成驗證碼字符數    public $code_len = 4;    //字體大小    public $font_size = 20;    //驗證碼    private $code;    //圖片內存    private $img;    //文字X軸開始的地方    private $x_start;    function __construct()    {        $this->font = './font/elephant.ttf';    }    /**     * 生成隨機驗證碼。     */    protected function creat_code()    {        $this->code = $_GET['code'];    }    /**     * 獲取驗證碼     */    public function get_code()    {        return strtolower($this->code);    }    /**     * 生成圖片     */    public function doimage()    {        $code = $this->creat_code();        $this->img = imagecreatetruecolor($this->width, $this->height);        if (!$this->font_color) {            $this->font_color = imagecolorallocate($this->img, rand(0, 156), rand(0, 156), rand(0, 156));        } else {            $this->font_color = imagecolorallocate($this->img, hexdec(substr($this->font_color, 1, 2)), hexdec(substr($this->font_color, 3, 2)), hexdec(substr($this->font_color, 5, 2)));        }        //設置背景色        $background = imagecolorallocate($this->img, hexdec(substr($this->background, 1, 2)), hexdec(substr($this->background, 3, 2)), hexdec(substr($this->background, 5, 2)));        //畫一個櫃形,設置背景顏色。        imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $background);        $this->creat_font();        $this->creat_line();        $this->output();    }    /**     * 生成文字     */    private function creat_font()    {        $x = $this->width / $this->code_len;        for ($i = 0; $i < $this->code_len; $i++) {            imagettftext($this->img, $this->font_size, rand(-30, 30), $x * $i + rand(0, 5), $this->height / 1.4, $this->font_color, $this->font, $this->code[$i]);            if ($i == 0) $this->x_start = $x * $i + 5;        }    }    /**     * 畫線     */    private function creat_line()    {        imagesetthickness($this->img, 3);        $xpos = ($this->font_size * 2) + rand(-5, 5);        $width = $this->width / 2.66 + rand(3, 10);        $height = $this->font_size * 2.14;        if (rand(0, 100) % 2 == 0) {            $start = rand(0, 66);            $ypos = $this->height / 2 - rand(10, 30);            $xpos += rand(5, 15);        } else {            $start = rand(180, 246);            $ypos = $this->height / 2 + rand(10, 30);        }        $end = $start + rand(75, 110);        imagearc($this->img, $xpos, $ypos, $width, $height, $start, $end, $this->font_color);        if (rand(1, 75) % 2 == 0) {            $start = rand(45, 111);            $ypos = $this->height / 2 - rand(10, 30);            $xpos += rand(5, 15);        } else {            $start = rand(200, 250);            $ypos = $this->height / 2 + rand(10, 30);        }        $end = $start + rand(75, 100);        imagearc($this->img, $this->width * .75, $ypos, $width, $height, $start, $end, $this->font_color);    }    /**     * 輸出圖片     */    private function output()    {        header("content-type:image/png\r\n");        imagepng($this->img);        imagedestroy($this->img);    }}$checkcode = new checkcode();$checkcode->doimage();

接下來要測試一下 編寫 test.py

import requests as reqfrom PIL import Imagefrom io import BytesIOimport numpy as npresponse = req.get('http://127.0.0.1:8080/xxxcms/create_img.php?code=1234')image = Image.open(BytesIO(response.content))gray = image.convert('L')  #灰值gray = gray.point(lambda x: 0 if x<128 else 255, '1') #去雜質gray.show()img = np.array(gray.getdata()) #轉換成數組print  img

運行 python test.py


如果打開看到控制臺以及黑白圖片後
那麼 代表驗證碼部分準備完成

0x004 驗證碼模塊適配採樣代碼

重點看幾個參數

驗證碼的 生成因子

驗證碼的

驗證碼的 位數

上面的類中我們可以看到 這幾個參數的值 依次為

複製一份 generate_captcha.py 為 xxxcms_generate_captcha.py

添加
from io import BytesIO 和 import requests as req 的 import

主要修改兩個地方

第一個是 開頭處的生成參數

width=130,  # 驗證碼圖片的寬 height=50,  # 驗證碼圖片的高 char_num=4,  # 驗證碼字符個數 characters='abcdefghkmnprstuvwyzABCDEFGHKLMNPRSTUVWYZ23456789'):

第二個是 gen_captcha 的方法中獲取圖片的方法修改成test.py中的方法

X = np.zeros([batch_size, self.height, self.width, 1])img = np.zeros((self.height, self.width), dtype=np.uint8)Y = np.zeros([batch_size, self.char_num, self.classes])image = ImageCaptcha(width=self.width, height=self.height)while True:    for i in range(batch_size):        captcha_str = ''.join(random.sample(self.characters, self.char_num))        imgurl = 'http://127.0.0.1:8080/xxxcms/create_img.php?code='+captcha_str        response = req.get(imgurl)        img = Image.open(BytesIO(response.content)).convert('L')        img = np.array(img.getdata())        X[i] = np.reshape(img, [self.height, self.width, 1]) / 255.0        for j, ch in enumerate(captcha_str):            Y[i, j, self.characters.find(ch)] = 1    Y = np.reshape(Y, (batch_size, self.char_num * self.classes))    yield X, Y

打開 train_captcha.py
把import generate_captcha 改為
import xxxcms_generate_captcha as generate_captcha

重新運行 python train_captcha.py

剩下的流程 就和 第一篇一樣了 。

0x005 一些小心得

相關焦點

  • 將您的代碼從 TensorFlow 1 遷移到 TensorFlow 2(二)
    INFO:tensorflow:Evaluation [1/5]INFO:tensorflow:Evaluation [1/5]INFO:tensorflow:Evaluation [2/5]INFO:tensorflow:Evaluation [2/5]INFO:tensorflow:Evaluation [3/5]
  • OpenCV+TensorFlow圖片手寫數字識別(附源碼)
    以下這個圖片是我隨機寫的一串數字,我的目標是利用訓練好的模型來識別出圖片裡面的手寫數字,開始實戰!2層卷積神經網絡的訓練:from tensorflow.examples.tutorials.mnist import input_datafrom tensorflow.python.framework.graph_util import convert_variables_to_constantsfrom tensorflow.python.framework
  • TensorFlow (2) CIFAR-10 簡單圖像識別
    本文主要學習獲取 CIFAR-10 數據集,通過簡單的模型對數據集進行訓練和識別。
  • 這些驗證碼不再安全
    此類識別方法就是流程化作業,基本不太需要在編程上思考太多。識別步驟如下:下載一定數量的目標驗證碼圖片,數量根據驗證圖片的複雜程度而定準備好一套標準的CNN圖像分類的項目模板,並做好相關的功課對項目模板進行簡單的參數調整,以適配當前問題的圖片尺寸將圖像輸入CNN,對輸出的結果和先驗標記的類型做誤差對比
  • Tensorflow官方語音識別入門教程 | 附Google新語音指令數據集
    訓練:開始訓練前,要先裝好TensorFlow,然後在source tree運行這行命令:python tensorflow/examples/speech_commands/train.py上面提到的語音指令數據集會自動開始下載,下載完成後會看到這樣的提示信息:I0730 16:53
  • Ubuntu 18.04安裝Tensorflow(CPU)
    打開老是出現閃退的問題,所以決定換個Ubuntu下繼續折騰tensorflow。>deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse4)更新源列表sudo apt-get update參考:https://www.linuxidc.com/Linux/2019-04/158157.htm二、
  • TensorFlow Serving入門
    docker pull tensorflow/serving2.docker run -p 8501:8501 \    --mount type=bind,\    source=/tmp/tfserving/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu,\    target=/models/half_plus_two
  • TensorFlow 安裝手冊 — 使用 pip 安裝 TensorFlow
    >程序包依賴項是自動安裝的。Python 2.7 GPU supporthttps://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.11.0-cp27-none-linux_x86_64.whlPython 3.4 CPU-onlyhttps://storage.googleapis.com/tensorflow
  • 【乾貨】快速上手圖像識別:用TensorFlow API實現圖像分類實例
    我對這個API小有了解,因為它來自tensorflow的早期版本。這是一個在1000類上訓練的cnn模型。更多詳細信息,請參閱tensorflow頁面。http://image-net.org/challenges/LSVRC/2014/browse-synsets https://www.tensorflow.org/tutorials/image_recognition在我開始向大家展示如何用這個API實現圖像分類之前,我們先來看一個例子:輸入是太空火箭/飛船的圖像。
  • TensorFlow 2.0 部署:TensorFlow Serving
    使用以下命令即可:tensorflow_model_server \ --rest_api_port=埠號(如8501) \ --model_name=模型名 \ --model_base_path="SavedModel格式模型的文件夾絕對地址(不含版本號)"註解TensorFlow
  • 聲網:基於 TensorFlow 在實時音視頻中實現圖像識別
    大家可以利用它將實時音視頻通話與人臉識別、圖像識別、聲紋識別或其它可能用到 Python 庫的應用結合起來,玩出不一樣的花樣。為了方便大家理解如何把它用在自己的項目中,我們還寫了一份 Python demo,與最流行的 TensorFlow 結合,在視頻通話的場景下實現了圖像識別,並已將其開源至 Github。
  • tensorflow(7)利用tensorflow/serving實現BERT模型部署
    本文將在此基礎上,將模型訓練後生成的ckpt文件轉化為pb文件(tensorflow/serving支持的部署文件格式),並使用tensorflow/serving來實現BERT模型的部署及預測。如何將ckpt文件轉化為pb文件?   該項目使用BERT+Bi-LSTM+CRF結構實現中文序列標註,對BERT進行微調,因此模型無疑是複雜的。
  • TensorFlow Profiler安裝指南(真香)
    默認重啟後還需輸入密碼才能完成網絡連接,若需自動連接還需額外配置(可選)。二. 運行環境配置運行環境主要包括:顯卡驅動、CUDA、docker、vps服務、瀏覽器代理插件等。2.1 python環境TensorFlow 2.x對python及作業系統版本有要求,見下圖:
  • Tensorflow如何導出與使用預測圖
    同時Saver支持全局步長參數,通過對不同的step自動保存為檢查點saver.save(sess, 'my-model', global_step=0) ==> filename: 'my-model-0'...
  • 教程 | 如何使用TensorFlow API構建視頻物體識別系統
    mAP 值越高就說明神經網絡的識別精確度越高,但代價是速度變慢。想要了解這些模型更多的信息,請訪問:https://github.com/tensorflow/models/blob/477ed41e7e4e8a8443bc633846eb01e2182dc68a/object_detection/g3doc/detection_model_zoo.md使用 API首先,我嘗試使用了其中最輕量級的模型
  • 詳解Tensorflow模型量化(Quantization)原理及其實現方法
    因此,為了解決此類問題模型量化應運而生,本篇我們將探討模型量化的概念原理、優缺點及tensorflow模型量化的實現方法。五、tensorflow訓練後量化(Post-training quantization)介紹及其實現方法tensorflow訓練後量化是針對已訓練好的模型來說的,針對大部分我們已訓練未做任何處理的模型來說均可用此方法進行模型量化,而tensorflow提供了一整套完整的模型量化工具,如TensorFlow
  • 一文上手最新TensorFlow2.0系列(二)
    這裡python和python3命名指向的都是系統自帶的python版本,apython命令指向的是我們剛剛創建的python虛擬環境。GPU版的TensorFlow包含了CPU版本,如果讀者手上有GPU資源的話,可以直接參考後文會提到的安裝GPU版的TensorFlow。我們可以直接使用「pip installtensorflow==2.0.0-alpha0」命令來進行安裝。
  • Tensorflow in R 系列(1) :數字圖片分類
    安裝 R 和 R studio此次省略300字,建議使用雲計算平臺如Kaggle Kernel/Google Codelab/Google Cloud 等安裝 keras package查看 tensorflow 版本
  • 教程 | Tensorflow keras 極簡神經網絡構建與使用
    發布於2015年,是一套高級API框架,其默認的backend是tensorflow,但是可以支持CNTK、Theano、MXNet作為backend運行。其特點是語法簡單,容易上手,提供了大量的實驗數據接口與預訓練網絡接口,最初是谷歌的一位工程師開發的,非常適合快速開發。
  • Tensorflow 入門:Tensor
    通過最後一句代碼可以看到:tensorflow 2.0 中的計算圖默認是立即執行的(Eagerly Execution)。 Tensor 持有標量值Tensor 可以持有標量:tensor 的 dtype 屬性給出了這個 tensor 的數據類型。這裡 tensorflow 推斷出該 tensor 的數據類型是 int32。