介绍
最近做题遇到好几次攻击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…