速習・ペンテスト(Linux BOF)

前回の続き。「Windowsだけではなく、Linux でもやってみよう」 という問題。やり方は、おおむね前回と同様で、しかもうまくいったので、メモは少しだけにする。

使ったデバッガは、もちろん異なる。Kali Linux には、edb-debugger という GUI のデバッガが同梱されているので、これを使った。


まずは、文字 "A"(0x41)の数を、少しずつ増やして送り込み、サーバをクラッシュさせる。



次に、一定のパターンを持った文字列を生成して、そのデータを投入する。これにより、EIP に格納された値が、「生成したパターンの、どこに含まれているのか」 について調べることができる。
これで、下の図の 1 のデータを投入することで、EIP にピンポイントで "BBBB" を格納することに成功する。簡単ではあるが、EIP の制御は、攻略できた(さらに、EAX および ESP のアドレスに格納される値も、自由に変更できた)。
この問題で少し面倒だったのは 2 つ。(1) EAX が指すデータの先頭に、必ず 「XXXXXXXXXXX 」 がくっついてくること、(2) 文字列 「C」 が 7 文字しかなく、シェルコードが格納しにくいこと。



そこで、プログラムの実行の流れを強制的に変えて、「AAAA … 」 の箇所に、シェルコードを投入することを検討する。
まずは、プログラムの中から JMP ESP を探す。JMP ESP の実行が制御できると、自分の好きなタイミングで、ESP に格納されているアドレスに、ジャンプできるからだ。すでに、EIP は制御できる。なので、「BBBB」 の箇所(つまり EIP の値を上書きする箇所)を、JMP ESP があるアドレスに書き換えることで、プログラムの流れを変えることができる。プログラムの制御は、命令 JMP ESP の箇所にとばされて、この命令が実行されることで、すかさず ESP が指すアドレス(つまり 「CCCCCCC」 の箇所)にジャンプする。


ちょっとだけ工夫が必要なのは、その後、「AAAA … 」 の箇所に制御を移すところ。といっても、EAX から 「XXXXXXXXXXX [space](12 バイト)」 先へジャンプすればよいだけ。つまり、「CCCCCCC」 の箇所で、ADD EAX, 0Ch して、JMP EAX すればよい。
これらの命令のバイト列を 「CCCCCCC」 の箇所に書き込んでおくことで、目的地へのジャンプが実現できる(余ったところには、何もしない命令 NOP を入れて、つじつまを合わせておく)。

こんなもん。