Protostar Format4

Level description

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

int target;

void hello()
{
  printf("code execution redirected! you win\n");
  _exit(1);
}

void vuln()
{
  char buffer[512];

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

  printf(buffer);

  exit(1);   
}

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

Intro

In this level we are given a program similar to the previous ones. The main difference to note here is that instead of a return from the function, we have an exit() call which will exit the process. In the level description we are given a hint to use objdump -TR for getting more info about the binary. Although this level too focuses on execution flow redirection, it does it in a different way from the previous levels, so I will suggest to read about Global Offset Tables and how do they work from [2] and [1] serves for easier understanding of [2]. [3] is also very useful.

Solution

Although there is a difference of approach to this level, it’s nothing too complicated, the only complicated thing (for me at least) was to learn how exactly the GOT works because there is a lot of details. In short, the GOT (Global Offset Table, not Game of Thrones) is just a table that contains references to variables or functions. For more details and inner workings of dynamic loading and GOT I suggest you red [1], [2] and [3] because there is plenty to read and I don’t want to deviate from the topic.

The idea for our exploit will be simple, instead of overwriting the return address of currently executing function as in the previous levels, we will now overwrite the GOT entry for an exported function which is called from the currently executing function.

We will use objdump -TR to get the information we need:

got.png

The Dynamic Symbol Table is a table that lists only functions that are exported from an object and we can see that GLIBC exports exit() function which is used to exit from the vuln() function. The place in the GOT in which the address of the exit() function will reside is located at the address 0x08049724. If we overwrite the exit()‘s address inside the GOT with another address, the execution flow will be redirected to that address whenever the exit() call gets called and this is the solution to this level. We will write hello() function’s address to that address. We can use objdump format4 | grep hello to get the address of the hello() function, as seen in previous levels. The address of hello() is 0x080484b4.

finish.png

The above exploit shows that we wrote to addresses 0x080497240x08049725 and 0x08049727 the values: 0xb40x0484 and 0x0508 accordingly. To clarify things a bit: We have 12 address bytes and with 168 bytes we have the value 0x000000b4=180 written to the address 0x08049724, and because we only care about the LSB and because bytes are written in little-endian format, in the GOT (at the offset 0x08049724) we have written: \xb4\x00\x00\x00. Then, by adding 976 more bytes, which gives us 0x0484=1156 bytes written thus far, we write that value one place “to the right” or to the address 0x08049725 wich overwrites the red zero bytes already written and gives us the following result, as viewed from the address 0x08049724\xb4\x84\x04\x00\x00. There is only one more byte that we need to write and that byte is \x08, but the problem is we cannot write less bytes than we already have, so I used a trick and wrote 132 more bytes using the %x specifier which gives us 1288 or 0x0508 bytes written thus far, so by using the %n specifier we write that value at the address 0x08049727, to preserve the previously written bytes. The final content starting from the address 0x08049724 is \xb4\x84\x04\x08\x05\0x00\x00. Green bytes are the hello() function’s address bytes and the red ones are the bytes we don’t need but are still written. The red bytes would be a problem because they overwrite whichever value was there before, and if that value was a control value (stack canary), we would get an error stating that a buffer-overflow has been detected.

References

[1] http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/
[2] http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries//
[3] http://grantcurell.com/2015/09/21/what-is-the-symbol-table-and-what-is-the-global-offset-table/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s