heap-zero

heap-zero is the first heap exploitation exercise from the phoenix vm from exploit education

Source code

/*
 * phoenix/heap-zero, by https://exploit.education
 *
 * Can you hijack flow control, and execute the winner function?
 *
 * Why do C programmers make good Buddhists?
 * Because they're not object orientated.
 */

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

Looking at the source code we see two calls to malloc(), which allocates space in the heap for further use. We might also observe that it uses strcpy() to copy an argument passed from the command line to the first allocated space. As we already know, using strcpy() might be dangerous because it won't stop the user from providing input larger than the allocated space, allowing a heap overflow to occur. After that, the program will store a pointer to the nowinner function in the second allocated space and then calls whatever functions it reads from this pointer.

In theory we are unable to control the value of fp, since it isn't set based on user input, but if we exploit a heap overflow on the first chunk (to which our input is copied) we might overwrite the value of fp and control the execution flow.

The challenge is available in a varity of architectures, so there will be a different solution to each of them, but all based on the same principle, though I recomend checking the i486 one out first because it's way more didactic than all the others, since I won't repeat the same information over and over again when I'm doing the other versions.

Summary

Last updated