This post spoils a CTF challenge … Don’t read if you want to try it !

Sogeti CTF was a qualifier for the Sogeti Cyber E-Scape. I could not find a team to participate in this event, so I played alone and finally managed to find a team for the final :)

[+] Presentation

The Game - You need to be admin to have the flag

Here’s the source code.

nc quals.shadow-league.org 5001

[+] Finding the bug

The file name is an hint : uaf stands for Use-After-Free, a well known type of vulnerability.

So basically, a use after free situation occurs when memory referenced by a pointer has been freed, but this pointer has not been set to NULL.
If you try dereferencing this pointer, it will not throw an error, but the value pointed by the pointer won’t be the expected one : it can be anything, since this memory portion is considered as “free” (understand not used by a variable).

In order to exploit this vulnerability, we need to create a pointer and allocate some memory space to it, then free this memory and find a way to write what we want at this previously occupied place.

Let’s read the code !

It’s a simple program which accept several commands :
- set <name> : free the current player if there is one, and create a new player called <name>
- del : free the current player if there is one WITHOUT SETTING POINTER TO NULL
- title : change the game title
- login : show the flag IF YOU ARE AN ADMIN
- exit : well… it leaves the program

As an example :

Example

[+] Exploitation

The player structure is the following :

typedef struct player {
  char name[MAX_NAME_SIZE];
  int64_t isAdmin;
} player_t;

The ‘set’ command allocate a new player structure, give it our name and set isAdmin to 0.
The ‘del’ command free the pointer holding our player structure, but don’t set it to NULL.

We need to exploit this uaf vulnerability to set current player’s isAdmin value to any value different than 0, and then login to retrieve the flag.

Here’s the simplified heap layout after ‘set aaaaaa’ command :

heap1

Here’s the same memory region, but after ‘del’ command :

heap2

If we could to allocate a new heap block with the content we want, we would be able to overwrite the “current player” pointed.

Basically, we can just use the ‘title a…a’ to allocate a new heap block with controlled value, because the ‘title’ commmand uses the strndup function, which returns a new heap block pointing to the string we want to duplicate.
We will just try several title size until our player structure is overwritten.

Here’s the same memory region, but after ‘title aaaaaaaaaaaaaaaaaaaaaaa’ command :

heap3

The player structure has been overwritten, and isAdmin value is not 0 anymore : we can now login and grab the flag !

Here’s my final solution script.

Flag : SCE{Th1s_wasnt_f0r_fr3e_r1ght?}

[+] Bye

Feel free to tell me what you think about this post :)