2.24-2.28的fsop:
2.23的fsop对这个版本段的glibc是无效的,多加的保护机制如下:
新版本(libc2.24以上)的防御机制会检查vtable的合法性,不能再像之前那样改vatable为堆地址,但是_IO_str_jumps是一个符合条件的 vtable,改 vtable为 _IO_str_jumps即可绕过检查。
_IO_str_jumps是一个方向,使用比较简单,这里就只讲这个方向了。
利用:
新版本(libc2.24以上)的防御机制会检查vtable的合法性,不能再像之前那样改vatable为堆地址,但是_IO_str_jumps是一个符合条件的 vtable,改 vtable为 _IO_str_jumps即可绕过检查。其定义如下
const struct _IO_jump_t _IO_str_jumps libio_vtable =
{
JUMP_INIT_DUMMY,
JUMP_INIT(finish, _IO_str_finish),
JUMP_INIT(overflow, _IO_str_overflow),
JUMP_INIT(underflow, _IO_str_underflow),
JUMP_INIT(uflow, _IO_default_uflow),
JUMP_INIT(pbackfail, _IO_str_pbackfail),
JUMP_INIT(xsputn, _IO_default_xsputn),
JUMP_INIT(xsgetn, _IO_default_xsgetn),
JUMP_INIT(seekoff, _IO_str_seekoff),
JUMP_INIT(seekpos, _IO_default_seekpos),
JUMP_INIT(setbuf, _IO_default_setbuf),
JUMP_INIT(sync, _IO_default_sync),
JUMP_INIT(doallocate, _IO_default_doallocate),
JUMP_INIT(read, _IO_default_read),
JUMP_INIT(write, _IO_default_write),
JUMP_INIT(seek, _IO_default_seek),
JUMP_INIT(close, _IO_default_close),
JUMP_INIT(stat, _IO_default_stat),
JUMP_INIT(showmanyc, _IO_default_showmanyc),
JUMP_INIT(imbue, _IO_default_imbue)
};
其中 IO_str_overflow 函数会调用 FILE+0xe0处的地址。这时只要我们将虚表覆盖为 IO_str_jumps将偏移0xe0处设置为one_gadget即可。(不常见的情况)
还有一种就是利用io_finish函数,同上面的类似, io_finish会以 IO_buf_base处的值为参数跳转至 FILE+0xe8处的地址。执行 fclose( fp)时会调用此函数,但是大多数情况下可能不会有 fclose(fp),这时我们还是可以利用异常来调用 io_finish,异常时调用 IO_OVERFLOW是根据IO_str_overflow在虚表中的偏移找到的, 我们可以设置vtable为IO_str_jumps-0x8异常时会调用io_finish函数。(就是执行FILE+0xe8,且此时参数为 IO_buf_base(就是rdi指向的地址))