Comments
Description
Transcript
第 5 回 パスワードクラッキング
第 5回 パスワードクラッキング 文●愛甲健二 IDAPro 5.0 最初に、IDAPro 5.0 がフリーウェア版として 公開されました ※ 1 のでご紹介します。4.9 との 大きな違 いは、ジャンプ系 の 命令を適切に解 釈し、逆アセンブルウインドウにおいてもグラ フィカルに分岐を表示してくれる機能です。こ れはかなり便利で、 本記事でもそれを利用す る前提で解説をしています。皆さんもぜひバー ジョンアップをお願いします。 エラーメッセージを探せ! 今回は前回に引き続き、付録 DVD-ROM 収 録 の crackme_ex.exe( 日付 制 限 を 回 避した crackme.exe )の解析を行います。付録 DVDROM には連載のバックナンバー PDF も収録し ていますので、必要に応じて参照してください。 さて、前回ユーザー 名は「 WizardBible 」と わかったので、次はパスワードです。解析のア プローチ方法はいくつかありますが、せっかく 「パスワードが間違っています」というエラー メッセージが表示されたので、このエラーメッ セージを手掛かりに処理を追 いましょう。IDA Pro のストリングウインドウ( Strings window ) から「パスワードが間違っています」という文 字列を探し出しダブルクリックすると、逆アセ ンブラウインドウ( IDA View-A )に対象のデー タ列と参照元アドレス( sub_4019F0 )が表示 されます(図 1 ) 。この sub_4019F0 をダブルク リックすることで、実際にこのデータ列を利用 しているアセンブラ命令が表示されます (図 2 )。 図 2 のアセンブラ命令を読むと、パスワード が 間違っている場合 は MessageBoxA が 呼び 出され、正解が入力されたら loc_402769 へジャ ンプし、call [ebp+var_208] が実行されます。 そして、それらは cmp ecx, 0C8C7h の結果で 分岐します。 となると、ecx が 0C8C7h となる ような 文字列 が 正解 パスワードになりますが、 別に正解パスワードを入力せずとも、jz short loc_402769 を jnz short loc_402769 に変えて、 ecx が 0C8C7h ではない場合にジャンプするよ うに書き換えても問題なさそうです。 で は OllyDbg で crackme_ex.exe を 開 き、 0040274C の jz 命令をダブルクリックし、jnz に 変更してください(図 3 )。そして、OllyDbg 上 で crackme_ex.exe を実行します。 問題なさそうに見えましたが、実行すると例 外発生と同時にプログラムが強制終了します。 停止アドレスは実行環境によりますが、パスワー ドを「 bbbbbbbb 」と入力すると下に示したよ うな命令コードで終了します。どうやら jz を jnz に変更するだけではダメだったようです。 図 2 「パスワードが間違っています」と表示する処理 図 1 実行ファイルの中に存在する文字列データ ・例外が発生した箇所 032D0000 032D0007 032D0008 032D000E 19B4DD F4DD04A0 5B 01AF BD4EAC5D 5C SBB DWORD PTR SS:[EBP+EBX*8+A004DDF4],ESI POP EBX ADD DWORD PTR DS:[EDI+5DAC4EBD],EBP POP ESP ※ 1 http://www.hex-rays.com/idapro/idadownfreeware.htm 1 図 3 jz 命令をjnz 命令に変更する ecxの算出方法は? 単純に jz 命令を書き換えただけではダメで したので、今度は素直にアルゴリズムを追いま しょう。ecx と 0C8C7h が 比較されている場所 から少しさかのぼり、004026FE 以降を IDAPro で開きます。 ・IDAPro( 004026FE ) 004026FE 00402700 00402703 00402708 0040270A 00402710 00402710 00402714 00402718 0040271A 0040271E 00402720 00402724 00402726 0040272A 0040272C 00402730 00402732 00402736 00402738 0040273B 0040273D 00402740 00402741 00402744 00402746 0040274C xor lea mov jmp ecx, ecx eax, [ebx+6] edx, 40h short loc_402710 loc_402710: movzx edi, byte ptr[eax-5] movzx esi, byte ptr[eax-6] add esi, edi movzx edi, byte ptr[eax-4] add esi, edi movzx edi, byte ptr[eax-3] add esi, edi movzx edi, byte ptr[eax-2] add esi, edi movzx edi, byte ptr[eax-1] add esi, edi movzx edi, byte ptr[eax+1] add esi, edi movzx edi, byte ptr[eax] add edi, ecx add eax, 8 dec edx lea ecx, [edi+esi] jnz short loc_402710 cmp ecx, 0C8C7h jz short loc_402769 難しい 命令はありませんので、 本連載 の 第 3 回、第 4 回で覚えた知識を駆使し 004026FE 以降を読み進めましょう。004026FE 以降より、 ecx=0、eax= 何かのアドレス、edx=40h が初 期値となり、その後 loc_402710 へジャンプし、 00402710 以降繰り返し処理が行われます。 繰り返し処理では、 「 1 バイトずつ 8 バイト分 のデータを加算する」というルーチンを 1 回と し、edx が 0 になるまで行われ、最後にその結 果 ecx が 0C8C7h になったか否かによって処理 図 4 左下のダンプウインドウに謎の 200h バイトが存在 を分岐します。edx の初期値は 40h なので、つ まりは 分岐 が 行 わ れる前 に、200h( 40h × 8 ) バイト分の値の加算値が ecx に格納されます。 以 上 の 処 理 の 概 要 で す が、IDAPro だけ で はどうしてもわかりにくい場合は、OllyDbg で 004026FE にブレイクポイントを仕掛 け、1 命 令 ずつ 処理を追っていきながらレジスタを確 認すると、より詳細を把握しやすいと思います。 さて、こうなると今度はアドレス ebx が指す 200h バイトのデータ列が気になります。私の 環境では 004026FE 時点での ebx の値は 032E 0000 で、その先のデータ列は「 19 B4 DD F4 DD ... 2A B3 4A 78 1E 」となっています(図 4 )。 パスワードは「 bbbbbbbb 」と入力しました。 つまり、最終的な ecx を 0C8C7h にするために は、 加算値が 0C8C7h になるように謎 の 200h バイトを調整する必要があります。 例外の原因は? 最初に試したとおり、jz を jnz に変更 するだ けでは正常に実行 できず、 例外 が 発生しまし た。例外が発生したアドレス 032D0000 をもう 一度確認すると、アセンブラ命令が sbb で、マ シン語が「 19 B4 DD F4 DD 04 A0 」となってい ます。また、ecx の算出方法を調べていて新た に見つかった謎の 200h バイトですが、このデー タ列も「 19 B4 DD F4 DD ... 」となっています。 この 事実は「もし謎 の 200h バイトの 加算値が 0C8C7h になったら、 謎 の 200h バイトそのも のをマシン語として解釈、実行する」ことを意 味します。 こうなると、今度は入力したパスワード 「bbbb bbbb 」と謎の 200h バイトの関係が気になりま す。ecx の 値 がこのデータ列 から算出されて いる以上、入力したパスワードは必ずこの 200h バイトに何かしらの影響を与えるはずです。試 しに入力するパスワードを「 abcdefgh 」に変更 すると、謎の 200h バイトは「 0D B0 89 69 B0 ... 」 となります。 また、たった 8 文字のパスワードから 200h バ イトものデータ列 が 生成されるとは考 えにく いため、入力されたパスワードによって変更さ れる前の「もともとの 200h バイト」がどこかに 2 あるはずです。IDAPro でアドレス 004026FE よ り前へ戻っていくと、いかにも怪しいデータ列 がスタックへ 連続して 格納されているのが 確 認できます(図 5 ) 。 以上から、次の仮説を立てます。まずスタッ クへ積まれているデータ列がもともとの 200h バイトで、これに対して入力されたパスワード を使 い「何らかのアルゴリズム(アルゴリズム X)」で謎の 200h バイトにデコード(もしくは復号) します。そして、このデコードされたデータ(謎 の 200h バイト)の加算値 ecx と 0C8C7h を比較 し、その結果が真ならば謎の 200h バイトをマ シン語として実行し、偽ならエラーメッセージ を表示して終了します(図 6 ) 。 仮説の確認 では、立てた仮説が本当に正しいのか、IDA Pro と OllyDbg を用いて確認していきましょう。 まず、アドレス 004026FE からさかのぼり、 関 数の先頭 004019F0 まで戻ります。OllyDbg で 004019F0 にブレイクポイントをセットし、ユー ザー名「 WizardBible 」とパスワード「 bbbbbb bb 」を入力 すると 004019F0 で 処理 が 止まり ます。その状態でスタックを確認すると、第 1 引数にパスワードとして 入力された 文字列 が 渡されており、呼び出し元は 00402891 となっ ています。00402891 の少し上には、lstrcmpA でユーザー 名と「 WizardBible 」を比較してい る箇所があります。 004019F0 以降を読み進めていくと、最初の 方は 200h バイトのデータをスタックへ 格納す る処理が延々と続きます。そして、00402690 で VirtualAlloc を呼び出してメモリ空間を確保し、 rep movsd を使い、その空間へでスタックに置 かれた 200h バイトのデータ列がコピーされま す(図 7 ) 。続いて call 00401000 で 00401000 へ 処理が飛びますが、 この 際引数として、 パ スワード「 bbbbbbbb 」と、Virtual Alloc で確 保し、200h バイトのデータ列が格納されたメ モリアドレスがスタックへ 格納されています。 00401000 の ルーチンが 終 わると、200h バイ トのデータ列は変更されていますので、どうや ら 00401000 以降が復号処理のようです。 となると、あとは「 00401000 以降のアルゴ リズムはいったい何か ? 」がわかれば全容が見 えるのですが、暗号アルゴリズムは一般的にか なり複雑 で、 一 から解読 するのはかなり骨 が 折れます。しかし、実行時に暗号処理ならでは の特徴的なデータ列が見られることが多いため、 怪しいデータ列を Google で検索しながら見て いくことで、アルゴリズムの特定が可能です。 例 えば、00401075 では 00409030 の アドレ スにある値「 39 31 29 21 19 11 09 ... 」を参照 していますが、 このデータ列を Google で 検 索すると「 DES 加密算法」というページがヒッ トします。また、004011B0 で参照されている 00409068 の値「 0E 11 0B 18 01 05 ... 」を検索 すると「 Outlook. Safeword Cards,... How do they work 」というWeb サイトがいちばん最初 にヒットし、この サイトには DES アルゴリズム に関する解説が書かれています。 つまり、00401000 のルーチンは DES 関係の アルゴリズムであると簡単に特定できます。ア ルゴリズムさえ特定できれば、わざわざアセン ブルコードは読まずとも Web からソースコー ドを探してそのまま利用できます。 これで、図 6 の仮説のとおりに処理が行われ ていることが確認でき、かつ、アルゴリズム X は DES のようだとわかりました。 パスワードクラッキング手法 さて、 仮説 が 正しいことはわかりましたが、 もともとの 200h バイト:1C 87 4C A2 17 FA ... 入力されたパスワード:bbbbbbbb アルゴリズム X 謎の 200h バイト:19 B4 DD F4 DD 04 A0 ... 実行 (加算値)ecx==0C8C7h エラー MessageBoxA→パスワードが間違っています 図 5 怪しいデータ列がスタックへ格納されている 3 図 6 推測できる処理フロー そもそもの目的は本当 のパスワードを特定す ることです。ここで少し考えてみましょう。 謎 の 200h バイトは平文(実行可能なマシン 語)、もともとの 200h バイトは暗号文、入力さ れるパスワードは鍵、アルゴリズムは DES、そ して 0C8C7h と比較する処理は、正常なマシン 語に復号されたことを確認するチェックサム計 算(のようなもの)とわかりました。では、この ような状態、つまり、暗号文と平文のチェック サムとアルゴリズムがわかっている状態で、鍵 となる復号パスワードを求めることは可能でしょ うか ? アルゴリズムにもよりますが、残念ながら一 般的に使われている暗号アルゴリズムを用 い られれば、この条件下で鍵となるパスワードを 算出することはまず不可能です。となると、残 る手段はパスワードクラッキングしかありませ ん。 パスワードクラッキングには大きく分けて、 「類 推」 「辞書」 「総当たり」の 3 つの方法があります。 類推とは、ターゲットの個人情報などからパ スワードを類推する方法で、 例えば管理者 の 好きな映画、誕生日、出身地などを推測し、1 つずつ試すことです。 技術的な壁がなく誰で も簡単に試 せますが、 重要なシステムにおい て使われていることは稀で、基本的には成功し ない前提で試されます。 次に辞書を使った攻撃です。これは、何百万 行にも及ぶ単語(ワード)が記述されたテキス トファイルを用意し、1 行ずつ順番に試してい く手法です。単語の意味が書かれてある一般 的な辞書とは異なり、よく使われる比較的出現 頻度 の 高 い 単語が 1 行ずつ載っています。 総 当たりでは現実的な時間内で解析できない(す べてのパターンを試すのに年単位の時間がか かる)場合に使われます。 最後に総当たり攻撃ですが、これはその 名 のとおり範囲内で再現できるすべてのパター ンを試す方法です。パスワードが大文字英字 6 文字だとわかっていれば、AAAAAA ∼ ZZZZZZ の 範囲内 のすべての パターンを 1 つずつ 試し ていけばいずれは解答にたどり着けますが、す べてのパターンを試すため、現実的な時間内 には終了しないことが多々あります。 パスワードを破ってみよう これで crackme_ex.exe のパスワードを解析 するためのすべての知識は揃いました。ここか ら先 は第 6 回目までの 宿題とさせていただき 図 7 VirtualAlloc 呼び出し後の処理 たいと思 います。 どのような方法を用 いても 構いませんので、見事パスワードを解析してみ てください。 基本的な処理の流れは図 6 のとおりで、アル ゴリズム X は DES です。DES のソースコードは Web で探せばいくつか見つかると思いますが、 OpenSSL ライブラリ※ 2 を用いる方が簡単かも しれません。また、パスワードクラックを行う プログラムを自作するのではなく、crackme_ ex.exe 自体を少し改造してうまくクラックルー チンを追加してもよいかもしれません。 あと、パスワードクラックの手法としては、8 文字以上のテキストを総当たりするのはかなり 時間がかかりますので、 今回は辞書攻撃を選 ぶべきでしょう。そのための辞書も DVD-ROM に収録していますのでぜひ使ってください。 最後に Windows7 を使っている方 へ。これ は私の確認ミスなのですが、crackme_ex.exe ( crackme.exe )は、Windows7 上では正しく 動作しません。正確には、間違ったパスワード が 入力されているうちは問題 なく動作 するの ですが、正しいパスワードが入力された場合に 「正解」を示すメッセージボックスが表示されず、 プログラムが強制終了してしまいます。よって、 正しいパスワードがわかったら、XP モード上で 実行するか、WindowsVista 以前のバージョン で動作をお試しください。本当に申し訳ありま せん。 さて、今回は crackme.exe のパスワード認証 部分の解析を行いましたが、いかがだったでしょ うか。次回は、実際にパスワードクラックする プログラムを作成し、本当のパスワードを見つ けたいと思います。では、またお会いしましょう。 ※ 2 OpenSSLプロジェクト公式サイト http://www.openssl.org/ 4