stdout(高版本glibc)

ida:Image_1770554399694_854
Image_1770554404484_470
开局直接就可以了bss处储存的_IO_2_1_stdout_的地址,libc基址就直接有了,且读入的fb就是这里bss段存了stdout结构的地址,且下面有puts的调用

漏洞:puts的调用会调用vtable中的xsputn,伪造vtable为另外合法的vtable,因为在高版本不能直接改写vtable了,再利用io_wfile_jumps->….seekoff->_IO_switch_to_wget_mode来跳转system

  1. ….seekoff可以在本地gdb里面打印出来,得到偏移,在seekoff里面想要调用上面调用链的最后一个还需要让elf结构中的write_ptr大于write_base
    进入到wget后的关键调用就是_IO_wdoallocbuf的调用,这里也有检查,要求_wide_data大于IO_buf_base处,其关键调用链:_wide_data->wide_vtable->doallocate(fd)
  2. 接下来就是在原vtable写入合法vtable,seekoff的偏移位置0x48,上面调用链偏移依次为0xe0和0x18,而wide_data的位置是从elf结构中0xa的偏移取得的
    所以再最后doallocate处设置system,前面就依次填入合适地址即可
  3. 此外锁的位置要有效,可以直接用原来的,也可以在换上对于ld文件及libc文件后用gdb算出原本锁地址和得到stdout地址的偏移,也可以换上后直接libc基址算偏移

exp:Image_1770556289540_890

参考文章:https://blog.mcitd.cn/posts/newstar2025/wp/#stdout