かずきち。の日記

サーバサイドエンジニアのつぶやき

強固な画像認証を突破するTips

Googleのアカウント登録画面であったり、ライブのチケットの購入画面には画像認証が設置されています。
英数字のランダムの文字列が出てきて、打ってくださいってやつですね。
マクロ組んでWEBページを回っていると、やはりそこで詰まってしまいます。
自動投稿、自動取得、自動購入するために、そのセッションを抜けることができれば、便利なことは間違いないです。
どうやら、あの画像認証部分は元になるフォントファイルとフォントサイズを指定して、バックグラウンドで自動生成しています。
ということは元になる認証系のフォントファイルを辞書にして持って、フォントサイズで0.5刻みくらいで回していけば…
いつか突破できるんじゃないかなって思います。
ところで認証系で使われるフォントファイルは世界にどれくらい存在するのでしょうか。
画像処理系のモジュールの勉強でもします。

<?php

// 必要パッケージ
require_once 'Text/CAPTCHA.php';

// 出力画像保存ディレクトリの設定
$imgdir = "img/";

// Text_CAPTCHAオブジェクト作成のパラメータ設定
$option = array(
    'font_path' => './fonts/',
    'font_file' => 'impact.ttf',
    'font_size' => 24
);

// Text_CAPTCHAオブジェクト作成
$captcha = Text_CAPTCHA::factory('Image');
// オブジェクトを初期化
$ret = $captcha->init(120, 60, null, $option);

// エラー処理
if (PEAR::isError($ret)) {
    echo "エラーが発生しました\n";
    echo $ret->toString();
    exit;
}
// 画像に表示させたフレーズ取得
$phrase = $captcha->getPhrase();

// 画像のバイナリデータ取得
$png = $captcha->getCAPTCHAAsPNG();

// 取得画像にエラー確認
if (PEAR::isError($png)) {
    echo "エラーが発生しました\n";
    echo $ret->toString();
    exit;
}

// 取得画像保存
$filename = $imgdir.md5($_SERVER["REMOTE_ADDR"]).".png";
$fp = fopen($filename, "wb");
fputs($fp,$png);
fclose($fp);

session_start();

?>

<form method="get" action="<?php $_SERVER["PHP_SELF"]; ?>" name="auth">
<img src="<?php echo $filename."?".uniqid(""); ?>" />
<input type="text" name="check" size=20>
<input type="submit" value="認証する">
</form>
<script language="javascript">
<!--
document.auth.check.focus();
//-->
</script>

画像認証結果画面<hr>
<?php

echo "入力値:".$_GET["check"];
echo "<hr>";
echo "画像フレーズ:".$_SESSION["phrase"];
echo "<hr>";
// 認証実行
if ($_GET["check"] == $_SESSION["phrase"]) {
    echo "OK";
} else {
    echo "NG";
}

// 次回認証用にフレーズをセッション保存
$_SESSION["phrase"] = $phrase;

?>