[-]=======================================================================[-] Wizard Bible vol.32 (2007,4,6) [-]=======================================================================[-] x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第0章:目次 --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○第1章:SPAMボット対策 金床 著 ○第2章:バイナリプロテクション1 〜Packed file loader〜 sourcerian 著 ○第3章:バイナリプロテクション2 〜アプリケーションデバッギングの防止〜 sourcerian 著 ○第4章:バイナリプロテクション3 〜解除されにくいアンチデバッギングの実装〜 sourcerian 著 ○第5章:PS2ソフトの音楽差し替え エクセル小林 著 ○第6章:ハニーポットを作ろう(連載第12回) Narusase 著 ○第7章:初めての量子コンピュータ 〜スパコンを超える超並列計算〜 結城瀬名 著 ○第8章:はじめてのハッキング 〜番外編:パスワードクラック〜 Defolos 著 ○第9章:基礎暗号学講座 〜 第8回 〜 IPUSIRON 著 ○第10章:お知らせ ○第11章:著者プロフィール x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第1章: SPAMボット対策 --- 著者:金床 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  本稿では掲示板やブログに対し無差別に宣伝目的の書き込みを行う、いわゆる SPAMボットを取り上げる。これらは主に英語圏で作成されており、自動的にウェ ブページを巡回し、フォームタグを見つけると手当たり次第に書き込みを行う。 筆者の掲示板にも最近いくつかのSPAMボットが入り込んでくるようになったため、 対策を講じる必要に迫られた。 ■0x02.) SPAMボットと砲台の違い  SPAMボットはかつてアングラシーンで戦争をまきおこした「砲台」とは異なり、 特定の掲示板に対しての爆撃のような多重投稿は目的としていない。そのため、 対策もやや方向性が異なる。たとえば強度の弱いCAPTCHAでも十分対策ができる。 特定の掲示板を執拗に(自動化したプログラムで)荒らすことを目的としている 場合にはCAPTCHAの画像を自動的に解析しそこを突破するような技術が用いられる 可能性があるが、SPAMボットはそのようなことはしないと考えられる。 ■0x03.) CAPTCHA  前項で触れたが、CAPTCHAを用いればほぼ確実なSPAMボット対策になる。CAPTC HA画像を解析するほどの高度なSPAMボットの登場はまだまだ先となるだろう。た だし、俗に「エログリッド」などと呼ばれる仕組みが投入された場合はこの限り ではない。  しかし、CAPTCHAにはユーザビリティの面で難点がある。ちょっと書き込みた いだけなのにわざわざ数字や文字を読みとり、さらにそれを入力するのはとても 面倒であるため、(特に無意識のうちに)ユーザが書き込みを避けてしまう可能 性がある。コメント欄への書き込みは反射的に行いたい。思いついたことを一瞬 にして書き、書き終えたその瞬間に「投稿」ボタンを押下。書き込み終わった画 面を見てtypoに気づき「orz」状態。これが望ましい姿である。画像から文字列を 読みとっているとその掲示板なりブログなりに生じている「空気」が逃げてしま うような気がするのは筆者だけだろうか。  このような理由から、可能ならばCAPTCHA以外の、ユーザビリティに優れた対策 が好ましい。 ■0x04.) JavaScript  掲示板やブログのコメント欄のような書き込みが生じる場面では、「書き込み 前」の画面と、「書き込む先」の画面が存在する(以下「画面1」及び「画面2」 とよぶ)。ここでユーザに対してJavaScriptの使用を強制できる場合には、画面 1においてJavaScriptのコードが動作しない場合コメントが投稿できないようにす るという手法が考えられる。例えば次のようなものだ。 -----
(略)
-----  SPAMボットがJavaScriptを解釈しない場合には、「js=js」というパラメータが 送信される。一方でJavaScriptを有効にしているユーザのウェブブラウザからは 「js=ss」というパラメータが送られる。この部分を画面2において判別すること で、多くのSPAMボットを遮断できる。  この方法のメリットはかなりの有効性があることと、ユーザビリティに優れて いることだ。そしてデメリットはJavaScriptを有効にしていないと書き込みがで きなくなってしまうことにある。そのため、もともとJavaScriptが有効でないと 利用できないように作られたウェブアプリケーションでは十分に実用的な対策と なる。 ■0x05.) Cookie  同じようにCookieを利用する方法も考えられる。しかしSPAMボットにはCookie に(不完全ながら)対応しているものも多く見られるため、ただ単に画面1でCoo kieを発行し、それを画面2で確認するという方法は回避されてしまう可能性が高 い。そこで、Cookieの細かな仕組みを利用するのがよいだろう。  例えば次のように、domain属性に間違った値(ウェブサイトのホストとは異な る値)を指定する。 ----- Set-Cookie: foo=bar; Path=/; Domain=.foobar -----  domain属性の値が不正なため、ウェブブラウザはこのCookieを受け入れない。 一方で実装が甘いSPAMボットでは受け入れてしまうかもしれない。このような細 かな点を付くことで、Cookieを利用する対策も可能である可能性はある。  Cookieを利用する方法のメリットおよびデメリットはJavaScriptの場合とほぼ 同じである。 ■0x06.) 文字参照  文字参照とはHTML中で使用されるいわゆるエスケープ処理のことだ。XSS対策で シングルクオートを「'」に変換する例がよく知られている。これを次のよう に使う。 -----
(略)
-----  ここで「あ」の部分が文字参照によって記述されたデータだ(12345では なく12354であることに注意)。「あ」は日本語のひらがなの「あ」のこと である(http://www.fileformat.info/info/unicode/char/3042/index.htm)。そ のため、意味としては次のように記述されている場合と等しい。 -----
(略)
-----  ウェブブラウザがフォームを実行する際に、この「あ」はさらにURLエンコード されて送られる。例えばShift_JISを用いているページであれば、この値はリクエ スト中で「param1=%82%A0」となる。つまりここでは以下の処理が行われる。 ・あが「あ」であると認識する ・ページの文字コードがShift_JISであると認識する ・「あ」のURLエンコードが必要であると認識する ・「あ」をURLエンコードして「%82%A0」とする  この4つのステップは通常のウェブブラウザは問題なく行うが、SPAMボットには なかなか難しい処理となる。12354が「あ」であることを認識するためにはUnico deに対応している必要があるし、さらにShift_JISという日本語の文字コードにも 対応している必要があるからだ。そのため、画面2においてparam1の値が「%82%A 0」でない場合の書き込みを拒否することで対策となる。  筆者はいくつかのウェブアプリケーションでこの方法を試してみたが、これを 突破したボットは今のところ存在しない。  この方法はJavaScriptやCookieを用いる場合のデメリットであった「ユーザが 設定を有効にしていないと書き込みできない」という点をクリアする。JavaScri ptとCookieがともに無効であっても正しく書き込みが可能であり、この点が大き なメリットとなる。また、もちろんCAPTCHAの読み込みのような無駄なステップが 不要となり、ユーザビリティにも優れているといえるだろう。 ■0x07.) まとめ  このように、8-1においてはBボタンをほぼ押しっぱなしで駆け抜ける疾走感が 何より大事であることがわかった。ただし、後半の2連続ジャンプが必要となる箇 所ではあえてBダッシュは使用せず、落ちる寸前まで通常の歩行で近づいてからジ ャンプすることで、確実にクリアーできる。SPAMボットでの書き込みに辟易して いる管理者の方々には是非文字参照の方法をテストしてほしい。もちろんこれも 「いたちごっこ」であり、SPAM業者がこの方法を認識する時点で使えなくなる方 法ではある。しかし特に海外からやってくるボットにはしばらくの間は有効なの ではないかと考えている。  読者を代表してひとこと  「 ま た 小 細 工 か (`Д´)ノ ゴ ラ ァ 」 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第2章: バイナリプロテクション1 〜Packed file loader〜 --- 著者:sourcerian x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  はじめまして、sourcerianと申します。解析から引退して6年の月日がたち、V BやVB.NETで業務アプリを書くつまらない日々が続いておりましたが、目にとまっ たWizard Bibleを読んで冷え切っていた魂がふつふつと燃え上がり、自分も何か 書きたいと思った次第です。  しかし解析から遠ざかったこの身では、解析の説明は荷が重いと感じましたの で、プロテクションに焦点を置いて説明していきたいと思います。説明で登場す るコードはすべてC言語で書いてあるため理解しやすいと思います。それでは、ま ずはpacked file loaderから始めます。 ●使用するファイル ・http://wizardbible.org/32/AntiDebugging.v1.zip ・http://wizardbible.org/32/PackedFileLoader.zip ■0x02.) Packed file loader  Packed file loaderとはパッカの一種です。端的に説明すると、パックされた 実行可能ファイルを読み込んでメモリに展開およびマップし、パックされる前の 動作を行います。アプローチとしてはWizard Bible vol.22の「自前でDLLをプロ セスへマッピングさせる方法 〜LoadLibrary関数の作成〜」に近いものがありま す。逆アセンブルを難しくするとともに機能制限版と製品版を分けてロードする といったことを可能にします。  ソースファイルはVS.NET 2003用のソリューションで3つのプロジェクトがあり ます。 ・target:テスト用に作成したパック対象。Win32アプリケーションのデフォルト 構成で作られたものです。 ・packer:ターゲットとなる実行可能ファイルをパックしてファイルに保存しま す。 ・loader:パックされたファイルをロードして実行します。  各々を順に追って説明していきます。 ■0x03.) target  Packed file loaderでパックできるファイルは限られていて、ベース再配置情 報が含まれていることが条件になります。ベース再配置情報とは実行可能ファイ ルが想定していたメモリアドレスとは異なる位置にロードされた時に、コード内 で参照されているアドレスを修正するためのデータです。また、そのアドレスを 修正することをベース再配置といいます。  一般的なパッカはターゲットがロードされるメモリアドレスを変えずにローダ ーを埋め込みますが、Packed file loaderではターゲットを異なるアドレスにロ ードするためにベース再配置情報が必要となるのです。  ベース再配置情報はDLLには付与されますが、EXEファイルには通常付与されま せん。一番最初にロードされる実行可能ファイルなのでロードに失敗することが ないためです。ですからビルドするときはリンカーオプションに/FIXED:NOを追加 してベース再配置情報を付与してやります。 ■0x04.) packer  処理の流れとしては次のようになります。 イメージファイルの読み込み  ↓ 不要なヘッダ情報を削除  ↓ 圧縮  ↓ ファイルに保存  EXEファイルをそのままパックしてしまうと、ロードされた後にメモリをダンプ することで簡単にアンパックすることができてしまいます。それを防ぐために不 要なヘッダ情報は削除してやります。実際にロードするために必要なデータは次 のようになります。 ・ヘッダのサイズ  セクション数によってヘッダサイズが可変になるから必要です。 ・セクションの数  これがわからなければセクションをロードできません。 ・エントリポイント  これがないとロードした後にどこから開始すればよいかわかりません。 ・イメージベース(想定していたロードされるアドレス)  ベース再配置に必要です。 ・イメージファイルをロードするために必要なサイズ  ロードするためのメモリを確保するためです。PEファイルフォーマットではヘ ッダを含めたサイズですが、ロードした後はヘッダが不要になるので全セクショ ンをロードするためのサイズとします。 ・インポートアドレステーブル(IAT)のデータディレクトリエントリ  IATをヘッダに含ませてセクションから削除したほうが強固になりますが面倒な ためセクションにそのまま残してバインドすることにします。 ・リソースのデータディレクトリエントリ  リソース関連のAPIに必要なために必要です。 ・ベース再配置情報のデータディレクトリエントリ  ベース再配置に必要なために必要です。。これもIAT同様ヘッダに含ませてセク ションから削除した方がより強固になるでしょう。 ・セクション  コードやデータなどのプログラム本体なので当然必要です。  PEファイルフォーマットと比べると随分すっきりしました。本来ならマルチス レッド用にTLS初期化情報のデータディレクトリエントリも必要ですが、今回は対 象外としました。  これを圧縮したファイルを私はスマートイメージ(Smart Image)と名づけ、拡 張子はSEXにしました。今回使用した圧縮はランレングスです。単純なアルゴリズ ムで圧縮率も良くありませんが、暗号化という点ではそこそこ効果があります。 ■0x05.) loader  処理の流れとしては次のようになります。 ファイルをロード  ↓ ランレングスを展開  ↓ VirtualAlloc()でメモリを確保  ↓ セクションをロード  ↓ インポート関数のバインド  ↓ ベース再配置  ↓ 自分自身のリソースディレクトリへのアドレスを変更  ↓ セクションのアクセス保護属性を適用する  ↓ オリジナルエントリポイントにジャンプ  全体を通してそれほどややこしい点はありませんが「自分自身のリソースディ レクトリへのアドレスを変更」では注意が必要です。リソース関連のAPIはリソー スディレクトリへのアドレスがイメージ内にあるかどうかチェックしているため、 自身のPEヘッダのイメージサイズをリソースを含めるように変更してやる必要が あります。また、リソースデータのアドレスはRVA(Relational Virtual Addres s:実アドレスからイメージベースを引いた値)で表現されており、実アドレスは 「イメージベース(リソース関連のAPIに渡されたHMODULE)+RVA」となるのでそ のままでは正しい実アドレスを取得できません。「ロードされたアドレス+RVA」 となるようにRVAに「ロードされたアドレス−自分のイメージベース」を足してや ります。「VirtualAlloc()でメモリを確保」する際にはフラグにMEM_TOP_DOWNを 指定しましょう。MEM_TOP_DOWNを指定するとVirtualAlloc()はできるだけ上位の アドレスにメモリを確保します。ツールを使ってイメージをダンプするとサイズ が2Gバイト近いファイルになるので嫌がらせになります(ネタばらしすると簡単 に解除されますが)。 ■0x06.) 最後に  解析を防ぐにはPacked file loaderだけでは不十分です。いくつもの妙技を組 み合わせてより強固なものにしていきましょう。次回はアプリケーションデバッ ギングを防ぎます。「デバッギングされるのが嫌=デバッガにアタッチされるの が嫌」ということですのでアタッチされる前に自分でアタッチしてしまえばよい のです。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第3章: バイナリプロテクション2 〜アプリケーションデバッギングの防止〜 --- 著者:sourcerian x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  デバッガには大別してカーネルデバッガとアプリケーションデバッガがありま す。SoftIceやWinDBGなどはカーネルデバッガ、W32DasmやOllyDbgなどはアプリケ ーションデバッガに分類されます。今回はそのアプリケーションデバッガによる デバッギングを防ぐというお話です。退出  本題に入る前に用語の説明をしないと頭が混乱しそうです。プログラムの不具 合をバグ(bug)、バグを取り除くことをデバッグ(debug)、バグの原因を突き 止める作業をデバッギング(debugging)、デバッギングの手助けをするツールを デバッガ(debugger)、ついでにデバッギングされるプログラムのことをデバッ ギ(debuggee)といいます。クラッカ達は「ある日付を超えたら動作しなくなる バグ」や「シリアル番号を入力しないと機能に制限があるバグ」などを、様々な ツール(そのうちのひとつがデバッガ)を使って、「何故そのような動きになる のか」を調査して(デバッギング)、取り除いてしまいます(デバッグ)。  そこで今回の目的は、アプリケーションデバッガでブレイクポイントを設置し たりAPIコールで停止させて引数を調べたりスタックフレームを調べてバグの箇所 を推定したりすることを防ぐことになります。以後、いちいちアプリケーション デバッガと書くのは面倒なので「デバッガ」と表記した場合は「アプリケーショ ンデバッガ」を指すこととします。 ●使用するファイル ・http://wizardbible.org/32/AntiDebugging.v3.zip ・http://wizardbible.org/32/DebuggerSample.zip ■0x02.) どうやって防ぐのか  よくあるのがデバッガが検出された場合プログラムを終了させてしまうという ものです。デバッガの検出方法はDegital Travesiaの『OllyDbg』Q&A(http://h p.vector.co.jp/authors/VA028184/OllyDbgQA.htm)に記載されていますのでそち らをどうぞ。他にもgoogleなどで「detect debugger」や「anti debugging」など をキーワードに検索するとたくさんひっかかります。  しかしこの方法はあまり効果がありません。クラッカにしてみればデバッガの 検出部分を調べて取り除いてしまえばよいだけの話です。デバッガの検出は決ま りきった処理のため突き止めるのも簡単です。デバッガ検出部分を巧妙に隠して あるようなものもありますが生半可な知識で仕込んでも熟練のクラッカ相手には 3分ともたないでしょう。  そこで今回紹介するのが「デバッギングされてしまうのが嫌なら自分が先にし てしまえ」という方法です。  デバッガは最初に「このプロセスを私にデバッギングさせてください」とWind owsにお願いしなければいけません。このとき、ターゲットプロセスが他のデバッ ガによって既にデバッギングされていた場合、そのお願いは却下されてしまいま す。「こいつ(デバッギ)にはもう恋人(デバッガ)がいるので諦めなさい」と いわれるのです(XPやVistaにはその恋仲を壊してしまう方法もあったりしますが)。  したがって、デバッギングされたくないプロセスがあるなら、自分が先にその プロセスをデバッギングしてしまえばよいことになります。ただし、自プロセス をデバッギングすることはできませんので、デバッガ担当とデバッギ担当(実作 業担当)にプロセスを分けて動作させます。デバッガ担当はデバッギングされて しまいますが、実作業担当のほうはデバッギングすることができなくなります。 ■0x03.) デバッガの基礎  さて、先にデバッギングしてしまえばよいというのは簡単ですが、デバッガと なるにはいくつかの手順や決まりがあります。  デバッガの基本的な構造は次のようになっています。 ①新規プロセスをデバッギとして生成(または既存プロセスをアタッチ) ②デバッグイベントを待機 ③デバッグイベントを処理 ④続行方法を指定してスレッドを再開 ⑤②へ戻る  各々のステップを順を追って説明していきます。 ①プロセスをデバッギとして生成(または既存プロセスをアタッチ)  前述した「ターゲットプロセスを私にデバッギングさせてください」とWindow sにお願いする部分です。CreateProcess()APIでプロセスを新しく生成する時にD EBUG_PROCESSフラグを指定すると新しく作られるプロセスはデバッギとなり、デ バッギプロセスを生成したデバッガにとってデバッギング対象となります。  DEBUG_PROCESSフラグだけではデバッギが作った子プロセスもデバッギング対象 となります(ただし、子プロセスの生成にDEBUG_PROCESSフラグを指定した場合を 除く)。DEBUG_ONLY_THIS_PROCESSフラグを指定すると子プロセスはデバッギング 対象外となります。  既存プロセスをデバッギングしたい場合はDebugActiveProcess()APIを使います。 その場合、子プロセスはデバッギング対象外となります。 ②デバッグイベントの待機  デバッギの実行中に例外が発生したりDLLをロードしたりするとデバッグイベン トとしてデバッガ側に伝えられます。デバッグイベントは例外発生、プロセスの 生成・終了、スレッドの生成・終了、DLLのロード・アンロードに分類され、例外 発生はブレイクポイントへの到達(INT 3の実行)やアクセスバイオレーションな どさらに細かく分類されます。  デバッギの起動時またはアタッチ時には必ずブレイクポイント例外が発生しま す(このブレイクポイントはAPIが設置したものでその場所はエントリポイントで はありません)。これをファーストチャンスイベントと言い、この時にブレイク ポイントの設置など初期化を行います。  デバッグイベントの待機にはWaitForDebugEvent()APIを使います。 ③デバッグイベントを処理  デバッグイベントがデバッガに伝えられるとデバッギの全スレッドが停止状態 になります。これを利用してメモリの内容やスタックの状態を表示したり、デバ ッギが処理を続けられるように例外の処理を行います。また、デバッギが終了し た場合、つまりデバッグイベントがこれ以上発生しなくなった場合には、デバッ グイベント待機のループから抜けないとデバッガがいつまでたっても終了しない ことになります。 ④続行方法を指定してスレッドを再開  デバッグイベント処理中はデバッギの全スレッドが停止状態にあるわけですか ら、処理が終わったことをWindowsに伝えて、デバッギの全スレッドを再開させて やらなければいけません。この時、例外をデバッギの例外ハンドラに渡すかどう かを指定します。ただし例外発生以外のデバッグイベントではこの指定は無視さ れます。  この例外を渡すかどうかの指定をデバッガは適切に判断しなければいけません。 例外をデバッギの例外ハンドラで処理しなければいけないのにデバッガでブロッ クしてしまうと同じデバッグイベントが無限に発生したり、デバッガが設置した ブレイクポイントへの到達をデバッギの例外ハンドラに渡してしまうと強制終了 してしまう可能性があります。  Digital Travesiaに記載されている「6.構造化例外ハンドラを用いたデバッグ 検出」(http://hp.vector.co.jp/authors/VA028184/OllyDbgQA.htm)で検出され るようなデバッガは適切に判断していないデバッガです。適切な判断をするデバ ッガは検出されません。サンプルプログラムDebuggerSample.zipを用意しました。 debuggee.exeは「構造化例外ハンドラを用いたデバッグ検出」とIsDebuggerPres ent()APIの戻り値の表示を行います。debugger.exeはdebuggee.exeをデバッギと して起動して、ブレイクポイント例外が発生した場合に例外をデバッギに渡すか どうか確認してきます。渡すかどうかでその後の処理の違いを確認してください。 ■0x04.) デバッガの実装  ここまで説明すれば後はソースファイルを見たほうが早いでしょう。C言語で記 述すると次のようになります。 ---------------------------------------------------------------------------- DEBUG_EVENT de = { 0 }; // デバッグイベント情報 STARTUPINFO si = { 0 }; // CreateProcess() から戻される情報 PROCESS_INFORMATION pi = { 0 }; // CreateProcess() から戻される情報 // プロセスをデバッグ対象として生成する BOOL bCreate = CreateProcess( NULL // lpApplicationName , "debuggee.exe" // lpCommandLine , NULL // lpProcessAttributes , NULL // lpThreadAttributes , FALSE // bInheritHandles , DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS // flags , NULL // lpEnvironment , NULL // lpCurrentDirectory , &si // lpStartupInfo , &pi); // lpProcessInformation if( bCreate == FALSE ) { return 1; } // デバッグイベントの待機 while( WaitForDebugEvent(&de, INFINITE) ) { // スレッドの続行方法 DWORD dwContinueStatus = DBG_CONTINUE; // 初期値は例外をデバッギに渡さない // 例外発生 if( de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT ) { EXCEPTION_RECORD* per = &de.u.Exception.ExceptionRecord; // ブレイクポイントに到達 if( per->ExceptionCode == EXCEPTION_BREAKPOINT ) { // ファーストチャンスイベント if( bFirstChance ) { bFirstChance = FALSE; // ブレイクポイントの設置など初期化を行う } else { // 身に覚えのないブレイクポイントはデバッギに処理させる。 dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; } } // その他の例外処理 else { // デバッギの例外ハンドラに例外を処理させる。 dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; } } // プロセスが終了した else if( de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT ) { // デバッグイベントの待機を辞める。デバッギの子プロセスを含めて // デバッグ対象としている場合は全てのプロセスが終了するまで処理 // を続ける break; } // その他、DLLのロード/アンロード、プロセスの生成、スレッドの生成/終了 //else //{ //} // 続行方法を指定してスレッドを再開 if( !ContinueDebugEvent(de.dwProcessId , de.dwThreadId, dwContinueStatus) ) { break; } } // プロセスハンドルとスレッドハンドルをクローズする CloseHandle(pi.hProcess); CloseHandle(pi.hThread); ---------------------------------------------------------------------------- ■0x05.) アンチデバッギングの実装  デバッガの骨組みが出来たところでアンチデバッギングの実装に取り掛かりま す。前述したようにデバッガ担当とデバッギ担当(実作業担当)にプロセスを分 けて動作させます。しかし、プログラムをデバッガ担当とデバッギ担当に分ける 必要はありません。Cランタイムスタートアップルーチン(WinMainCRTStartup) が実行される前にデバッガ部分が実行されるようにして、次の手順を行います。 ①自プログラムをデバッギとして起動 ②ファーストチャンスイベントでエントリポイントにブレイクポイントを設置 ③エントリポイントに設置したブレイクポイントに到達したらオリジナルエント リポイント(WinMainCRTStartup)にジャンプ  ブレイクポイントの設置とは、設置したい場所のプログラムコードを0xCC(IN T 3のマシン語コード)に変更することです。また、オリジナルエントリポイント へのジャンプはスレッドのCPU状態(CONTEXT)を操作するGetThreadContext()AP IとSetThreadContext()APIを使って現在実行中のアドレス(EIP)を変更します。 これを実装したのがAntiDebugging.cです。デバッギングを防止したいプログラム のプロジェクトにAntiDebugging.cを追加し、プロジェクトの設定でエントリポイ ントをEntryPointにするだけでデバッギングが防止できます。サンプルとしてAn tiDebugging.v1.zipを用意しましたので、OllyDbgなどでデバッギングを試してみ て下さい。ブレイクポイントは上手く機能しないし、既存プロセスのアタッチも 失敗します。 ■0x06.) 簡単に解除されてしまうアンチデバッギング  確かにデバッギングが防げましたが、これを簡単に解除してしまうことができ ます。 ①SetThreadContext()APIにブレイクポイントを設置。 ②①で設置したブレイクポイントに到達したら、APIに渡された引数のCONTEXT構 造体のEipの値を控える。 ③プログラムのエントリポイントを②のEipの値で書き換える。  たったこれだけです。これはデバッガ部分がデバッギをオリジナルエントリポ イントにジャンプさせるだけの役割しか果たしていないからです。これを防ぐに はデバッガ部分が動作しないとデバッギが動作しないようにしてやる必要があり ます。次回はその方法と説明を行います。 ■0x07.) 最後に  前回のPackedFileLoaderではPEフォーマットの知識ありきで説明してしまった ためかなり説明を省いてしまいましたが、今回はいかがでしたでしょうか。ほと んどデバッガの説明で終わってしまった気もしますが、デバッガの仕組みを理解 するのはとても重要なことです。アンパック後に逆アセンブルするdispeやジェネ リックアンパッカなどもデバッガなので対策をたてる上で役にたつからです。例 えば親プロセスのプログラムがWaitForDebugEvent()APIをインポートしている場 合はデバッガがアタッチされていると判断できます。自分でもいろいろと考えて みてください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第4章: バイナリプロテクション3 〜解除されにくいアンチデバッギングの実装〜 --- 著者:sourcerian x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  前回ではアンチデバッギングを実装しましたが簡単に解除されてしまうので、 デバッガ部分が動作しないとデバッギ部分が動作しないように改良しましょうと いう話で終わりました。今回はその改良方法の説明です。 ●使用するファイル ・http://wizardbible.org/32/AntiDebugging.v3.zip ■0x02.) PackedFileLoaderとアンチデバッギングを組み合わせる  第1回のPackedFileLoaderと第2回のアンチデバッギングを組み合わせて、デバ ッガ部分にローダを担当させることでエントリポイントを修正しただけでは解除 できないようにします。PackedFileLoaderのローダ部分をデバッガ部分に組み込 むので処理の流れは次のようになります。 ①自プログラムをデバッギとして起動する。 ②ファーストチャンスイベントでエントリポイントにブレイクポイントを設置す る。 ③エントリポイントに設置したブレイクポイントに到達したらデバッギプロセス にスマートイメージファイルをロードする。 ④スマートイメージファイルのロードが完了したらデバッギのスレッドのEIPをオ リジナルエントリポイントに変更する。  ここで色々と問題が発生します。  PackedFileLoaderではインポートアドレステーブルのバインドにLoadLibrary( )APIとGetProcAddress()APIを使っていました。ところが、今回は別プロセスにD LLをロードさせるわけですから、LoadLibrary()APIとGetProcAddress()APIは使用 できません。そこで別プロセスにDLLをロードさせるInjectLibrary()関数と、別 プロセスにロードされたDLLのエクスポート関数のアドレスを取得するGetProcAd dressEx()関数を作ります。  しかしここで別の問題が発生します。InjectLibrary()関数はCreateRemoteThr ead()関数にスレッドルーチンとしてLoadLibraryを指定してスレッドをつくり、 DLLのロードが完了するまでWaitForSingleObject()APIで待機します。しかし、デ バッグイベントの処理中はデバッギの全スレッドが停止されることを思い出して ください。つまりデバッグイベントの処理中にInjectLibrary()関数を使うことは できないのです。そこでスマートイメージをロードするのは別スレッドに担当さ せ、デバッガを担当するスレッドはデバッギのスレッドをSuspendThread()APIで 停止させた後、スレッドの続行・デバッグイベントの待機に入ります。そうする ことで、CreateRemoteThread()APIで作られたスレッドが動き出してDLLをロード するのです。そしてスマートイメージファイルのロードが終わった時点でデバッ ギのスレッドのEIPをオリジナルエントリポイントに変更してResumeThread()API でスレッドを再開させます。  以上を反映させるとデバッガ部分の処理の流れは次の通りです。 ①自プログラムをデバッギとして起動する。 ②ファーストチャンスイベントでエントリポイントにブレイクポイントを設置す る。 ③エントリポイントに設置したブレイクポイントに到達したらSuspendThread()A PIでデバッギのスレッドを停止、デバッガ側の別スレッドでスマートイメージフ ァイルをデバッギのプロセスにロードする。 ④スマートイメージファイルのロードが完了したらデバッギのスレッドのEIPをオ リジナルエントリポイントに変更してResumeThread()APIによりデバッギのスレッ ドを再開させる。  これまでの内容を実装したAntiDebugging.v2.zipを用意しました。AntiDebugg ing.v2.zipにはPackedFileLoaderと同じソリューション構成のソースが入ってい てloader以外は全く同じです。Loaderプロジェクトには以下のソースファイルが 含まれています。 ・Except.h/Except.c  今回からエラー処理の簡略化に構造化例外処理(SEH:Structured Exception Handling)を使うことにしました。SEHのラッパの宣言と定義がこの2ファイルに なります。 ・ApiWrapper.h/ApiWrapper.c  ReadProcessMemory()やWriteProcessMemory()などのAPIのラッパ関数の宣言と 定義です。APIコールに失敗するとSEHの例外を投げるようにしただけの単純なも のです。 ・InjectLibrary.h/InjectLibrary.c  前述したInjectLibrary()関数とGetProcAddressEx()関数の宣言と定義です。 ・LoadSmartImageEx.h/LoadSmartImageEx.c  スマートイメージファイルのロードを行う関数とそれに付随する関数の宣言と 定義です。第1回のLoadSmartImage()関数のメモリI/OをひたすらReadProcessMem ory()APIとWriteProcessMemory()API(のラッパ関数)で行うようにし、それらを別 スレッドで実行するようにしたものがLoadSmartImageEx()関数です。 ・Loader.c  WinMain()関数とデバッガ部分です。前回はEntryPoint()関数をエントリポイン トとしましたが、VisualC++でSEHを使うとCランタイムライブラリを使うことにな るためWinMain()で定義してあります。  実際にスマートイメージファイルを実行させてみてOllyDbgなどでデバッギング できないことを確認してみてください。 ■0x03.) ダンプ対策にAPIコールをフックする  PackedFileLoaderそのものの弱点ですが、スマートイメージファイルがロード された後にメモリをファイルにダンプしてPEファイルフォーマットの整合性をと ることで、そのまま実行できてしまいます。それをデバッギングされてしまって は意味がありません。  そこで一部のAPIにブレイクポイントを仕掛けて、そのブレイクポイントに到達 した時点で本来とは異なる動作をするように変更します。当然、デバッギ側は変 更された動作でないと正しく動作しないようにします。  抽象的にいっていてもわかりにくいので具体的な説明をしましょう。今回、私 が目をつけたのはLoadResource()APIです。PackedFileLoaderのローダ部の説明で、 次のように記述しました。 ----- リソースデータのアドレスはRVA(relational virtual address:実アドレスからイ メージベースを引いた値)で表現されており、実アドレスは「イメージベース(リ ソース関連のAPIに渡されたHMODULE)+RVA」となるのでそのままでは正しい実ア ドレスを取得できません。「ロードされたアドレス+RVA」となるようにRVAに「 ロードされたアドレス−自分のイメージベース」を足してやります。 -----  この説明の実アドレスを取得するAPIがLoadResource()APIで、そのほかのLoad String()APIなどリソースを取得するAPIは全てLoadResource()APIをコールしてい ます。LoadResource()APIは第二引数のHRSRCからRVAを取り出し、第一引数のモジ ュールハンドルにそのRVAを足したものを返します。つまり、ロード時にRVAを修 正しなくてもLoadResource()の戻り値に「ロードされたアドレス−自分のイメー ジベース」を足してやれば良いことになります。戻り値を修正するにはAPIのコー ル元(戻り先)にブレイクポイントを設置してそのブレイクポイントに到達した際 にEAXレジスタの値を書き換えます。  したがって、処理の流れは次のようになります。 ①LoadResource()APIにブレイクポイントを設置する。 ②LoadResource()APIに設置したブレイクポイントに到達したら以下の処理を行う。 ②−①スタックから戻り先を調べて戻り先にブレイクポイントを設置する。 ②−②LoadResource()関数本来の動作をさせるためにブレイクポイント設置前に 戻し、EIPを一つ前(INT 3実行する前)に戻す。 ②−③ブレイクポイント設置前の動作を行わせた後に再度ブレイクポイントを設 置するために、スレッドのシングルステップフラグをオンにする。 ③②−③で設定したシングルステップフラグのせいでスレッドは1命令実行毎にシ ングルステップ例外を発生します。この時LoadResource()APIにブレイクポイント を再設置してシングルステップフラグを解除します。 ④②−①で設置した戻り先のブレイクポイントに到達し、戻り値が自分のリソー スを指しているようだったら、戻り値(EAXの値)を修正します。  これでメモリをダンプしてもリソースのRVAが正しくないのでリソースのロード に失敗して正常に動作してくれません。ただし、逆アセンブルはできますのでシ リアルナンバーのチェック部分などクリティカルな部分は隠しておきましょう。  上記を実装したAntiDebugging.v3.zipを用意しました。v2からの修正箇所はス マートイメージファイルのロード時にリソースのRVAを修正しないのと、デバッガ 部分で上記の流れを追加したものになります。 ■0x04.) 最後に  というわけで、アンチデバッギングの話は終わりです。SoftIceなどのカーネル デバッガによるデバッギングは防げませんが、OllyDbgなどを防げるだけでも非常 に効果が高いと思います。個人的にはこれにアンチカーネルデバッガが(巧妙に) ついていたらもう解析する気が起きないです。  そういえばSoftIceの開発・販売が終了したようですね。64ビットの転換期が近 くクラッカご用達のSoftIceがなくなってしまった解析の世界はどのようになって いくのでしょうか。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第5章: PS2ソフトの音楽差し替え --- 著者:エクセル小林 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) 自己紹介&はじめに  どうも初めましてこんばんわ。  元ネタを知ってる人は知ってる、知らない人は売れない芸人みたいな名前だな と思われるエクセル小林です。  さてこの度は周りの皆様が素敵な文章を載せてるのを気にせずに、PS2ソフトの 音楽差し替えについて書きたいと思います。この記事を参考にすれば、自分の好 きな音楽に変えることができます。中には音声を変えられるのもあります。  さぁ、あなたも———世界でひとつしかないソフトを作ってみませんか? ■0x02.) 差し替え可能ソフトについて  題名にはPS2ソフト音楽差し替えと書いてありますが、全部が全部差し替え可能 ってワケでなく、ソフト起動時にこんな感じの画面が出るゲームが差し替え可能 になります(図1参照)。 (図1)http://sfx64.hp.infoseek.co.jp/ps2/20070219_85610.jpg  要するにCRI社のADXを使用してサウンド再生してるか否かってことですね。こ ちらでその画面が出る「.hack//G.U. Vol.1〜3」「モンスターハンター2」を試し てみたところ、一応不具合なく起動して遊べました。しかし、上記の画像が出る からといっても、すべてがうまくできるワケではありません。自分で色々確認し てみてください。  例をあげると、ADXファイルがCVMファイルに音楽が格納されている「メルティ ブラッド アクトカデンツァ」は、以下に書いてある方法では差し替え不可能にな ります。 ■0x03.) 注意  自分用に差し替えたところで、バックアップディスクを起動させることができ なければまったく意味がありません。個人的にはSwapMagicが一番お手軽です。一 回だけ知り合いに借りてメモカブートも楽でGOOD。まあそこら辺の解説は検索す ればすぐわかると思いますので、割愛します。 ■0x04.) 差し替えディスクのつくりかた ●AFSファイルのエクスポート 1:差し替えたいPS2ゲームディスクをドライブに入れ、中身を全て適当なフォル ダにコピーします。 2:「afsexplorer.zip」をダウンロードして解凍します。 http://sfx64.hp.infoseek.co.jp/ps2/tool/afsexplorer.zip 3:「afsexplorer.exe」を起動し、File→configで"Ignore descriptor's lengt h"をチェックします。 4:File→Import AFS fileから、ステップ1でコピーした「*.AFS」を読み込ませ ます。 5:Action→Export folderで適当なフォルダにエクスポートします。 ●ADXオーディオファイルの作成 1:差し替え用の音楽ファイルを用意します。 2:フォーマットが「48,000 kHz,16ビット,ステレオ」のWAVファイルに変換しま す。 3:「adxencd.zip」をダウンロードして解凍します。 http://sfx64.hp.infoseek.co.jp/ps2/tool/adxencd.zip 4:コマンドプロンプトを起動し、「adxencd.exe」を実行します。 5:"adxencd [ファイル名]"(例:adxencd 1.wav)と入力し、エンタキーを押し ます。 6:音楽をループして再生させるために"adxencd [ファイル名] -lps0 -lpe[ルー プ終了ブロック]"(例:adxencd 1.wav -lps0 -lpe54568525)と入力してエンタ キーを押します。[ループ終了ブロック]は入力音声サンプル数の右にある数字を 入力します。 ●AFSファイルのインポート 1:作成したADXファイルを、AFSファイルのエクスポートした中にある差し替えた い音楽のファイル名にし、元ファイルに上書きします。 2:「afsexplorer.exe」を起動し、適当なAFSファイルを読み込ませます。 3:Action→Import folderを選び、AFSファイルのエクスポートのステップで読み 込ませたAFSファイル名で適当な場所にインポートします。 ●バックアップディスクの作成 1:インポートしたAFSファイルを、AFSファイルのエクスポートで保存したフォル ダに移動し、元ファイルに上書きします。 2:空のDVD-Rをドライブにセットします。 3:「Nero」をダウンロードし、インストールします。 4:Nero Burning ROMを起動します。 5:プルダウンメニューから「DVD」を選び、「DVD-ROM (UDF/ISO)」を選択して新 規作成ボタンを押します。 6:AFSファイルのエクスポートのステップ1で保存したフォルダの中身をすべてド ラッグアンドドロップします。 7:書き込みボタンを押し、適度な書き込み速度に設定して、書き込みを開始しま す。 8:以上で完成です。  AFSExplorerは3.7が最新版だそうですが、こちらの環境でしっかり動いてくれ なかったので3.2を使用しました。バックアップディスク作成編で使うのはNeroじ ゃなくても構いません。ウルトラISOなどがよいんじゃないでしょうか? しかし、 Neroならば面倒なLBAの設定をしなくていいので、非常に楽な作業になります。 ■0x05.) おわりに  どうだったでしょうか? きちんと起動しましたか? これで友達に自慢でき ますね(笑  さて、これよりが需要ありそうな音声の差し替えですが、大体のソフトがAHXが 利用しているため、こちらはまだまだできないソフトが多いです。噂ではAHXファ イルの中身はmp2+ADXヘッダらしいので、ソース書き換えたらなんとかなるかもし れないらしいですが…。今後の発展に期待です。  では、機会があったらまた会いましょう。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第6章: ハニーポットを作ろう(連載第12回) --- 著者:Narusase x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  前回はSnortのフロントエンドであるACIDのインストールと設定について解説し ました。今回はTripwireかnepentesについて解説する予定でしたが、ちょっと趣 向を変えて、最低限必要なファイルの作成と削除だけに絞ってHIDSもどきを自作 する方法を紹介してみたいと思います。  ・・・いや、手抜きとかじゃないですよ(汗。 ■0x02.) HIDSもどきの作成  今回作るスクリプトで実現できる機能は、ファイルが作成または移動されたこ とと、ファイルが削除あるいは移動されたことを発見することです。行うことと しては、ある時点でのファイルのリストと、現在のファイルのリストの差分を取 ることで、変更のあったファイルを見つけ出し、その後、作成された物と、削除 された物をその中から抽出します。  まずは、ある時点でのファイルのリストを作るスクリプトを作ります。そのた めのスクリプトのファイル名は「hids-mklist-org.sh」としておきます。 ----- # vi hids-mklist-org.sh ----- ----- 「hids-mklist-org.sh」ファイルの内容(行番号付き) 01: #!/bin/bash 02: FILENAME="/root/list" 03: find / > ${FILENAME}.org -----  行っていることはごくごく簡単で、findコマンドを用いて1行毎に1つのファイ ルをフルパスで表示させ、それをリダイレクトしてファイルに書き込んでいるだ けです。  次は、現在のファイルのリストを作り、差分を取るスクリプトを作ります。そ のためのスクリプトのファイル名は「hids-mklist.sh」としておきます。 ----- # vi hids-mklist.sh ----- ----- 「hids-mklist.sh」ファイルの内容(行番号付き) 01: #!/bin/bash 02: FILENAME="/root/list" 03: find / > ${FILENAME}.now 04: cat ${FILENAME}.now ${FILENAME}.org | sort | uniq -u > ${FILENAME}.uniq 05: cat ${FILENAME}.org ${FILENAME}.uniq | sort | uniq -d > ${FILENAME}.del 06: cat ${FILENAME}.now ${FILENAME}.uniq | sort | uniq -d > ${FILENAME}.make 07: echo "#########################################################" 08: echo "削除もしくは移動されたファイル" 09: cat ${FILENAME}.del 10: echo "`cat ${FILENAME}.del | wc -l`個のファイルを発見しました" 11: echo "#########################################################" 12: echo "作成もしくは移動されたファイル" 13: cat ${FILENAME}.make 14: echo "`cat ${FILENAME}.make | wc -l`個のファイルを発見しました" 15: echo "#########################################################" -----  03行目は、先ほどのスクリプトとの違いはファイル名だけで、現在のファイル のリストを作っています。  04行目は、まず現在と過去のファイルのリストを出力し、それをソートし、un iqコマンドを使い「重複がなかった行」のみをファイルに出力しています。つま りこの時点でlist.uniqファイルの内容は新しく作られたファイルと移動されたフ ァイル、削除されたファイルのリストということになります。  05行目は先ほどとほぼ同等でuniqコマンドのオプションのみが違います。これ は、過去のファイルのリストとユニークなファイルのリストを出力し、それをソ ートし、uniqコマンドを使い「重複があった行」のみをファイルに出力していま す。つまりこの時点でlist.delファイルの内容は削除されたもしくは移動された ファイルのリストということになります。  06行目はも同じようなことをしていますがこちらでは現在のファイルのリスト とユニークなファイルのリストを比較しています。list.makeファイルの内容は当 然、作成されたもしくは移動されたファイルのリストということになります。  07行目からは見つけたファイルを表示しています。 ■0x03.) HIDSもどきの使い方  これらのスクリプトの使い方は簡単です。  まず、hids-mklist-org.shを実行し、正しい状態を記録します。  次に、hids-mklist.shを定期的に実行し不審なファイルが作成されたり、必要 なファイルが削除されていないか目視で確認するという感じです。loggerコマン ドとかを使ってsyslogにログを吐かせるのもよいかも知れません。また、cloneに 登録すれば自動的に一定時間ごとに問題が起きていないか調べることも可能です。 ■0x04.) スクリプトの拡張(宿題?)  ここまでくると移動されたファイルを見つけ出したいと思うでしょうが、それ は皆さんの宿題(?)ということで・・・。  ヒントとしてはファイルは移動された場合であってもi-node番号が変わらない という性質を利用すれば良いということです。さらにヒントを出すと「stat FIL E -c"%n %i"」とするとファイル名とi-node番号が表示されますので、findで作っ たファイル名のリストからひとつひとつのファイル名を取り出しに繰り返し同じ コマンドを実行すればi-node番号まで含んだリストを作れそうです。後は、i-no de番号が同じでファイル名が違う物を探し出せばそれが移動したファイルだとい うことがわかると思います。 ■0x05.) おわりに  今回はHIDSもどきの作成について話しました。  色々と忙しかったため、内容に欠ける物になってしまって申し訳ありません。 次回はこそは、nepentesのインストールと設定に関してきちんと説明したいと思 います。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第7章: 初めての量子コンピュータ 〜スパコンを超える超並列計算〜 --- 著者:結城瀬名 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  皆さんは量子コンピュータというものをご存知でしょうか。恐らく初めて耳に するという方も多いのではないかと思います。量子コンピュータとは量子力学の 原理を用いたコンピュータの総称です。一般に広く普及しているコンピュータと は計算の仕組みがまったく異なっており、近年ではカリフォルニア工科大学やス タンフォード大学といった海外の大学や専門の研究機関を中心に開発が進められ ています。日本においても北海道大学などにおいて研究開発が進められています。  今回はその量子コンピュータの魅力について解説したいと思います。 ■0x02.) 量子コンピュータとは何か  量子コンピュータが量子力学の原理を利用したコンピュータであることはすで に述べました。では「量子」とはそもそも何でしょうか? 量子とは簡単に説明 するならば粒子と波の性質をあわせ持つもののことです。例えば、エネルギー単 位「光子」によって構成される光、単位として「電子」によって構成される電気 などといった光や電気を構成する基本単位が量子の代表例です。この他にもC60と 呼ばれる炭素原子から構成される巨大分子についても粒子と波の性質を持つこと が知られていますが、一般的には上記の2つの例が一番想像が付きやすいのではな いかと思います。  量子コンピュータはこのような粒子と波の性質をもつ基本単位を利用して並列 計算を行うコンピュータです。我々が現在使用しているコンピュータ(以降、古 典的コンピュータと呼ぶ)は1ビットの値に0か1という2つのパターンの値しか持 ちません。一方、量子コンピュータが扱うビットはこれら2つの値の状態を同時に 取る「重ね合わせ」という性質を持ちます。そうしたビットを量子ビットと呼び ます。つまり、古典的コンピュータと量子コンピュータの大きな違いはまさにこ の「量子ビット」にあります。「重ね合わせ」は単に0もしくは1を確率的にとっ ているのではなく、その間に確定的な位相関係がある不思議な状態のことです。  量子コンピュータが「重ね合わせ」の性質を持っていることが古典的コンピュ ータとの大きな違いであり、ここに量子コンピュータがそれらの古典的コンピュ ータとは比較にならないほど高速に計算をこなせる秘密があります。例えば、2個 の量子ビットを用いると4つ(=2^2)の状態を、3個の量子ビットを用いると8つ (=2^3)の状態といった感じで重ねあわせにある状態の数は量子ビットの数に対 して指数的に増大します。仮に、この量子ビットの数が40ビットなら状態数は1兆 にも達します。  このような重ね合わせの状態をフルに活用することができれば、少ない量子ビ ット数で結果として膨大な数の重ね合わせを用いた超並列計算が可能になるので す。 ■0x03.) 計算不可能とされる問題が見事に解決?  これまでの説明でなんとなく漠然としながらも「とにかく量子コンピュータを 用いることで超高速な計算が可能になるんだな」ということはわかっていただけ たかと思います。現在広く普及しているいわゆる市販の古典的コンピュータが1秒 間にこなす計算は平均して約10億回とされています。数年前まで世界最速と謳わ れた地球シミュレータは最大で毎秒40兆回の計算が可能とされていましたが、こ れだけ高速な計算を可能とする計算機をもってしても計算が不可能とされる問題 が現実的に存在するのです。  代表的な計算不可能問題としていくつか次に示します。 ・10,000桁の素因数分解 ・巡回セールスマン問題  これらの問題が現代の古典的コンピュータでは「計算不可」とされる共通した 理由として計算に時間がかかり過ぎることが挙げられます。  それでは各問題の簡単な解説に入りたいと思います。 ●10,000桁の素因数分解  これは文字通り10,000桁の整数の素因数分解です。素因数分解とは、ある整数 を因数が素数になるまで分解することです。  素因数分解のもっとも基本的なアルゴリズムとして、エラトステネスのふるい があります。素因数分解の対象である整数nがあったときに、√n(小数点切り捨 て)以下のすべての素数で割れるかどうかを調べれば十分であるという定理です。 アルゴリズムの世界ではひとつでも素因子がわかれば、素因数分解に成功したと 考えることに注意してください。エラトステネスのふるいは総当りの対象を減ら してくれるのに役に立ちますが、それでも素因数分解の対象が10,000桁もあれば、 古典的コンピュータで解くのは到底無理です。  他にも素因数分解アルゴリズムとして、Pollard(ポラード)の(p-1)法、Poll ard-ρ(ロー)法、2次ふるい法、数体ふるい法などがあります。現在もっとも効 率のよい素因数分解アルゴリズムは数体ふるい法となっています。余談ですが、 暗号解読チャレンジのRSA-129(10進数で129桁という意味)は1994年に2次ふるい 法で解読されました。その後RSA-130,140,155などは数体ふるい法で解読されまし た。  このように素因数分解を解くのが困難ということは広く信じられていますし、 暗号理論のもっともよく登場する基本的な概念となっています。もし量子コンピ ュータで計算できてしまえば、素因数分解問題が困難であることをベースにして いる暗号理論はすべて崩壊してしまうといえます。ただし、量子コンピュータで 解けるのはあくまで素因数分解問題や離散対数問題といった数論的なものが対象 なので、それ以外の暗号は大丈夫です(そうした暗号は使いにくいのでマイナー ですが)。また共通鍵暗号系ならば、単に鍵長を2倍にするだけで、古典的コンピ ュータにおける従来の安全性と同値になります。 ●巡回セールスマン問題  具体的な都市を登場させてみると、この問題は次のようになります。ある会社 の営業員が東京から出発し札幌・青森・仙台・新潟・横浜・名古屋・大阪・金沢 ・京都・神戸・広島・福岡の各都市を移動距離が最短になるように回り、最後に また東京に戻るというものです。  ここで話を簡単にするために次の2つの条件を付け加えます。 ・すべての都市間では道がつながっており、その間の距離は直線距離とする。 ・同じ都市には2度立ち寄らなくもよい。  上記で挙げた都市は東京を除くと全部で12都市あります。これらの都市の回り 方の順序の総数は12!(=12×11×10×・・・×1)ですから、これを計算すると約4億 8千万となります。都市の数をさらに4都市増やし16都市とすると上記の総数は約 21兆となり爆発的に総数が増加することがわかります。  例えばこれにさらに14都市を足して30都市にしたとします。これを1秒間に約 10億回の計算をこなす一般のPCで計算すると、解答に要するまでの時間は1,000兆 年以上になります。  このように巡回セールスマン問題は都市の数をほんの数個足しただけで計算に かかる時間が莫大に増加してしまうということが上記の例からお分かりいただけ るかと思います。 ●古典的コンピュータ vs 量子コンピュータ  では古典的コンピュータでの解答は不可能とされるこれらの問題に対し量子コ ンピュータはどれくらいの時間で解答を導き出すことが可能なのでしょうか。  10,000桁の素因数分解は、スパコンで大体1,000億年かかりますが、量子コンピ ュータを使うと数時間程度で計算できます。  また、巡回セールスマン問題は、最新のPCで1,000兆年以上かかります。量子コ ンピュータを使った計算結果はまだわかりませんが、現在世界中の量子コンピュ ータ研究者が挑戦中です。  他にも計算不可能問題の種類はここで挙げた以外にいくつか存在しますが、こ の2つの例から量子コンピュータの計算速度がどれほどのものか分かっていただけ たのではないでしょうか。 ■0x04.) 終わりに  ここまで古典的コンピュータと比較しつつ量子コンピュータがいかに速く計算 を行えるのかということについて書きましたが、量子コンピュータの研究はまだ まだ開発段階の途上にあり課題も山積しています。現在の日本においてもこれら の研究を行っている施設は極少数であり、完成まで少なくともこれからまだ10年 以上を要するといわれています。  今回はお題に「初めて」とあるように量子コンピュータとはどのようなもので あるのか、あくまでその表面的な概要についてのみ書かせていただきました。し たがって、内容についてもほとんど深みはなく書いている著者本人としてもなん だか味気のないものになってしまった感は否めません。しかしながら今回の記事 を元に少しでも量子コンピュータについて知っていただき、また興味をもってい ただけたなら筆者としても幸いです。意欲がありさらに詳しく学んでみたいと思 われる方は『量子コンピュータ 〜超並列計算のからくり〜』竹内繁樹 著(講 談社ブルーバックス)をお勧めします。  最後に、今回の記事を書くにあたり応援してくださったMaDさん、Defolosさん には深く感謝いたします。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第8章: はじめてのハッキング 〜番外編:パスワードクラック〜 --- 著者:Defolos x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  プログラミングの基礎の確認を終えたところで、C言語によるプログラミングの 練習を行いましょう。題材としてはハッキングにも関係が深いパスワードクラッ カーの作成を通して、パスワードの基礎およびプログラミング技術の確認を行い ます。  近年では、パスワードクラッカーは多くの種類が出回っています。John The R ipperをはじめ、高性能なパスワードクラッカーが簡単に手に入り、その気になれ ば小学生でさえパスワードクラックを楽しむことができるようになりました。し かし、パスワードの原理やパスワードクラッカーに必要な動作を知らずしてツー ルを用いることは、何の進歩にもなりえないと考えます。そこで、簡単なパスワ ードクラッカーを作成し、パスワードとそれを取り巻く技術について知識を深め ることを本レポートの目的とします。  パスワードクラッキングに関するより詳しい解説はWizard Bible vol.7のKenj iさんの記事を参照ください。 参考→http://wizardbible.org/7/7.txt ■0x02.) Linuxログインパスワード  Linuxのログインパスワードは「/etc/passwd」に暗号化されてテキストファイ ルとして保存されています。/etc/passwdはすべてのユーザが閲覧できるようにな っているため、セキュリティの観点からは好ましいものではありませんでした。 そのため、一般ユーザが閲覧さえできない「/etc/shadow」に暗号化したパスワー ドを置く方法が一般的になっています。この方法のことをShadowと呼びます。  以前まで多くのLinuxはパスワードの暗号化にDESを用いていましたが、近年で はMD5で暗号化することが一般的になっています。そこで、このレポートでは事前 に入手した「/etc/shadow」内のMD5で暗号化されたパスワードをクラックし、も とのパスワードを入手するツールを作成します。 ●単方向のハッシュ関数  MD5(Message Digest 5)は単方向のハッシュ関数と呼ばれるものです。また、 DES(Data Encryption Standard)は共通鍵暗号(ブロック暗号と呼ばれるタイプ )ですが、連鎖して使うことでハッシュ関数のように使うこともできます。  ある文字列を入力すると、まったく別の文字列(ビット長が小さい)を出力す る関数をハッシュ関数と呼び、出力された文字列をどういじくっても入力された 文字列を求めることはできません。ハッシュ関数を用いて文字列を変形させる場 合、正確にはエンクリプトとは呼ばずエンコード(あるいはハッシュ化)と呼び ます。また、出力されたエンコードされた値はハッシュ値と呼びます。  Linuxではエンコードされたパスワードは「/etc/shadow」に置かれます。ログ イン時に入力されるパスワードを同じアルゴリズムでエンコードし、「/etc/sha dow」に格納されているエンコード済みのパスワードと比較します。もし、両者が 一致すれば正確なパスワードが入力されたとして認証可能とします。上記のハッ シュ関数の性質のうちで、特に一方向性の概念が大きく影響していることがわか るでしょう。こうしたログイン時と同じ原理を用いてパスワードクラッカーの作 成に応用することができます。 ●ソルト  単方向ハッシュ関数をクラックする最も高速な方法は、事前にすべての文字列 をエンコードし、それと/etc/shadow内に保存されているエンコードされたパスワ ードとの比較を行う方法です。この方法では文字列が一致した場合、その文字列 がパスワードであったと判断できます。この方法では、パスワードによく使われ る文字列をエンコードして保存しておいても10Gバイトにも満たないことが多く、 なおかつ高速でクラックが可能です。このような弱点を克服するため、単方向ハ ッシュ関数にはソルト(salt)という概念を導入している場合が多いです。本レ ポートの攻撃対象であるMD5関数にもソルトは導入されています。  ソルトはエンコードパターンに多様性を持たせるための仕組みです。ソルトは ごく短い文字列で構成されます。入力文字列の先頭にソルトを配置し、エンコー ドします。エンコード結果の先頭にはソルトを配置します。これで認証時に照合 は可能になりながらエンコードパターンが一意に定まらず、事前に文字列をエン コードする手法は防ぐことができます。仮にソルトの長さが8文字、使える文字が [A-Z],[a-z],[0-9],[.],[/]の64文字だとすれば、エンコードパターンはあるひと つの入力に対して4,398,046,511,104通り考えられることになります。もしパスワ ードによく使われる文字列を事前にエンコードして保存しておくとすれば、10Tバ イトではすまない可能性もあります。  このため、本レポートで作成したパスワードクラッカーは別のアプローチを行 っています。簡単に言えば、エンコードされたパスワードからソルトを取得し、 そのソルトを用いてパスワードによく使われる文字列をMD5でエンコードします。 それを比較し、一致した場合その文字列がパスワードであったと判断します。非 常に多くの文字列に対してハッシュ化を行うため、速度は期待できません。 ●crypt関数  暗号化にはcrypt関数を利用します。crypt関数は引数としてソルトとキーの格 納されたアドレスをとり、ハッシュの先頭3文字が「$1$」で始まるときはMD5で、 それ以外のときはDESでエンコードします。また、crypt関数を利用するには-lcr yptオプションが必要であり、次のようなマクロとインクルードを行わなければな りません。 ----- #define _XOPEN_SOURCE #include -----  MD5は非可逆なハッシュアルゴリズムで、最大8文字のソルトをとり出力は最大 34バイトとなります。出力は「$1$+ソルト+$」で、は[A-Z],[a -z],[0-9],[.],[/]の64文字の集合から選ばれる22バイトです。 ●ソースコード  それでは以上の事項を踏まえ、パスワードクラッカーのソースコードを記述し ます。 ----- passcrack.c #define _XOPEN_SOURCE #include #include #include enum {CMD_NAME, DICTIONARY, SALT, PASSWD}; int main(int argc, char *argv[]){ FILE *file; char salt[11]; char pass[35]; char key[256] ={"newbie"}; char *code; int i = 0; if (argc != 4){ printf("Usage:<%s> Dictionary Salt Passwd\n", argv[CMD_NAME]); printf("-----[Example]-----\n"); printf("if passwd is $1$N9rTnvmD$Z.e92/gt.SqCmUyyxHI6A0\n"); printf("passcracker.exe dic.txt N9rTnvmD Z.e92/gt.SqCmUyyxHI6A0\n"); return 0; } salt[0] = '$'; salt[1] = '1'; salt[2] = '$'; i = 0; while(i < 8){ salt[i+3] = *(argv[SALT] + i); i++; } salt[i+3] = '\0'; i = 0; while(i < 11){ pass[i] = salt[i]; i++; } pass[i] = '$'; i = 0; while( i < 23){ pass[i+12] = *(argv[PASSWD] + i); i++; } pass[i+12] = '\0'; file = fopen(argv[DICTIONARY], "r"); while(1){ if(fgets(key,256,file) == NULL){ printf("it end of file\n"); return 0; } i = 0; while(key[i] != '\0'){ if(key[i] == '\n'){key[i] = '\0';} i++; } if((code = crypt(key, salt)) == NULL){ printf("crypt error\n"); return 0; } printf("code = %s\n", code); printf("key = %s\n", key); if(strcmp(pass, code) == 0){ printf("[ found ]\n"); printf("password is %s\n", key); return 0; } else{ printf("[ not found ]\n\n"); } } fclose(file); return 0; } -----  上記のソースコードをコンパイルして、次のような引数をとって実行します。 testは辞書ファイルとなるファイルです。N9rTnvmDがソルト、Z.e92/gt.SqCmUyy xHI6A0が暗号化されたキーです。ここでは「/etc/shadow」内のあるユーザーのパ スワードフィールドが「$1$N9rTnvmD$Z.e92/gt.SqCmUyyxHI6A0」であったとして、 これをクラックします。 ----- 実行例 defolos@glazheim:~/Desktop$ ./a.out test N9rTnvmD Z.e92/gt.SqCmUyyxHI6A0 code = $1$N9rTnvmD$HTOCZbrTwxdy.4HSpNHRA0 key = Jack [ not found ] code = $1$N9rTnvmD$6jFamv7jEuqDcqkomYXx31 key = test [ not found ] code = $1$N9rTnvmD$LXBqOZGaTLotR//T0.DgD. key = Yahoooooooo!!!!!! [ not found ] code = $1$N9rTnvmD$aDtpAyAr7IuXPA/2xMvqs1 key = Hello [ not found ] code = $1$N9rTnvmD$Z.e92/gt.SqCmUyyxHI6A0 key = newbie [ found ] password is newbie -----  パスワードクラックに成功していることが確認できました。パスワードはnewb ieであるとわかりました。用意した辞書ファイルは次のようなファイルです。5行 目にnewbieの文字があります。 ----- test Jack test Yahoooooooo!!!!!! Hello newbie apple computer root ----- ■0x03.) おわりに  本レポートで紹介したパスワードクラッカーは、最小限の機能しかもっていな い低速なパスワードクラッカーです。実際のところJhon The Ripperなどの有名な パスワードクラッカーとの速度の差は歴然としたものがあります。しかし、パス ワードクラッカーの動作原理を理解するという目的では、本レポートのパスワー ドクラッカーは十分に妥当性があると考えられます。  このレポートを通して原理を知ることの楽しさを伝えられれば幸いと存じます。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第9章: 基礎暗号学講座 〜 第8回 〜 --- 著者:IPUSIRON x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  こんばんは、IPUSIRONです。  今回のWBは合併号なので、2ヶ月ぶりのリリースとなります。ちょっと間隔が空 いたので、前回の内容(群・環・体から始まって、拡大体まで解説した)を忘れ た方もいるかもしれません。今回は暗号の花形ともいえる公開鍵暗号系の解説に なりますが、実は前回の内容を使っていないので、安心して読んでください。  それではさっそく解説に入ります。 ■0x02.) 公開鍵暗号系とは  暗号化のための鍵を公開して、復号のための鍵のみを秘密にする暗号系を公開 鍵暗号系(スキーム)と呼びます。公開鍵から秘密鍵を計算することは困難なの で、敵は暗号文を解読することはできません。 (図)http://security2600.sakura.ne.jp/main2/image1/p.jpg  公開鍵暗号系は応用面は広く、盛んに研究されている分野です。例えば、デジ タル署名や鍵配送などでも活躍しています。 ■0x03.) 共通鍵暗号系 vs 公開鍵暗号系  暗号化方式を大別すると共通鍵暗号系と公開鍵暗号系に分けることができます。 共通鍵暗号系についてはすでにWBでも紹介しました。どちらとも一長一短があり、 状況に応じて使い分けられます。一般的に言われている特徴を次に列挙します。 ●共通鍵暗号系 ・処理速度が速い。 ・鍵配送問題を解決するのが大変。 ・鍵の総数が多く、管理が大変。 ・量子コンピュータが実現しても、鍵長を2倍にすれば安全性を維持できる。 ●公開鍵暗号系 ・鍵配送問題を用意に解決できる。 ・鍵の総数が少なくてすむ。 ・NP-Pに属する問題を利用している。数論的問題、格子に関する問題、多項式の 零点問題などが含まれる。コンピュータと相性がよい数論的問題を利用している タイプの暗号が多いが、数論的問題は量子PCに弱い。 ■0x04.) 公開鍵暗号系の構成  公開鍵暗号系は次の3つのアルゴリズムから構成されます。 ・鍵生成アルゴリズム ・暗号化アルゴリズム ・復号アルゴリズム  公開鍵暗号系の仕様を定義しろといったら、この3つをきちんと述べる必要があ るわけです。アルゴリズムなので入出力を明確にし、復号アルゴリズムではアル ゴリズムの仕様通りに動けばきちんと暗号文から平文に変換できていることを確 かめる必要があります。 ●鍵生成アルゴリズムG  1^k(kはセキュリティパラメータ)を入力として、公開鍵pkと秘密鍵skを出力 します。 (図)http://security2600.sakura.ne.jp/main2/image1/p_g.jpg  公開鍵pkを公開情報としてします。正当な暗号文の受信者はもちろんのこと、 敵であっても読めるわけです。  秘密鍵skは暗号化アルゴリズムを使う者だけが利用し、秘密にしておきます。  1^kというのは1のkビット列であり、これをGに入力することで、2進数の桁を教 えていることになるわけです。なぜkを入力とせずに1^kを入力しているのかとい うと、アルゴリズムは一種のチューリングマシンと考えることができ、kが入力さ れてしまうとチューリングマシンは使用する数値の桁数はlog(k)と解釈してしま いまずいからです。k桁で考えたいわけなので、わざわざ1^kを入力しているわけ なのです。 ●暗号化アルゴリズムE  (暗号文の)送信者Aは、受信者Bの公開鍵pk_Bを用いて、平文mから暗号文cを 作ってから、それをBに送ります。 (図)http://security2600.sakura.ne.jp/main2/image1/p_e.jpg ●復号アルゴリズムD  Bは復号アルゴリズムDと自分の秘密鍵sk_Bを用いて、暗号文cから平文mに復号 します。 (図)http://security2600.sakura.ne.jp/main2/image1/p_d.jpg ■0x05.) 合同式  暗号の世界では合同式という概念がよく登場するので、合同式とは何か説明し ます。まず合同式の定義は次の通りです。 [定義] 整数a,bの差が0または正の整数Nの倍数であるとき、「a≡b (mod n)」と記述し、 aとbとはnを法として合同であるといい、このような関係式を合同式と呼びます。  この定義ですぐに理解できなければ、次に示す例により、合同式の世界に慣れ てもらえればと思います。私も具体例からその世界に慣れて、今では合同式の世 界が身近になった口です。  いくつか例を出しましょう。 ・5≡2 (mod 3) ・13≡6 (mod 7) ・4≡0 (mod 2) ・10≡1 (mod 3)  一番最初の例は、5を3で割ると2が余るという意味です。つまりmod 3という世 界では5も2もイコール(通常のイコール「=」と区別するために「≡」という記 号を使う)になるわけです。このイコールになることを「合同」といいます。  また、4番目の例を見るとmod 3の世界では10も1も合同になっています。もちろ ん4も7も1と合同になります。  2つの合同式があったとき(ただし、両方とも同じ法を持つとする)、左辺と右 辺をそれぞれ加えたり・掛けても合同は保持されます。きちんとそれを定理とし て書くと次のようになります。 [定理] 「a≡a' (mod n)」かつ「b≡b' (mod n)」のとき、次が成り立つ。 ・a±b≡a'±b' (mod n) ・ab≡a'b' (mod n)  定義からすぐに証明できますが、ここでは具体的な数値例で考えてみます。  まず「5≡2 (mod 3)」かつ「7≡1 (mod 3)」のときを考えます。このとき、足 し算・引き算・掛け算の3つの場合を考えてみます。 [1]足し算 (左辺)=5+7=12 (mod 3)≡0 (mod3) (右辺)=2+1=3 (mod 3)≡0 (mod 3)  よって、(左辺)=(右辺)が成り立っており、足し算における上記の定理の 妥当性がわかります。 [2]引き算 (左辺)=5-7=-2 (mod 3)≡1 (mod3) (右辺)=2-1=1 (mod 3)  よって、(左辺)=(右辺)が成り立っており、引き算における上記の定理の 妥当性がわかります。 [3]掛け算 (左辺)=5×7=35 (mod 3)≡2 (mod3) (右辺)=2×1=2 (mod 3)  よって、(左辺)=(右辺)が成り立っており、掛け算における上記の定理の 妥当性がわかります。  以上で合同式の基本的な計算は理解できたと思います。それでは次に、mod nの 世界を集合として考えてみましょう。 [定義] {0,…,n-1}の整数の集合をZn(Zは太文字、nは添え字)という記号で表されます。 即ち、次のような関係が成り立ちます。 Zn={0,…,n-1}  つまり、mod nの世界の要素たちは0,1,2,…,n-1のn個が存在するということで す。例えば、mod 4の世界は0,1,2,3という4つの要素が存在し、mod 4の世界全体 であるZ4は{0,1,2,3}の集合と同等です。  このZnの右肩に*(スター)が付くと、Znからnと素な要素だけを取り出した集 合になります(ただし、0は除外しておく)。きちんと定義すると次のようになり ます。 [定義] {1,…,n-1}のうち、nとの最大公約数が1(即ち、nと互いに素)である整数の集合 をZn^*で表します。つまり、次の関係式が成り立ちます。 Zn^*={x|1≦x≦n-1,gcd(x,n)=1} ←(nを法とする)既約剰余類  例えば、mod 6のときのZ6とZ6^*を考えてみましょう。  Z6のほうは簡単です。0からカウントしてn-1=6-1=5までのすべての整数を要素 とする集合であるわけなので、Z6={0,1,2,3,4,5}となります。  問題はZ6^*です。n=6と素である要素をZ6から抽出しましょう。各要素について きちんと見ていきます。 ・0⇒除外して考える。 ・1と6は互いに素⇒Z6^*の要素になる。 ・2と6は両方とも2で割れる⇒Z6^*の要素にならない。 ・3と6は両方とも3で割れる⇒Z6^*の要素にならない。 ・4と6は両方とも2で割れる⇒Z6^*の要素にならない。 ・5と6は互いに素⇒Z6^*の要素になる。 ・6と6は両方とも6で割れる⇒Z6^*の要素にならない。  よって、1と5だけがZ6^*の要素となります。よって、Z6^*={1,5}となります。  次はmod 7のときのZ7とZ7^*を考えてみてください。結果からいうと、Z7={0,1 ,2,3,4,5,6}、Z7^*={1,2,3,4,5,6}となります。各自確かめておいてください。  実はmod nのnの値が素数か素数じゃないかで、Zn^*が大きく異なります。nが素 数ならば、Zn^*はZnから単に0を除外したものになります。暗号では主にnが素数 であるときを考えていきます。 ■0x06.) 素数 [定義] 2以上の整数pが、1とp自身以外に約数を持たないときに、pを素数といいます。  例えば、2,3,5,7,11,13,…があります。余談ですが、100以下の整数のうち素数 は25個あるという事実は覚えておくと結構便利ですので、きちんと自分でカウン トしてみてください。  素数というのはとても魅力的な性質を持っており、多くの数学者を魅了してい ます。その中でもっとも基本となるフェルマーの小定理(フェルマーの大定理で はないので注意)を紹介します。このフェルマーの小定理は今後暗号の計算にお いてよく登場するので、知っておくとかなり後が楽です。いきなり定理の中身を 紹介してもつまらないので、ここでは数値実験から入っていきます。  例えばp=7として、a=1からp-1までの整数について、mod pでべき乗(何回も同 じ数値で掛け算していくこと)して、観察してみます。その結果を表にまとめる と次のようになります。 a | 1 | 2 | 3 | 4 | 5 | 6 ---------------------------- a^1 | 1 | 2 | 3 | 4 | 5 | 6 ---------------------------- a^2 | 1 | 4 | 2 | 2 | 4 | 1 ---------------------------- a^3 | 1 | 1 | 6 | 1 | 6 | 6 ---------------------------- a^4 | 1 | 2 | 4 | 4 | 2 | 1 ---------------------------- a^5 | 1 | 4 | 5 | 2 | 3 | 6 ---------------------------- a^6 | 1 | 1 | 1 | 1 | 1 | 1 ---------------------------- a^7 | 1 | 2 | 3 | 4 | 5 | 6 ----------------------------  まず表の見方を説明します。1行目はaの1〜6(=p-1=7-1)の値になり、縦にそ の値をどんどん掛けていくことになります。あくまでmod 7で考えていくので、す べての数値は6以下の値になっています。  次に、pが合成数のときを考えましょう。pといったら普通素数(prime)を意味 してしまうので、ここでは合成数であることを意味するためにhとしておきます。  例えば、合成数h=8として、mod hでべき乗して、観察してみます。 -------------------------------- a | 1 | 2 | 3 | 4 | 5 | 6 | 7 -------------------------------- a^1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 -------------------------------- a^2 | 1 | 4 | 1 | 0 | 1 | 4 | 1 -------------------------------- a^3 | 1 | 0 | 3 | 0 | 5 | 0 | 7 -------------------------------- a^4 | 1 | 0 | 1 | 0 | 1 | 0 | 1 -------------------------------- a^5 | 1 | 0 | 3 | 0 | 5 | 0 | 7 -------------------------------- a^6 | 1 | 0 | 1 | 0 | 1 | 0 | 1 -------------------------------- a^7 | 1 | 0 | 3 | 0 | 5 | 0 | 7 -------------------------------- a^8 | 1 | 0 | 1 | 0 | 1 | 0 | 1 --------------------------------  pが素数のときと異なり不規則になっています。0が登場するので、a^7の行でa の値に限らずすべてが1になるということはありえません。  さらに、p=5(素数)の整数について、mod pでべき乗して観察してみます。 -------------------- a | 1 | 2 | 3 | 4 -------------------- a^1 | 1 | 2 | 3 | 4 -------------------- a^2 | 1 | 4 | 4 | 1 -------------------- a^3 | 1 | 3 | 2 | 4 -------------------- a^4 | 1 | 1 | 1 | 1 -------------------- a^5 | 1 | 2 | 3 | 4 --------------------  上記のpが素数のときの2つの表から似たような結果が見えます。p=7の表ではa^6 の行がすべて1になっています。またp=5の表ではa^5の行がすべて1になっていま す。実はpが素数の場合、a^(p-1)のとき必ず1になるという結果が知られています。 これがフェルマーの小定理です。きちんと定理としてまとめると次のようになり ます。 [定理]フェルマーの小定理 p:素数、a∈Zp^* ⇒∀a;a^(p-1)≡1 (mod p)  ここでは証明については省きます。それよりも実際の使い方をマスターしてお きましょう。このフェルマーの小定理を使うとmod pのべき乗計算をするときに楽 にできるのです。  例えば、x≡123^45 (mod 13)を計算したいとします。 x ≡123^45 (mod 13) ≡6^45 (mod 13) (∵123≡6 (mod 13)) ≡6^(12×3+9) (mod 13) (∵フェルマーの小定理より「6^12≡1 (mod 13)」が 成り立つので、12でまとめておく) ≡{(6^12)^3}×(6^9) ≡(1^3)×(6^9) ←ここがポイント。1は何乗しても1になるから、値が小さくな っている。 ≡6^9 ≡5 (mod 13) ■0x07.) 位数と原始元  位数という概念の定義を紹介します。 [定義] p:素数、a∈Zp^*; a^x≡1 (mod p)となる最小の正整数xをaの位数といい、x=ord_p(a)と表します。  これも具体例を見たほうがわかるでしょう。p=5の表で考えてみます。これはす でに登場したので、それを再び表しておきます。 -------------------- a | 1 | 2 | 3 | 4 -------------------- a^1 | 1 | 2 | 3 | 4 -------------------- a^2 | 1 | 4 | 4 | 1 -------------------- a^3 | 1 | 3 | 2 | 4 -------------------- a^4 | 1 | 1 | 1 | 1 -------------------- a^5 | 1 | 2 | 3 | 4 --------------------  a=2のところを列で見ていくと、a^4のときに初めて1になっていることがわかり ます。よって、ord_5(2)=4と表記されます。  次にa=3のときも、a^4のときに初めて1になっていることがわかります。よって、 ord_5(3)=4と表記されます。  それでは、a=4のときはどうでしょうか。a^4のときに1になっているのは当然と して(フェルマーの小定理が成り立つから)、a^2のときに初めて1になっている ことがわかります。よって、ord_5(4)=2と表記されます。  位数とセットで知っておくべき概念として原始元というものがあります。これ は位数がp-1となるときの値aのことです。これも上記のp=5の例で考えてみましょ う。 ・ord_5(2)=4 ・ord_5(3)=4 ・ord_5(4)=2  原始元はp-1となる値aということなので、4(=p-1=5-1)となる値は2と3です( 括弧の中の値が原始元と覚えておけばよい)。つまり、Z5^*の原始元は2,3という ことになります。きちんと表で落ち着いて考えれば、難しくないと思います。  原始元の定義を理解したところで、それに関する定理をひとつ紹介します。 [定理] p:素数 g:Zp^*の原始元とする。 このとき、a_i=g^i (mod p)(i=0,…,p-2)とおくと、次が成り立つ。 {a0,a1,…,a_(p-2)}={1,2,…,p-1}  この定理の証明は省略するとして、再び具体例で考えてみましょう。p=5のとき ですでにわかっている事実を次に列挙します(ここまで読んできたならわかるは ず)。 ・p=5 ・Zp={0,1,2,3,4} ・Zp^*={1,2,3,4} ・原始元g∈Z5^* ・g=2,3 [1]g=2のとき ・a0≡g^0≡2^0≡1 (mod 5) ・a1≡g^1≡2^1≡2 (mod 5) ・a2≡g^2≡2^2≡4 (mod 5) ・a3≡g^3≡2^3≡8≡3 (mod 5)  よって、{a0,a1,a2,a3}={1,2,4,3}={1,2,3,4}が成り立っていることがわかりま す。 [2]g=3のとき ・a0≡g^0≡3^0≡1 (mod 5) ・a1≡g^1≡3^1≡3 (mod 5) ・a2≡g^2≡3^2≡4 (mod 5) ・a3≡g^3≡3^3≡27≡2 (mod 5)  よって、{a0,a1,a2,a3}={1,3,4,2}={1,2,3,4}が成り立っていることがわかりま す。  いずれにしても、gの値がいずれにしても定理が必ず成立することが確かめられ ました。  実はもっと位数とオイラー関数の関係、巡回群などと解説したいのですが、今 回の記事ではこのぐらいで十分なので止めておきます。 ■0x08.) 離散対数問題とElGamal暗号  公開鍵暗号系はたくさん存在します。例えば、RSA暗号・ElGamal(「エルガマ ル」と呼ぶ)暗号・Rabin暗号・逆数暗号などがあります。今回は特に仕様が簡単 なElGamal暗号について解説します。  ElGamal暗号とは離散対数問題の困難さに基づく暗号です。離散対数問題(DLP )とは、p,g,a=g^x (mod p)から、xを知る問題のことです。 (図)http://security2600.sakura.ne.jp/main2/image1/DLA.jpg ・p:素数 ・g:Zp^*の原始元 ・a:Zp^*の元 ・x:{0,1,…,p-2}のどれかになる  一般にpが大きくなるほどこの問題は困難になっていきます。  例えば、3≡2^x (mod 5)という合同式を満たすxを求めたいとします。xの取り 得る値は0,1,2,3のいずれかであるので、すべて代入して確かめればよいのです。 [1]x=0のとき、(右辺)=2^0=1≠(左辺) [2]x=1のとき、(右辺)=2^1=2≠(左辺) [3]x=2のとき、(右辺)=2^2=4≠(左辺) [4]x=3のとき、(右辺)=2^3=8≡3=(左辺)  よって、x=3であることがわかる。これはp=5と小さい値なので、総当りでも4つ の場合を調べればよかったわけですが、pの値が200桁ぐらいになってしまうと途 端に難しくなってきます。実際に今のところ離散対数問題を効率的に解くアルゴ リズムは見つかっていません。そのようなアルゴリズムは将来的にも見つからな いだろうという仮定を離散対数仮定(DLA)といいます。これから解説するElGam al暗号はこの離散対数仮定を前提としています。  やっと具体的な暗号の解説に入る準備ができました。それでは本題のElGamal暗 号について解説します。ElGamal暗号は公開鍵暗号系なので、次の3つのアルゴリ ズムから定義されます。 [1]鍵生成アルゴリズム  受信者Bは、まず大きな素数pとZp^*の原始元gを選びます。次に、x∈Z_(p-1)を ランダムに選び、y=g^x (mod p)を計算します。  受信者Bは公開鍵pk=(p,g,y)を送信者Aに公開し、秘密鍵sk=xは秘密に保持しま す。 [2]暗号化アルゴリズム  送信者Aは、受信者Bの公開鍵pkと平文m∈Zpを入力として、暗号文C=(c1,c2)を 次のように求めます。r∈Z_(p-1)をランダムに選び、c1,c2を次のように計算する。 ・c1=g^r (mod p) ・c2=my^r (mod p)  この2つのペアをセットとして、受信者Bに送ります。 [3]復号アルゴリズム  受信者Bは暗号文C=(c1,c2)を受信したら、次のように計算して平文mを復号しま す。 m=c2×c1^(p-1-x) (mod p)  以上の3つのアルゴリズムをまとめると次のようになる。このように図で表現す ると一目瞭然だろう。 (図)http://security2600.sakura.ne.jp/main2/image1/elgamal_alg.jpg  この段階で3つのアルゴリズムが定義されたわけだが、まず始めにやるべきこと は復号アルゴリズムで本当にmが正しく復号されているかを確認することです。こ れが確認できて初めて、アルゴリズム自体の正当性がいえます。つまり、c2×c1 ^(p-1-x) (mod p)という計算をして、式変形をして本当にmになるかどうかという こをと見ていきます。 c2×c1^(p-1-x) (mod p) =(my^r)×(g^{r(p-1-x)}) =(mg^rx)×(g^{r(p-1-x)}) (∵y=g^x) =mg^r(p-1) (mod p) ≡m×1^r (∵フェルマーの小定理より「g^(p-1)≡1 (mod p)」) ←ここがポ イント =m (mod p)  もっとElGamal暗号について知るために、色々な状況を想定してみましょう。ま ずElGamal暗号の暗号化アルゴリズムの中身を見てみると、乱数を生成して利用し ている。もし平文を暗号化する度にこの乱数が毎回ランダムに選ばれずに、常に 一定ならばどうなるでしょうか。これは現実でもありえる現象といえます。ElGa mal暗号のプログラム設計において、乱数を取り得る範囲を狭い場合、偶然次の暗 号化でも同じ乱数になってしまう可能性があるからです。  それでは、これをきちんと考えてみます。2つの平文m1,m2のそれぞれの暗号文 をc1={a1,b1},c2={a2,b2}とします。ここで、a1≡g^r、a2≡g^rが成り立ちます。 1回目の暗号化と2回目の暗号化で同じ乱数を使うので、これをrと固定しておくと、 a1=a2となります。つまり、c1={a,b1},c2={a,b2}となります。  m1=b1/yより、y^r≡b1/m1 (mod p)が成り立ちます。一方、y^r≡b2/m2 (mod p) が成り立ちます。よって、この2式より、b1/m1≡b2/m2が成り立ちます。  このとき、何らかの方法で、c1={a,b1}の平文m1を何らかの方法で奪われてしま うと、b1,b2は既知なので、m2までばれてしまいます。つまりこうした特殊な状況 下において、芋づる式に2回目の暗号化における平文まで敵にばれてしまうわけで す。これでは安全とはいえないわけです。  次に考えるべき状況は、pの値が小さい場合です。例えば、公開鍵がpk=(p,g,y) =(5,2,3)であるElGamal暗号を破ろうとする敵がいたとします。  すると、敵は「3≡2^x (mod 5)」を満たすxを解こうとします。xはZ_(p-1)=Z_ (5-1)=Z4={0,1,2,3}の集合の要素なので、この4つの数字について総当りで式を満 たすかどうか調べます。 ・2^x≡2^0≡1⇒満たさない ・2^x≡2^1≡2⇒満たさない ・2^x≡2^2≡4⇒満たさない ・2^x≡2^3≡8 (mod 5)≡3⇒満たす  よって、sk=x=3となります。つまり敵は総当りで離散対数問題を解いて、秘密 鍵が3だと絞り込めるわけです。  このとき、もし敵が暗号文c=(4,2)を盗聴したとしたら、秘密鍵sk=3を用いて平 文mを求めることができます。 m ≡c2c1^(p-1-x) (mod p) ≡2×4^(5-1-3) (mod 5) ≡2×4^1 ≡8 ≡3  よって、暗号文cの平文mは3と計算できます。以上のことから、pの値は大きく 設定しなければならないということがわかります。 ■0x09.) 終わりに  普通は公開鍵暗号系といえばRSA暗号などが最初に来るものですが、今回はあえ てElGamal暗号を解説しました。それはRSA暗号よりもElGamal暗号のほうが安全で あるということもありますが、合同式と素数という重要な数学的概念をちょうど この機会に解説と思ったからです。RSA暗号に関しては後ほどきちんと解説します ので、安心してください。  次回はDH鍵配送について解説します。実はElGamal暗号とDH鍵配送は面白い関係 性も持っており、そのためこのようなあえて変則的な流れにしています。  では、また来月会いましょう。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第10章:お知らせ --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○Wizard Bible(http://wizardbible.org/)では随時、執筆ライターを募集して います。  扱う内容のテーマは広義での「under ground」です。例えばハッキングからサ リンガスの合成法などと幅広い内容を考えています。また特殊な職業や趣味を持 った方のレクチャーなども含まれます。  一回きりでも構いません。また必ず毎回連載する義務もありませんので、でき る範囲で構いません。気軽に声をかけてください。 ○Kenji AikoさんがQ&Aを作ってくれました。初めて参加する人でもわかりやすく 書かれていますので、参考にしてください。 http://wizardbible.org/wbQandA.html ○Wizard Bibleに参加希望の方は気軽にメール(ipusiron@gmail.com)ください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第11章:著者プロフィール --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■金床 ●Job: プログラマー ●Web: http://guardian.jumperz.net/, http://www.jumperz.net/ ●Mail: anvil@jumperz.net ●Comment:  先月の末の時点ではネタがなく「WB32は落とした」と思っていたのですが、合 併号になり締め切りが3月末になったおかげでこうしてノコノコと姿を現しており ます。そういえばもうしばらく経ちましたが、mixiやめました。おかげで時間が できて、原稿も順調に進んでおります。もう数日でいよいよ入稿を開始します。 編集のまどさんが締め切りを急かすときだけビジネスライクな口調になるのが怖 いです。 ●5年後のインターネットはどうなっているのか?  オールドタイプでしかもひねくれているので、「5年後どうなっているか?」と きかれると「今とそんなに変わんねんじゃね?」と脊髄反射します。が、予想を 以下に列挙する。 ・ウェブアプリケーションの増加と機能の増強により、XSSやCSRFを利用する攻撃 が激増し、また深刻な被害が多数発生する ・それに引きづられて「ITセキュリティ」というキーワードはもはや「ウェブア プリのセキュリティ」と同義となる ・ウェブアプリのセキュリティを扱う含む本が次々にリリースされ、どれも売り 上げを伸ばす ・現在執筆中の某書がベストセラーに。海外で18カ国語に翻訳され、印税がなだ れ込む ・貯金が貯まったため、リタイア。南の島で毎日朝から晩まで釣りをする生活に  途中から予想じゃなくて願望になってますが気にしない。 ■sourcerian ●Job: オサーン ●Comment:  日本ファルコムの名作sorcerianを文字って命名しました。so[u]rcerianなので お間違い無きよう。ええ、おっさんですとも。 ●5年後のインターネットはどうなっているのか?  2011年にアナログ放送が終了。しかし、6万円の地デジ対応テレビを買うぐらい なら6万円のPCを買ってインターネット申し込む人が多数で、インターネットおよ びブロードバンドの普及に拍車がかかるがテレビの普及率が伸び悩む。2012年、 各局がインターネットテレビに参入するが、受信料を徴収できない狗HNKが死亡。  なんてことになってたら楽しいですね。その頃には対応テレビも安くなってるで しょうが。 ■エクセル小林 ●Job: Student ●Web: http://erinn.jugem.jp/ ●Mail: wlfen.p@gmail.com ●Team(Group): N/A ●Comment:  どうも、一方的にはじめましてこんばんわ。エクセル小林です。  いやー、冬はキツイですね。ワタシは手汗というものを全然掻かないので、す ぐに手がシワシワのガサガサになってしまうのです。まぁ乳液つければいい話な んですが、どーもあの油っぽさが苦手でダメ。あー何かいい方法ないかな? さて、Fate/stay nightのPS2版は一体いつ出るんだろうか?本当は去年の12月に 発売だったのに…。早く出てくれー。 ●5年後のインターネット:  Googleがネット上のサービスのほとんどをやってるんじゃないでしょうか?(笑 ■Narusase ●Job: Student ●Web: (裏)雑学の博物館(http://k-o-m.hp.infoseek.co.jp/) Narusaseの日記 -ハニポってどうよ?(仮)-(http://d.hatena.ne.jp/narusase/) ●Mail: narusase@mcn.ne.jp ●Team(Group): N/A ●Comment:  こんにちわ、Narusase(ナルサス)です。  今回も、締め切り日間近に焦って書き上げました。…回を追うごとに内容が薄 くなっているような気がして読んでくださっている方々には申し訳がありません。 今回はHIDSもどきの自作について書きました、単なる標準的なコマンドの組み合 わせでも色々できるということのひとつの例として見ていただければ幸いです。 今頃になって気がついたのですが、今回で(途中中断もありましたが)連載も12 回を数え、ちょうど1年分になりました。  これも、読んでくださっているみなさんと、我らが編集長IPSIRONさんのおかげ です。こんなだめだめな文書につきあってくださるみなさんに改めてお礼をいわ せていただきます。  サイトのほうは全然更新してませんが、ヘタレな文章と、未熟な技術、ヘボい プログラムを紹介するサイトということで、暇があったらあら探しでもしてみて ください。誤植とかミスとかはメールでもしてくだされば、こっそり修正しとき ます(笑。ブログの方はほぼ毎日更新で、技術ネタから投資ネタ、どうでもいい 独り言などあんまり役に立たない情報をそろえてます。 ●5年後のインターネットはどうなっているのか?  まず、考えられるのはIPv6への移行が真剣に話され、一部では移行が始まって いるということですね。そのころにはすでにIPv4の枯渇が始まっており、IPv6へ の移行に伴い色々と大変な状態になっているような気がします。例えば、ARPスプ ーフィングのような現在のIPv4の技術をハックした様な技術は使えなくなるかも 知れません。  もう一つ考えられることとしては、インターネットを介した犯罪の増加と、そ のことを理由とした規制の強化が考えられます。すでに、スパム対策としてOP25 Bの様なISP側での規制や、著作権法の拡大解釈や不正アクセス禁止法のような政 治的な規制などが始まっています。今後はさらなる規制が行われることはまず間 違いないでしょう。  また、法解釈の話としてはフォレンジック方面で動きがあるかと思います。… というのも、現在耐震強度偽装問題でパソコン内の保存書類についての証拠性に ついて騒がれており、裁判所の判決がそのころには出てきており、法的な解釈が 定まっているのではないかと思います。 ■結城 瀬名 ●Job:Student ●Web:None ●Mail:sena-yuki@wak.bbiq.jp ●Team(Group):None ●Comment:  初めまして、結城瀬名と申します。  これまで長い間「読む側」でしたが、今回初めて「書く側」に回らせていただ きました。ついこの間やっと2年間の浪人生活から開放され、4月から晴れて情報 系の大学生になることができそうです。  これからも定期的に記事を投稿していけたらと思いますので是非是非よろしく お願いいたします。 ●5年後のインターネットはどうなっているのか?  全然想像つきませんね。どうなっているんでしょうね…。 ■Defolos ●Job: Student ●Web: http://ruffnex.oc.to/defolos/ ●Mail: defolos@ruffnex.oc.to ●Team(Group): none ●Comment:  こんにちは、Defolosです。  今回は番外編ということで、プログラミングの練習と言うもっともらしい題名 にしていますが、実際は時間がなくて以前書いたソースを流用しただけです。い い加減なレポートになってしまって申し訳なく思います。次回はしっかりとした レポートを提出するつもりです。 ●5年後のインターネットはどうなっているのか?  願望としては現実世界とのリンクが実現できていることでしょうか。インター ネットが世界の脳となる前段階として、現実世界の情報がインターネットという 仮想世界に反映されるようになっているとよいですね。 ■IPUSIRON ●Job:Student ●Web:http://akademeia.info/ ●Mail:ipusiron@gmail.com ●Team(Group):N/A ●Comment:  もう新学期の季節ですね。私ももう修士2年なので、そろそろ新しい発見をした いものです。そのために日々論文を読み漁る日々を送っています。単に読むだけ でなく、きちんと頭を使って行間を埋めながら、新しい着想に対して肉付けして いきたいと思っています。 ●5年後のインターネットはどうなっているのか?  ソフトウェアとハードウェアがそれぞれ利点を取り入れたアタックが、数年前 から登場し始めてきました。今後はそれがもっと顕著化していくはずです。  例えば、IPv6化が進めば、ハードウェア(家電なども含む)もどんどんネット ワークと接続されて、グローバルIPアドレスが割り振られ、その結果としてアタ ックの被害がネット以外にも拡がるでしょう。  また、組み込みOSを実装しているようなハードウェアは現在も多くの場面で使 われていますが、最近ではこの組み込みOSにWindows系を用いるところもあります。 しかも、マイコンが載っている家電は一般にセキュリティアップデートを前提と していません。つまりセキュリティホールを残したままの家電がごろごろしてい るのです。それが家庭に置いてあるだけならよいのですが、ネットに繋がるとし たら、ワームの餌食になることは目に見えているでしょう。  逆に考えれば、逆境はチャンスともいえます。今後は組み込みOSにもセキュリ ティを考えていこうとするセキュリティ会社も登場するでしょう。