fsop

type
status
date
slug
tags
summary
category
icon
password

fsop

FSOP 是 File Stream Oriented Programming 的缩写,根据前面对 FILE 的介绍得知进程内所有的_IO_FILE 结构会使用_chain 域相互连接形成一个链表,这个链表的头部由_IO_list_all 维护。
FSOP 的核心思想就是劫持_IO_list_all 的值来伪造链表和其中的_IO_FILE 项,但是单纯的伪造只是构造了数据还需要某种方法进行触发。FSOP 选择的触发方法是调用_IO_flush_all_lockp,这个函数会刷新_IO_list_all 链表中所有项的文件流,相当于对每个 FILE 调用 fflush,也对应着会调用_IO_FILE_plus.vtable 中的_IO_overflow。
_IO_list_all 形成的链表如下图所示:
notion image
glibc中有一个函数_IO_flush_all_lockp,该函数的功能是刷新所有FILE结构体的输出缓冲区,相关源码如下,文件在libio\genops中:
输出缓冲区的数据保存在fp->_IO_write_base处,且长度为fp->_IO_write_ptr-fp->_IO_write_base,因此上面的if语句实质上是判断该FILE结构输出缓冲区是否还有数据,如果有的话则调用_IO_OVERFLOW去刷新缓冲区。其中_IO_OVERFLOW是vtable中的函数,因此如果我们可以控制_IO_list_all链表中的一个节点的话,就有可能控制程序执行流。
可以看出来该函数的意义是为了保证数据不丢失,因此在程序执行退出相关代码时,会去调用函数去刷新缓冲区,确保数据被保存。根据_IO_flush_all_lockp的功能,猜测这个函数应该是在程序退出的时候进行调用的,因为它刷新所有FILE的缓冲区。事实上,会_IO_flush_all_lockp调用函数的时机包括:
  • libc执行abort函数时。
  • 程序执行exit函数时。
  • 程序从main函数返回时。
 

利用的方式

伪造IO FILE结构体,并利用漏洞将_IO_list_all指向伪造的结构体,或是将该链表中的一个节点(_chain字段)指向伪造的数据,最终触发_IO_flush_all_lockp,绕过检查,调用_IO_OVERFLOW时实现执行流劫持。
其中绕过检查的条件是输出缓冲区中存在数据:
 
上一篇
io入门
下一篇
large bin attack
Loading...
文章列表
Hi~, I ‘m moyao
reverse
pwn
pentest
iot
android
others
ctf
iOS