Don't like this style? Click here to change it! blue.css
First let's do a daily micro-pwn from the weekend:
Micro PWN will just be to assess what the weakness might be. Here are the files: Dockerfile (to see the glibc) and free_real_estate the binary
OK so this week is all about FSOP. But perhaps more importantly I'd like to share with you a process of "security research".
Our goal is to take this technique which was most effective in glibc 2.23 and see if we can find ways to trigger it in glibc 2.34.
If I do this correctly (or close enough) you'll realize that there is a rich landscape of possible targets and fixes for you to find if you're obsessive enough. This is my exploit, there are many like it, but this one is mine.
So as we dive into a particular technique, keep in mind that you are seeing a possible process for hunting general purpose exploits.
Filestreams are used all of the time. In particular anytime you write to screen, read from a device, display an error message, or read from a file you are using a filestream.
You may even notice that in something as high-level as Python we can do f=open("filename", "r") f.read() f.seek(0) f.read() f.close()
That is, when you read a file you open a "file handler" and you "stream" from the file and if you try to stream twice you get an empty string.
The high-level WHY is to reduce locking the kernel:
The HOW is using structs:
There are three structs we care about this week:
In general we will be dealing with all of the wacky symbols in glibc that start with _IO_
and the main source code that implements all of this is in
Source for those two (glibc 2.34 version) are at the bottom of today's notes.
So, just like when we learned tcache and main_arena we need a treasure map for _IO_FILE and _IO_jump_t:
The story is roughly like this:
_IO_list_all
_IO_FILE_plus
_IO_FILE_plus
is just a thin struct that wraps an _IO_FILE
and an struct _IO_jump_t*
(pointer to a jump table)_chain
attribute is a pointer to the next filestream.By the way you can inspect these things in gdb as follows:
We left off here but I'll make it another site
So the jump_table is a struct full of function pointers.
This is needed for object-oriented coding.
If you can overwrite a function pointer inside the vtable of a filestream then trigger that function you can control the instruction pointer.
When a filestream flushes it's buffers it will stream from the ptr to the end of the stream. If we control those addresses we can get arbitrary reads.
Likewise if we take over stdout and can carefully control pointers we can dump a buffer into a region.
_IO_flush_all_lockp
From our perspective this is a target rich topic, but a little light on blog-posts and articles and pretty pictures. We'll have to forge our own path. Exciting!
I'll be updating this as we go for sure, but I'd like to start with an FSOP playground for making a fake _IO_FILE_plus and linking it into the _IO_list_all: