When a new FILE structure is allocated and its pointer returned from fopen(). , glibc has actually allocated an internal structure called struct _IO_FILE_plus
, which contains struct _IO_FILE
and a pointer to struct _IO_jump_t
, which in turn contains a list of pointers for all the functions attached to the FILE. Overwrites a ‘FILE’ pointer (stdin, stdout, stderr or any other file handler opened by fopen()
) to point to own forged structure for gain control over execution flow.
File structure contains vtable
, which is a pointer to a table which contains functions which are called when the original ‘FILE’ pointer is used to perform different operations (such as fread, fwrite, …).
_IO_FILE_plus
struct is the extended version of _IO_FILE
struct, which is _IO_FILE
+ vtable
(virtual table = array of pointers to the helper fucntions during executing the IO operation):
How the vtable
will be filled during creating a new extended File
struct. Depending on the method u use. Ex: fopen(), the vtable
initialized with the existed vtable
called _IO_file_jumps
(other vtavle
like _IO_str_jumps
).
[_IO_jump_t](https://code.woboq.org/userspace/glibc/libio/libioP.h.html#_IO_jump_t)/ [glibc2.35](https://elixir.bootlin.com/glibc/glibc-2.35/source/libio/libioP.h#L293):
- stdin/stdout/stderr, fopen also use it.
- Extra Virtual function table.
- The export symbol of this type in the libc file is [_IO_file_jumps](https://code.woboq.org/userspace/glibc/libio/fileops.c.html#_IO_file_jumps).
_chain
(linked list). The head of linked list is called _IO_list_all
Some good targets in FILE structure:
_lock
(usually need to construct it for exploitation)
c struct _IO_FILE { ... _IO_lock_t *_lock; }
_lock
= 0x88This is also a FILE structure in glibc. We can overwrite the global variable in glibc to control the flow execution. (in glibc symbol table)
Control the linked list of File stream:
Powerful function:
_IO_flush_all_lockp
It will process all FILE in FILE linked list. We can construct the linked list to do oriented programing. Then line 9 will trigger virtual function.
The vtable must be in libc _IO_vtable
section. Otherwise, it will check if the vtable permits virtual function call.
_IO_vtable_check
For compatibility:
https://outflux.net/blog/archives/2011/12/22/abusing-the-file-structure/
https://www.slideshare.net/AngelBoy1/play-with-file-structure-yet-another-binary-exploit-technique
research
pwn