house of orang 基本原理:

覆盖unsorted bin空闲块,修改其大小为0x61(small bin [4]),修改bk指向 _IO_list_all-0x10,同时布置fake file struct,然后分配堆块,触发unsorted bin attack 修改 _IO_list_all,将修改过的unsorted bin 放入 small bin 4中,继续遍历unsorted bin会触发异常,调用 malloc_printerr,该函数调用栈如下:

malloc_printerr
   _libc_message(error msg)
       abort
           _IO_flush_all_lockp -> JUMP_FILE(_IO_OVERFLOW)

如果能够伪造 _IO_OVERFLOW 函数,便可以get shell。

在调用_IO_OVERFLOW 之前,会做一些检查

0841       if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
0842 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
0843        || (_IO_vtable_offset (fp) == 0
0844            && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
0845                     > fp->_wide_data->_IO_write_base))
0846 #endif
0847        )
0848       && _IO_OVERFLOW (fp, EOF) == EOF)

要绕过这些检查,可以伪造:

  1. fp->_mode = 0
  2. fp->_IO_write_ptr < fp->_IO_write_base
  3. fp->_IO_read_ptr = 0x61 , smallbin4 + 8 (smallbin size)
  4. fp->_IO_read_base = _IO_list_all - 0x10, smallbin -> bk, unsorted bin attack

Glib 2.23 之前可以伪造vtable , 使得_IO_OVERFLOW = system ,将fp指向的内容开始的字符串布置为 "sh"即可。

GLIBC 2.24 引入的新机制

2.24开始引入vtable 的检测函数—— IO_validate_vtable,该函数定义如下:

static inline const struct _IO_jump_t *
IO_validate_vtable (const struct _IO_jump_t *vtable)
{
  /* Fast path: The vtable pointer is within the __libc_IO_vtables
     section.  */
  uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
  const char *ptr = (const char *) vtable;
  uintptr_t offset = ptr - __start___libc_IO_vtables;
  if (__glibc_unlikely (offset >= section_length))
    /* The vtable pointer is not in the expected section.  Use the
       slow path, which will terminate the process if necessary.  */
    _IO_vtable_check ();
  return vtable;
}

vtable必须要满足 在 __stop___IO_vtables__start___libc_IO_vtables 之间,而我们伪造的vtable通常不满足这个条件,但是可以找到 __IO_str_jumps__IO_wstr_jumps 进行绕过,二者均符合条件。其中,利用 __IO_str_jumps 绕过更简单。

pwndbg> p __start___libc_IO_vtables
0x7fcbc6703900 <_IO_helper_jumps> ""
pwndbg> p __stop___libc_IO_vtables
0x7fcbc6704668 ""
pwndbg> p &_IO_str_jumps
(const struct _IO_jump_t *) 0x7fcbc6704500 <_IO_str_jumps>
pwndbg> p &_IO_wstr_jumps
(const struct _IO_jump_t *) 0x7fcbc6703cc0 <_IO_wstr_jumps>

利用__IO_str_jumps 绕过

__IO_str_jumps 结构如下:

c

点击收藏 | 3 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖