**** Sun Sep 2 05:51:25 2007 からログ記録開始 9月 02 05:51:25 * Now talking on #lykeion 9月 02 05:51:32 Defolos こんばんはー 9月 02 05:51:44 be-be- こんばんは 9月 01 21:01:09 Defolos さて、そろそろ9時ですね 9月 01 21:03:38 wahiko はい 9月 01 21:04:06 Defolos では、はじめましょうか 9月 01 21:04:07 be-be- もう、9時になりましたね 9月 01 21:04:43 Defolos 準備OKでしょうか 9月 01 21:04:55 be-be- 大丈夫ですw 9月 01 21:05:05 Defolos それでは宜しくお願いします 9月 01 21:05:20 wahiko よろしくおねがいします 9月 01 21:05:26 Defolos まず、配布資料をお開きください 9月 01 21:05:31 Defolos 資料はhttp://ruffnex.oc.to/defolos/exploiting/exploiting_practice/data/exploiting-02.htmlに 9月 01 21:05:33 be-be- よろしくおねがいします 9月 01 21:05:35 Defolos アップロードしておきました 9月 01 21:06:03 Defolos 今回の目標は 9月 01 21:06:24 Defolos シェルコードの作成方法を知ることに重点を置きました 9月 01 21:06:54 Defolos 実際にバリバリとプログラムを書くのは次回になります 9月 01 21:07:57 Defolos ペイロードの作成の前にぺいロードについて復習します 9月 01 21:08:22 Defolos ぺイロードとはアタック対象マシン上で動かしたいプログラムのことで 9月 01 21:09:05 Defolos 通常はコントロール権を得るためにシェルを起動するプログラムとすることが多いです 9月 01 21:09:43 Defolos シェルを起動するぺイロードはシェルコードやエッグと呼ばれますが 9月 01 21:10:05 Defolos これ以外にも様々な動作を行うぺいロードを記述する事ができます 9月 01 21:10:17 Defolos あ、 9月 01 21:10:20 wahiko はい 9月 01 21:10:40 Defolos 今漢字変換にcannaを使ってるので 9月 01 21:10:51 Defolos ちょっと変な変換になってる事があるかもしれませんが 9月 01 21:11:07 Defolos その辺は脳内補完していただけると嬉しいです 9月 01 21:11:37 be-be- だいじょうぶですw 9月 01 21:11:45 Defolos 読みづらくて申し訳ありません 9月 01 21:12:12 Defolos それで、ぺいロードはアセンブリ言語で記述する事が多いですので 9月 01 21:12:37 Defolos ぺいロードの記述にはアセンブリ言語を学んでおく必要があります 9月 01 21:13:06 Defolos さらに、ぺいロードの作成には独自のプログラミングスタイルがありますので 9月 01 21:13:21 Defolos ただアセンブリ言語を知っているだけでは作成できません 9月 01 21:13:51 Defolos ぺいロード化に伴って必要となる種々のテクニックを知っている必要があるのです 9月 01 21:14:11 Defolos 今回はこのテクニックを知る事を第一の目標としています 9月 01 21:14:38 Defolos それでは次に進みます 9月 01 21:14:55 Defolos ぺいロードの作成にも一定の流れがあります 9月 01 21:15:11 wahiko はい 9月 01 21:15:27 Defolos まずはアタック対象のマシン上でどんな動作を行いたいかを決定します 9月 01 21:16:06 Defolos これが決定できたなら、アタック対象がどんなOSを使っているのかを調べます 9月 01 21:16:19 Defolos その理由については、後で説明します 9月 01 21:16:49 Defolos 次に実際にアセンブリ言語や機械語でぺいロードを記述します 9月 01 21:17:23 Defolos アセンブリで作った場合はこれをコンパイルして 9月 01 21:17:44 Defolos 16進数エディタで開いて機械語に翻訳されたプログラムを得ます 9月 01 21:17:49 Defolos ちなみに 9月 01 21:18:04 Defolos 16進数エディタとは日本語的にいえばバイナリエディタのことです 9月 01 21:18:32 Defolos 海外ではバイナリエディタとは呼ばずに16進数エディタと言うことが多いそうです 9月 01 21:19:08 Defolos で、機械語のプログラムを得た後に 9月 01 21:19:16 Defolos ちゃんと動くのかどうかをテストします 9月 01 21:19:42 Defolos この一連の流れに従ってぺいロードの作成を行います 9月 01 21:20:01 Defolos ここまではよろしいでしょうか 9月 01 21:20:13 be-be- はい、大丈夫です 9月 01 21:20:40 Defolos では次に、アセンブリ言語に付いての復習。。。というか捕捉を行います 9月 01 21:20:41 wahiko はい 9月 01 21:21:29 Defolos アセンブリは機械語に近い細やかな操作ができる割に、人が読んで理解しやすい言語です 9月 01 21:21:44 Defolos まぁ、ぱっとみたらわけわからないんですけれどね^^; 9月 01 21:22:40 Defolos 機械語と1対1に命令が対応していて細かい操作指定ができるため、ぺいロードの作成ではこのアセンブリを用います 9月 01 21:23:19 Defolos アセンブリ言語にもいくつかの派閥があるわけですが、その中でGNUがバックに付いている 9月 01 21:23:31 Defolos GASを用いる事にします 9月 01 21:24:03 Defolos アセンブリにはAT&T形式とINTEL形式の2つに大別できますが 9月 01 21:24:50 Defolos GASはAT&T形式を採用していますので「命令、Xに、Yを」のように記述します 9月 01 21:25:11 Defolos INTEL形式だと「命令、Xを、Yに」という書き方になります 9月 01 21:25:28 Defolos 両者の違いはこのXとYの順番の違いだけですので 9月 01 21:25:43 Defolos 片方に精通できればもう片方もすぐ覚えられると思います 9月 01 21:26:02 Defolos INTELはどちらかと言うと英語の語順ですね 9月 01 21:26:41 Defolos このあたりの基本的な所は第0回その2を参照ください 9月 01 21:27:21 Defolos アセンブリの命令として今回多用するのは資料に挙げたものだけです 9月 01 21:27:47 Defolos 今回はこれ以外の命令は使用しなくても大丈夫だと思います 9月 01 21:28:27 Defolos 命令の種類に関しては必要に応じて適宜参照してもらうこととし、次の下位互換命令について説明します 9月 01 21:28:50 Defolos コンピュータは昔、8ビットで動いていました 9月 01 21:29:48 Defolos 8ビットコンピュータ等と呼ばれていたものがそうなのですが、これはメモリのアドレスを8ビットを使って表現するということです 9月 01 21:30:21 wahiko はい 9月 01 21:30:36 Defolos 8ビットなので、つまり、最大256の値しか保持できないということになりますね 9月 01 21:31:16 Defolos これだとさすがにメモリ不足ですので、この後16ビットや32ビットのコンピュータが出現しました 9月 01 21:31:37 Defolos 今現在は64ビットのコンピュータが一般市場に売られていますが、主流は32ビットです 9月 01 21:32:37 Defolos それで、32ビットになった今でも、昔のプログラムが動くように(下位互換性を保ため)8ビットの命令が残っています 9月 01 21:33:12 Defolos 32ビットのコンピュータではレジスタは32ビットの値を保持できるわけですが 9月 01 21:34:18 Defolos この下位互換命令を使うとレジスタ全体の32ビットのうち、下位8ビットのみをコピーしたり減算したりできます 9月 01 21:35:08 Defolos 例えばmovという、移動命令を32ビット用に記述するとmovlとなります 9月 01 21:35:25 Defolos 一方、これを8ビット用に記述すればmovbとなります 9月 01 21:35:38 Defolos movlでは32ビットまるまる移動させますが 9月 01 21:35:53 Defolos movbでは下位の8ビットのみを移動させます 9月 01 21:37:03 Defolos 例えば0000 01010 0000 0000 0000 省略 01010 1111 という値がレジスタに格納されていたとします 9月 01 21:37:17 wahiko はい 9月 01 21:37:26 Defolos movlでは0000 01010 0000 0000 0000 省略 01010 1111が移動対象ですが 9月 01 21:37:49 Defolos movbでは下位8ビットの01010 1111だけが移動対象です 9月 01 21:38:06 Defolos これと同じように、レジスタにも下位互換の仕組みがあります 9月 01 21:39:04 Defolos 32ビット全てを参照領域とする32ビット用レジスタはeaxのようにきじゅつします 9月 01 21:39:51 Defolos 8ビットの場合は下位8ビットを参照するalが存在します 9月 01 21:40:10 Defolos 図1を参照ください 9月 01 21:41:10 Defolos 実際のプログラミングの段階では、32ビット命令を使っておきながら16ビットレジスタに格納するような記述のしかたはしませんので 9月 01 21:41:41 Defolos そこのサンプルにもあるように命令とレジスタは基本的に合わせて使います 9月 01 21:42:09 Defolos 32ビットで操作する時はmovlにeaxを指定するというように 9月 01 21:42:28 Defolos 命令とレジスタで矛盾が起きないようにします 9月 01 21:42:48 Defolos ここまでは大丈夫でしょうか 9月 01 21:43:07 be-be- 大丈夫ですよ 9月 01 21:43:11 wahiko はい 9月 01 21:43:59 Defolos では次に、作成の流れで始めに出てきた、要求の決定について述べます 9月 01 21:44:40 Defolos ハッキングでも何でも、「何をやりたい」という要求が必ず存在しています 9月 01 21:45:16 Defolos 在庫をうまく把握したいから在庫管理システムを開発するというように 9月 01 21:45:39 Defolos 他人のシステムを乗っ取りたいからハッキングする 9月 01 21:45:52 Defolos などの要求がハッキングにも存在します 9月 01 21:46:02 Defolos この要求と言うのは人それぞれだと思います 9月 01 21:46:49 Defolos 要求という目的に合わせてぺいロードも適宜変えていく必要があります 9月 01 21:47:14 Defolos まずは何を行いたいのかと言う要求をしっかりさせることが大切ですね 9月 01 21:47:30 wahiko ですよね 9月 01 21:47:34 Defolos 例えば、システムのコントロール権を得たいとか 9月 01 21:47:40 Defolos 人に迷惑をかけたいとか 9月 01 21:47:59 Defolos そのような要求を持つ所からはじめるべきです 9月 01 21:48:27 Defolos まぁ、後者の要求は世間一般では否定的にみられるでしょうが///^^; 9月 01 21:48:55 Defolos このような要求の決定はシステム開発でもかなり重要な位置にあります 9月 01 21:49:14 Defolos 要求があやふやだと出来上がるものもぐにゃぐにゃのものになってしまいますので 9月 01 21:49:23 Defolos 注意しましょう 9月 01 21:49:53 Defolos 今回は私達はコントロール権を得る練習をしていますので 9月 01 21:50:21 Defolos 一番始めに挙げたシステムのコントロール権を得ることを要求とします 9月 01 21:50:44 Defolos 次に、要求が決まりましたら要求から仕様を導きます 9月 01 21:51:02 Defolos よく要求と仕様はごっちゃになりがちなのですが 9月 01 21:52:03 Defolos 要求は「 ̄したい」というような望みであって、仕様は「 ̄するためにXXする」というような、要求を満たす手段のことを指します 9月 01 21:52:30 Defolos つまり、仕様は要求があって始めて成り立つものであって、仕様だけが何の理由も無しに存在できないということです 9月 01 21:53:01 Defolos では先程の要求の例の仕様を考えますと 9月 01 21:53:24 Defolos コントロール権を得たいのであればROOT権限でシェルを起動すれば良いですね 9月 01 21:54:09 Defolos ファイルをかいざんして迷惑をかけたいのであれば重要なシステムファイルをぐちゃぐちゃに上書きすれば良い事になります 9月 01 21:54:37 Defolos では特定のグループに加入したいという要求の場合はどうすれば良いでしょうか 9月 01 21:54:54 Defolos このグループはlinuxのアカウントグループの事ですが 9月 01 21:55:29 Defolos グループに自分のアカウントを追加するシェルコマンドを実行できれば良いですね 9月 01 21:56:02 Defolos このように、要求を満たすには何をすれば満たされるのかを考えます 9月 01 21:56:30 Defolos 後は考えた通りにプログラミングして行けば、要求を満たすぺいロードが出来上がるというわけです 9月 01 21:57:11 Defolos あ、質問は適宜して頂きたく思います 9月 01 21:57:19 Defolos ここまでは大丈夫でしょうか 9月 01 21:57:28 wahiko はい 9月 01 21:57:59 Defolos では次に進みますね 9月 01 21:58:21 Defolos 先程、アタック対象のOSを調べる必要があると述べましたが 9月 01 21:58:46 Defolos その理由はOSによってシステムコールの仕様が異なるからです 9月 01 21:59:42 Defolos 例えば、linuxではwriteというシステムコールの番号が0番なのに、windowsでは21番になっていると言う可能性もあります 9月 01 22:00:20 Defolos また、linuxではeaxにシステムコール番号、ebxから引数が始まるというルールになっていますが 9月 01 22:01:12 Defolos BSDではeaxにシステムコール番号、引数は全てスタックに積んだ順にというルールになっていたいりします 9月 01 22:01:40 Defolos このようなシステムコールに関する仕様の違いが存在しているので、OSによってぺいロードを書き換える必要があるのです 9月 01 22:02:17 Defolos OSにはたくさんの種類がありますが、有名かつ大きなシェアを持っている種類は4種類あります 9月 01 22:02:40 Defolos 一つはマイクロソフト社のWindowsです 9月 01 22:03:05 Defolos もうひとつはUNIXクローンのOSであるLinux系OSです 9月 01 22:03:08 wahiko はい 9月 01 22:03:35 Defolos 残りの2つは関係性が強いのですが 9月 01 22:03:51 Defolos BSD系OSとSolarisです 9月 01 22:04:02 wahiko Macはないのですか? 9月 01 22:04:14 wahiko Unixベースですが 9月 01 22:04:23 Defolos あ、MACについては考慮不足でした 9月 01 22:04:39 Defolos MACはあまりサーバ機として用いられないので 9月 01 22:04:44 be-be- BSD系に近いのではないのでしょうか? 9月 01 22:04:53 Defolos 紹介している書籍が無かったのですよね^^; 9月 01 22:05:24 Defolos システムコールの仕様によってどれに分類されるかが変わってくるのですが 9月 01 22:05:50 Defolos これについては調べておきます 9月 01 22:05:54 Defolos 申し訳ありません 9月 01 22:06:18 wahiko いえいえ(^^; 9月 01 22:06:44 Defolos それで、このようにOSによってぺいロードを書き分ける必要があるので 9月 01 22:07:11 Defolos ぺいロードから自作するハッカーはアタック対象のOSが何なのか知る必要があります 9月 01 22:07:42 Defolos 全く独自のOSを使っているのだとしたら、システムコールの仕様までも調べる必要が出て来てしまうのですけれどね 9月 01 22:08:18 Defolos 個人的見解ではSolaris系が一番ややこしいように思います 9月 01 22:08:46 Defolos 資料もないですし、結構なテクニックを使うようです。TT 9月 01 22:08:48 be-be- Solaris系は特殊なんですか? 9月 01 22:08:53 Defolos はい 9月 01 22:09:00 be-be- なるほど 9月 01 22:09:16 Defolos 普通に書いてると、必ずNULLバイト(後述します)がコードに含まれてしまうのですよ 9月 01 22:09:44 Defolos これを防ぐためにプログラムをリアルタイムに書き換えるテクニックを用いないと行けないみたいです 9月 01 22:10:04 Defolos それで、ですね 9月 01 22:10:17 Defolos アタック対象のOSを知る手段なのですが 9月 01 22:10:22 Defolos たくさんあります 9月 01 22:10:46 Defolos ポートスキャンだとか、管理者をだまして聞き出すだとか 9月 01 22:11:13 Defolos これらはハッキングの範疇に含まれるものではあるのですが 9月 01 22:11:40 Defolos エクスプロイティングという範疇からは少し外れてしまいますので、他のドキュメントを参照してもらうことにします 9月 01 22:12:18 Defolos この実習の中ではLinux系のDebianを利用しているということが分かっているので 9月 01 22:12:23 Defolos この手順は省きます 9月 01 22:12:54 Defolos では次に、実際にぺいロードを作成する練習をしましょう 9月 01 22:13:10 Defolos 今回要求はぺいロードのテストなので 9月 01 22:13:31 wahiko はい 9月 01 22:13:39 Defolos プログラムのテストとしては非常に有名なHelloWorldをやってみましょう 9月 01 22:14:05 Defolos アセンブリでの例は第0回その2で書いていますので 9月 01 22:14:20 Defolos それを流用してもらうか、資料に載せたコードをお使いください 9月 01 22:14:50 Defolos 実はこのコード、あまり行儀のいいものとは言えません 9月 01 22:15:17 Defolos プログラムが全て終った事を示すexitシステムコールを呼び出していないためなのですが 9月 01 22:15:43 Defolos ここで例題をやってみましょう 9月 01 22:16:13 Defolos これにexitシステムコールを追加して、この不良プログラムを更生しましょう 9月 01 22:16:33 Defolos exitでは0を引数にとれば正常終了した事を示します 9月 01 22:19:08 Defolos あ 9月 01 22:19:11 Defolos ごめんなさい 9月 01 22:19:30 Defolos システムコール番号の一覧は/usr/src/linux-2.4.18/include/asm/unistd.hにありますので 9月 01 22:19:34 Defolos これを参照してください 9月 01 22:21:32 be-be- これは以前と同じようにログインして行うのでしょうか? 9月 01 22:21:41 Defolos はい 9月 01 22:21:47 Defolos SSHでログインしてください 9月 01 22:21:56 be-be- サーバ名を教えていただけませんか? 9月 01 22:22:53 Defolos えと 9月 01 22:23:01 Defolos glazheim.mydns.jp 9月 01 22:23:04 Defolos です 9月 01 22:23:48 be-be- ありがとうございます 9月 01 22:24:02 Defolos ログイン名はSASSNSに登録してもらった名前のローマ字小文字ですので 9月 01 22:24:49 be-be- すいませんパスワード忘れてしまいました。 9月 01 22:25:02 be-be- アカウントはkazuiです 9月 01 22:25:10 Defolos 以前一度パスワードを変えましたか? 9月 01 22:25:22 be-be- はい 9月 01 22:25:27 Defolos Σ 9月 01 22:25:36 Defolos それだと分からないのですが/// 9月 01 22:25:57 be-be- 少し思い出してみます 9月 01 22:26:22 be-be- 平行して自分のマシンでプログラミングしてみます 9月 01 22:26:50 Defolos お願いします ̄ 9月 01 22:28:07 Defolos exitのシステムコール番号は1です 9月 01 22:28:24 Defolos 先程指定したファイルですが、どうやら場所が変わっているみたいですので 9月 01 22:28:51 Defolos 必要となるシステムコールは番号を言う事にします^^; 9月 01 22:28:55 wahiko USR/SRCにフォルダが見当たりません 9月 01 22:29:47 Defolos はい、どうやらこのシステムは違う場所に保存されているようでして 9月 01 22:30:17 Defolos とりあえずの処置なのですが、システムコール番号をお知らせしますので 9月 01 22:30:28 Defolos それでプログラミングして頂きたく思います 9月 01 22:30:46 Defolos exitの場合は番号が1ですので、それを指定してください 9月 01 22:33:07 wahiko objdumpで書いたとおりコマンドを打ってみたのですけど 9月 01 22:33:15 wahiko 確認するのはどうしたらいいですか? 9月 01 22:34:08 Defolos objdumpからなにか出力されませんでしたか? 9月 01 22:34:18 wahiko 確かめてみます 9月 01 22:34:31 Defolos あ、先にコンパイルが必要なので 9月 01 22:34:46 Defolos gcc hello.sのようにしてコンパイルしておいてくださいね 9月 01 22:36:01 be-be- ログインできました 9月 01 22:36:08 be-be- ご迷惑をおかけしました 9月 01 22:36:16 Defolos あ、でしたら 9月 01 22:36:26 Defolos パスワードをもう一度変えて頂けますか?^^; 9月 01 22:36:37 be-be- はい 9月 01 22:41:10 Defolos あれ?objdumpで何も表示されない? 9月 01 22:41:31 wahiko viで編集したhello.sをgcc hello.sでコンパイルしましたa.outがアセンブラですね 9月 01 22:41:40 be-be- …あれ、ログインした時のパスワードで変更できなくなっています… 9月 01 22:42:00 Defolos ごめんなさい、パスワードはnewbieです 9月 01 22:42:12 Defolos さっきちょうど書き換えちゃったところでして/// 9月 01 22:42:35 Defolos a.outが機械語に翻訳されたプログラムですね 9月 01 22:42:36 be-be- すいません、お手数をおかけしまして 9月 01 22:42:54 Defolos これを16進数で表示するために16進エディタを使ってるのですが 9月 01 22:43:34 Defolos おかしいなぁ。。。 9月 01 22:44:50 wahiko 16 9月 01 22:45:26 wahiko 16進数で表示するにはhtmlに書いてあるコマンドを入力すればいいのですね 9月 01 22:45:32 Defolos はい 9月 01 22:45:43 Defolos objdump -d a.out で表示できるはずなのですが 9月 01 22:45:53 wahiko こちらでも試してみます 9月 01 22:46:20 wahiko 出ました 9月 01 22:46:26 Defolos でましたか? 9月 01 22:46:52 Defolos あ、一応出てますね 9月 01 22:47:12 Defolos be-be-さんもできてますでしょうか 9月 01 22:47:21 wahiko はいアドレス番地 16進数 命令 テキスト の順で出ました 9月 01 22:47:21 be-be- はい今出ました 9月 01 22:47:31 Defolos では一旦ここで説明しますね 9月 01 22:47:36 wahiko は 9月 01 22:47:38 wahiko はい 9月 01 22:48:07 Defolos これは本来2進数、つまり機械語で表されたものを16進数に置き換えているものなのですが 9月 01 22:48:28 Defolos ちょうど真中の部分がそれです 9月 01 22:48:38 Defolos 8048254: 55 push %ebp 9月 01 22:48:52 Defolos のようなものが延々と続いていると思います 9月 01 22:49:06 Defolos 55とかの部分を抜きだして 9月 01 22:49:27 Defolos 前回使った挿入ベクター生成プログラムのぺいロードとしてセットすれば 9月 01 22:49:44 Defolos hellowordlがroot権限で表示されるはずです 9月 01 22:49:47 Defolos ただし、 9月 01 22:50:08 Defolos 今回作ったhello.sはぺいロード化にともなうテクニックを一切使用していないため 9月 01 22:50:14 Defolos 正常に動作しません 9月 01 22:50:51 Defolos 手順としては先程のように、プログラミング、コンパイル、16進エディタのようにして 9月 01 22:51:01 Defolos 16進数で記述されたぺいロードを得ます 9月 01 22:51:21 Defolos この16進で書かれたぺいロードの事をバイトコードと呼びます 9月 01 22:51:36 Defolos このバイトコードのどこがダメなのか解説して行きましょう 9月 01 22:51:46 Defolos まず、NULLバイトの存在です 9月 01 22:52:00 Defolos NULLバイトとは00のことです 9月 01 22:52:15 Defolos 先程のobjdumpの出力を見てください 9月 01 22:52:38 Defolos とくに、start戸書かれた部分から 9月 01 22:52:54 Defolos 90が連発する部分までの間を御覧ください 9月 01 22:53:24 wahiko はい 9月 01 22:53:35 Defolos 結構な数で00が含まれている事が分かりまsね 9月 01 22:54:18 Defolos 80482b8: e8 00 00 00 00 call 80482bd 9月 01 22:54:18 Defolos 80482bd: 5b pop %ebx 9月 01 22:54:18 Defolos 80482be: 81 c3 c7 12 00 00 add $0x12c7,%ebx 9月 01 22:54:18 Defolos 80482c4: 50 push %eax 9月 01 22:54:18 Defolos 80482c5: 8b 83 10 00 00 00 mov 0x10(%ebx),%eax 9月 01 22:54:18 Defolos 80482cb: 85 c0 test %eax,%eax 9月 01 22:54:18 Defolos 80482cd: 74 02 je 80482d1 9月 01 22:54:23 Defolos こんな感じで 9月 01 22:54:39 Defolos 00がいっぱい出て来ます 9月 01 22:55:02 Defolos 00というのは、STRCPY関数などでは文字列の終りを意味する特別な記号です 9月 01 22:55:32 Defolos バッファオーバフローなどの脆弱性は、STRCPY関数などでぺいロードをコピーしてもらわなければ 9月 01 22:55:46 Defolos ならないので、ぺいロードの途中に00が出現すると 9月 01 22:56:01 Defolos そこで文字列が終りなのだとSTRCPY関数に思われてしまいます 9月 01 22:56:24 Defolos そうするとぺいロードが途中までしかバッファにコピーされず、最後までぺいロードが実行できません 9月 01 22:56:39 Defolos 結果行いたい動作とは違った動作をしてしまいます 9月 01 22:56:52 Defolos 具体的には、サンプルに挙げたように 9月 01 22:57:15 Defolos HelloWordlとコピーしたかったのに 9月 01 22:57:33 Defolos Helloの後ろに00があるためにそこで文字列が終りと判断され、 9月 01 22:57:44 Defolos 残りの部分がコピーされずに残ってしまいます 9月 01 22:58:01 Defolos このような事がシェルコードで起きるとシェルが起動できないため 9月 01 22:58:14 Defolos 00の出現を無くさなければなりません 9月 01 22:58:26 Defolos 次に、もうひとつダメな点がありまs 9月 01 22:58:41 Defolos これはアドレッシング問題と呼ばれるもので 9月 01 22:59:16 Defolos .dataディレクティブでことなるセグメントを利用してしまうのが問題です 9月 01 22:59:52 Defolos ぺいロードはスタックセグメント上にコピーされ、呼ばれます 9月 01 23:00:20 Defolos それゆえに、他のセグメントへはアクセスできません 9月 01 23:00:54 Defolos 通常のスタンドアロンのプログラムであれば.dataで他のセグメントにデータを保持するのは普通なのですが 9月 01 23:01:27 Defolos ぺいロードの場合はちょっと特殊な方法で、文字列をスタックに格納する必要があります 9月 01 23:01:48 Defolos ここまでは大丈夫でしょうか 9月 01 23:02:05 be-be- はい 9月 01 23:02:08 wahiko はい 9月 01 23:02:27 Defolos 出は次に、この問題を解決するテクニックを紹介します 9月 01 23:02:44 Defolos まず、アドレッシング問題を解決しましょう 9月 01 23:02:59 Defolos アドレッシング問題では異なるセグメントを利用するのが問題でした 9月 01 23:03:36 Defolos ですので、スタックセグメントにデータを確保し、何らかの方法でデータの先頭のアドレスを取得することで 9月 01 23:03:51 Defolos データへのアクセスを行います 9月 01 23:04:07 Defolos これには2つの解決策がありますが 9月 01 23:04:21 Defolos まずはjmp/callテクニックから解説します 9月 01 23:04:48 Defolos call命令はC言語の関数呼び出しのようなものです 9月 01 23:05:21 Defolos Callで呼ばれた先でretが実行されれば、Callの次のアドレスの命令を実行します 9月 01 23:05:48 Defolos この仕組みを実現するために、callは自身の次のアドレスを保持します 9月 01 23:06:08 Defolos これを応用して文字列の先頭のアドレスを取得する分けです 9月 01 23:06:21 Defolos 資料のサンプルに挙げたように 9月 01 23:06:36 Defolos まずJMP命令でONE:に飛びます 9月 01 23:06:49 Defolos JMP命令はC言語のGOTO命令と同じようなものです 9月 01 23:07:09 Defolos ONE:に飛んだ先にはCALL命令が待ち受けていますので 9月 01 23:07:18 Defolos CALLでTWO:に飛びます 9月 01 23:07:46 Defolos このとき、CALLはRETで戻って来るときのためにスタック上に戻りアドレスを積みます 9月 01 23:08:28 Defolos そこで、POPでスタックの一番上を取り出せば、CALL命令の次のアドレスである文字列の先頭アドレスを取得できる分けです 9月 01 23:09:00 Defolos この例ではECXレジスタにSTRINGという文字列の先頭アドレスが入れられた事になります 9月 01 23:09:43 Defolos これならスタックセグメントしか利用していないにもかかわらず、文字列の先頭アドレスを取得する事ができます 9月 01 23:10:04 Defolos もうひとつの解決策はプッシュテクニックと呼ばれます 9月 01 23:10:19 Defolos 文字を4バイト毎にぐぎって 9月 01 23:10:36 Defolos リトルエンディアン順にプッシュします 9月 01 23:10:46 Defolos MORNING!なら 9月 01 23:10:57 Defolos !GINをプッシュして 9月 01 23:11:15 Defolos その後NROMをプッシュします 9月 01 23:11:45 wahiko はい 9月 01 23:11:51 Defolos その後はスタックポインタ、つまりESPを参照すれば文字列の先頭アドレスが分かります 9月 01 23:12:15 Defolos ただ、文字列はNULLで終ってないとダメという決まりになってますので 9月 01 23:12:24 Defolos 一番最初に00をプッシュしておきます 9月 01 23:12:35 Defolos JMP/CALLテクニックとの違いは 9月 01 23:13:03 Defolos JMP/CALLテクニックがあらかじめ文字列を保持しておいて、その先頭アドレスを取得するのに対し 9月 01 23:13:24 Defolos プッシュテクニックは文字列をスタック上に生成するところから始める点です 9月 01 23:13:49 Defolos プッシュテクニックはJMPやらCALLやらの周りくどい事をしなくて済むので 9月 01 23:14:00 Defolos プログラムを短くする事ができます 9月 01 23:14:16 Defolos ただし、文字列が4の倍数でないとこのテクニックは使えません 9月 01 23:14:24 Defolos ここまではOKでしょうか 9月 01 23:14:49 be-be- はい、大丈夫です 9月 01 23:15:08 wahiko はい 9月 01 23:15:18 Defolos では次に、NULLバイト問題を解決します 9月 01 23:15:40 Defolos NULLバイトが出現してしまう一番の原因は、コード中のOです 9月 01 23:16:14 Defolos つまり、0を使わずにコードを書けば良いのですが 9月 01 23:16:19 Defolos そんなわけには行きませんね 9月 01 23:16:48 Defolos ですので、0を使わずしてレジスタ内に0を格納するテクニックを紹介します 9月 01 23:17:06 Defolos 最も手っ取り早いのはXORを使う方法です 9月 01 23:17:38 Defolos XORは、AとBのビットが同じときは0、それ以外のときは1になる論理集合です 9月 01 23:18:13 Defolos 例えば、Aが11010010、Bが01110111の時は 9月 01 23:18:43 Defolos 一番下位からみていって、0と1で異なる数字なので1 9月 01 23:19:02 Defolos 2桁目は1と1で同じ数字なので0////というように 9月 01 23:19:17 Defolos XORをとって行くと10100101になります 9月 01 23:19:23 Defolos ここで重要な事は 9月 01 23:19:32 Defolos 同じ数字だったら0になるということでs 9月 01 23:19:43 wahiko はい 9月 01 23:19:44 Defolos では、AとAをXORしたらどうなるでしょうか 9月 01 23:19:56 Defolos AとAは全部同じ数字に決まっていますので 9月 01 23:20:08 Defolos XORをとると0になってしまうのです 9月 01 23:20:34 Defolos つまり、コード内に0という数字を使わずしてレジスタ内をゼロクリアしたことになります 9月 01 23:20:58 Defolos もうひとつ、NULLが入ってしまう余地があるのですが 9月 01 23:21:13 Defolos それが32ビット命令のうめくさです 9月 01 23:21:27 Defolos movl $0x5, %eax 9月 01 23:21:47 Defolos は32ビットのレジスタに5を入れるという命令です 9月 01 23:22:08 Defolos しかしながら、5と言う数字は101ですので 9月 01 23:22:19 Defolos 32ビットも必要ありません 9月 01 23:22:29 Defolos 3ビットで済んでしまうのですが 9月 01 23:22:57 Defolos 命令は32ビットレジスタへの数字の移動なので、なにがなんでも32ビットにしなければならないのです 9月 01 23:23:17 Defolos その結果、前方に29ビットの0がうめくさとして入ってしまいます 9月 01 23:23:48 Defolos これを解決するために、下位互換命令を活用します 9月 01 23:24:22 Defolos 5は8ビットで表現可能なので、命令は8ビット用のmovbを使います 9月 01 23:24:42 Defolos レジスタも8ビットあれば十分なのでalを使います 9月 01 23:25:19 Defolos こうすれば、うめくさは不要なので00000101として解釈され、NULLが入る余地は無くなります 9月 01 23:25:41 Defolos ここまではOKですか? 9月 01 23:26:18 be-be- 5の場合でしたら8ビットでもうめくされませんか? 9月 01 23:26:40 Defolos 8ビットの場合ですと、先頭に5ビットの0が入ってしまいますが 9月 01 23:26:50 wahiko はい 9月 01 23:26:57 Defolos 数字は8ビットずつくぎって考えるので 9月 01 23:27:08 Defolos 先頭の0は無視されて5として見られます 9月 01 23:27:18 be-be- あ、なるほど 9月 01 23:27:46 Defolos 29バイトもあると、間に3つもNULLが出て来てしまう分けですね 9月 01 23:28:25 wahiko 16進数を2つづつで解釈しているからですね 9月 01 23:28:51 Defolos そうです 9月 01 23:29:28 Defolos とにかく16進で00が出て来なければOKなので 9月 01 23:29:45 Defolos 7ビットまでの0のうめくさは許容されるわけです 9月 01 23:30:20 Defolos 大丈夫そうですか 9月 01 23:30:36 be-be- はい、わかりました 9月 01 23:31:18 Defolos では、ここで先程のHello.sを修正して、ぺいロードとして動くようにしてみましょうか 9月 01 23:31:26 wahiko はい 9月 01 23:31:42 Defolos アドレッシング問題の解決はどっちを津かって解決してもらっても結構ですが 9月 01 23:31:58 Defolos JMP/CALLのほうがやりやすいと思います 9月 01 23:32:06 Defolos ではやってみましょうー 9月 01 23:39:24 -wahiko/#lykeion- msg: .ascii "Hello!" 9月 01 23:39:24 -wahiko/#lykeion- .global main 9月 01 23:39:24 -wahiko/#lykeion- main: 9月 01 23:39:24 -wahiko/#lykeion- jmp ONE 9月 01 23:39:24 -wahiko/#lykeion- TWO: 9月 01 23:39:24 -wahiko/#lykeion- popl %ecx 9月 01 23:39:26 -wahiko/#lykeion- movl $4, %eaxjmp ONE 9月 01 23:39:28 -wahiko/#lykeion- movl $4, %eax 9月 01 23:39:30 -wahiko/#lykeion- movl $0, %ebx 9月 01 23:39:32 -wahiko/#lykeion- movl $msg, %ecx 9月 01 23:39:34 -wahiko/#lykeion- movl $6, %edx 9月 01 23:39:36 -wahiko/#lykeion- int $0x80 9月 01 23:39:38 -wahiko/#lykeion- ret 9月 01 23:39:40 -wahiko/#lykeion- ONE: 9月 01 23:39:44 -wahiko/#lykeion- call TWO 9月 01 23:39:46 -wahiko/#lykeion- .string "HELLO" 9月 01 23:39:48 wahiko こうですか? 9月 01 23:41:17 Defolos a 9月 01 23:41:29 Defolos えーと 9月 01 23:41:40 -wahiko/#lykeion- .global main 9月 01 23:41:40 -wahiko/#lykeion- main: 9月 01 23:41:40 -wahiko/#lykeion- jmp ONE 9月 01 23:41:40 -wahiko/#lykeion- TWO: 9月 01 23:41:40 -wahiko/#lykeion- popl %ecx 9月 01 23:41:40 -wahiko/#lykeion- movl $4, %eaxjmp ONE 9月 01 23:41:44 -wahiko/#lykeion- movl $4, %eax 9月 01 23:41:46 -wahiko/#lykeion- movl $0, %ebx 9月 01 23:41:48 -wahiko/#lykeion- movl $6, %edx 9月 01 23:41:50 -wahiko/#lykeion- int $0x80 9月 01 23:41:52 -wahiko/#lykeion- ret 9月 01 23:41:54 -wahiko/#lykeion- ONE: 9月 01 23:41:56 -wahiko/#lykeion- call TWO 9月 01 23:41:59 -wahiko/#lykeion- .string "HELLO!" 9月 01 23:42:06 wahiko ごめんなさい送信してしまいました 9月 01 23:42:24 Defolos 和彦さんのはあってると思います 9月 01 23:42:50 Defolos 細かいミスまでは見てませんが、流れは正解です 9月 01 23:44:04 Defolos JMP ONEがちょっと変な所に入ってるのが 9月 01 23:44:17 Defolos 問題かな 9月 01 23:46:18 Defolos 完成しましたら、コンパイルしてOBJDUMPで表示させてください 9月 01 23:47:12 wahiko だめでしたorz 00がたくさんありました 9月 01 23:47:23 Defolos ^^; 9月 01 23:47:40 Defolos 多分、NULLバイト問題のところでひっかっかってますね 9月 01 23:50:11 wahiko となるとpopb %ecxですか? 9月 01 23:50:24 Defolos いえ 9月 01 23:50:34 Defolos ECXのところはアドレスをポップして来るので 9月 01 23:50:42 Defolos 32ビット無いと困りますね 9月 01 23:51:14 Defolos 他のMOV $4、 %EAXのあたりが問題になってるっぽいです 9月 01 23:51:32 wahiko そうですよね 9月 01 23:51:37 wahiko やってみます 9月 01 23:52:35 Defolos MOVBを指定したら、レジスタも8ビット用のを指定しないとダメですよ 9月 01 23:52:52 Defolos be-be-さんはできてますでしょうか 9月 01 23:53:10 be-be- 少し苦戦しています。 9月 01 23:54:47 Defolos なるほど 9月 01 23:55:44 wahiko movb $4 al みたいにしてコンパイルしたのですがまだ00がありますね 9月 01 23:56:37 Defolos あ、始めの.code32を消してもらえますか? 9月 01 23:56:48 be-be- こちらもコンパイルしたら00が残ります 9月 01 23:57:32 Defolos うーん。時間的にもちょっとやばくなって来ましたので 9月 01 23:57:41 Defolos 回答例を示したいと思います 9月 01 23:57:58 Defolos 他のファイルを作ってもらって、そちらにコピーしてください 9月 01 23:58:18 Defolos .global main 9月 01 23:58:18 Defolos main: 9月 01 23:58:18 Defolos jmp ONE 9月 01 23:58:18 Defolos TWO: 9月 01 23:58:18 Defolos popl %ecx 9月 01 23:58:18 Defolos movb $0x4, %al 9月 01 23:58:18 Defolos xorl %ebx, %ebx 9月 01 23:58:18 Defolos movb $0x6, %dl 9月 01 23:58:18 Defolos int $0x80 9月 01 23:58:18 Defolos xorl %eax, %eax 9月 01 23:58:18 Defolos inc %eax 9月 01 23:58:18 Defolos int $0x80 9月 01 23:58:18 Defolos ret 9月 01 23:58:18 Defolos ONE: 9月 01 23:58:18 Defolos call TWO 9月 01 23:58:18 Defolos .string "Hello!" 9月 01 23:58:26 Defolos これが一応の回答例です 9月 01 23:58:59 Defolos これをコンパイルしてobjdump -d a.outで見て頂きたく思います 9月 01 23:59:31 wahiko はい 9月 02 00:01:43 Defolos OBJDUMPで見てみると、結構たくさん表示されると思います 9月 02 00:02:07 Defolos ですが、実際にはここに表示されるものの一部分だけを利用すれば良いのです 9月 02 00:02:30 Defolos 具体的には
:と書かれた部分から 9月 02 00:02:52 Defolos 90が連発するまでの部分が必要な部分で 9月 02 00:03:06 Defolos それ以外はぺいロードに直接関係しない部分です 9月 02 00:03:29 Defolos その間だけを抜きだして、テキストエディタ等にコピーしてください 9月 02 00:04:45 Defolos ここまでは大丈夫でしょうか 9月 02 00:05:20 -wahiko/#lykeion- 08048354
: 9月 02 00:05:20 -wahiko/#lykeion- 8048354: eb 0f jmp 8048365 9月 02 00:05:20 -wahiko/#lykeion- 08048356 : 9月 02 00:05:20 -wahiko/#lykeion- 8048356: 59 pop %ecx 9月 02 00:05:20 -wahiko/#lykeion- 8048357: b0 04 mov $0x4,%al 9月 02 00:05:20 -wahiko/#lykeion- 8048359: 31 db xor %ebx,%ebx 9月 02 00:05:22 -wahiko/#lykeion- 804835b: b2 06 mov $0x6,%dl 9月 02 00:05:24 -wahiko/#lykeion- 804835d: cd 80 int $0x80 9月 02 00:05:26 -wahiko/#lykeion- 804835f: 31 c0 xor %eax,%eax 9月 02 00:05:28 -wahiko/#lykeion- 8048361: 40 inc %eax 9月 02 00:05:31 -wahiko/#lykeion- 8048362: cd 80 int $0x80 9月 02 00:05:32 -wahiko/#lykeion- 8048364: c3 ret 9月 02 00:05:34 -wahiko/#lykeion- 08048365 : 9月 02 00:05:36 -wahiko/#lykeion- 8048365: e8 ec ff ff ff call 8048356 9月 02 00:05:38 -wahiko/#lykeion- 804836a: 48 dec %eax 9月 02 00:05:40 -wahiko/#lykeion- 804836b: 45 inc %ebp 9月 02 00:05:44 -wahiko/#lykeion- 804836c: 4c dec %esp 9月 02 00:05:46 -wahiko/#lykeion- 804836d: 4c dec %esp 9月 02 00:05:48 -wahiko/#lykeion- 804836e: 4f dec %edi 9月 02 00:05:50 -wahiko/#lykeion- 804836f: 21 00 and %eax,(%eax) 9月 02 00:05:52 -wahiko/#lykeion- 8048371: 90 nop 9月 02 00:05:54 -wahiko/#lykeion- 8048372: 90 nop 9月 02 00:05:56 -wahiko/#lykeion- 8048373: 90 nop 9月 02 00:05:58 -wahiko/#lykeion- 8048374: 90 nop 9月 02 00:06:00 -wahiko/#lykeion- 8048375: 90 nop 9月 02 00:06:02 -wahiko/#lykeion- 8048376: 90 nop 9月 02 00:06:04 -wahiko/#lykeion- 8048377: 90 nop 9月 02 00:06:06 wahiko こうですか 9月 02 00:06:08 wahiko ログ汚しごめん 9月 02 00:06:17 Defolos そうです 9月 02 00:06:30 be-be- 自分も同じように表示されています 9月 02 00:06:34 Defolos ここからはかなりアナログで申し訳ないのですが 9月 02 00:06:35 wahiko みごとに00がありませんね 9月 02 00:06:41 wahiko はい 9月 02 00:06:49 Defolos 真中の16進数以外の部分を全て削除します 9月 02 00:07:05 Defolos あまりにも面倒臭いので 9月 02 00:07:13 Defolos 表示島sね 9月 02 00:07:15 Defolos eb 0f 59 b0 04 31 db b2 06 cd 80 31 c0 40 cd 80 c3 e8 ec ff ff ff 48 65 6c 6c 6f 21 9月 02 00:07:36 Defolos これが先程のぺいロードを16進数で表示したものです 9月 02 00:07:51 Defolos では、これが間ともに動くかどうかをチェックしてみましょう 9月 02 00:08:11 Defolos 前回使った、挿入ベクター生成プログラムにこのぺいロードをセットします 9月 02 00:08:45 Defolos その場合はC言語の規則にしたがって、16進数は始めに¥xを付けます 9月 02 00:08:51 Defolos ですので、次のようになります 9月 02 00:08:58 Defolos "\xeb\x0f\x59\xb0\x04\x31\xdb\xb2\x06\xcd\x80\x31\xc0\x40\xcd\x80\xc3\xe8\xec\xff\xff\xff\x48\x65\x6c\x6c\x6f\x21" 9月 02 00:09:20 Defolos これをぺいロードの所にセットして、コンパイルして実行してみてください 9月 02 00:09:50 Defolos 先に言っておきますと、たぶんとんでもない事になると思います^^; 9月 02 00:12:53 Defolos できましたでしょうか 9月 02 00:14:35 be-be- helloWorldが表示された後に、戌と??がひたすら続きました 9月 02 00:14:44 Defolos はい 9月 02 00:14:53 Defolos それでいいのです 9月 02 00:15:19 Defolos Hello!と表示されたあとはむちゃくちゃな文字列が表示されたと思います 9月 02 00:15:29 wahiko どうも貼り付けがうまくいきません 9月 02 00:15:44 Defolos 張り付けは右クリックでできませんか? 9月 02 00:17:28 wahiko なんとかできました 9月 02 00:17:34 Defolos b 9月 02 00:17:59 Defolos 大量の文字が表示されたと思いますが 9月 02 00:18:22 Defolos これは、writeシステムコールが文字列の終りはNULLであるという決まりを忠実に守った結果なのです 9月 02 00:18:46 Defolos 今回私達は用意した文字列の後ろのNULLを置かずにぺいロードを実行しました 9月 02 00:19:21 Defolos その結果、NULLを見付けられなかったWRITEシステムコールがメモリ内をNULLにぶちあたるまで延々表示し続けた結果なのです 9月 02 00:19:51 Defolos 前回までは.dataで異なるセグメントを使用するようにしていましたので 9月 02 00:20:13 Defolos 自動的にNULLが文字列の後に補完されていたのでのような自体にはならなかったのですが 9月 02 00:20:34 Defolos 今回は文字列の最後にNULLをいれる必要があったのです 9月 02 00:20:52 Defolos これにもちょっとしたテクニックが必要ですので、次回解説したいと思います 9月 02 00:21:12 Defolos ところで、このHello!という文字列、ROOT権限で表示された分けですが 9月 02 00:21:22 Defolos あんまり有用とは言えませんね 9月 02 00:21:48 Defolos そんなわけで、次回はもっと有用な、シェルを起動するぺいロードを作成したいと思います 9月 02 00:22:05 Defolos 今回はここまででおしまいです 9月 02 00:22:19 Defolos 大変な外時間おつき合い頂きありがとうございました 9月 02 00:22:54 be-be- ありがとうございます 9月 02 00:23:10 Defolos 質問はありませんでしょうか 9月 02 00:23:45 wahiko 有難うございます、HELLO 9月 02 00:23:47 wahiko no 9月 02 00:23:50 wahiko の後に 9月 02 00:24:31 wahiko いろんな文字が出てきたのですがこれはrootで実行しているのですね? 9月 02 00:24:35 Defolos はい 9月 02 00:24:47 Defolos ROOT権限で表示した文字たちですね^^; 9月 02 00:25:13 wahiko 終わったあとkazuhiko@glazheim:~$ となっているのですが 9月 02 00:25:21 Defolos はい 9月 02 00:25:56 wahiko rootの#にはならないのですがこれでいいのですか? 9月 02 00:26:02 Defolos そうですね 9月 02 00:26:06 Defolos あくまで 9月 02 00:26:15 Defolos HELLOを表示して終るだけのプログラムですので 9月 02 00:26:33 Defolos プログラムが終了した時点でROOT権限は放棄され、もとの一般ユーザ権限に戻ります 9月 02 00:27:13 wahiko なるほど 9月 02 00:27:19 Defolos 前回#になっていたのは、シェルを起動するプログラムをぺいロードに使っていたからなのですよ 9月 02 00:27:54 Defolos シェルはEXITコマンドをいれない限り終らないので。。。 9月 02 00:28:34 Defolos これで回答になりましたでしょうか 9月 02 00:28:39 wahiko 有難うございます 9月 02 00:29:07 Defolos 今回はかなり時間オーバーしてしまって申し訳ありませんでした 9月 02 00:29:56 wahiko いえいえ、こちらこそ長い間付き合っていただき有難うございますm(__)m 9月 02 00:30:12 wahiko 今回も有益な時間になりました 9月 02 00:30:22 Defolos 次回はちゃんと3時間に納めれるように頑張りますー 9月 02 00:30:26 be-be- 今回もお疲れ様です 9月 02 00:30:40 Defolos そういって頂けると嬉しい限りです 9月 02 00:30:59 wahiko お疲れ様です 9月 02 00:31:01 Defolos 例題2、2は次回やることにしましょう 9月 02 00:31:10 Defolos それでは、また次回お会いしましょうー 9月 02 00:31:22 wahiko ではー 9月 02 00:31:26 * wahiko has quit ("Leaving...") 9月 02 00:31:26 be-be- また、次回よろしくお願いします 9月 02 00:31:46 be-be- では、失礼します 9月 02 00:31:49 Defolos また宜しくお願いします 9月 02 00:31:53 Defolos ノシ 9月 02 00:31:53 * be-be- has quit ("Leaving...") 9月 02 00:31:56 Tcl interface unloaded 9月 02 00:31:56 Python interface unloaded **** Sun Sep 2 00:31:56 2007 でログ記録終了