Problem
Solution
In this problem, we’re given a binary, chall
, and it’s source code, chall.c
. Before inspecting the source, let’s run the binary.
Running chall
locally will greet us with a hint:
This points us in the direction of a use after free (UAF) vulnerability. The intuition is nicely explained by this illustration from the CWE entry:
Before exploiting the vulnerability, let’s first demonstrate it. We first print the heap:
Then we free x
and print x->flag
. Notice that printing x->flag
produces the same result as before. Why is that?
This is because free
does not remove x
’s data from the heap, but rather, marks that chunk of memory as available to re-allocate. x->flag
, when used after x
is freed, still references the same address and thus retrieves the same value as before.
The task is then very simple: allocate our own object that changes the value accessed by x->flag
. Let’s now take a look at chall.c
to see how we can do this.
chall.c
Two of the most important portions of the source code are highlighted below.
object
First (and most notably), x
is an instance of a struct
named object
.
// Create struct
typedef struct {
char a[10];
char b[10];
char c[10];
char flag[5];
} object;
object *x;
object
’s members will be stored in contiguous memory addresses, so overflowing one will leak into the next.
Once x
is freed, x->flag
can be changed into any four letter string (remember the null terminator! or don’t) by simply allocating 30 characters of junk data to bypass a
, b
, and c
, followed by the new value:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<win>
check_win
Second, check_win
leaks the <win>
condition.
void check_win() {
if(!strcmp(x->flag, "pico")) {
printf("YOU WIN!!11!!\n");
// ...
}
// ...
}
Hence, our payload is
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAApico