機械学習を使ってCAPTCHAをわずか15分で突破するチャレンジが行われる
By Becky Stern
ネット上で不正なログインを防ぐために使われるCAPTCHAが少し面倒だと思った人は少なからずいるはずですが、進歩著しい人工知能の機械学習技術を用いることで、わずか15分でCAPTCHAそのものを学習し、自動で文字を認識して突破できるようにしてしまった人がいます。
How to break a CAPTCHA system in 15 minutes with Machine Learning
https://medium.com/@ageitgey/how-to-break-a-captcha-system-in-15-minutes-with-machine-learning-dbebb035a710
この試みは、機械学習関連の技術に詳しいAdam Geitgeyさんが行ったものです。Geitgeyさんは、WordPressのプラグインディレクトリの中で「captcha」で検索した時に最も上位にヒットした「Really Simple CAPTCHA」をベースに、CAPTCHAを解析するアプリケーションを開発しています。
このプラグインを選んだ理由は、100万回以上もインストールされていることに加え、ソースコードが公開されているためとのこと。すでにこのプラグインの作者ですらも「もうセキュアとはいえないので他の対策をすべき」と表明している古いプラグインなので、現時点でどれほどの有用性があるかは不明ですが、機械学習のポテンシャルをはかるために今回の試みが行われています。
Really Simple CAPTCHAが生成するCAPTCHAの画面は以下のようなもの。異なるフォントで表示された4つの文字を見てキーボードで入力するというもので、ごく一般的なCAPTCHAの仕組みといえます。
そして公開されているReally Simple CAPTCHAのソースコードがコレ。4文字をランダムなフォントで表示させるというもので、「O」と「I」の2文字はユーザーの混乱を避けるために使われていないとのことです。
Geitgeyさんは今回、次のような環境を用意して今回のチャレンジに挑んでいます。
・Python 3
プログラミング言語のPython 3は、機械学習とコンピュータービジョンに関するライブラリが優れていることが理由。
・OpenCV
コンピュータービジョン技術とイメージ処理で人気のフレームワークであるOpenCVをCAPTCHAの解析に使用。Python向けAPIが提供されているのもメリット。
・Keras
Pythonで書かれたディープラーニングフレームワーク。最小限のコーディングでニューラルネットワークの定義、学習、運用が可能。
・TensorFlow
Googleが提供しているディープラーニングのフレームワーク。コーディングにはKerasを使うものの、ニューラルネットワークのロジックはTensorFlowを流用しているため。
Geitgeyさんが目指したのは、以下のようにCAPTCHAが生成した画像を解析し、含まれる文字を自動で判別するという結果を出すことです。
GeitgeyさんはReally Simple CAPTCHAを使い、学習用に1万種類のCAPTCHA画像を作成。その際には、画像と一緒に正解の文字列を出力しておき、学習の検証を行えるようにしてあるとのことです。ここまでに要した時間は5分。
次に、畳み込みニューラルネットワークにCAPTCHAを読み込ませ、正答率を上げるための学習を進めさせます。
ここで行われたのが、4つの文字を分解して個別に分けた状態で認識を行わせるというもの。そうすることで対象を単純化し、学習効率と正答率を上げようという目論見です。
今回のチャレンジでは、CAPTCHAが出力した文字は4文字である、という条件が決まっているので、画像の分解と解析は比較的容易だった模様。OpenCVに実装されている「findContours()」を使って文字と背景の領域を区別させ、1文字ずつに切り出しを行います。
その際には、画像を2階調に変換することで、文字の部分と背景の部分が完全に区別されるような処理が行われています。
こうすることで、4つの文字を自動で切り分けることができました。
しかしここで問題が発生。Really Simple CAPTCHAが生成した画像の中には、以下のように2つの文字が重なっているものもあり、これをうまく判別できないということが判明。
無理やり判別させてみると、このように「3文字」として認識されてしまうそうです。
そこでGeitgeyさんは、「認識した文字の縦横比で、横の方が広い場合は2文字ある」と判断させるようにアルゴリズムを作成。そして切り出された画像を左右の中心で切り分けることで、重なった文字を分離させるという仕組みを考案しました。
実際に、文字が重なっていたものを切り分けたのが以下の例。隣の文字の一部がはみ出しているものもありますが、文字単体としては正確に切り出しが行われているといえそう。
次に、このようにして切り出された画像に含まれる文字を認識させるための学習を行わせます。今回は、シンプルな画像から文字を判別するという比較的ハードルの低い課題なので、Geitgeyさんは特徴量の畳み込みを行うConvolutional Layerを2つ、そして特徴量から、最終的な判定を行う「Fully Connected Layer」を2つ用いるシンプルな畳み込みニューラルネットワークのアーキテクチャを構築しています。
実際のコーディングにはKerasが用いられているので、以下のように行数の少ないシンプルなコードが作成されているとのこと。
そして実際の学習を以下のコードで実行させます。
学習は全画像に対して10回行われ(10パス)、その結果ほぼ100%の正答率を実現することができたとのこと。そして実際に、ここまでかかった時間は作業開始からたった15分だったそうです。
コマンドラインへの出力はこんな感じ。
Geitgeyさんは、今回のチャレンジで作成したコードを公開しており、このリンクからZIPファイルをダウンロードすることが可能。実際にCAPTCHAが使われる機会は減少しており、複雑な背景があるCAPTCHAだと認識率は激減すると思われるので、このコードをそのまま悪用できるとはとても思えませんが、機械学習が可能にするパワーを自分でも体験できるという意味では興味深いものといえそうです。
・関連記事
歪んだ文字や数字を入力する「CAPTCHA」を突破できるマルウェアが出現、どういう仕組みなのか? - GIGAZINE
CAPTCHA認証の「私はロボットではありません」をロボットが突破するムービー - GIGAZINE
ヘヴィメタ信者とボットを速攻で見分けて面倒なCAPTCHA認証を不要にする「Metal Captcha」 - GIGAZINE
無力感で心が折れそうなほどある意味ひどい認証用のCAPTCHA画像まとめ - GIGAZINE
・関連コンテンツ