上一篇的提示版本,在glibc2.24中增加了对io_fp里面vtable虚表的检查
1 | static inline const struct _IO_jump_t * |
增加了两个指针指向定义vtable数据段的一头一尾。这里我们没有办法再把vtable放在堆上了,当有后面检查也可以绕过,这里假设不能往堆写了vtable了,用一种新的攻击方式来讲解。既然不能用堆上任意构造的vtable,那么现有的vtable有没有办法利用呢?
这里将利用_IO_str_jumps
或_IO_wstr_jumps
来实现str和wstr区别是一个字符占1字节,wstr是一个字符占2字节。
1 | void |
这里看到只要满足if的条件判断,就能执行fp上指向的任意地址的函数。
1 | pwndbg> p _IO_str_jumps |
可以看到__finish函数指针在__overflow-0x8的位置,所以这个时候需要把vtable=_IO_str_jumps - 0x8 再来看一下_I0_buf_base这个结构
1 | struct _IO_streambuf |
(_IO_strfile *) fp)->_s._free_buffer = system
即可,具体看exploit
1 | from pwn_debug.pwn_debug import * |
精髓还是在布局上,这种padding的布局值得学习,统一!