Exploit Education Phoenix : Format Zero
Table of Contents
Exploit Education Phoenix - This article is part of a series.
Overview of the challenge #
The aim of the Phoenix challenges is to analyse the source code of an executable in order to find and exploit a vulnerability. This second series of challenges concerns the format string vulnerabilities.
The first thing to do is to analyse the executable’s source code. Looking for a vulnerability to exploit.
int main(int argc, char **argv) {
struct {
char dest[32];
volatile int changeme;
} locals;
char buffer[16];
printf("%s\n", BANNER);
if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) {
errx(1, "Unable to get buffer");
}
buffer[15] = 0;
locals.changeme = 0;
sprintf(locals.dest, buffer);
if (locals.changeme != 0) {
puts("Well done, the 'changeme' variable has been changed!");
} else {
puts(
"Uh oh, 'changeme' has not yet been changed. Would you like to try "
"again?");
}
exit(0);
}
The first thing you notice is the structure containing a 32-character buffer and the changeme
variable. The aim of this challenge is to modify the value of the changeme
variable. There is also a second buffer of 16 characters.
The second thing is to use the sprintf
function. When we look at the documentation for the function with the command: man sprintf
. The documentation in the BUGS
section explains that using the sprintf
function can be dangerous, especially if the format is given by the user. In other words, the function is used in this way: sprintf(foo);
instead of sprintf(format, foo);
with the format is given by the programmer.
Furthermore, it is not possible to know what the size of the final character string will be, as the use of %
characters will allow an attacker to change the size of the final character string.
The challenge is to exploit a buffer overflow and modify the changeme
variable, while being restricted by a 15-character buffer for user input. This prevents us from using a stack buffer overflow and modifying the variable directly.
Exploiting the vulnerability #
To do this, we need to exploit a buffer overflow vulnerability, we need to instrument a string so that the sprintf
function generates a long string of characters.
$ echo "%32x" | ./format-zero
Using the %32x
parameter tells the sprintf
function to represent a variable in hexadecimal. However, we also indicate the size of the hexadecimal representation, in this case 32
. At the output of the sprintf
function, the string of characters will be 32
characters long, which allows us to modify the value of the changeme
variable by exploiting a buffer overflow. The interesting thing about this method is that we can bypass the buffer size using the sprintf
function parameters.
Finally, we can see that the changeme
variable has been modified, so we can complete the challenge.