Skip to main content

Exploit Education Phoenix : Format One

·517 words·3 mins
Exploit Development Reverse Engineering Exploit Education
Exploit Education Phoenix - This article is part of a series.
Part 9: This Article
Before you look at the solution to the challenges, I invite you to try it for yourself. You can find all the challenges here.

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];

  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 != 0x45764f6c) {
    printf("Uh oh, 'changeme' is not the magic value, it is 0x%08x\n",
  } else {
    puts("Well done, the 'changeme' variable has been changed correctly!");


This challenge is very similar to the previous one, but with a little extra difficulty.

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 and set the value at 0x45764f6c. 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.

$ python -c "print '%32x'+'\x6C\x4F\x76\x45'" | ./format-one

Using the %32x parameter tells the sprintf function to represent a variable in hexadecimal. However, we also specify the size of the hexadecimal representation, in this case 32. At the output of the sprintf function, the string will be 32 characters long, allowing us to change 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 by using the sprintf function parameters. Finally, when we reach the correct padding, we overwrite the value of the changeme variable with the correct ASCII code.

Exploit Result
Result of exploiting the vulnerability.

Finally, we can see that the changeme variable has been modified with the right value, so we can complete the challenge.

Exploit Education Phoenix - This article is part of a series.
Part 9: This Article