__IO_FILE之FSOP链
参考资料:
FSOP 链执行过程:
FSOP __Stream Oriented Programming. 是针对 glibc 标准 IO 流(_IO_FILE 结构体)的堆漏洞利用技术,核心是通过篡改文件流(stdin/stdout/stderr 等)的结构体数据,劫持程序执行流,实现任意代码执行。
我们通对 __IO_FILE 的学习可以知道:进程内所有的 __IO_FILE 结构会使用 chain 域互相连接形成一个链表,这个链表的头部由 __IO_list_all 维护
1 | pwndbg> p _IO_list_all->file._chain |
FSOP 的核心思想就是劫持_IO_list_all 的值来伪造链表和其中的_IO_FILE 项,但是单纯的伪造只是构造了数据还需要某种方法进行触发。FSOP 选择的触发方法是调用_IO_flush_all_lockp,这个函数会刷新_IO_list_all 链表中所有项的文件流,相当于对每个 FILE 调用 fflush,也对应着会调用_IO_FILE_plus.vtable 中的_IO_overflow
_IO_flush_all_lockp函数
1 | int |
在 malloc 时 unsorted bin出错会调用malloc_printerr 输出错误:
__init_malloc函数中部分
1 | _int_malloc (mstate av, size_t bytes) //这是 malloc 的内部函数,用于从内存池中分配内存. |
如果 chunk 的大小无效,调用 malloc_printerr 函数报告内存损坏错误
malloc_printerr函数
1 | malloc_printerr (int action, const char *str, void *ptr, mstate ar_ptr) |
跟进__libc_message函数,最后也调用了abort函数:
__libc_message函数
1 | /* Abort with an error message. */ |
跟进abort函数,其中调用了fflush函数:
about 函数:
1 | /* Cause an abnormal program termination with core-dump. */ |
跟进fflush函数,fflush是一个宏定义,调用了IO_fflush函数,且参数是NULL
fllush 函数
1 | int |
继续跟进IO_fflush(NULL),由于传入的参数为NULL,所以会调用_IO_flush_all函数:
__IO_flush_all 函数:
1 | int |
_IO_flush_all_lockp调用了_IO_flush_all_lockp(1):
跟进_IO_flush_all_lockp(1),而 _IO_flush_all_lockp就是这条FILE终点:
1 | int |
查看_IO_OVERFLOW(fp, EOF)定义,以及最后的
1 | //libc_2.23 的定义 |
最后找函数地址时,使用了_vtable_offset 即 _IO_FILE 结构体的 vtable 指针,而vtable 指针指向的是一个虚表,所以相当于最后调用到了下面的_IO_file_overflow函数,并且传入的参数是fp指针,即文件的地址


所以最后IO_FILE链为:malloc报错 ==> malloc_printerr ==> __libc_message ==> abort ==> fflush ==> IO_fflush ==> _IO_flush_all ==> _IO_flush_all_lockp ==> _IO_OVERFLOW(最后使用vtable 指向的虚表中的指针),
最后在_IO_flush_all_lockp中时有两个判断条件需要绕过,才能调用到_IO_OVERFLOW :
1 | fp->_mode <= 0 |
更新: 2026-03-31 12:54:08
原文: https://www.yuque.com/idcm/wnemg9/ryo4gboq4x7kmgmm