During FAUST CTF 2017, we were able to exploit toilet challenge first, here is the write-up :
Toilet was a x64 stripped binary running on port
The service can load and store user data, the user structure is directly written to files : ./data/sha256(username) after the logout. The flags were stored in the data files as usernames.
The important features are :
- Login : Connect using a username (max 65 bytes long), if it exists load the user data from the corresponding file
- Show current settings : Show user ID, user name and other parameters
- Drop a load : As you can imagine 😀 (you can add a text note to your load)
- Flush : Call the flushing function to free the previous load
- Show Log : List the last users connected (only the sha256 of the usernames are shown)
The vulnerability we found and exploited was a off by one in the login functionality : (The binary had another vulnerability which we didn’t exploit)
The user structure is defined like this :
The function fgets reads 64 bytes and adds a null byte at the end of the read buffer. So the flush function pointer can be overflowed by one null byte. By the way, the flush attribute was a function pointer because two flush functions exist (quick_flush and long_flush) and the menu command 3 allows to change it for the current logged user.
By chance or thanks to the author, the quick_flush(char * load_note) function address was 0x40301B and 0x403000 was exactly the address of the stub reading the data file and loading it in current user structure : read_info(char * filename).
Yeah ! We can use this vulnerability to read other users information :
- Show Log to get the recent users names (anonymized with sha256)
- Login using 64 bytes username to overflow the flush function
- Drop a load to enable flushing and store the flag sha256 in the load note
- Flush to load the user data of the load note
- Show current settings to view the raw current user name (which is one of the flags)
We can read all the usernames by repeating these steps. Our exploit for toilet is pretty ugly (link) so, you can view the author exploit in the link below (the other vulnerability exploit is in it too).
Also, this CTF was an attack/defense CTF so we patched this vulnerability by changing the fgets length parameter to 64.
Challenge author exploit : https://gist.github.com/m1ghtym0/44a4bdf7621fa60ac8ec69f10b8af5f4