#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int target;
void vuln()
{
char buffer[512];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
if(target == 64) {
printf("you have modified the target :)\n");
} else {
printf("target is %d :(\n", target);
}
}
int main(int argc, char **argv)
{
vuln();
}
Intro
Very similar to the previous level, this level introduces a more controlled format string vulnerability exploitation. It forces us to put exactly the number 64 inside the target variable. I will reuse the trick from the previous Format1 level.
Solution
In the previous level, we used this command to exploit the vulnerability:
./format1 `python -c ‘print “\x38\x96\x04\x08” + “%129$n”‘`
We can reuse it with a bit of modification to make an exploit for this level, but first, we need to find 2 things: the address of our target variable and the printf()‘s internal pointer offset to the address we want to write to (in this case, the address of the beginning of the format string, where the 4 bytes of the target address will be located).
To get the address of target variable we can use the same command from the previous level:
objdump -t | grep target
This gives us the location of target: 0x080496e4. Now, to get the aforementioned offset, we can do some probing by using a dummy string instead of the real address in the following way:

“AAAA” is used so we can spot easily the location of the beginning of the format string on the stack, which will be shown as “41414141”, its ASCII representation. Now we know that we need to move the printf()‘s internal pointer 4 places to get to the starting location of the format string. We now have all the information we need to write a functional exploit:
python -c ‘print “\xe4\x96\x04\x08” + “%60x%4$n”‘ | ./format2
The main difference between this and the previous exploit is that we added the “%60x” specifier. The exploit explained: At the beginning of the format string we first write 4 bytes which represent the address of the target variable, then we write 60 bytes of garbage which consists of hexadecimal representation of 4 bytes starting at the address of current printf()‘s internal pointer and the rest is blank padding, and finally, the %4$n specifier will write the current number of bytes written (which is 64) to the location pointed by the address found at current printf()‘s internal pointer location, which is the start of the format string that we found out earlier. Here is the proof that it works:

And that’s it! Thanks for reading!
Pingback: Protostar Format3 | SecInject