Skip to main content

Exploit Education Phoenix : Format Zero

·477 words·3 mins
Exploit Development Reverse Engineering Exploit Education
Exploit Education Phoenix - This article is part of a series.
Part 8: 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];

  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.

Exploit Result
Result of exploiting the vulnerability.

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



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