[-]=======================================================================[-] Wizard Bible vol.15 (2005,3,5) [-]=======================================================================[-] x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第0章:目次 --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○第1章:ハニーポットってな〜に? Narusase 著 ○第2章:ハニーポットを作ろう 〜 第1回 〜 Narusase 著 ○第3章:自転車の錠の開錠 Defolos 著 ○第4章:マニアックJavaプログラミング 〜 第2回 〜 SSL Man In The Middle Attack 金床 著 ○第5章:リバースエンジニアリング Kenji Aiko 著 ○第6章:第1回セキュリティアカデメイア・クラックコンテスト IPUSIRON 著 ○第7章:元偽造職人インタビュー MaD 著 ○第8章:お知らせ ○第9章:著者プロフィール x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第1章: ハニーポットってな〜に? --- 著者:Narusase x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  ここ数年、ハニーポットという言葉をよく聞くようになりました。しかし、ハ ニーポットとはいったいどんなものなのでしょうか? ハニーポットとは不正な 攻撃を調査・研究するためにインターネット上に設置された、サーバやネットワ ーク機器のことを言います。ここで言う不正な攻撃の調査・研究とは、不正侵入 の手法の調査・研究やウイルスの動作などの解析などを意味します。また、ハニ ーポットは不正侵入の防御・回避などの実際的なセキュリティ確保の手法として も用いることができます。  この分野で活躍されている方としては日本では、「ハニーポッターの部屋」 (http://d.hatena.ne.jp/connect24h/)のはまもとさんが一番有名でしょう。ま た、企業ではラックが独自開発したハニーポットシステム「Sombria」などを用い て実際にハニーポットを設置し不正アクセスの「侵入傾向分析レポート」などを 発行しています。海外では「Honeynet Project」(http://project.honeynet.org/) のスピッツナー氏が有名です。  しかし、実はハニーポットに関する日本語の文献はほぼほとんどありません。 私の知る限りハニーポットに焦点を当てて書かれた日本語の書籍は次のものしか 知りません。 ○『ハニーポット—ネットワーク・セキュリティのおとりシステム』 ・Lance Spitzner (著), 小池 英樹 (翻訳), ・電気通信大学小池研究室セキュリティ研究グループ (翻訳) ・出版社: 慶應義塾大学出版会 ; ISBN: 4766410866 ・価格: ¥8,400 (税込)  実際のハニーポットの構築方法については皆無と言っても差し支えありません。 ・・・というか筆者は知りません(知ってる方はご一報を・・・)。  もっとも、ハニーポット自体ではなくIDSやログの解析、インシデントレスポン ス、フォレンジックなどハニーポットに関連する技術の書籍についてはいろいろ とあるようです。  と言うわけで、少ないなら自分で書いてしまえと言うことで、ハニーポットの 基礎知識などについて少し書いてみたいと思います。 ・ハニーポットの基礎知識  まず、ここではハニーポットに関する基礎知識について簡単に話したいと思い ます。 ■0x02.) なぜハニーポットが必要か  では、なぜハニーポットが必要なのでしょうか? ハニーポットが必要な理由 としては様々なものが考えられますが、代表的な理由としては不正侵入の手法の 調査や、ウィルスの挙動の解析、同じくウィルスの捕獲、IDSのシグネチャの作成 支援、他の重要なサーバを守るための目くらましなど様々なものが考えられます が、一言で言うならばセキュリティの強化・確保のために必要であると言うこと ができると思います。 ■0x03.) ハニーポットの長所・短所  ハニーポットには当然、長所と短所があります。 ●ハニーポットの長所  まず、長所ですがハニーポットは通常のサービスを行わないため一般的なユー ザからアクセスされず、不正な攻撃や、調査のためのアクセスのみを受けること になります。このため、大きく分けて3点の長所が考えられます。  不正アクセスによって生じる通信量は正常なサービスを提供している場合に比 べ少ないと考えられます。そのため、不正アクセスの解析を行う場合に処理する データ量を少なくすることができると言うのが一つ目の長所です。言い換えれば、 不正アクセスの情報のみをログなどから簡単に見つけだすことができる点が長所 であると言えます。  二つ目としてはIDSなどで問題とされる、正しいアクセスを侵入行為として判定 しまうフォールスポジティブ(false positive)を低減することができる点です。 これは、ハニーポットはそもそも正常な通信の対象とならないため、正常な通信 を誤って不正アクセスと判断することがないためです。  最後は検知すべき攻撃を見逃してしまうフォールスネガティブ(false negative) の対策になると言う点です。つまり、ハニーポットに対するアクセスは全て不正 なものであると仮定することで、シグネチャなどが登録されていない道の攻撃で あっても不正アクセスであると判断できるのです。 ●ハニーポットの短所  次に、短所ですが一つ目としては実際にサーバに侵入されてしまうと踏み台に されてしまうなどリスクが高いという点があげられます。仮に、不正侵入を許す のは問題ないとしても他人に迷惑をかけてしまったり、自分に嫌疑が向くのは避 けたいところです。  二つ目としては、実際にハニーポットを設置・運用するには高度な知識や経験 が必要であり、容易に設置・運用することが難しいという点があげられます。  三つ目として、通常のハニーポットが監視できる範囲は自分自身だけですので 監視できる範囲が狭いという点もがあげられます。  最後としては、何台ものハニーポットを集中的に設置・管理することは、台数 分の設定やログの監査などを行う必要があり難しいと言う短所が考えられます。 ■0x04.) ハニーポットの分類  ハニーポットは大きく分けて次の二種類に分類できます。  ひとつは高インタラクション型、もう一つは低インタラクション型です。ハニ ーポットを高インタラクション型ハニーポットではOSそのもの(仮想マシン上のO Sを含む)に対する完全なアクセスを許し実際のサービスをそのまま用います。し たがって、より多くの情報の収集を行うことができ、どちらかというと研究の分 野で使われます。しかし、高インタラクション型のハニーポットでは侵入される 危険度が高く、管理するには様々な技術に精通していなければなりません。たと えばホストベース、ネットワークベースのIDSの設置や、lkmrootkit対策、ファイ アウォールの設定、実際に攻撃を受ける各種サーバの設定などなど多くの対策が 必要です。  また、ログの解析や、インシデントレスポンスに関する準備、場合によっては フォレンジックなどの技術も必要となってきます。  それに対し、低インタラクション型のハニーポットでは実際のサービスをまね るソフトウェアを用いることでOSそのものに対するアクセスを許しません。した がって、多くの情報を得るには向かず、攻撃を逸らすための囮として企業内の重 要なサーバの盾として使われ、主に攻撃の防御・回避のための分野で用いられま す。  そして、低インタラクション型は高インタラクション型に比べ設置や管理が比 較的簡単であると言われます。もっとも、サーバを攻撃にさらすことは変わらな いため様々な設定などが必要なことは言うまでもありません。 ■0x05.) まとめ  と言うわけで、簡単にハニーポットについて説明してきました。  つまりは、ハニーポットの設置や管理はとてもめんどくさいものと言うことで ・・・。今後、もし要望や人気があれば、実際にハニーポットの作成についての説明 などを連載形式で少しずつ書いていくかも知れません。まぁ、読んでみたいとい う奇特な方がいらっしゃったら私宛にメールでもしてみてください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第2章: ハニーポットを作ろう 〜 第1回 〜 --- 著者:Narusase x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  第1章では、ハニーポットとは何なのか、特徴、長所と短所を解説していきまし た。この章からは、連載形式でハニーポットの構築について解説します。 ■0x02.) ハニーポットの構築における大前提  まずハニーポットを構築するに当たって、どんな環境で話を進めるかを明確に します。 ●戦略  まず、どのようなハニーポットにするかを考えましょう。  そこでいくつかの条件を考えました。 1.ユーザーの自宅に設置 2.自家サーバなども同時に使用 3.ルータとしても使用 4.セキュリティのことも考える 5.なるだけ無料で作る  これらの課題をクリアするためにはいろいろと考える必要がありそうですね。  まず、1に関しては普段使用しないPCが一台あれば問題はなさそうです。  2に関しては特定のポートをハニーポットの監視対象から外すことで、そのポー トを監視できなくなりますが何とかできそうです。  3に関してはいろいろとめんどくさそうですが、ネットワーク内部のPCからイン ターネットを利用する程度ならiptablesなどを使うことで実現できます。  4は様々なセキュリティ関連のソフトを入れることで問題ないでしょう。  5はソフトに関してはオープンソース系のOSやソフトを使うことで解決できます。 ハードに関しては場合によっては出費が必要かもしれません。  ではこのあとはもう少し詳しく話を詰めていきましょう。 ●インターネット接続環境  インターネットへの接続環境はADSLの設定が面倒なのでグローバルIPがもらえ るタイプのCATVとします。このCATVではDHCPによってIPアドレスの割り当てを行 っています。また、ネームサーバなどの情報もDHCPによって割り当てられます。 ●ネットワーク図  インターネットから普段使用するPCまでのネットワーク図としては下記のよう なものを想定します。ネットワーク図としてはルータがグローバルIPを持つ型の ADSLの一般的な接続環境と大して変わりません。 +----------------------+ | インターネット(CATV) | +----------------------+ | +----------------------+ | ハニーポット(ルータ) | +----------------------+ | +-------+-------+ | | | +-----+ +-----+ +-----+ | P C | | P C | | P C | +-----+ +-----+ +-----+ ●ハードウェア  ハニーポットとなるマシンのスペックは特に強力なスペックはいりませんが、 最低環境として次のようなものを規定しておきます。 ・CPU: Pentium II 266Mhz ・メモリ: 128MB ・グラフィックボート: ビデオメモリ16MB以上 ・NIC: 10BASE-T × 2  CPUに対してメモリが少し多いように感じるかもしれませんが最近のOSを扱うに はこれくらい無いときついかと思います。  また、XなどのGUIを使う場合ビデオメモリはもう少し多い方が快適です。  NICに関してはルータとして動作させるため二枚必要です。DMZとかを作りたい という場合は三枚必要ですね。 ●ソフトウェア  インストールするソフトウェアとしては下記のものを考えました。 ・OS: Vine Linux 3.1 ・ハニーポットソフトウェア: Honeyd ・ネットワークベースIDS: Snort ・ホストベースIDS: Tripwire ・ファイアウォール: iptables ・アンチウィルスソフト: Clam Antivirus ・遠隔管理ソフト: ssh ・自家サーバ: apache,samba  インストールや設定の順番としては次の順番で考えていきます。 1. Vine Linux 3.1 2. iptables 3. samba 4. ssh 5. apache 6. Honeyd 7. Snort 8. Tripwire 9. Clam Antivirus  ここで、それぞれのソフトについて簡単に説明します。 ○Vine Linux 3.1  言わずと知れたLinuxディストリビューションのひとつで、他と比較して日本向 けに作られている点と、パッケージ管理システムとしてAPTを採用している点が特 徴と言えます。 ○iptables  Linuxカーネル内で動作するファイアウォールでNATなどの機能を持ちます。 ○samba  Windowsのファイル共有機能をLinuxで実現するサーバソフトです。 ○ssh  セキュアなリモートシェル、外部からLinuxを操作する場合に利用するサービス のことです。 ○apache  世の中でもっとも使われているHTTPdです。 ○Honeyd  これがこの連載の目的であるハニーポットです。今回はHoneydというメジャー なソフトウェアを用いることにしました。 ○Snort  ネットワークベースのIDSソフトです。 ○Tripwire  ホストベースのIDSソフトです。ファイルの改竄を検知することができます。商 用版とオープンソース版があります。 ○Clam Antivirus  Linuxで動作するアンチウィルスソフトです。オープンソースながら高い性能を 有します。 ■0x03.) おわりに  次回からは実際にVine Linuxのインストールから解説する予定です。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第3章: 自転車の錠の開錠 --- 著者:Defolos x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  読者の皆様、お久しぶりです。  Vol.7、8、9でピッキング講座をしていたDefolosです。今回は以前解説できな かった自転車の錠の開錠を説明していきたいと思います。 ■0x02.) 前輪のロック  古いタイプのママチャリなどの自転車ではこの錠が標準的です。セキュリティ 的に問題があることが世間に認められ、今では後輪ロックに取って代わったりで、 そんなに見かけるタイプの錠ではなくなってきています。ロック機構はきわめて 単純で、錠から伸びる棒をスポークまで伸ばし、スポークが動かないようにして ロックします。 参照 -> http://scel.fc2web.com/figure/figure18.GIF  ここで紹介するのは中学生の間で流行った方法で、傘の骨を使って鍵を作る方 法です。 ■0x03.) 鍵を作ってみよう 1:コンビニで売ってるビニール傘を買ってきましょう。 2:傘を開いてみるとたくさんの骨があるのが見えると思いますので、この中から 一本取ってきます。 3:それを6cmぐらいに寸断します。 4:この骨を平たく伸ばします。平たく伸ばすからといって、完全に平らにしては いけません。 5:中央に凸を残すように伸ばします。 6:鍵穴に入るぐらいに伸ばしたら完成です。 7:あまりに小さいときは傘の中央部の太い骨を使って製作してみましょう。 参照 -> http://scel.fc2web.com/figure/figure19.GIF ■0x04.) 鍵の使い方  鍵穴に差し込んで前後左右に動かしてみましょう。ぐりぐりと上下に動かすと いいようです。  これでだめなら、鍵の凸を大きくしたり、小さくしたり、調整してみます。そ れでも開かないようなら金鋸(金属切断用ノコギリ)をもってきてギコギコやり ましょうヽ(´¬`)ノ ■0x05.) 後輪ロック  後輪ロックは最近主流になりつつあるタイプの錠で、後輪に取り付けられてい ます。C状の本体を車体に固定し、本体に収納してあるバーをスポークを挟んでス ライドさせることでロックします。  後輪ロックにも様々な種類があります。 ○簡易ロックタイプ  下図のような鍵を持つタイプの錠。 参照 -> http://scel.fc2web.com/figure/figure20.GIF  このドキュメントの考査対象であり、最も単純な構造を持ちます。ホームセン ターで300円〜700円ぐらいで売られています。 ○ピン、ディスクタンブラータイプ  ピンタンブラー、あるいはディスクタンブラーを用いたタイプです。これは以 前までに解説した技術を用いて開錠しましょう。ホームセンターで1200円前後で 売られています。安いからといって簡易ロックを買わず、できるだけこちらを買 うようにしましょう。 ○ディンプルタイプ  ディンプルキーを用いたタイプの錠です。開錠は不可能なので金鋸に登場して いただきましょう。電動自転車などの高価な自転車についています。8000円ぐら いで売られている安い自転車には宝の持ち腐れかもしれません・・・。 ■0x06.) 構造  ここでは簡易ロックの内部構造についてを考査していきたいと思います。いく ら簡易とはいえ、図で説明するのは至難ですので、写真を使っていきたいと思い ます。 参照 -> http://scel.fc2web.com/figure/photo1.jpg  別窓で開いて、参照しながら読んでください。 ●photo2 参照 -> http://scel.fc2web.com/figure/photo2.jpg  これは分解したところです。写真の左側にあるのがロック機構です。  右にあるバネはロックバーと直結していて、常に引き戻そうとする力が働きま す。そのままではロックできないので左側にロック機能を設けてあります。ロッ クバーには穴が開いています。この穴にロックを入れ込むことで施錠しています。 ロックはバネによって常に右方向に力がかかっていて、支点を中心に左回りに移 動します。このため、ロックバーに設けられた穴に入り込むようになっています。  このあたりの説明は静止画と文字で説明するのが難しいので、実際にホームセ ンターで錠を買ってきて、分解してみるとよいでしょう。 ●photo3 参照 -> http://scel.fc2web.com/figure/photo3.jpg  ロック機能を詳しく見たところです。  ロックには突起があるが、ロックバーの穴に隠れて見えません。この突起がロ ックバーの穴の淵に引っかかって施錠していることになります。何らかの方法で このロックを緩めて、ロックバーの穴からロックの突起を出せば開錠できます。 ●photo4 参照 -> http://scel.fc2web.com/figure/photo4.jpg  かなりぼやけた画像で申し訳ありません。これはロックが外れたときの画像で す。  ロックが緩んで、ロックにある突起が見えているのがわかります。 ●photo5、photo6 参照 -> http://scel.fc2web.com/figure/photo5.jpg 参照 -> http://scel.fc2web.com/figure/photo6.jpg  これは非常に重要な点です。赤いまるで囲まれた突起が見えると思います。こ れが全ての鍵の中からある一定(付属品の鍵)の鍵以外で開けることができない 仕組みです。  photo6と合わせて見てください。ロックの裏にはプロジェクションがついてい て、これに鍵を引っ掛けて力をかけることでバネに反発する力を与えています。 その結果ロックにある突起がロックバーの穴から出てきて開錠できるわけです。  さて、photo5に戻って改めてみてみましょう。緑丸で囲ったところがプロジェ クションに引っかかることになる。しかし、鍵についてるくぼみが赤丸で囲また 突起の位置、深さと一致しないと突起に引っかかってバネに対する力を与えるこ とができません。これが鍵を識別する仕組みです。ちなみにこの写真の鍵は違う 鍵を差し込んであるので微妙に深さがあってません。これでは開錠はできません。 逆に、この赤丸突起の位置と深ささえ予測できれば、鉄板を削って合鍵を作るこ とができます。 ■0x07.) 開錠 さて、実際の開錠についてを説明しましょう。 まず、http://scel.fc2web.com/figure/figure21.GIFを確認してみてください。 これはダイワ精工から発売されているラインカッター「ダイワ ラインカッター 50K」 という釣具です。これをピックとして利用します。「フィッシング楽天店」 (http://www.rakuten.ne.jp/gold/naturum/index-f.html)に商品があるのを確 認しています。  これをどう使うかというと、そのままナイフの部分を差し込んでください。本 物の鍵を開けるように動かすと、抵抗が感じられ、さらに動かすと鍵がガチャッ と開きます。  どうしてこれで開くのかと言うと、photo5の赤丸の突起はロック部分との間に 1mm程度の隙間があります。これをラインカッターの薄い刃が回避し、ロックにあ るプロジェクションに直接力をかけられるため、開錠できます。この隙間は、こ のタイプの錠にはほぼ例外なくあります。というのも、このタイプの錠は製造に かかるコストを極限まで削減しなければならないからです。造りこみを良くしよ うとするとコストがかかり、簡易ロックの最大の魅力である安さが損なわれ、よ り安全なピン・ディスクタンブラー式のロックに客を取られてしまいます。それ 故に造りこみをいい加減にしなければ採算が合わないわけです。  さらに、刃の付け根と刃付けしてある部分の間(リカッソ)にある半円に削れ た部分にも注目してください。この部分にロックの支点がぴったり合わさり、よ り開錠を容易にしています。その上、刃の付け根にある段差と支点の位置がぴっ たり同じなので、何も考えずに差し込めば開錠に丁度いい位置になります。  まさしく後輪ロック開錠のために生まれてきたような構造・・・。設計者はこれを 狙ってたのでしょうかね。 ■0x08.) 鍵の自作  ダイワのラインカッターが手に入らない場合は自作してしまいましょう。  例のごとくホームセンターに行きましょう。 ●購入するもの ・1㎜厚のステンレス板 ・ステンレス用のヤスリ(大きい作業用と細かい作業用) ・万力 ・金鋸(金属用ノコギリ) ●手順 1:ステンレス板にhttp://scel.fc2web.com/figure/figure22.GIFの図を写してケ ガキます。 2:ケガいた線にそって金鋸で切断します。 3:ヤスリで削って整えます。 4:刃の部分を斜めに削ります。ちょっと角度つけるぐらいがよいでしょう。 5:細かいところを形成して完成です。結構簡単に作れると思います。ただし、こ のままではまだ未調整です。実際に錠に差し込んで開くかどうかを試し、開かな かったら調整して完成させます。  なお、この図は少し大きめに描いていますので、調整が必要です。実は1㎜以下 の厚さのヤスリや、バーベキュー用の串でも開いたりしますが、開錠にコツがい りますので時間がかかってしまうかもしれません。 ●使用に際してのコツ  この鍵を使う場合には少しコツがあります。 1:明らかに内部が錆付いてそうな錠には使わないこと。錆で動きにくく、最悪ラ インカッターが折れてしまいます。 2:開錠する際、ロックバーを施錠する方向に押しながらラインカッターを動かす。 開錠する際に結構力がいると思いますが、これはロックバーがバネによって戻ろ うとする力が働いているからです。戻ろうとする力を自分で押さえつければ少な い力で開けることができます。ラインカッターの寿命を長くする意味でも重要で す。 3:開錠した後、ロックに挟まってラインカッターが抜けなくなることがあります。 このとき無理に抜こうとせず、ラインカッターを少し捻りながら抜くようにしま す。これで比較的簡単に抜けます。無理やりはダメです。 4:この方法で開錠すると、錠に鍵が刺さっていない状態になるので、ダミーキー を差し込んでおいたほうがよいです。ダミーキーはキーの切込みがある辺りを削 り取ることで製作できます。 ■0x09.) 最後に  さて、今回も思ったより簡単に錠が開いてしまったことと思います。  もしも簡易錠をお使いの読者の方々はすぐにピン/ディスクタンブラー錠に交 換することをオススメします。自転車の錠は「安かろう悪かろう」がかなり当て はまりますので、ある程度高いものを買うようにしましょう。  最後の最後になりましたが、ここまで読んでくださった皆様、どうもありがと うございました。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第4章: マニアックJavaプログラミング 〜 第2回 〜 SSL Man In The Middle Attack --- 著者:金床 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  マニアックJavaプログラミングの第二回です。本当はIPアドレスからホスト名 への高速逆引きをネタにするつもりだったのですが、ふと気がついたらせっせと インチキ証明書を作っている自分がいました。ということで、今回のネタはSSL Proxyを使ったMITM攻撃です。プロキシサーバーばかり作ってはや数年、今回初め てSSLに手を出してみましたが、最終的にかなり面白いものができました。  SSL Proxyの仕組みやルート証明書のインストールなどを実際に試してみること で、最近流行のフィッシング(ファーミング?)詐欺についての考察も深めるこ とができることでしょう。 ■0x02.) きっかけ  そもそものきっかけは@ITというウェブサイトに掲載された「HTTP暗号化通信の パラドックス 安心が情報漏えいの穴になる不思議」という記事です。 http://www.atmarkit.co.jp/fsecurity/special/52ssl/ssl.html  まずはこちらの記事を読んでください。さんざん煽りつつも正体は自社製品の 宣伝というイカした記事ですが、ネットワーク管理者が把握しておくべきネタを 取り上げていることは確かです。要点を簡単にまとめると「社員の通信は管理者 の監視下におかれるべきであり、HTTPSによるウェブブラウザとサーバーの間の暗 号化通信も例外にするべきではない」といったところでしょうか。しかし、HTTPS でやりとりされるデータはネットワーク上では暗号化されているわけですから、 監視をしたくてもできないのでは?という疑問が沸きます。  そして、まさにその点について「HTTPSのコンテンツフィルタ?」という題名で @ITの会議室にスレッドが立てられました。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=17604&forum=14&7 ■0x03.) HTTPSのフィルタリングは可能なのか?  このスレッドを立てた方と同じように、私も以前は「HTTPSというのは暗号化通 信なのだから、途中でデータを見たり、フィルタリングしたりできるはずがない」 と考えていました。しかし、実はちゃんと方法が存在したのです。それは、プロ キシサーバーがHTTPSサーバーのフリをしてクライアントからリクエストを受け取 り、その内容に基づいて、今度は自身がHTTPSクライアントとして本物のHTTPSサ ーバーと通信し、レスポンスを受信し、そしてそのレスポンスをクライアントに 返す、というものです。  この場合、プロキシサーバーはクライアントからのリクエストの内容も、サー バーからのレスポンスの内容も全て把握することができるため、フィルタリング はもちろんのこと、内容を改竄することさえできてしまいます。  しかし、HTTPSの通信には「データの暗号化」と共に、証明書に基づく「なりす ましの防止」という機能があります。クライアントは通信している相手が本物か どうかを判別することが可能なのです。このため、上で説明したようにプロキシ サーバーが偽のHTTPSサーバーとして動作する場合、このHTTPSのなりすまし防止 機能によって、クライアントは「このサーバーはニセモノだ!」と見破ることが できます。これは、プロキシサーバーが正しい証明書を持っておらず、間に合わ せの偽の証明書を使っているからです。  つまり、「HTTPSのフィルタリングは可能ではあるが、クライアントはこれを見 破ることができる」と言って良いでしょう。証明書におかしい点がある場合には、 ウェブブラウザはダイアログを出してユーザに警告してくれるのです。 ■0x04.) ウェブブラウザのダイアログを回避  しかし、@IT会議室のスレッドのcn009さんの書き込みを見て驚きました。なん と、プロキシサーバーが使用する、いわば偽の証明書をルート証明書としてクラ イアントのマシンにインストールしてしまうことで、このダイアログを回避する ことができるというのです。この方法にはかなり驚かされました。たしかに、企 業内ネットワークなどでは社員のPCに対して色々なポリシー等を強制することが できるので、偽の証明書をルート証明書としてインストールさせることもできる はずです。このステップを踏めば、クライアントが行うHTTPS通信は、ウェブブラ ウザが警告のダイアログを出すこともなく、完全に管理者の監視下におかれるわ けです。これには非常にわくわくさせられ、実際にこの仕組みが動作するところ を見てみたい、と思いました。そんなわけで作り始めたのが、今回のSSL Proxyで す。とりあえずの目的は、自身が発行した偽の証明書をルート証明書としてイン ストールした場合に、ウェブブラウザに警告のダイアログを一切出させずに、 HTTPS通信を完全に管理下に置くことができるのかどうかを確かめることです。 ■0x05.) 百聞は一見にしかず  まずは完成したブツを実際に味わってみてください。  期間は未定ですが、SSL Proxyをwww.jumperz.netの4128番ポートで起動してい ます。HTTPSのプロキシサーバーとしてwww.jumperz.net:4128を使用するようにウ ェブブラウザを設定し、どこでもよいのでHTTPSのウェブサイトへアクセスします。 すると、ウェブブラウザが証明書が正しくない、と警告のダイアログを出してく れるはずです。このダイアログを無視すれば、無事に(?)目的のウェブサイト が見えるはずです。ウェブブラウザのウィンドウにはばっちり鍵マークが出現し、 サーバーとの間で強固な暗号化通信が行われているかのように思えます。SSLのバ ージョンなどにより、うまくアクセスできないサイトもあります。アクセスでき ない場合にはいくつか他のサイトを試してみてください。  このHTTPS Proxyには、今回の実験の目的のひとつである「HTTPSのフィルタリ ングは可能なのかどうか」を確かめるため、またどこかの誰かがオイタをしない ように、以下のいくつかの小さな仕掛けを施してあります。 1. クエリーパラメータを持たないGETリクエストのみ許可します。 2. CookieやSet-Cookieなどをはじめ、いくつかのヘッダーフィールドをリクエスト及びレスポンスから削除します。 3. レスポンスがHTMLファイルの場合、タグ部分を書き換えます(どのように書き換えられるかは実際に確認してみてください)。  また、ログについては必要に応じて取得する可能性があるので、ネットバンク のユーザIDとパスワードなどのような機密事項などは送らないで下さい。ログは 第三者へは公開しない方針ですが、ネタになるものがあればIPアドレス等分から ないような形で部分的に公開させて頂く可能性があります。 ■0x06.) Got R00t?  上の実験で、HTTPSの通信はプロキシサーバーを使用することで、フィルタリン グが可能であることがわかりました。ただし、クライアントマシン上ではウェブ ブラウザが証明書に対して警告のダイアログを出してくれるので、これに気づく ことができます。そこで、さらに一歩進み、このダイアログを出さないようにし てみましょう。  まず、証明書を下のURLよりダウンロードしてください。 http://www.jumperz.net/tools/jumperz_net.cer  次に、この証明書を、あなたが使っているウェブブラウザにルート証明書とし てインストールして下さい(インストール手順が分からない場合には「ルート証 明書 インストール」等のキーワードで検索してください)。この際、Netscape Navigatorの4系統はCONNECTメソッドを使用する際の実装にバグがあるため使用 できません。他のウェブブラウザを使ってください。  ルート証明書としてインストールが完了したら、上の0x05と同じ手順で、好き なHTTPSのサイトへアクセスしてください。するとなんと驚くべきことに(?)、 ウェブブラウザが警告のダイアログを全く出さないようになってしまったはずで す。しかし、上で説明した通りのフィルタリング(パラメータなしのGETリクエス トのみ許可し、レスポンスの<title>タグ部分を書き換える)は依然として行われ ているはずです。一見ウェブサーバーとの間で完全な形で行われているかのよう に見えるHTTPS通信が、実際には見事にフィルタリングされているのです。 ■0x07.) 何を意味するのか  このように、HTTPSのアクセス用にプロキシサーバーの設定を行い、ルート証明 書としてたった一つのファイルをインストールしただけで、HTTPS通信の「暗号化」 と「なりすましの防止」の神話はもろくも崩れ去ることがわかります。この事実 は、想定される状況によって異なる意味を持ちます。  まず、そもそも今回のネタ元であった企業内ネットワークを考えてみます。イ ンターネット上のHTTPSのサイトへアクセスするためにクライアントマシンにプロ キシサーバーの設定を行わせることは、非常に一般的に行われているでしょう。 多くの場合、この設定を行わなければHTTPSのサイトへアクセスできない、という 状態ではないでしょうか。また、クライアントのPCは社員のものではなくあくま でも会社のものである場合が多いため、管理者が社員に対し、プロキシサーバー が使用する証明書をルート証明書としてインストールすることを強制できる場合 も多いでしょう。あるいは、社員がいない間に勝手に(笑)インストールしてい るかもしれません。証明書がインストールされてしまえば、社員のHTTPSのサイト に対するアクセスは完全にプロキシサーバー上で監視・管理され、情報漏洩や業 務と関係がないサイトへのアクセスなども全て把握することが可能となります。 このとき社員のPC上でウェブブラウザはまったくダイアログを出すこともなく、 あたかもウェブサーバーと正しくHTTPS通信が行われているように見えることにな ります。@ITの記事が示す「HTTPSのコンテンツフィルター」とは、まさしくこの ような形で運用されるプロキシサーバーを指しているのではないかと思います。  さて、会社などの組織のネットワーク管理者がこのような形でクライアントを 監視することはある意味一般的であり、何の問題もありません。しかし、このプ ロキシサーバーを運用し、クライアントの通信を監視しているのがハッカー(こ こでは攻撃者・侵入者の意味)だったらどうでしょうか。Exploitやウイルスなど の不正なプログラム、あるいは直接コンピュータに触れられることでクライアン トのマシンがハッキングされ、「HTTPSのプロキシサーバーの設定」と「ルート証 明書のインストール」という2つの操作が行われてしまえば、その後ありとあらゆ るHTTPSサイトに対するアクセスは、ウェブブラウザが警告のダイアログを出すこ ともなく、完全にハッカーに監視・操作されてしまうことになります。これはhosts ファイルの書き換えやDNSスプーフィングなどとは比較にならないほど大きな脅威 であると言えるでしょう。組織内ネットワークで管理者が使えば「HTTPSのコンテ ンツフィルター」となる平和な存在のHTTPS Proxyも、ハッカーが使えば「Man In The Middle攻撃用のツール」という凶悪な存在になってしまうというわけです。 SSL通信の安全性を確保する上で最も重要な点は「ウェブブラウザのプロキシ設定 を勝手に変更されないこと」「ルート証明書を勝手にインストールされないこと」 の2点であると言えます。  一般的なPCの使用者は、自衛の手段としてこの2点について定期的にチェックす るのが好ましいと言えるでしょう。 ■0x08.) 実装について  では、いよいよ実装についての解説を行います。今回作成したHTTPS Proxyは独 立したアプリケーションとしてではなく、Guardian@JUMPERZ.NETのプラグインと いう形で作成しました。Guardian@JUMPERZ.NETは本来はウェブサーバーやウェブ アプリケーションを守るために使用するウェブアプリケーションファイアウォー ルですが、その実態はHTTP Proxyであるため、一般ユーザがローカルプロキシと して利用することや、今回のようにHTTPが絡んだ特殊なプロキシサーバーとして 使用することもできます。Guardian@JUMPERZ.NETについての詳細は次のURLを参照 してください。 http://guardian.jumperz.net/  今回作成したHTTPS Proxyについて、細かい部分まで完全に把握したい、という 場合には、Guardian@JUMPERZ.NETの動かし方やプラグインの仕組みなどをある程 度把握する必要があります。ここから先の解説は、これらの知識があるという前 提のもとに行います。不明な点などありましたらドキュメントやメーリングリス トを利用してください。  必要なファイルは以下からダウンロードできるようになっています。 1. http://www.jumperz.net/tools/sslFilter.jar 2. http://www.jumperz.net/tools/bc.jar 3. http://www.jumperz.net/tools/rule.txt 4. http://guardian.jumperz.net/download/jumperz_net_074.jar  1はHTTPS ProxyのJavaのソースコード及びクラスファイルをまとめたjarファイ ル、2はサードパーティ(bouncycastle.org)の暗号化ライブラリをまとめたjarフ ァイル、3はGuardian@JUMPERZ.NETをHTTPS Proxyとして動作させる場合に使用す るruleファイルのサンプル、4はGuardian@JUMPERZ.NET本体などを含むjarファイ ルとなっています。  まずはruleファイルから解説を開始します。クライアントから送信された CONNECTメソッドをもつHTTPリクエストは、次のルールを発動させます。 ----- <rule> id=L2 revision=1 name=loadSslFilter type=requestLine pattern=^CONNECT [-a-zA-Z0-9.]+:443 HTTP/1\.[01]$ condition=match case_sensitive=no log=no action=none command=none plugin=sample.sslFilter.MSslFilter </rule> -----  pluginの行から分かるとおり、このルールはSslFilterプラグインを起動します。 このプラグインがHTTPS Proxyの中核です。では、中身を見ていきましょう。  Guardian@JUMPERZ.NETの起動時に、初期化のためにstartup()関数が呼び出され ます。 ----- public void startup() throws IOException { privateKeyFileName = getRequiredProperty( "sslFilter.privateKeyFileName" ); publicKeyFileName = getRequiredProperty( "sslFilter.publicKeyFileName" ); algorithm = getRequiredProperty( "sslFilter.algorithm" ); -----  秘密鍵、公開鍵が格納されているファイル名と、アルゴリズム名をパラメータ として取得します。これらは全てString型のオブジェクトです。次に、秘密鍵と 公開鍵をそれぞれファイルから取り出し、オブジェクトとして取得します。 ----- try { caPrivateKey = MSecurityUtil.loadPrivateKeyFromFile ( privateKeyFileName, algorithm ); caPublicKey = MSecurityUtil.loadPublicKeyFromFile ( publicKeyFileName, algorithm ); } catch( Exception e ) { e.printStackTrace(); throw new IOException( e.getMessage() ); } } -----  初期化はこれで完了です。MSecurityUtilクラスはセキュリティ関連の処理を行 うstaticメソッドをまとめたユーティリティクラスです。処理の中身に興味があ る方はソースコードを読んでみてください。  では次に、プラグインがルールから呼び出されるときの処理を記述した、 execute()関数を見てみましょう。 ----- public Map execute( Map sessionInfo ) throws IOException { Map pluginResult = new HashMap(); -----  pluginResultは最終的にこの関数の戻り値として使用するオブジェクトです。 このマップに名前・値のペアを格納することで、Guardian@JUMPERZ.NETの本体に 様々な情報を伝えることができます。 ----- Socket clientSideSocket = ( Socket )sessionInfo.get( "clientSideSocket" ); InputStream in1 = clientSideSocket.getInputStream(); OutputStream out1 = clientSideSocket.getOutputStream(); // reply to connect request out1.write( "HTTP/1.0 200 OK\r\n\r\n".getBytes( MCharset.CS_ISO_8859_1 ) ); -----  Guardian@JUMPERZ.NETから見て、クライアントとの接続に使用しているソケッ トがClientSideSocketです。このSocketクラスのインスタンスをsessionInfoから 取得し、それぞれの入力・出力ストリームを取得します。ここで、クライアント はCONNECTメソッドを送信し、それに対するレスポンスを待っている状態なので、 ステータスコード200のレスポンスを返信してやります。本来ならばクライアン トが接続を希望するサーバーに正しく接続してからレスポンスを返すべきですが、 今回のプロキシサーバーは様々なトリックを駆使したある種のインチキプログラ ムですので、気にせずに変則的な処理を行っていきます。 ----- // connect to server MHttpRequest request = ( MHttpRequest )sessionInfo.get( "request" ); String uri = request.getUri(); String[] array = uri.split( ":" ); String host = array[ 0 ]; int port = Integer.parseInt( array[ 1 ] ); Socket serverSideSocket = MSecurityUtil.getBogusSslSocket( host, port ); pluginResult.put( "serverSideSocket", serverSideSocket ); -----  次に、クライアントが希望するSSLサーバーへの接続を行います。  まず、sessionInfoからクライアントが送ってきたHTTPリクエストを取得します。 このリクエストはCONNECTメソッドを持つものです。getUri()によって取得したuri には"www.example.com:443"のような文字列が格納されるので、split関数でホス ト名とポート番号に分け、それぞれhostとportという名前で取得します。サーバ ーとの接続に使用するSocketクラスのインスタンスをserverSideSocketという名 前で作成しますが、ここで接続する相手はSSLサーバーなので、このソケットイン スタンスは実際にはSSLのクライアントソケットのインスタンスを使用します。今 回の実験では相手のSSLサーバーが期限切れやCNが違うなどの問題のある証明書を 使用していても構わず接続したいので、getBogusSslSocket()メソッドを使用しま す。この時点で接続先SSLサーバーとの間でSSLのネゴシエーションが行われ、ア プリケーション層のデータのやりとりを行う準備ができます。Guardian@JUMPERZ.NET から見てサーバー側のソケットの準備ができたことになり、pluginResultに serverSideSocketを格納してやります。このインスタンスはSSLの処理をラッピン グしたものなので、普通のソケットと同じようにデータを読み書きすると、データ は暗号化された形でネットワークを伝わることになります。いやはや便利ですね。 ----- // listen ssl server socket ServerSocket sslServerSocket = getSslServerSocket( host ); -----  200のレスポンスを受信したクライアントは、次にSSLサーバーとの通信に入り ます。従って、プラグインはSSLサーバーとしてクライアントと通信を行う必要が あります。ここでSSLの処理をいちいち行うのは非常におっくうなので、内部で SSLサーバーソケットを一つ作成し、それを利用してしまうことにします。この SSLサーバーソケットを作成する処理をまとめたサブルーチンがgetSslServerSocket() です。引数にはクライアントがCONNECTリクエストで送ってきたホスト名を使用し ます。ここで作成するSSLサーバーソケットのインスタンスがクライアントに送信 するX509証明書をどのように扱うのかが、このアプリケーションのキモの部分の ひとつになります。SSL接続においてウェブブラウザはX509証明書のCN(Common Name)項目の値と接続先のホスト名が一致しているかどうかを確認し、もしもこ の2つが異なっていれば、警告のダイアログが出てしまいます。これを防ぐために このプロキシサーバーは、クライアントが接続を希望しているホスト名を取得し たのちに、そのホスト名をCNの値として持つX509証明書をリアルタイムで作成し (いわばでっちあげて)、それをSSL接続におけるサーバー側の証明書として使用 する必要があります。この処理(任意の値を使用したX509証明書のリアルタイム での作成)がJavaのコードで実装できるのか、が私にとって個人的に最も興味が ある部分でした。通常ならばSSLサーバーソケットというのはひとつのX509証明書 を用いてSSLクライアントからの接続を待つ存在であり、このように毎回相手に合 わせて自在に証明書を変えるような方法はまさに型破りであり、最高にインチキ なSSLサーバーと言えるでしょう。execute()関数の途中でしたが、ここでこのイ ンチキSSLサーバーソケットを作成するためのサブルーチンである、 getSslServerSocket()の中身を見ていきます。 ----- private synchronized ServerSocket getSslServerSocket ( String commonName ) throws IOException { X509Certificate cert = getCertificate( commonName ); -----  まず、引数として渡されるホスト名をSubjectのCNとして持つX509証明書を発行 しなければなりません。この証明書の作成はさらに別のサブルーチンである getCertificate()で行います。ここでさらにこのサブルーチンの解説に移ります。 ----- private X509Certificate getCertificate( String commonName ) throws IOException { if( certMap.containsKey( commonName ) ) { return ( X509Certificate )certMap.get( commonName ); } -----  無駄な証明書の作成を避けるため、一度作成したX509証明書はHashMapクラスの インスタンスであるcertMapに、CNをキーに格納することにしてあります。  そこで、まずはこのcertMap内に該当する証明書が無いかどうかを調べ、あれば X509Certificateクラスのインスタンスとして取得し、それを戻り値として返しま す。CNに対応する証明書が無い場合には、以下の処理に進みます。 ----- Hashtable issuerAttrs = new Hashtable(); Vector issuerOrder = new Vector(); issuerAttrs.put( X509Principal.C, "JP" ); issuerAttrs.put( X509Principal.O, "JUMPERZ.NET" ); issuerAttrs.put( X509Principal.ST, "Kanagawa" ); issuerAttrs.put( X509Principal.L, "Yokohama" ); issuerAttrs.put( X509Principal.CN, "JUMPERZ_NET_PRIVATE_CA"); issuerAttrs.put( X509Principal.EmailAddress, "anvil@jumperz.net" ); issuerOrder.addElement( X509Principal.C ); issuerOrder.addElement( X509Principal.O ); issuerOrder.addElement( X509Principal.ST ); issuerOrder.addElement( X509Principal.L ); issuerOrder.addElement( X509Principal.CN ); issuerOrder.addElement( X509Principal.EmailAddress ); -----  Javaコード内で各種の値を指定したX509証明書を作るためには、標準のAPIだけ では機能不足であり、今回はオープンソースで提供されているライブラリを使用 しました。 http://www.bouncycastle.org/  まず、issuerの情報として必要な項目を設定します。ここでは見ての通りのい い加減な値を設定しています。 ----- Hashtable subjectAttrs = new Hashtable(); Vector subjectOrder = new Vector(); subjectAttrs.put( X509Principal.C, "JP" ); subjectAttrs.put( X509Principal.O, "JUMPERZ.NET" ); subjectAttrs.put( X509Principal.CN, commonName ); subjectOrder.addElement( X509Principal.C ); subjectOrder.addElement( X509Principal.O ); subjectOrder.addElement( X509Principal.CN ); -----  次にsubjectの情報を設定します。ここでcommonNameを動的に設定していること に注目してください。 ----- v3CertGen.reset(); v3CertGen.setSerialNumber ( BigInteger.valueOf( random.nextInt() ) ); v3CertGen.setIssuerDN ( new X509Principal( issuerOrder, issuerAttrs ) ); v3CertGen.setSubjectDN ( new X509Principal( subjectOrder, subjectAttrs ) ); -----  シリアルナンバーはランダムに生成した値を使ってしまいます。issuerとsubject それぞれの情報を設定します。 ----- v3CertGen.setNotBefore( new Date( System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30 ) ); v3CertGen.setNotAfter( new Date( System.currentTimeMillis() + ( 1000L * 60 * 60 * 24 * 356 * 5 ) ) ); -----  証明書の有効期限を設定します。有効期限ももちろん勝手に設定してしまうこ とができます。ここでは現在時刻の30日前から5年後までを有効期限として設定し ています。 ----- v3CertGen.setPublicKey( caPublicKey ); v3CertGen.setSignatureAlgorithm( "MD5WithRSAEncryption" ); -----  公開鍵としてあらかじめファイルから作成しておいたcaPublicKeyを使用します。 また、アルゴリズムとしてMD5WithRSAEncryptionを使用します。 ----- X509Certificate cert; try { Security.addProvider( new BouncyCastleProvider() ); cert = v3CertGen.generateX509Certificate( caPrivateKey ); certMap.put( commonName, cert ); } catch( Exception e ) { e.printStackTrace(); throw new IOException( e.getMessage() ); } return cert; } -----  ProviderとしてBouncyCastleのライブラリ内で提供されているBouncyCastleProvider を使用します。そのため、SecurityクラスのaddProviderメソッドを呼び出してお きます。そしていよいよ、あらかじめファイルから作成しておいたcaPrivateKey を使用して、X509証明書を作成します。作成されたインスタンスはCNをキーに certMapに格納しておきます。そして、証明書のインスタンスを戻り値としてこの 関数か ら抜けます。  次に、先ほど最初の1行だけ見た、getSslServerSocket()関数の解説へと戻りま す。 ----- ServerSocketFactory serverSocketFactory = null; try { Certificate[] certList = new Certificate[]{ cert }; KeyStore keyStore = KeyStore.getInstance( MSecurityUtil.KEYSTORE_TYPE ); keyStore.load( null, null ); keyStore.setKeyEntry ( MSecurityUtil.KEYSTORE_ALIAS, caPrivateKey, MSecurityUtil.KEY_PASS.toCharArray(), certList ); serverSocketFactory = MSecurityUtil.getServerSocketFactory( keyStore ); } catch( Exception e ) { e.printStackTrace(); throw new IOException( e.getMessage() ); } return serverSocketFactory.createServerSocket ( 0, 1, InetAddress.getByName( "127.0.0.1" ) ); } -----  SSLサーバーソケットを作成するにあたってX509証明書と秘密鍵を使用しますが、 これらはKeyStoreクラスを経由して使用することになります。KeyStoreという考 え方はJavaでの「おきまりの作法」のひとつで、最初は若干戸惑うかもしれませ ん。KeyStoreクラスのインスタンスを使用して、SSLサーバーソケットを作成する 機能を持つServerSocketFactoryを取得します。最後にcreateServerSocket()メソ ッドを呼び出してSSLサーバーソケットを取得し、関数を抜けます。ここで作成す るSSLサーバーソケットはアプリケーション内部で使うものなので、使用するポー トはその都度空いているものを使います。そのため、BINDするポートを指定する 第一引数は0となっています。また、このソケットは一度しか接続に使用しないの で、第二引数は1を使用します。そしてローカルインターフェースを使用するため、 第三引数には上にある通り127.0.0.1のInetAddressを使用します。  では、execute()関数の続きの解説へと戻ります。 ----- int listeningPort = sslServerSocket.getLocalPort(); -----  getSslServerSocket()の戻り値であるsslServerSocketは既にBINDを完了してい ます。ポートはOSによってそのとき空いている番号を適当に割り当てられている はずなので、getLocalPort()を呼び出してポート番号を取得します。 ----- // intermediate socket Socket socket2 = new Socket( "127.0.0.1", listeningPort ); InputStream in2 = socket2.getInputStream(); OutputStream out2 = socket2.getOutputStream(); -----  次に、準備したSSLサーバーソケットに対して接続するクライアントソケットを 用意します。SSLサーバーソケットは127.0.0.1で接続を待ち受けているので、上 のようにソケットを生成します。この時点で接続が完了し、送受信用に使用でき るストリームを取得することができます。 ----- Socket socket3 = sslServerSocket.accept(); sslServerSocket.close(); -----  ここで確立した新しい接続について、サーバー側からみたソケットを、accept() を呼び出し、socket3として取得します。listenしていたsslserverSocketはもう 使用しないので、ここでclose()を呼び出して閉じておきます。 ----- // ssl nego MStreamConnector streamConnector1 = new MStreamConnector( in1, out2 ); MStreamConnector streamConnector2 = new MStreamConnector( in2, out1 ); -----  MStreamConnectorクラスは、InputStreamからデータを読み、それをOutputStream に書き込む、という作業をひたすら(ストリームが閉じられるまで)繰り返すも のです。MCommandインターフェースを継承しており、Commandパターンを利用して 使われます。ここでは2つのMStreamConnectorクラスのインスタンスを生成してい ます。これらのインスタンスが繋げているストリームは、先ほど生成したSSLサー バーソケットに対して接続した内部のクライアントソケットと、CONNECTリクエス トを送信し、ステータスコード200のレスポンスを受信し終えたクライアント側の ソケットのそれぞれのストリームです。この辺りはとってもややこしいので、は っきりいって理解不能だと思います。これを理解するには自分でHTTPS Proxyを作 ってみるのが一番です。ってそしたらここで解説している意味ないし…。とにか くここでクライアント側のストリームをSSLサーバーソケットに繋げてやると、SSL のネゴシエーションが開始されるわけです。 ----- MStreamConnectorObserver streamConnectorObserver = new MStreamConnectorObserver( streamConnector1 ); streamConnectorObserver.addSocket( clientSideSocket ); streamConnectorObserver.addSocket( socket2 ); streamConnector1.regist( streamConnectorObserver ); -----  ストリームを繋げるMStreamConnectorクラスはObserverパターンによる通知を 行うことができるように、MSubjectクラスも継承しています。今回はストリーム が閉じられたときにソケットを閉じるためにこれを利用します。ストリームが閉 じられたときにMStreamConnectorObserverクラスのupdate()メソッドが呼び出さ れ、その中でソケットを閉じるようになっています。 ----- MThreadPool threadPool = MGuardian.getInstance().getThreadPool(); threadPool.addCommand( streamConnector1 ); threadPool.addCommand( streamConnector2 ); -----  スレッドプールのaddCommand()メソッドに対してMStreamConnectorクラスのイ ンスタンスを渡すと、内部で生成したSSLサーバーソケットとクライアントのソケ ットが繋がり、SSLネゴシエーションが行われます。 ----- // receive http request BufferedInputStream in3 = new BufferedInputStream( socket3.getInputStream() ); OutputStream out3 = socket3.getOutputStream(); request = new MHttpRequest( in3 ); -----  socket3はSSLサーバーソケットのaccept()によって取得したSocketクラスのイ ンスタンスです。つまりこのソケットはSSLの処理をラッピングしてあるので、こ こから取得したInputStreamおよびOutputStreamは通常のストリームと同じように 扱うことができます。クライアントはSSLネゴシエーションの後、HTTPSサーバー に対するHTTPリクエストを送ってくるはずなので、これをrequestという名前のイ ンスタンスで取得します。 ----- pluginResult.put( "request", request ); pluginResult.put( "clientSideSocket", socket3 ); return pluginResult; } -----  最後にこのリクエストをGuardian@JUMPERZ.NET本体に伝えるためにpluginResult に"request"をキーに格納します。さらに、クライアント側のソケットとしてsocket3 を使用するように"clientSideSocket"をキーに同じく格納し、pluginResultを戻 り値としてexecute()を抜け、処理が完了します。 ■0x09.) <TITLE>タグ部分の改竄  おまけで、<TITLE>タグ部分の改竄を行っているコードについても解説を行って おきます。処理はMDefacerというプラグインで行いますが、このプラグインを呼 び出すルールは次のようになっています。 ----- <rule> id=L6 revision=1 name=DefaceTitle type=responseHeader pattern=^Content-Type: ?text/html condition=match case_sensitive=no log=no action=none command=none plugin=sample.sslFilter.MDefacer </rule> -----  画像ファイルなどのHTMLファイル以外のHTTPレスポンスはスルーしたいので、 Content-Typeフィールドに注目し、text/htmlという値を持つ場合にのみプラグイ ンを起動するようにしています。  さて、ではこのMDefacerクラスのソースコードを最初から見ていきます。 ----- public class MDefacer extends MGuardianPlugin { private static String title = "Big brother is watching you =)"; -----  <TITLE>タグの内部をどのように書き換えるかを、staticな文字列のtitleの値 として持っています。 ----- MHttpResponse response = ( MHttpResponse )sessionInfo.get( "response" ); if( response == null || !response.hasBody() ) { return null; } -----  sessionInfoから"response"をキーにHTTPレスポンスを取得します。レスポンス が無い場合(誤ってリクエストに対してトリガーするルールから呼び出された場 合)やレスポンスがボディ部分を持たない場合には処理を終えます。 ----- String responseBody = MStreamUtil.streamToString( response.getBodyInputStream() ); String after = "<title>" + title + "</"; responseBody = responseBody.replaceFirst ( "<(TITLE|Title|title)>[^<]*</", after ); -----  HTTPレスポンスのボディ部をStringクラスのインスタンスとして取得し、<TITLE> タグの部分を置換します。正規表現が使えてとても便利です。 ----- response.setBody( responseBody ); response.setHeaderValue ( "Content-Length", Integer.toString( responseBody.length() ) ); -----  置換済みのボディ部をレスポンスにセットします。ボディ部分のサイズが変わ った可能性が高いので、Content-Lengthヘッダーを修正します。このようにして <title>タグ部分の書き換えは終了です。 ■0x0A.) まとめ  今回はSSL Proxyサーバーを実際に作り動かすことで、HTTPSのフィルタリング が可能であること、また、あやしいルート証明書をインストールすることがどん なに危険であるかなどを体験することができたかと思います。また、よく目にす る「公開鍵を秘密鍵によって署名して…」などの作業を実際にJavaのコード内で 行うことができるので、PKI(なのか?)について、本やウェブなどで読むのとは 異なり、実際に感覚的なものとして身につけることができるのではないでしょう か。  今回のコードを見て、いきなり全てを理解するのは難しいかもしれません。SSL や暗号のコーディングについてはオライリーの『Java Security』(書籍)がオス スメです。また、ウェブを検索するとコードの断片が大量に出てくるので、それ らも参考になります。Javaは標準ライブラリだけでも暗号について非常に柔軟に プログラムを作成できるので、ぜひチャレンジしてみてください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第5章: リバースエンジニアリング --- 著者:Kenji Aiko x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  最初に断っておきますが、私はKrackerではありませんし、またリバースエンジ ニアリングについてさほど詳しいわけでもありません。そんな人が「リバースエ ンジニアリング」などと銘打って文章を書くこと自体がそもそもおかしいですが、 今回は、私がリバースエンジニアリングについていろいろと調べた結果をテキス トとしてまとめてみようということでこの文章を書き上げました。よって、この 文章は私がここ1ヶ月くらいで学んだ過程を書き綴っています。ただ、まとめたと いっても、デバッガの使い方といった初歩の部分から書いているわけではないの で、少なくともアセンブリ言語を理解していることが前提となります。また場合 によっては、WindowsやDLLの仕組み、そして暗号アルゴリズムに関してもある程 度の知識が必要かもしれません。  実験を行った私の環境はWinXP、コンパイラはVC++.NET、デバッガはOllyDbgで すので、その他の環境の方はいろいろと内容に違いがでてくるかもしれません。 ご了承ください。 ■0x02.) リバースエンジニアリングとは  リバースエンジニアリングとは、ソフトウェアやハードウェアなどを分解、あ るいは解析し、その仕組みや仕様、目的、構成部品、要素技術などを明らかにす ることです。プログラムの分野では、モジュール間の関係の解明やシステムの基 本仕様の分析といった行為を含みます。  一般にはあまり良いイメージがないかもしれませんが、仕様書と実装の食い違 いを指摘したり、セキュリティホールやバグの発見につながるなど、システム保 守やセキュリティ強化の面で役立つこともあります。 【IT用語辞書「e-Words」より】 ■0x03.) crackme.exe  では、とりあえず以下のプログラムをDLしてください。 http://ruffnex.oc.to/kenji/crackme/crackme.exe  「crackme.exe」ですが、その名の通りクラックするためのEXEファイルです。 それで、さっそく実行してみると、どうやら1192年5月15日にしか実行できないと いうダイアログが表示され、勝手にプログラムが終了してしまいます。 http://ruffnex.oc.to/kenji/crackme/crackme.bmp  1192年は確か鎌倉幕府ができた年です。今年の大河ドラマは「義経」なので、 ちょうどこの時代に作成されたEXEファイルということになります。面白くない冗 談はさておき、この時間制限をどうやってクリアするか? まずは、Windowsの時 刻設定を変更して対応する、といったもっともシンプルな方法が思いつきますが、 さすがのWindowsXPも1980年以降の時間しか設定することはできません。1192年に 設定することはできないので、却下となります。  次に、デバッガ(OllyDbgなど)を使って、内容を解析するといったことが考え られます。では、とりあえずOllyDbgで中身を見てみることにしましょう。  OllyDbgはフリーのデバッガでありOllyDbgのページからダウンロードすること ができます。 http://home.t-online.de/home/Ollydbg/  OllyDbgに関しては「Digital Travesia」(http://gamereverserz.cjb.net/) がとても参考になります。  その他、日本語化パッチや、DokoDonさん作成のOllyDbgプラグイン「OllyDump」 やその他有用なツール盛りだくさんですのでぜひ参考にしてください。 ----- crackme.exe (OllyDbg) 00402900 >/$ 81EC 14080000 SUB ESP,814 00402906 |. A1 78934000 MOV EAX,DWORD PTR DS:[__security_cookie] 0040290B |. 338424 1408000>XOR EAX,DWORD PTR SS:[ESP+814] 00402912 |. 898424 1008000>MOV DWORD PTR SS:[ESP+810],EAX 00402919 |. 8D4424 00 LEA EAX,DWORD PTR SS:[ESP] 0040291D |. 50 PUSH EAX ; /pSystemTime 0040291E |. FF15 10704000 CALL DWORD PTR DS:[<&KERNEL32.GetSystemT>; \GetSystemTime 00402924 |. 66:8B4424 00 MOV AX,WORD PTR SS:[ESP] -----  OllyDbgで開くこのような場所からスタートするのが分かります。その場所から 少し下へ進んでいくと、GetSystemTimeというAPIが表示されています。さらにそ の下にはDialogBoxParamが呼び出されています。 ----- crackme.exe (OllyDbg) 00402945 |. 8B8C24 1808000>MOV ECX,DWORD PTR SS:[ESP+818] 0040294C |. 6A 00 PUSH 0 ; /lParam = NULL 0040294E |. 68 A0274000 PUSH crackme.Dlg_Proc ; |DlgProc = crackme.Dlg_Proc 00402953 |. 6A 00 PUSH 0 ; |hOwner = NULL 00402955 |. 6A 65 PUSH 65 ; |pTemplate = 65 00402957 |. 51 PUSH ECX ; |hInst 00402958 |. FF15 CC704000 CALL DWORD PTR DS:[<&USER32.DialogBoxPar>; \DialogBoxParamA 0040295E |. EB 38 JMP SHORT crackme.00402998 -----  よって、この辺りに時間条件判定のコードがあることが分かります。というか、 GetSystemTime関数で現在の時間を取得して、「1192年 5月15日」ではなかったら プログラムを終了するという処理が行われているのだろうと推測できます。さら に、その判定処理は、GetSystemTime より後であり、DialogBoxParamAより前であ ることが予想できます。なのでその間の処理を調べてみます。 ----- crackme.exe (OllyDbg) 00402924 |. 66:8B4424 00 MOV AX,WORD PTR SS:[ESP] 00402929 |. 66:3D A804 CMP AX,4A8 0040292D |. 66:8B4C24 06 MOV CX,WORD PTR SS:[ESP+6] 00402932 |. 66:8B5424 02 MOV DX,WORD PTR SS:[ESP+2] 00402937 |. 75 27 JNZ SHORT crackme.00402960 00402939 |. 66:83FA 05 CMP DX,5 0040293D |. 75 21 JNZ SHORT crackme.00402960 0040293F |. 66:83F9 0F CMP CX,0F 00402943 |. 75 1B JNZ SHORT crackme.00402960 -----  重要なのは、3つのJNZ命令であり、すべて00402960へジャンプしようとしてい ます。追ってみれば分かりますが、その先はエラーを知らせるメッセージボック スの処理となります。つまり、ここでジャンプしないように進めればプログラム が実行できるということです。JMP命令と同じくCMP命令も3つあります。これで比 較を行っているわけですが、GetSystemTime関数呼出し後、スタックから取り出し てきた値をレジスタに格納しています。AXレジスタにはおそらく「年」が、DXレ ジスタには「月」が、CXレジスタには「日」が入るだろうことが予測できます。 3つのCMP命令による比較と、3つのJNZ命令によるジャンプです。これらのデータ からどの部分を書き換えれば、エラーメッセージを出さずに正常にプログラムを 起動できるかを考えると、答えは明白です。3つのJNZ命令は、すべてSHORTジャン プなので2バイトで表現されています。よって3つのJNZ命令、計6バイトのデータ をNOPに書き換えることで、プログラムを正常に起動できそうです。  しかし、ソフトウェアのKrackingパッチは、変更するデータをなるべく少なく した方がエレガントであるらしいので、なるべく変更箇所を少なくしましょう。 ということで、最初のJNZ命令のジャンプ先を00402960から00402945へ変更するこ とにしましょう。これなら1バイトを書き換えるだけで、プログラムを実行できる ようになります。  では、最初のJNZ命令があるアドレス00402937の「75 27」の2バイトを「75 0C」 に変更してください。OllyDbgでは、ポインタを変更箇所に合わせて「右クリック →バイナリ→編集」で任意の場所を編集することができます。あとはそれを実行 ファイルへ書き込まなければならないので、「右クリック→実行ファイルへコピ ー」を選択して、実行ファイルへ書き込むと、無事、書き込み後のEXEファイルが 作成されます。そして、作成されたEXEファイルをダブルクリックすると、エラー が表示されずにプログラムは終了せずに、ウィンドウが表示されます。 http://ruffnex.oc.to/kenji/crackme/crackme2.bmp ■0x04.) パッキング  パッキングとは、EXEファイルを実行できる状態のまま圧縮することです。そし て、それを行うツールのことをパッカーと呼びます。パッカーとは、本来、EXEフ ァイルを実行できる状態のまま圧縮してくれるというとても便利なツールです。 ただ、最近では、圧縮してくれるだけではなく、リバースエンジニアリングを行 いにくくするためにも使用されています。というより、むしろこのような「アン チKrack対策」として利用される方が多いようです。では実際どのようなものなの かを理解するために、使ってみることにしましょう。パッカーにはいくつもの種 類が存在しますが、今回は、オープンソースで有名なUPXを使ってcrackme.exeの パッキングを行ってみます。UPXのサイトからDLしてください。私は「UPX ver1.24」 をDLしました。 http://upx.sourceforge.net/  前回使ったcrackme.exeはすでに実行できるようにバイナリを書き換えてしまっ たので、新しくcrackme.exeをDLするか、もしくは、変更箇所を元の値である「27」 に戻してください。そして、そのcrackme.exeをUPXを使ってパッキングしてくだ さい。パッキングするのがメンドクサイという方は以下にcrackme.exeをパッキン グしたpcrackme.exeをDLしてください。ただし、以後パッキングされたものを crackme.exeと呼ぶので、DLされた方はファイル名をpcrackme.exeからcrackme.exe に変更してください。 http://ruffnex.oc.to/kenji/crackme/pcrackme.exe ----- コマンドプロンプト C:\>upx crackme.exe Ultimate Packer for eXecutables Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 UPX 1.24w Markus F.X.J. Oberhumer & Laszlo Molnar Nov 7th 2002 File size Ratio Format Name -------------------- ------ ----------- ----------- 26624 -> 15872 59.61% win32/pe crackme.exe Packed 1 file. C:\> -----  パッキングが完了したら、まずはcrackme.exeのサイズをみてください。明らか にファイルサイズが小さくなっています。そして、もちろんファイルサイズが小 さくなっても実行することができます。ただ、お馴染みの「1192年5月15日にしか 実行できません」というようなメッセージボックスが表示されてプログラムが終 了してしまいます。なので、もう一度OllyDbgからバイナリを変更することにしま しょう。ということで、OllyDbgで UPXパッキングがなされたcrackme.exeを開い てください。変なエラーメッセージができるかもしれませんが、無視して構いま せん。 ----- crackme.exe [UPX版] (OllyDbg) 0040CC80 > $ 60 PUSHAD 0040CC81 . BE 00904000 MOV ESI,crackme.00409000 0040CC86 . 8DBE 0080FFFF LEA EDI,DWORD PTR DS:[ESI+FFFF8000] 0040CC8C . 57 PUSH EDI 0040CC8D . 83CD FF OR EBP,FFFFFFFF 0040CC90 . EB 10 JMP SHORT crackme.0040CCA2 -----  するとパッキング前とは全然違うコードになっています。どこにもGetSystemTime 関数はありませんし、何かわけの分からないことを行っており、意図したプログ ラムのソースコードになっていません。しかし、実行することは可能なのです。 つまり、パッカーを使うと実行ファイルのサイズが小さくなり、かつ、内部構造 を簡単に解析させないようにさせることが可能なのです。うーん、なんて便利な んだろう。つまり、これはリバースエンジニアリングを行う者にとってはやっか いな代物となるわけです。最初にパッカーを作ったのが誰かは知りませんが、さ ぞかし「Krackerのやつらめ、ざまーみろ!」と思ったに違いありません。ホント か?(笑)。  しかし、天下の解析屋Krackerも負けてはいません。彼らはこのようなパッキン グされたEXEファイルを解析し、元のEXEファイルに戻す手法を開発(?)しまし た。それを「アンパッキング」と呼びます。どのような複雑なパッキングがなさ れていても、彼らはそれを破り、元のEXEファイルを復元させてしまうのです。さ らに「アンパッカー」と呼ばれるパッキングを解除するツールまで開発しました。 まさに彼らは「ソフトウェアに不可能は無い」という、その言葉通りのことを証 明したのでした。めでたし、めでたし(完)。 ■0x05.) アンパッキング  えっと、何の話でしたっけ? ああーそうそう、パッキングですね。それで、 今度はそのパッキングされたcrackme.exeをアンパッキングしてみたいと思います。 といっても、そもそもUPXは「-d」コマンドを使えば復元(アンパック)できるの で、わざわざ手動でアンパッキングするのもどうかと思いますが、何事も練習と 思ってやってみます。  UPXにてパッキングされたcrackme.exeをOllyDbgで開くと、以下のように表示さ れます。 ----- crackme.exe [UPX版] (OllyDbg) 0040CC80 > $ 60 PUSHAD 0040CC81 . BE 00904000 MOV ESI,crackme.00409000 0040CC86 . 8DBE 0080FFFF LEA EDI,DWORD PTR DS:[ESI+FFFF8000] 0040CC8C . 57 PUSH EDI 0040CC8D . 83CD FF OR EBP,FFFFFFFF 0040CC90 . EB 10 JMP SHORT crackme.0040CCA2 -----  パッキングとは、簡単に言えば「EXEファイルを圧縮しているだけ」です。ただ、 圧縮するだけだったらZIPやLHAと同じですが、実行できる状態で圧縮してる部分 が大きく違います。それで、実行できる状態で圧縮するわけですから、当然パッ キングされたcrackme.exeには、オリジナルな crackme.exeの処理の前に展開(解 凍)ルーチンが付加されていることになります。ZIPで圧縮されたEXEファイルは、 まず展開(解凍)してから生成されたファイルをダブルクリックで実行しますよ ね。考え方はそれと同じです。ただ、パッキングされたEXEファイルの場合は、EXE ファイルの中に展開(解凍)する処理も組み込まれているだけなのです。つまり、 EXEファイルが実行されたら、最初に、圧縮されたオリジナルcrackme.exeをメモ リ上に展開(解凍)する処理を実行します。そして展開(解凍)後、オリジナル crackme.exeの先頭アドレス(「Original Entry Point」略して「OEP」)へジャ ンプして、実際のcrackme.exeの処理を行うわけです。すっごい分かりにくい説明 のような気がしますが、私の文章力ではこの辺りが限界ですので、あとは、google で調べてください(^^;。  要するに、パッキングを行ったら「本来のデータが圧縮されて、さらにその圧 縮されたデータの展開(解凍)を行う処理が最初に追加される」ということです。 ということは、パッキングされたEXEファイルから本来の圧縮されてないデータ部 分を取り出すためには、展開(解凍)処理が行われたすぐあとのメモリ状態をダ ンプすればよいということになります。なので「OEP」を探す必要が出てくるとい うわけなんです。よって、アンパッキングを行う際に、最初にやらなければなら ないこととは、その「オリジナルcrackme.exeの先頭アドレス」である「OEP」を 探すこととなります。  では、早速探しましょう。OllyDbgの最初の1行は「PUSHAD」命令です。レジス タの内容をすべてスタックに退避するといった便利な命令ですが、では、これに 対応する「POPAD」を見つけてください。PUSHADをずっと下に検索していった先に あると思います。 ----- crackme.exe [UPX版] (OllyDbg) 0040CDC6 .^EB E1 JMP SHORT crackme.0040CDA9 0040CDC8 > FF96 9CC00000 CALL DWORD PTR DS:[ESI+C09C] 0040CDCE > 61 POPAD 0040CDCF .-E9 505CFFFF JMP crackme.00402A24 -----  見事に見つけたら、そのPOPAD以下のJMP命令にブレークポイントを仕掛け、プ ログラムを実行します。実行したら、当然のごとくこの位置で止まりますので、 F8で処理を1回進めてください。 ----- crackme.exe [UPX版] (OllyDbg) 00402A24 6A 60 PUSH 60 00402A26 68 78724000 PUSH crackme.00407278 00402A2B E8 70030000 CALL crackme.00402DA0 00402A30 BF 94000000 MOV EDI,94 ....(省略).... 00402A43 56 PUSH ESI 00402A44 FF15 48704000 CALL DWORD PTR DS:[407048] ; kernel32.GetVersionExA 00402A4A 8B4E 10 MOV ECX,DWORD PTR DS:[ESI+10] -----  するとアドレス「00402A24」にジャンプします。ちょっと下に「kernel32.Get VersionExA」というありふれたAPI名がありますので、どうやらここがOEPだと決 めうちします。実際、OEPを探しますと言いましたが、OEPを探す一定の法則は無 いそうです。まぁ考えてみれば当たり前ですよね。展開(解凍)を行う処理がど こで終わるのかなんて分かるわけありません。そういうことはパッカーを作成し た人に聞いてください。なので、地道にマシン語を追いかけるしかありません。 ただPUSHADやPOPADが少なからず手がかりになるようなので、それを元に運と勘 とニオイで探し当ててください。アンパッキングは予想以上にメンドクサイ作業 なのです。  OEPで止まったら、当然のごとくプラグインとしてインストールされている OllyDumpを使って、メモリ状態をファイルに落とします。とりあえずファイル名 は「crackme_dump.exe」としておきます。その時に「get EIP as OEP」ボタンを クリックして算出されたアドレス「2A24」を覚えておきます。 http://ruffnex.oc.to/kenji/crackme/ollydump.bmp  「OllyDumpって何?」という方は「http://ollydbg.win32asmcommunity.net/stuph/」 からg_ollydump221b.zipというファイルをDLして、プラグインとしてOllyDbgに組 み込んでおいてください。「Digital Travesia」(http://gamereverserz.cjb.net/) から辿ることもできます。  アンパッキングはまだまだ続きます。  現在、手元にあるのは、OllyDumpを使ってダンプした「crackme_dump.exe」と 「get EIP as OEP」ボタンを押したときに算出されたアドレス「2A24」です。そ れで、メモリ状態をダンプしてきた「crackme_dump.exe」早速実行しても、残念 ながら実行することができません。以下のようなエラーメッセージがでます。 http://ruffnex.oc.to/kenji/crackme/error2.bmp  それで、次にIATの再構築というものをやらなければなりません。IATというの は「Import Address Table」の略だそうです。「何それ?」という方はPEフォー マットについて勉強しましょう。  マシン語大研究「http://hp.vector.co.jp/authors/VA015412/」というサイト にPEフォーマットの詳細というものがありますので、それを参考にしてください。  それで、通常はこのIATの再構築をツールを使って行います。例えば、スペシャ ルねこまんま57号「http://www.vector.co.jp/soft/win95/hardware/se254476.html」 です。汎用プロセスメモリエディタ兼デバッガと銘打ってますが、ものすごい高 機能なツールで、汎用プロセスメモリエディタ兼デバッガにとどまりません。IAT の再構築なんて朝飯前っぽい雰囲気を漂わせているので、使ってみてください。 他にもいろいろと使い道があり、本当にすばらしいツールのようです。  ただ、読者の方には、「ハードディスクの容量が少ないので、新しくツールを DLするなんて夢のまた夢です」という人や「ツールなんてコンパイラとデバッガ があれば十分、仕組みを教えてくれりゃーあとは自分で作るぜ!」という人もお られるかもしれません。なので、今回はIATの再構築をバイナリエディタでやって みようと思います。  私はStirling「http://www.vector.co.jp/soft/win95/util/se079072.html」と いうバイナリエディタを使用しています。  では、Stirlingを起動して「crackme_dump.exe」を読み込んでください。まず は「Import Address Table」を探します。探しますといってもPEフォーマットを 知っている人だったら簡単に探せるんですが、知らない人だったら、ただの数字 の羅列にしか見えませんので、ここでOllyDbgを使います。OllyDbgでパッキング された「crackme.exe」を開きます。別にメモリイメージをダンプした「crackme _dump.exe」でもよいですが、Stirlingで読み込んでいる状態だとファイルの排他 制御が働いて、Stirlingからファイルへ書き込めなくなる恐れがあるので、 「crackme.exe」の方がよいです。  OllyDbgで「右クリック→検索→ラベル名」もしくは「Ctrl + N」とすると、新 しくウィンドウが開きます。すると以下のように表示されていると思います。 ----- 現在のモジュール内検索(OllyDbg) 0040D09C .rsrc Import ( KERNEL32.ExitProcess 0040D098 .rsrc Import ( KERNEL32.GetProcAddress 0040D094 .rsrc Import ( KERNEL32.LoadLibraryA 0040D0A4 .rsrc Import ( USER32.wsprintfA 00402A24 UPX0 Export <モジュールエントリーポイント> -----  それでタイプに「Import」となっているAPIのアドレスを見てみるとKERNEL32. ExitProcessの場合だと「0040D09C」となっています。400000はベースアドレスで すので無視します。すると0000D09Cというアドレスが算出されます。バイナリエ ディタで0000D09Cの部分を調べてください。 ----- crackme_dump.exe(変更前)(stirling) 0000D090 00 00 00 00 D8 05 E4 77 FD A5 E3 77 B5 5C E3 77 0000D0A0 00 00 00 00 6A C9 CF 77 00 00 00 00 4B 45 52 4E 0000D0B0 45 4C 33 32 2E 44 4C 4C 00 55 53 45 52 33 32 2E 0000D0C0 64 6C 6C 00 00 00 4C 6F 61 64 4C 69 62 72 61 72 0000D0D0 79 41 00 00 47 65 74 50 72 6F 63 41 64 64 72 65 0000D0E0 73 73 00 00 45 78 69 74 50 72 6F 63 65 73 73 00 0000D0F0 00 00 77 73 70 72 69 6E 74 66 41 00 00 00 00 00 -----  0000D09Cからの4バイトは「B5 5C E3 77」となっています。それを正しいアド レスである「E2 D0 00 00」に変更してください。そのままバイナリエディタを見 てください。crackme_dump.exeのアドレス0000D0E2には、 ExitProcessという文 字列が存在しているのが確認できます。次に進みます。OllyDbgを見ると次は GetProcAddressのアドレス「0040D098」ですね。ベースアドレス400000を省いて 0000D098として、バイナリエディタからこのアドレスの位置にあるデータを調べ ると「FD A5 E3 77」です。そのデータを正確なGetProcAddress文字列のアドレス 「D2 D0 00 00」に変更します。文字列のアドレスといっても実際には、文字列の 先頭より2バイト前のアドレスとなっていますが、この説明は割愛します。これに ついてはPEフォーマットを学んでください。このようにして、OllyDbgを見ながら crackme_dump.exeのIATを変更していきます。この例だと4箇所、計16バイトあり ますね。すべて変更すると、以下のようになります。 ----- crackme_dump.exe(変更後)(stirling) 0000D090 00 00 00 00 C4 D0 00 00 D2 D0 00 00 E2 D0 00 00 0000D0A0 00 00 00 00 F0 D0 00 00 00 00 00 00 4B 45 52 4E 0000D0B0 45 4C 33 32 2E 44 4C 4C 00 55 53 45 52 33 32 2E 0000D0C0 64 6C 6C 00 00 00 4C 6F 61 64 4C 69 62 72 61 72 0000D0D0 79 41 00 00 47 65 74 50 72 6F 63 41 64 64 72 65 0000D0E0 73 73 00 00 45 78 69 74 50 72 6F 63 65 73 73 00 0000D0F0 00 00 77 73 70 72 69 6E 74 66 41 00 00 00 00 00 -----  上から2行目(32ビット)までに変更データがあります。下5行は変更していま せん。これでIATの再構築は終了です。では、「crackme_dump.exe」を実行してみ てください。無事実行されて、時間うんぬんのエラーメッセージがでたら成功で す。これでアンパッキングは終了となります。が、あくまでもアンパッキングが 終了しただけで、ここから一般的な解析が始まるわけです。  IATの再構築を行った「crackme_dump.exe」をOllyDbgで開いてください。変な 警告がいくつか表示されるかもしれませんが、無視して構いません。 ----- crackme_dump.exe (OllyDbg) 00402A24 > 6A 60 PUSH 60 00402A26 68 78724000 PUSH crackme_.00407278 00402A2B E8 70030000 CALL crackme_.00402DA0 00402A30 BF 94000000 MOV EDI,94 00402A35 8BC7 MOV EAX,EDI -----  こんな感じになっているはずです。では「右クリック→検索→同上全モジュー ル内」を選択して、GetSystemTimeにブレークポイントを仕掛けます。そして「解 析→実行」で実行させると、 ----- crackme_dump.exe (OllyDbg) 77E21608 > 55 PUSH EBP 77E21609 8BEC MOV EBP,ESP 77E2160B 83EC 18 SUB ESP,18 77E2160E A1 1800FE7F MOV EAX,DWORD PTR DS:[7FFE0018] -----  ここで、止まります。ここはおそらく関数内なので、「F8」ボタンを押してRET 命令まで処理を進めます。 ----- crackme_dump.exe (OllyDbg) 77E21673 66:8948 0E MOV WORD PTR DS:[EAX+E],CX 77E21677 C9 LEAVE 77E21678 C2 0400 RETN 4 77E2167B > A1 1800FE7F MOV EAX,DWORD PTR DS:[7FFE0018] -----  アドレス77E21678がRET命令なので、そこでさらにもう一度「F8」を押すと関数 を抜けます。そして ----- crackme_dump.exe (OllyDbg) 00402924 66:8B4424 00 MOV AX,WORD PTR SS:[ESP] 00402929 66:3D A804 CMP AX,4A8 0040292D 66:8B4C24 06 MOV CX,WORD PTR SS:[ESP+6] 00402932 66:8B5424 02 MOV DX,WORD PTR SS:[ESP+2] 00402937 75 27 JNZ SHORT crackme_.00402960 00402939 66:83FA 05 CMP DX,5 0040293D 75 21 JNZ SHORT crackme_.00402960 0040293F 66:83F9 0F CMP CX,0F 00402943 75 1B JNZ SHORT crackme_.00402960 -----  このような場所に辿り着きます。ここは以前見たことがありますね。そうです、 3つのJNZ命令と3つのCMP命令です。前回と同じように、アドレス 00402937の 「75 27」を「75 0C」に変更して、保存してください。保存したEXEファイルを 実行すると、見事プロテクトが外れてウィンドウが表示されます。 http://ruffnex.oc.to/kenji/crackme/crackme2.bmp  「アンパッキングってややこしい!」というのが私の感想です。なんかいろい ろなツールを使い分けて、あーだこーだとやらなければならないわけです。さら にパッキングがひとつだけしか施されてないならばまだ良いのですが、2重3重と パッキングされていたら、もうやる気でません(笑)。ということで、次は別の アプローチで、このパッキングされたcrackme.exeのプロテクトを破っていくこと にします。 ■0x06.) APIフック  WindowsのAPIは、kernel32.dllやuser32.dllといったような、DLLファイルとし て実装されています。よって、プログラム(EXEファイル)は、実行時にこれらの DLLを暗黙のうちにリンクしなければなりません。これはすなわち、APIはEXEファ イルに実装されているわけではない、というなんとも当たり前な結論に行き着き ます。  そこで、例えば時間を取得するAPIであるGetLocalTimeやGetSystemTimeを使っ て、ソフトウェアの使用期限を設けているツールがあるとします(crackme.exeで すね)。このようなツールは、GetLocalTimeやGetSystemTimeから渡されたデータ (時間)が正しいということを前提としています。しかし、そもそもGetLocalTime やGetSystemTimeといったAPIはEXEファイルではなく、外部のDLLファイルにて実 装されているわけであり、このデータを信頼することは必ずしも安全ではないと 考えられます。何故なら、kernel32.dllとまったく同じエクスポート関数を持っ ており、まったく同じ挙動を示すlernel32.dllを作成してしまえば、そのDLLは、 kernel32.dllに取って代わることができるからです。  kernel32.dllとまったく同じエクスポート関数を持っているDLLを作成すれば、 それはEXEファイルにkernel32.dllと認識させることが可能となります。しかし、 本来kernel32.dllやuser32.dllといったWindowsの動作に直接関係するDLLは、プ ログラムの実行時に特別なカタチでリンクされることになるので、本物のkernel32 .dllがリンクされる前に、偽物のkernel32.dllをリンクさせることはできません。 よって、EXEファイルのバイナリを多少変更する必要がでてきます。  UPXでパッキングされたcrackme.exeをバイナリエディタ(stirling)で開き 「KERNEL32.DLL」をキーワードに文字列検索を行います。すると、以下のアドレ スで見つかります。 ----- crackme.exe (stirling) 000042A0 00 00 00 00 F0 D0 00 00 00 00 00 00 4B 45 52 4E 000042B0 45 4C 33 32 2E 44 4C 4C 00 55 53 45 52 33 32 2E -----  ここでヒットします。では、試しに「KERNEL32.DLL」の「K」の部分を「L」に 変更してください。そして、保存しプログラムを実行してみます。 ----- crackme.exe (stirling) 変更後 000042A0 00 00 00 00 F0 D0 00 00 00 00 00 00 4C 45 52 4E 000042B0 45 4C 33 32 2E 44 4C 4C 00 55 53 45 52 33 32 2E -----  「LERNEL32.dll」というようにバイナリを変更した状態でプログラムを実行す ると、「LERNEL32.dllが見つかりません」というダイアログボックスが表示され、 プログラムが起動しません。これは当たり前で、どのフォルダを探しても 「LERNEL32.dll」なんていうDLLは存在しませんので、このようなダイアログが表 示されるわけです。 http://ruffnex.oc.to/kenji/crackme/error.bmp  さて、ここからがポイントです。lernel32.dllが無いならば、作りましょう。 作るといっても、適当なDLLファイルではいけません。 EXEファイルはkernel32. dllと思ってlernel32.dllをリンクするわけですから、これから作るlernel32.dll は、 kernel32.dllとエクスポート関数、挙動が同じでなければなりません。その ためには、まずkernel32.dllのエクスポート関数を調べる必要があります。そん なものはいったいどこに書かれてあるのか? それは、もちろんkernel32.dllに 書かれてあります。というわけで、 Windowsシステムフォルダからkernel32.dll をコピーしてください。間違ってもシステムフォルダからkernel32.dllを消さな いように。  さて、エクスポート関数を調べるということですが、根性のある人はバイナリ エディタでkernel32.dllを開いて、エクスポート関数のようなものを、ひとつず つ手動でコピーしていけばOKです。でも、kernel32.dllのエクスポート関数は約 1000個ほどあるので、とてもじゃないですが、根性のない私にはできません(^^;。 なので、エクスポート関数を集めるツールを作りました。 http://ruffnex.oc.to/kenji/text/listexport/  システムフォルダのkernel32.dllをlistexport.exeと同じフォルダにコピーし て、コマンドプロンプトから以下のように実行します。 ----- コマンドプロンプト C:\..\wb15>listexport kernel32.dll > kernel32exp.txt C:\..\wb15> -----  すると、同じフォルダにkernel32exp.txtというテキストファイルが作成されま すので、それをテキストエディタで開くと、kernel32.dllのエクスポート関数が 列挙されています。 ----- kernel32exp.txt 序数: 0001 名前: ActivateActCtx 序数: 0002 名前: AddAtomA 序数: 0003 名前: AddAtomW 序数: 0004 名前: AddConsoleAliasA ......(省略)...... 序数: 039D 名前: lstrcpynW 序数: 039E 名前: lstrlen 序数: 039F 名前: lstrlenA 序数: 03A0 名前: lstrlenW -----  listexport.cppがソースコードですが、解説は割愛させていただきます。とい うのも、このソースはどんなに説明しても、PEヘッダフォーマットを理解してい ないと読めないからです。そして、逆に理解していれば解読は容易にできます。 つまり、解説したとしても、ソースの解説ではなく PEヘッダフォーマットの解説 になってしまい、この記事とは主旨がずれてしまうからです。というわけで、興 味のある方は、読んでみてください。コメントも不必要なほどつけてますので(笑)。  さて、現在crackme.exeのバイナリをLERNEL32.dllにしてしまったので、crack me.exeが実行できなくなっています。なので、これからlernel32.dllを作成する ことにします。再びlistexport.exeを使います。-fileオプションをつけて以下の ように実行してください。 ----- コマンドプロンプト C:\..\wb15>listexport -file kernel32.dll lernel32 ソースファイル lernel32.cpp, lernel32.def を生成しました C:\..\wb15> -----  すると「ソースファイル lernel32.cpp, lernel32.def を生成しました」を表 示されます。これでlistexport.exeと同じフォルダにこれらのファイルが生成さ れています。あとはこの2つのファイルを VC++などでビルドするだけで、kernel 32.dllとまったく同じエクスポート関数を持ったlernel32.dllを作成することが できます。  まず、VC++で「lernel32」という空のDLLプロジェクトを作成します。そして、 これら2つのファイルをプロジェクトに追加し、あとはビルドを行うだけです。た だし、VC++.NETに関しては少し違います。VC++.NETはとても不親切で、.defファ イルをプロジェクトに追加しても、ビルド時のリンカオプションに.defファイル を追加してくれません。これはバグなんじゃないのかと私は思いますが、とにか くダメなので、VC++. NETに関しては、「ファイル→新しい項目の追加」で新しく lernel32.defファイルを作成して、そこにlistexportで生成された lernel32.def の内容をコピーしてください。.cppに関しては問題ありませんので、そのままプ ロジェクトに追加してください。  あと、ひとつlistexportを利用する上で重要なこととして、.defファイルはそ の性質上「@マーク」を関数名に含んだ関数を扱えません。その他特殊文字も同様 です。よって、そのような関数名を持つDLLを偽装する場合は、あらかじめ「@」 を「*」などに置換しておいてビルドを行い、DLL になった状態で、再度バイナリ レベルで「*」を「@」に置換するといった方法をとってください。「crtdll.dll」 などがそのようなDLLに該当します。  さて、山あり谷ありでなんとかlernel32.dllが作成できたら、crackme.exeと同 じフォルダにコピーしてください。無事crackme.exeが実行できたら、成功となり ます。ただ、実行といっても年月日が違うので、すぐに終了してしまうんですけ どね。  無事、lernel32.dllが作成できました。さて、問題はここからです。今度は、 いよいよcrackme.exeの時間制限プロテクトを破らなければなりません。時間取得 に利用していたAPIはGetSystemTimeでした。まず、このAPIをMSDNなどで検索して、 戻り値や引数などを調べます。そしてこのAPIとまったく同じ挙動のエクスポート 関数を作成します。  最初に、lernel32.cppの以下の行をコメントアウトします。おそらく1257行目 辺りです。そして変わりの自作GetSystemTime関数を定義します。 ----- lernel32.cpp //__declspec( naked ) void WINAPI d_GetSystemTime() { _asm{ jmp p_GetSystemTime } } __declspec(dllexport) VOID WINAPI d_GetSystemTime(LPSYSTEMTIME t); -----  この定義はMSDNなどで調べることで分かります。そして次に、自作GetSystem Timeを作成します。なので、lernel32.cppの一番下に以下のソースを追加します。 ----- lernel32.cpp __declspec(dllexport) VOID WINAPI d_GetSystemTime(LPSYSTEMTIME t) { t->wYear = 1192; t->wMonth = 5; t->wDay = 15; t->wDayOfWeek = 0; t->wHour = 1; t->wMinute = 1; t->wSecond = 1; t->wMilliseconds = 1000; } -----  とりあえず、年月日を「1192年5月15日」として、他の値は適当に設定します。 これで完了です。プロジェクトを再度ビルドして、 lernel32.dllをcrackme.exe と同じフォルダにコピーしてください。偽装kernel32.dllであるlernel32.dllを 作成し、GetSystemTime APIを偽装しました。これでcrackme.exeを実行してくだ さい。見事実行されたら成功です。 http://ruffnex.oc.to/kenji/crackme/crackme2.bmp  最終的に作成した「lernel32」の.cppファイル、.defファイル、そして.dllフ ァイルは、以下のZIPファイルにまとめました。 http://ruffnex.oc.to/kenji/crackme/lernel32.zip  さて、このように、場合によってはアンパッキングしなくても破ることができ ることもあります。要するに物事は考え方次第ということです。ただ、もちろん このテクニックは時間関連のプロテクトのみに有効です。なので、パスワードが 必要となるプロテクトでは、残念ながらこのテクニックは使えませんので、地道 にアンパッキングを行って破ってください。 ■0x07.) 実行されたcrackme.exe  さて、さまざまな方法でKrackされ、見事にプロテクトを解除されたcrackme.exe は、次にユーザー名とパスワードを必要とします。この実行されたcrackme.exeは、 私が考えうる「Krackされないソフトウェア」を実現しています。リバースエンジ ニアリングのスキルに自信のある方はぜひ解いてみてください。その概要を次の 章に書きます。 ■0x08.) 絶対にKrackされないソフトウェアの作り方を考える  絶対にKrackされないソフトウェアの作り方を考えます。ただし本当に、絶対に Krackされないソフトウェアを作るのは、まず無理です。ただし限りなくそれに近 づくことは可能です。多数のパッカーを使用するのもひとつの方法ではあります が、今回はあえてパッカーを使用しない方法を考えてみます。  まず、リバースエンジニアリングにかけて、ものすごいスキルの持ち主である 某氏の格言を紹介します。彼は「メモリ上にCPUが解釈できるマシン語が展開され る限り、Krackできないことなど有り得ない!」と仰いました。かっこよすぎです! 感動しました。マジですごすぎです(汗)。つまり、「どんなに圧縮(パッキング) されてようが、CPUが解釈できるならば人間に解釈できないわけはない」という意 味だと思います。もちろん、この格言はパッキングに限らず、すべてのアンチKrack 対策に当てはまることだと思います。結局、CPUが解釈できるわけですから、人間 にだって解釈できるわけです。よって、某氏からみると、CPUが解釈できるプログ ラムを組んでしまった時点で、すでにそのソフトはKrackできてしまうものですよ、 というわけです。では、どうしましょうか?  ならばいっそ、CPUが解釈できないプログラムを組むってのはどうでしょう?  バイナリエディタを開いて、自分の好きな数字を適当にどんどん書き込んでいき ます。そしてファイル名hogehoge.exeで保存します。そして、そのファイルをダ ブルクリックしてみてください。まずCPUは解釈できません。これなら、絶対に Krackできないと思います。絶対にKrackできないソフトウェアの完成です。でも 実行もできないと思います。なのでソフトウェアじゃないですね。ってゆーか、 それただのバイナリデータやん。  ただ、この考えは一理あると思います。つまりCPUが解釈できないプログラムを 書けばよいわけです。何が問題であるかというと、要するに「入力されたパスワー ドを判定する部分が存在する」からダメなのです。もっというと、この部分をCPU が解釈できてしまうからダメなのです。よって、パスワードを判定しないという のはどうでしょう? パスワードが正しいかどうかを判定しないわけです。とい うことで、私が考えた方法を次に示します。  まずは、正確なパスワードが入力されたあとの処理部分をすべて暗号化してお きます。つまり、正確なパスワードが入力されたことによって使用可能になるあ らゆるプログラムを暗号化しておきます。そして、復号化のためのキーをパスワ ードに割り当てます。パスワードが入力されたら、正確なパスワードであるかど うかを確認せずに、そのパスワード(キー)を使って、以後の処理部分の復号化 を行います。そして、復号化されたあとの処理部分へジャンプします。  もし、正確なパスワードが入力されていたら、復号化されたデータは正常なプ ログラムとなっているので問題ありません。そのまま処理が実行されます。しか し、間違ったパスワードが入力されていたら、間違ったキーで以後のプログラム の復号化処理を行ったことになるので、復号化は失敗します。復号化は失敗して いるので、もちろん以後のプログラムは正常な動作を保障できません。つまり、 処理部分にジャンプしたら間違いなく、プログラムがフリーズするでしょう。で もそれは仕方ないです。間違ったパスワードは入力しちゃダメだよ、ということ です(ぉぃ。ただ、さすがにフリーズさせるのはまずいので、あらかじめ復号化 されたデータのチェックサムを取っておきます。そしてそのチェックサムと比較 して正しければ、99%の確立で正しいパスワードが入力されたと判断して、復号 化したプログラムを実行します。  大抵の暗号アルゴリズムは、アルゴリズムと暗号文からキーと平文を求めるの は不可能であると数学的に証明されています。なので、パスワードを探しあてる には、アルゴリズムを再現して、総当りでキーと平文を探すしかありません。し かし、アルゴリズムを再現している時点でEXEファイルのソースコードを復元して いるようなものですので、そこまでやってしまうKrackerの方にはお手上げという ことで、パスワードを教えても構わないでしょう(笑)。  この方法は、パスワード入力以後のプログラムをデータとしてマシン語で持っ ておかなければならないので、大きなプログラムだとまず実用的ではありません。 というかこんなややこしい方法するくらいなら、ソフトウェアの質をもっと上げ ろ! と思います。ただ、例えばEXEファイル自体を実行できない形式に暗号化、 あるいは圧縮を行い、別の認証EXEファイルを起動して、パスワードを入力させ、 そこから暗号化、あるいは圧縮されたファイルをEXEファイルとして復元するとい ったような芸当は可能だと思います。というかパスワード認証をそなえたZIP圧縮 のファイルが、おそらくそういうことをやっているんじゃないかなぁと推測した だけなのですが。でもこのZIP圧縮ファイルもKrackされたらしいですので、結局、 絶対にKrackされないソフトウェアというのは作れないということでしょう。いや はや、リバースエンジニアリングも奥が深いです。 ■0x09.) さいごに  さて、いかがだったでしょうか。今回は、リバースエンジニアリング繋がりで 個人的に気になる内容を解説しました。実際に、PEフォーマットやDLL の仕組み、 そしてリバースエンジニアリングや暗号論といった多方面の知識が必要になるも のを目指したつもりですが、幅広い分だけそれぞれが浅かったりします。まさに、 私のスキル不足を露呈しているようで、読者の方には申し訳ないです。ただ、何 かを実現するときに多方面の知識が必要になることはよくあります。そのような 場合に、取っ掛かりだけでも知っていると、案外考えが広がるものです。という わけで、今回はこのへんで終わりたいと思います。  では、また会う日まで... x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第6回セキュリティアカデメイア・クラックコンテスト --- 著者:IPUSIRON x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  『ハッカーの教科書』がそろそろ在庫がなくなるとMaDさんにいわれ、急遽『ハ ッカーの教科書・完全版』(仮題)を書くことになりました。それにあたり昔の 原稿を読み直したのですが、口調メチャクチャ(「ですます」調と「である」調 の混合)、図の指定とかもバラバラで、自分の原稿ながら結構てこずってます。  なお、『ハッカーの教科書』は在庫がなくなり事実上売切れのようです。 ----- http://ruffnex.oc.to/ipusiron/cgi/che.cgi ハッカーの教科書  投稿者:まど  投稿日: 03/03 Thu 14:59:23 ハカーの教科書、在庫がついに無くなりました。 事実上の売り切れです。 あとは流通に乗っているものだけとなります。 長い間、有難うございました!<(_ _)> 次作、超改定“完全版”に期待してください。<(_ _)> -----  そんなこんなで、パスワード解析の章を書き直していると、「最近オフライン パスワードクラッキングをやっていないなあ」と思いました。  最近(でもない? )のアタックは、サービスプログラムのバグを突いて一気 にそのプログラムの権限を奪ってしまうアタック、フィッシング詐欺やXSSといっ たブラウザ依存のアタックが主流になっています。ただ、こんな時代になっても パスワードやパスワード解析の重要性は変わらないと私は思います。 ■0x02.) セキュリティアカデメイア・クラックコンテスト  そこで、セキュリティアカデメイア内で抜き打ちコンテストを催すことにしま した。  名付けて「セキュリティアカデメイア・クラックコンテスト」(Security Aka demeia Crack Contest:SACC)です。  インストールしたらできる、マニュアルを見ればできるというのではなく、す ぐに実験できるというのが本当に「できる」アタッカーだと思います。だからこ そ今回抜き打ちという形で実施することにしました。 ・今回のテーマはパスワード解析です。これを機会にパスワード解析の楽しみを 知ってもらえれば光栄です。 ・次に示すパスワードファイルを用いて、パスワード解析をしてもらいます。 ----- akademeia-pass.txt user1:$1$9hbw4RS/$aSfltABiXo.l1xP1xT1d51 user2:$1$tP2tmREy$5glmkzpOzCuNCZDxjmH2j0 user3:$1$EsdmX/oB$..LXWJANstnYRN/Yqi9Bj0 user4:$1$7UqWvCQW$YJN34BE/3XAWPlfOUE2Mv0 ----- ・user1〜user4までの4つのアカウントがあります。これをどんなオフラインパス ワードクラッカーを用いても構いません。 ・期日は今月の20日の24時までとします。このWizard Bibleがリリースされて、 だいたい2週間後に当たります。 ・ひとつのアカウントでも解析できた人は、次のテンプレートを用いて、私宛て (ipusiron@ruffnex.oc.to)に「第1回SACC」という件名でメールを送ってきてく ださい。 ----- テンプレート(本文内容) HN:hogehoge ←使用するハンドルネーム メアド:hogehoge@hotmail.com ←使用しているメールアドレス サイト:http://〜 ←Webサイトがあれば記載してください。 アカウント名:user1 ←解析できたアカウント名 パスワード:xxxxxxxx ←パスワード パスワードクラッカー名:John the Ripper ←使用したパスワードクラッカー 使用OS:Linux 解析スペック:CPU 2.8GHz、メモリ1GB 解析時間:32分 ←解析結果がパスワードクラッカーに表示されるはず プレゼント:希望する ←「希望する」or「希望しない」でお願いします。 WBでの言及:○ ←次回のWizard Bibleにおいてあなたの結果を載せてもよい場合は「○」、ダメな場合は「×」でお願いします。 コメント:辞書ファイルを見つけるのが大変でした。 ←適当に感想。特になければ「なし」でOKです。 ----- ・解析が成功したアカウントが複数あれば、上のテンプレートに他のアカウント の分も追加する形でお願いします。 ・パスワードの正解者(かつ、プレゼント希望者)から抽選で3人に『ソーシャル 娘。萌絵ちゃんのスパイ大作戦』hacksection著(データハウス)をプレゼントし たいと思います。 http://www.data-house.co.jp/book/7971.html ・最速で投稿した人、全部解析できた人やユニークな方法で解析した人(自作プ ログラムで解析したなど)などは、MVPとなります。 ■0x03.) ヒント ●オフラインパスワードクラッカー ・特別講座<パスワードクラッキング編> http://akademeia.info/main/lecture3/tokubetu_password_cracking.htm ・特別講座<オフラインパスワードクラッキング編> http://akademeia.info/main/lecture2/tokubetu_offline_password_cracking.htm ●代表的なオフラインパスワードクラッカー ○LC5(LC3,LC4) ・質問掲示板の「LC4について」スレッド http://ruffnex.oc.to/ipusiron/cgi/forum/patio.cgi?mode=view&no=29 ・対抗馬 ○John the Ripper(Windows、DOS、UNIX用) ・特別講座<John the Ripper編> http://akademeia.info/main/lecture1/tokubetu_john.htm ・『ハッカーの教科書』を参考。 ・本命。 ○Crack ・特別講座<Crack編> http://akademeia.info/main/lecture2/tokubetu_crack.htm ・『ハッカーの教科書』を参考。 ○MacCrac ・特別講座<MacCrac編> http://akademeia.info/main/lecture1/tokubetu_maccrac.htm ただし、DLするリンクは切れています。 ・MacCrac本体は現在入手が困難のようです。どうしても欲しい人は『ハッカー の教科書』のCD-ROMからどうぞ。 ●辞書 ・Wordlist Archive ftp://coast.cs.purdue.edu/pub/dict/wordlists/ ・『ハッカーの教科書』を参考。 ●それぞれのアカウントに対するヒント ・user1は、英単語なので辞書ファイルがよければヒットするはずです。 ・user2は、日本語単語(ローマ字)に数字を付加したタイプのパスワードです。 ・user3は、特殊記号も含まれています。総当りでなければ見つからないと思いま す。 ・user4は、特殊記号も含まれています。総当りでなければ見つからないと思いま す。user3より文字数が多いです。 ●その他 ・他に質問があれば、質問掲示板の質問スレッドにお願いします。 http://ruffnex.oc.to/ipusiron/cgi/forum/patio.cgi?mode=view&no=248 ■0x04.) おわりに  今回は新しい試みですが、奮って挑戦してもらえたらと思います。次回は、今 回のコンテストの結果と解析テクニックについて言及するつもりです。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第7章: 元偽造職人インタビュー --- 著者:MaD x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  おいこら、血管君! なにしとんねや! ファンのまどさんやぞ。最近、どな いした? 心配してんのよ(編注1)。  ということで、今回は『☆☆の☆☆増補版』(編注2)の発売にあたり、わざわ ざ関西のムショ仲間とコントクトしてメシおごらされて取材をしたのに、最終的 に誌面で使うことを差し止められた危険ネタを一部伏せ字で公開しとく。  真似してもできへんで(笑)。  あっ、それと、よくあるエクスキューズではなくて、本人のためを思ってお父 さんはいうけど、紙幣偽造は絶対にやらんこと。殺人並の重罪になるよ。初犯で あっても懲役確定やからね。絶対にやったらあかん!  クレカのスキミングとか振り込め詐欺くらいにしておきや(おいおい)。 【編注1】雑談掲示板の例の人物は私がアクセス制限かけたから入って来れないん だと思います。 【編注2】http://www.data-house.co.jp/book/8102.html ■0x02.) まどさんvs偽造職人 ○まどさん:「もう、現役をやめたそうやけど、過去の略歴を一応、教えといて」 □偽造職人:「大昔、パソコンを用いた紙幣偽造の技術が産まれたんや。その黎 明期に、わしらが現役でやってたいうことや。ほとんどが手探りの状態で始めた。 まぁ、当然ながら最後はパクられたけどな。娑婆に戻ってからはキッパリと足洗 って、今は、その技術を活かして小さいながらもデザイン事務所を経営しとる。 相変わらず印刷関係の仕事や。芸は身を救うとはこのことやな(笑)。そういう 意味では現役がどんなもんか、モノを見れば察しがつくということや」 ○まどさん:「そうだね。旧一万円札の偽造の事件が相次いで起こったわけやけ ど、昔と現在とでは、技術や環境など、どんな部分が変化したの?」 □偽造職人:「昔も今も技術自体はほとんど変わらんよ。パクられた連中のモノ を見てみろや。あれって、どこに技術がある? 取り込んだまんま出力して、カ ットしただけや。もう、アホかと。単なるハードの進化に身を任せて、勢いだけ でやっただけのことや。あんなもんやったら主婦でもやれるがな」 ○まどさん」「相変わらず、言葉汚いなぁ。留置場におるみたい(笑)。つまり、 技術自体はそう変わってなくて、ハードが進化しただけということ?」 □偽造職人:「君らも知ってるやろうけど、紙幣偽造のために使うもんはスキャ ナー、パソコン、プリンターやな。プリンターのみはハイブリッド仕様のものに なってきたな。しかし、基本的に道具は同じ。性能が上がって、安くで手に入る ようになっただけや。道具はこれだけで十分や。ただな、肝心なのはソフトや。 色々使い分けることが基本やな」 ○まどさん:「ソフトどんなもん使ってんの?」 □偽造職人:「別段、特殊なものはないな。DTPで使われている基本ソフトだ けや。具体的には画像のレタッチソフトで本体の色相などを処理して、あとはレ イアウトソフトで組むという流れになるな」 ○まどさん:「なるほど。昔と同じやね。●●●●●●●と●●●●●●●●や ろ? そういえば、テレビ局の関係者からリークあったんやけど、『紙幣偽造専 用ソフト』いうの出てたらしいね。当局が追い込みかけてるとか。あれってどう 思う?」 □偽造職人:「紙幣偽造専用ソフトかいな? あれは、素人でも旧一万円札紙幣 を簡単に偽造できるようにプログラムされたやつやろ。わしらはいらんで(笑)。 わしらにとって、そのソフトはどうでもええ話や。わしらが使うのは、そんなん じゃ無理や。職人が手に馴染んだ道具でなければならんのはどこの世界でも同じ や。あと、自分の道具やないと自由度が狭まることになるしな。結果としてレベ ルの低い仕上がりになってまうさかいな」 ○まどさん:「やっぱ、普及している汎用のソフトで作るということね」 □偽造職人:「さっき『ソフトが重要』といったが厳密にいうと『ソフトで作ら れたヒナ(雛形・テンプレート)がどこまで作り込まれているのか』、そこが重 要や。それこそスキルの世界といえるんちゃうか」 ○まどさん:「そやね。わしら『ヒナ』としかいわんやんか。パクリのときは防 犯カメラのことを『メガネ』いうみたいに。以前、うちから『☆☆の☆☆』いう 本を出したんや。そん時に、わしが『ヒナ』のこと『テンプレート』って、読者 にも分かりやすい言葉にして書いたらネットのどっかのアングラサイトで『ぼく らみたいな偽造のプロはテンプレートを使っている。それは見せられないけど (笑)』とか平気でヌカしとんねや。相変わらず知恵遅れのヘタレばっかや(笑)。 なんで、テンプレートという嘘の伝説を作ったのはわしや(笑)」 □偽造職人:「『テンプレート伝説』やな(笑)。そやけど、お前が作った本で どんなんや? 見せてくれや」 ○まどさん:「これや。本を作る手伝いみたいな仕事や。著者のハッタリを見抜 いて、ケツカキ入れるんが仕事や」 □偽造職人:「ふーん。なんか難しいことばかり書いてあるな。まぁ、よくでき てるけど、能書き多いな」 ○まどさん:「分からん人が読むわけやから、能書き書かな始まらへん。それよ り実践いこか? 今、ヒナ作ってみってよ」 □偽造職人:「現行の万札を見本ということにして簡単なもんを作ってみたるわ。 そやけど万札の取り込みと出力だけはせえへんで。そこらは頭でイメージしてや。 せっかく足洗ったんや、パクられるのだけはご免やからな(笑)」  一万円札全体の寸法を物差しで計り、細かい部分も物差しで計り始める。  さらにルーペを用いて、拡大して細かく見ている。  そして、あるソフトウェアを起動してファイルを作り始め、数分後、インター ネットで検索をしながら、ファイルの確認をしている。  ……数十分後。 □偽造職人:「……できたよ。荒いけど、まぁ、こんなもんや」 ★試しに作った新一万円札テンプレート → ヤバ杉で公開不可(´Д`) ○まどさん「なんでしょか、これは?」 □偽造職人:「ホンマやったら、まず最初に万札を荒く取り込んで、そこから起 こすんやけど、それはできへんから、すでに万札をスキャナーで1200dpi程度で取 り込んだもんやと思ってくれ。それでも、実際にモノを物差しで計るやろし、色 分解のためにルーペも使うで。わしらデジタルだけを信じてない。プロセスはど うでもええんや。判別する相手は人間の目と指先の感覚になる。そやから、目で 見た感覚と触った感触だけを重要視して作るわけや。メモしとけよ」 ○まどさん:「なるほど、偽造の哲学を感じたような気がするね(笑)。……そ れで、この色々ある、丸や四角のものはなんでしょ?」 □偽造職人:「わしらは職人や。素人みたいに『スキャナーで取り込んでプリン ターで出力してハイ終わり!』みたいな真似はせんのや。あいつらのは通し番号 が同じやったやろ? それじゃアカン。そこもレイヤーかけて文字を割り振れる ようにするのが本物の偽造テンプレートいうことや」 ○まどさん:「『本物の偽造テンプレート』かい。言葉に重みがあるね(笑)。 では、具体的にどういう部分に力を注ぐわけ?」 □偽造職人:「わしが現役なら、マイクロ文字の部分に神経がいくな。この部分 は、普通にやると取り込みできへんはずや。これは目視だけで十分にわかる。仮 に取り込めても、おそらく業者レベルのスキャナーがいるやろし、取り込んだフ ァイルは数GBのサイズになることは間違いないな。……いや、やってへんから分 からんけどな(笑)。これじゃ高速なパソコンでも動きが重なってレイヤー組ん でも事実上動けへん。そやから、こういう部分をフォントで代用するいうことや。 フォントは自作になるな。この方法やったら、マイクロ文字といえど、高解像度 で取り込まんでも再現できるわけや」 ○まどさん:「さっきからいってる、レイヤーとはなに?」 □偽造職人:「グラフィックソフトに付いている機能のひとつや。一枚のマスタ ーに対して、上にいくつも透明な層を作り、そこに加工した画像データなりを上 からかぶせたりできる機能や。偽造紙幣では透かしなんかで使う。ほかにも免許 証や保険証の偽造では写真の張り替えや文字の入れ替えでは必須の機能や。レイ ヤーがないとなんもできへんからな」 ○まどさん:「透かしの処理はどうやってんの?」 □偽造職人:「透かしの再現は無理や。無理いうのは不可能いう意味やないで。 万札偽造のポイントは、透かしの部分だけわざと●●●●かけてクッキリと出力 するんや。ほんで、その紙を一度、●●に●●せて●●●●させる。これを元に して何度もパーツごとに上からプリントしていくわけや。だから、透かしの部分 も空けてあるやろ?」 ○まどさん:「なるほど、それぞれのパーツを別々に分けて印刷するということ やね」 □偽造職人:「そういうこっちゃ。あと、一万円の文字の部分な。ここのインク の厚さはキモなんや。この部分はインクのタンクに●●●●●という液体を入れ て混ぜるんや。これ使うとその部分が微妙に膨らむんや。これで手触りもほぼ同 じになる。ただし、規定外の特殊なインクになるからプリンターは百枚も出力し たらインク部分が目詰まりしてイカれる。プリンターはいくらあっても足りへん」 ○まどさん:「なるほど。ホログラムの部分についてはどうするんですか?」 □偽造職人:「わしは、もう現役やないから試してない。でもな、素人なら諦め るやろうけど、わしらにしたら、そう大きな問題でもないよ。モノはここまでの 作業で見た目も感触もほぼ同じになっとるわな。ただ、ホログラムの部分一緒に 出力したらアウトや。この部分は少し不細工やけど市販されてる薄い素材のホロ グラムを流用すれば一時的には誤魔化せる、できんことないよ」 ○まどさん:「ホログラムなんてどうやって手に入れるんでしょうか?」 □偽造職人:「簡単や。●●●●●に行ってみ。色々あるから。そこから単純に 乱反射しまくるのを選べばええんや。わし、昔から素材で煮詰まったらいつもあ っこに行ってた」 ○まどさん:「本物に近いホログラムは作れへんの?」 □偽造職人:「楽勝や。国内だけで考えるからあかんねや。●●や、特に●●● あたりにある、それらの製造工場に背広にネクタイ付けて真っ当な格好で、持っ て行ってビジネスライクに商談として持ちかけたらかなり質の高いのが作れるよ。 その部分だけを切り抜いていくわけや。相手は田舎におる●●人やろ。そこだけ 見ても意味分かるわけない。わしが現役ならそないするよ。完璧にすることない、 サクラ、一万、日銀のマーク、いずれかだけで十分やろけど、わしなら、一万の マークの周りにサクラを8個並べただけで、どこから見ても全部が見えるパターン を作るな。要は目をどう誤魔化すかだけが重要なんやから、それで乱反射しとっ たら十分や。それ以上、する必要ない」 ○まどさん:「素朴な疑問やけど、自分で偽造した紙幣を実際に使ったことはあ る?」 □偽造職人:「ありそうでない話や。そんなんしたら、わしは今頃、億万長者に なって左団扇の生活や。世界を征服しとるで(笑)。わしらのような職人になる と、モノを流すだけでかなりのシノギになった。そやから、偽造紙幣など使う必 要もないわけや。あと、重要なのが『モノを流す』のと『モノを使う』のとでは、 どっちがリスク低いと思う? 使ってパクられるんはどうせ末端や。わしらには 関係ない話になるわな。そこやと思うよ。シャブの流通体系と同じで、製造者は 雲隠れして、パクられるのは末端だけいうことや。その辺り、履き違えへんのも 職人いうことになる。ルートは想像に任せる。君なら分かるやろ?」 ○まどさん:「いらん。そんなん聞きたない。……あと、巷では『偽造紙幣は紙 質で決まる』とよくいわれてるやんか、そのあたりはどうなん?」 □偽造職人:「はっきりいおか? あんまり関係ないんや。知らん者は『紙、紙!』 と、宝もんみたいにいうけど、もうそんな時代やないで。今の紙幣を見てみろや。 ドル紙幣ならともかく、どこが原紙かわからんくらいカラフルな印刷になっとる がな。厚さが近いだけで十分や。やや薄めの紙を選ぶのは当然の話や。●●●● ●で売られている紙でも十分や。ただな、どの紙使っても必ず通さなあかん工程 があるんや。これは真似する輩がでたら困るから細かくいえんけど、ヒントは洗 濯機と特殊な油や。それさえあれば、かなり精度の高い偽造ができる。特殊な油 いうても簡単に手に入る程度のものや」 ○まどさん:「特殊な油を混ぜた水に濡らすということ?」 □偽造職人:「それもある。むしろ重要なのは乾燥のプロセスや。あと、水に強 いインクな。……これ以上いうと、面が割れてまうから想像せいや」 ○まどさん:「……なるほどねぇ。これらは自動販売機などにある紙幣を識別す るシステムなどでも通用するのでしょうか?」 □偽造職人:「それはまったく違う話や。識別システムを通る紙幣は、わしらと は違う畑になる。文系と理系くらい考え方が根本的に違う。つまり、それ専門の 偽造屋になるということや。あちらは目ではなく機械を騙すことに特化した専門 家なわけや。そもそも機械を騙す場合は、サイズは共通やけど、色なんか必要な い。一色のバーコードのような柄と磁気インクだけの世界や。数回、モノを見た ことあるけど、『こんなんでいけるの?』と笑うくらい万札に見えへんかった。 ……どこまでチェックしているかは専門外やからわからんけど、そのチェックポ イントを通過することだけに特化した印刷やった。製造の関係者が絡んでなけれ ばネタ出えへんはずやで」 ○まどさん:「そういえば偽五百円硬貨も製造の関係者が絡んでいるという噂が あったね」 □偽造職人:「つまり、識別システムを通る偽一万円札は偽五百円硬貨と同じ属 性になるやろ? そやから、わしの管轄外というわけや。あっちはデータで機械 を騙す、こっちは見かけで人を騙すという住み分けが自然とできてきたんや」 ○まどさん:「……パソコンに話を戻すわ。……けっこう古い機種やね?」 □偽造職人:「わしの専用機や。WindowsからG5までなんでもあるよ。でもな、重 要なのは手慣れたソフトが使えるかどうかや。あとフォントな。これも重要や」 ○まどさん:「フォントとは?」 □偽造職人:「フォントいうのは、いわゆる文字の形をそれぞれのタイプ別に印 刷するためのデータのことや。これが多いに越したことはない。あらゆる局面で 対応できるさかいな。そやから、このソフトとフォントの資産をそのまま使える システムに合ったマシンを選ぶ必要があるわけや」 ○まどさん:「なぜ、古いシステムなわけ?」 □偽造職人:「元来、パソコンのシステムは常に発展途上やろ? バージョンア ップいうやつが常に目の前にあるということや。バージョンが上がると、ソフト も対応せなあかんのやけど、それでトラブルがよく起こる。わしらはクリエーター 気取りなんかない。完璧に使えるものを作ればそれでええんや。そういう意味で いうと古いシステムこそ完成されたシステムということになるわけや。もうメー カーも放置や。開発がストップしてるからなんの心配もないやろ? そこから便 利に使えるシステムを選ぶだけの話になるわな」 ○まどさん:「じゃぁ、低いスペックのマシンでもいいということ?」 □偽造職人:「CPUは高速に越したことはないが、最近の機種やったら十分クリ アできるレベルや。重要なのはビデオや。ノーマルのままではしんどいから、こ こだけは上げておかなあかんな。もし、これからやるとしたら256MBは欲しいと こやな。高速なマシンを使うのはマスターを取り込むときだけや。あとはほとん どいらん」 ○まどさん:「ビデオってなに?」 □偽造職人:「ビデオボードや。モニター画面に映像が映るやろ? それを表示 させるためだけに働くハードのことや。紙幣偽造の場合やと、取り込み段階で 1200dpiを選んだもんやけど、それをサクサクと表示させるためには、それなり のパワーがいるわけや。それをこなすのがビデオボードということや」 ○まどさん:「dpiとは?」 □偽造職人:「おいこら、わしはパソコン教室の先生かい?(苦笑)」 ○まどさん:「分かっとるけど、知らん人もあるから聞いてんねんて」 □偽造職人:「君らも大変やのう(笑)。……dpiとは、画像に対する目の細かさ の値、つまり表示密度のことや。同じ画像でも表示密度でも値が高ければ高いほ ど現物に近い高精度な印刷ができる。たとえば、ポスターとかの写真あるやろ?  あれなんか1200dpiはザラや。そうなるとCPUやビデオに負荷がかかって処理が遅 くなる。そやから数値はすべてデカイに越したことはないということや」 ○まどさん:「ソフトはどうなんでしょうか?」 □偽造職人:「●●●●●●●でレタッチかける。それに●●●●●●●●でレ イアウトを組む。これだけやったな」 ○まどさん:「有名すぎてソフトの名前は出されへんね(笑)」 □偽造職人:「いや、ソフトにこわだわる必要はないよ。『これが定番』という わけでもない、ただ単に使い慣れているいうだけの話や。ヒナからコツコツと作 るんなら手慣れたソフトで十分やろ」 ○まどさん:「なるほど。これらでレイヤーやらをするのね?」 □偽造職人:「そや。レイヤー、コピー&ペースト、変形、文字組みという作業 になるな。それだけできたらスタートラインに立てたことになるね。そっから先 はフォント作りになるね。それは素人じゃ無理な仕事や」 ○まどさん:「ふーん。保険証や免許証の偽造についてはどうなの?」 □偽造職人:「保険証や免許証の偽造は簡単や、わしらの副業みたいなもんやっ た。これこそヒナとフォントだけの世界や。パスルみたいに入れ替えするだけや。 5分もありゃ、楽勝にできるから語るほどのことでもない。君の作った『☆☆の☆ ☆』いう本を見せてもらったけど、ようできとる(笑)。概要はあんなもんや。 あれ、ソフトは●●●●●●●●やろ?」 ○まどさん:「ビンゴ〜(笑)」 □偽造職人:「アホか、わしらみたいな騙しのプロの目を騙せるかいや(笑)」 ○まどさん:「理に適った発言やね(笑)。……時間もないようやから、最後の 質問になるけど、ズバリ、新一万円札製造のプロセスで一番重要な部分はどこに なりますか?」 □偽造職人:「マイクロ文字の再現や。そこだけを追及すればどうにかなる。や れるならってみろ、マイクロ文字の部分は真っ黒になって出力されるはずやから (笑)。これをクリアできる環境は素人では簡単に作られへんで。逆にマイクロ 文字の部分を正確に出力できりゃ、それ、なんもイジらんでも使えるレベルにな っているはずや。やってる奴は、もうすでにやってると思うけどな」 ○まどさん:「……ということは、これから新一万円札の偽造紙幣も出回る可能 性があると?」 □偽造職人:「当たり前の話や。わしがパクられへんかったら、とっくにやっと るがな(笑)」  というわけで、詳しくは書籍を立ち読みして、まどさんのヘタクソなイラスト を見て「プ」と笑うのはやめろ(編注1)。 【編注1】http://data-house.oc.to/gizou1_01.jpg x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第8章:お知らせ --- 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 ---- 第9章:著者プロフィール --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■Narusase ●Job: Student ●Web: (裏)雑学の博物館(http://k-o-m.hp.infoseek.co.jp/) ●Mail: narusase@mcn.ne.jp ●Team(Group): N/A ●Comment:  初めまして、Narusase(ナルサス)です。今回、金床さんに薦められてハニーポ ット関連のネタを書かせていただきました。本業は学生をやっているのですが、 この時、期就職活動、学会、研究、壊れたPC再構成など死にそうになりながら頑 張っています。  ・・・と書いている翌日(翌朝か・・・?)もラックの説明会だったりします。  雇ってくれ〜〜(汗  サイトの方はまあ、ヘタレな文章と、未熟な技術、ヘボいプログラムを紹介す るサイトと言うことで、暇があったらあら探しでもしてみてください。クレーム はBBSにでも書いてくだされば、こっそり修正しときます(笑 ●マイブーム:  とりあえず、本を読むことです。現在スタックが、40冊近くたまっているので 消化せねば・・・。いくつか本を探していたりするのですが、NHKの「新・電子立国」 の書籍版(全6巻+別巻)の2巻以降が見つからず、読みたいのに読めない状況です。 もし見かけた方は情報をくださると助かります。ちなみに、内容的にはICの誕生 から初めてのパソコンの登場、そして日本のインターネットの草創期(1995年あ たり)のあたりまでを時系列で追ってゆくもので、まさにパソコンのたどってき た歴史の本です。ちなみに、「電子立国」という新がつかないシリーズ(全4巻) もありこちらはトランジスタの発見からICの誕生までを追いかけたものです。こ れらのシリーズは通して読むこともでき、パソコンの歴史を知るには最良の書で しょう。また、ハッカーの歴史については「ハッカーズ」をおすすめします。 ■金床 ●Job: プログラマー ●Web: http://guardian.jumperz.net/, http://www.jumperz.net/ ●Mail: anvil@jumperz.net ●Team(Group):JUMPERZ.NET ■Defolos ●Job:Student ●Web:none ●Mail:pan1124@luck.ocn.ne.jp ●Team(Group):none ●Comment:  こんにちは、今回もWizard Bibleに参加させていただいたDefolosです。 ピッキングとナイフメーキングとナイフファイティングの訓練、PCいじりが趣味 の学生(正確に言うと生徒)です。これからも参加させてもらいたいと思います ので、よろしくお願いします。 ■Kenji Aiko ●Job: Student ●Web: http://ruffnex.oc.to/kenji/ ●Mail: kenji@ruffnex.oc.to ●Team(Group): N/A ●Comment:  どうも、ケンジです(^^;。良いコメントが思いつかないので、今回はこの著者 コメントを使って、「リバースエンジニアリング」で扱った「実行されたcrackme」 の解答をやりたいと思います(^^;。ということで解答編スタート! まずユーザ ー名は「WizardBible」です。これはOllyDbgなどで解析していけばlstrcmpを呼び 出してるところが分かるので、その部分に渡されている引数を見れば分かります。 いたって簡単です。そして、問題のパスワードは「OtmPpLvQ」です。これは、DES 暗号化アルゴリズムを利用しています。「正確なパスワードが入力されなければ、 以後のプログラムが正常に動作しない。」という手の込んだことをやってますが、 まず実用的ではないので、一般的に使われることは無いでしょう(笑)。それで、 実際どうやって解析するのかというと、まずこのプログラムが、DES暗号化アルゴ リズムを利用していることを断定します。これは根気よく見ていけばわかります。 そして、さらに暗号文を抽出します。これもデータセクションに生の状態で確保 されていますので簡単です。さて、ここからですが、大抵の暗号化アルゴリズム は、暗号文から平文を逆算して求めることはできないと証明されていますので、 総当りで求めるしかありません。DESアルゴリズムを再現して、総当りで解析して いきます。といってもDESは、総当りには結構もろいですので、数分もあれば完了 します(多分)。これで見事パスワード「OtmPpLvQ」をゲットということになり、 解析完了です。ちなみに、解析が成功し正確なパスワードを入力すると、ソース コードが入手できるようになっていますが、「解析するのメンドクサイ」という 方は「http://ruffnex.oc.to/kenji/crackme/crackme_src.zip」からダウンロー ドしてください。解答編は以上です。では、また来月お会いしましょう。 ■MaD ●Job:DATA HOUSE ●Web:http://www.data-house.co.jp/ ●Mail:mad@data-house.co.jp ●Team(Group):h@cksection,ruffnex ●Comment:  元ハカージャパソと危ない28号の百円ライター。趣味は、空き缶拾いと牛乳瓶 のフタ集め。2ちゃんねるでは「矢崎マサユキ」、「白鶴・丸」、「大同曲芸人 」、「泥棒・詐欺師」として通っている。ウソばかりつくので友達はいない。  現在は会社でヒッキーをしているが、将来はネットカフェの店員なるという目 標に向かってまっしぐら。とぁっ!(`Д´)。 ●お気に入りのツール  今回、著者プロフェールとしてIPUSIRONさんが「お気に入りのツール」を書い てくれとのことなので最新情報を紹介しよう(編注1)。  Windowsの定番テキストエディタとして有名な「秀丸エディタ」、v5シリーズ第 1弾のβ1で縦書きや段組に対応し、ドラッグ&ドロップによるタブの分離や結 合も可能となった。  →http://hide.maruo.co.jp/  →http://www.forest.impress.co.jp/article/2005/03/01/hidemaru500beta1.html  さらに驚きの機能は、正規表現用ライブラリ“HMJRE.DLL”の仕様が変更され、 Perlと互換性のある書式が使えるようになった点が挙げられる。  テキストエディタにPerlの機能が加わればテキスト編集の作業効率が格段に向 上するはずだ。おそらく有志による様々なライブラリが公開されるはずなので、 知識のないユーザーでも、それらを利用するだけで様々な機能を実行できること になる。また、知識があればライブラリの改造から作成も可能となるだろう。  また、“Hidemarnet Explorer”を組み込むことにより、Webサイトもテキスト レベルでのブラウズが可能となっている。それらHTMLファイルの保存も可能なの で、テクニカルライターからテキストファイルを扱う編集者にとっては好都合だ といえる。さらにGoLiveとも連携できるためWebサイト構築から糞ブログ垂れ流し にも役立ちそうだ。  パソコンとインターネットをベースにしてリソースを集めるなどして執筆をお こなうテクニカルライターからテキストファイルをブロック単位で扱う編集者に とっては最適なツールになるはずだ。  ちなみに、「秀丸エディタ」は、シェアウェアとなっており、価格は税込みで 4,200円となっている。現在同社のWebサイトからダウンロードできるようだ。  しかし、仕事で使うのであれば、説明書も付属しているパッケージ版がリリー スされてからでも遅くはないだろう。 Mar 2,2005 MaD特派員 【編注1】vol.14の方でのお願いでした(笑)。 ■IPUSIRON ●Job:サイト更新 ●Web:- Security Akademeia -(http://akademeia.info/) ●Mail:ipusiron@ruffnex.oc.to ●Team(Group):hacksection ●Comment:  最近は大航海時代Onlineをやり始めました。エウロス鯖のイスパニアの軍人で プレイしています。今月号のWizard Bibleにも参加しているDefolosさんも同じ鯖 でプレイしています。  今回のWizard Bibleは多くの執筆者に参加していただき本当に助かりました。 自分も参加したい!という勇士があれば、メールください。  後、mixiもやってるので招待して欲しい人はメールください。マイミクシィも 気軽にメッセージ送ってきてください。コアな内容の日記はmixiの方で公開して います。