介绍
最近做题遇到好几次攻击IO_FILE结构体的,整理一下相关资料。(抄 ctf wiki ^ - ^)
FILE文件结构
在标准I/O 库中,每个程序启动时有三个文件流是自动打开的:stdin、stdout、stderr。因此在初始状态下,_IO_list_all 指向了一个有这些文件流构成的链表,但是需要注意的是这三个文件流位于 libc.so的数据段。而我们使用fopen创建的文件流是分配在堆内存上的。
但是事实上_IO_FILE 结构外包裹着另一种结构_IO_FILE_plus,其中包含了一个重要的指针vtable指向了一系列函数指针。
1 | struct _IO_FILE_plus |
1 | struct _IO_FILE { |
vtable 是IO_jump_t类型的指针,IO_jump_t中保存了一些函数指针,在后面我们会看到在一系列标准IO函数中会调用这些函数指针.
1 | void * funcs[] = { |
伪造vtable劫持程序流程
修改vtable,使其指向一个我们可以控制的地址,然后在进行文件操作的时候,就会调用,从而控制程序流程。
根据 vtable在_IO_FILE_plus的偏移得到 vtable 的地址,在 64 位系统下偏移是 0xd8。之后需要搞清楚欲劫持的 IO 函数会调用vtable 中的哪个函数。关于IO 函数调用 vtable的情况已经在 FILE结构介绍一节给出了,知道了printf会调用 vtable 中的xsputn,并且 xsputn的是 vtable 中第八项之后就可以写入这个指针进行劫持。
新版本利用
TODO…