# Dangers of the Heap

## Lecture

{% embed url="<https://youtu.be/Cr9IeGQxFoc>" %}
Dangers of the Heap
{% endembed %}

![Security vs. Performance](https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FWDGdjIsGJxlvOBOXDSvw%2Fimage.png?alt=media\&token=b1909e74-29b8-40ba-aa7d-859146bfbf4b)

## Dangers

More than one way to misuse the heap!

* **Forgetting to free memory:** leads to resource exhaustion
* **Forgetting that we have freed memory:** using free memory freeing free memory
* **Corrupting metadata used by the allocator to keep track of heap state:** conceptually similar to corruption internal function state on the stack

## Memory Leaks

{% hint style="info" %}
**Problem:** Allocated memory must be explicitly `free()`d.
{% endhint %}

Consider the following C code snippet:

```c
int foo()
{
	char *blah = malloc(1024);
	// ...
	// use blah in safe ways
	// ...
	return 1;
}
```

**Q:** What happens with the memory pointed to by `blah`?

**A:** It is never freed, so this part of the memory is always occupied. If too many such pointers exist, the memory may be exhausted.

**Q:** Why is this a security issue?

**A:** Sensitive data might be left in the memory.

## Use After Free (UAF)

Consider the following C code snippet:

```c
int main() {
    char *user_input = malloc(8);

    printf("Name? ");
    scanf("%7s", user_input);
    printf("Hello %s!\n", user_input);
    free(user_input);

    long *authenticated = malloc(8);
    *authenticated = 0;

    printf("Password? ");
    scanf("%7s", user_input);

    if (getuid() == 0 || strcmp(user_input, "hunter2") == 0) *authenticated = 1;
    if (*authenticated) sendfile(0, open("/flag", 0), 0, 128);
}
```

Pointers to an allocation remain valid after `free()`ing the allocation, and might be used afterwards!

**Q:** Why is this bad?

**A:** Modify the code a little bit in order to print out the addresses of `user_input` and `authenticated`:

```c
//uaf.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include<fcntl.h>
#include <sys/sendfile.h>

int main() {
    char *user_input = malloc(8);
    // Debugging information
    printf("user_input address: %p\n", user_input);

    printf("Name? ");
    scanf("%7s", user_input);
    printf("Hello %s!\n", user_input);
    free(user_input);

    long *authenticated = malloc(8);
    // Debugging information
    printf("authenticated address: %p\n", authenticated);
    *authenticated = 0;

    printf("Password? ");
    scanf("%7s", user_input);

    if (getuid() == 0 || strcmp(user_input, "hunter2") == 0) *authenticated = 1;
    if (*authenticated) sendfile(0, open("./flag", 0), 0, 128);
}
```

Compile this source code and create a fake flag:

```bash
gcc uaf.c -o uaf
echo 'ctf{this_is_a_flag}' > flag
```

After `free(user_input)` gets called, the pointer `user_input` remains valid. Later on, the program allocates another chunk of memory `long *authenticated = malloc(8)`. Since the allocation size (8 bytes) is the same, the memory region owned by `user_input` now is assigned to `authenticated`. You can verify this fact based on the debugging information output:

![user\_input and authenticated have the same address](https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FIdioVaW7JoD3RHTABJp4%2Fimage.png?alt=media\&token=749581b8-0b78-433b-b3f6-85e38e069304)

In the end, UAF is triggered by `scanf("%7s", user_input)`. Since both pointers `user_input` and `authenticated` are pointing to the same memory location at this moment, `scanf("%7s", user_input)` is essentially the same as `scanf("%7s", authenticated)`. If we enter any nonempty password, `authenticate` will be overwritten, and thus the check `if (*authenticated)` is bypassed.

## **Memory Disclosure**

**Simple case:** UAF, but with a `printf()` instead of a `scanf()`.

**Complex case:** Some heap implementations (including dlmalloc and ptmalloc) reuse `free()`d chunks to store metadata.

Some heap implementations (including dlmalloc and ptmalloc) reuse `free()`d chunks to store metadata. Consider the following C code snippet:

```c
// heap_disclosure.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

int main() {
    char *password = malloc(8);
    char *name = malloc(8);

    printf("Password? ");
    scanf("%7s", password);
    assert(strcmp(password, "hunter2") == 0);
    free(password);

    printf("Name? ");
    scanf("%7s", name);
    printf("Hello %s!\n", name);
    free(name);

    printf("Goodbye, %s!\n", name);
}
```

Compile it:

```bash
gcc heap_disclosure.c -o heap_disclosure
```

Note that the pointer `name` shows up in `printf` after being `free()`d:

```c
free(name);

printf("Goodbye, %s!\n", name);
```

This error leaks the address of `name` from the heap:

![heap\_disclosure](https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FQCXh2QezxHy8XjfJr3K9%2Fimage.png?alt=media\&token=fc603684-6faa-4e7b-a669-daaed82f7dd8)

## **Metadata Corruption**

Allocator metadata can be written, not just read, to cause crazy effects. One of the earliest widespread heap exploits, developed by Solar Designer in 2000:

{% embed url="<https://www.openwall.com/articles/JPEG-COM-Marker-Vulnerability>" %}
The earliest heap exploit, by Solar Designer
{% endembed %}

Soon formalized in hacker literature in 2001:

* [Vudo malloc tricks, by MaXX](http://phrack.org/issues/57/8.html)
* [Once upon a free(), by anonymous](http://phrack.org/issues/57/9.html)

Now a whole genre in the hacking scene!

## **Hackers are Weird: The Rise of the Houses**

Phantasmal Phantasmagoria developed a "lore" around heap metadata corruption:

{% embed url="<https://seclists.org/bugtraq/2005/Oct/118>" %}
The Malloc Maleficarum
{% endembed %}

Described and named a number of metadata corruption techniques:

* House of Prime
* House of Mind
* House of Force
* House of Lore
* **House of Spirit** (still works nowadays)
* House of Chaos

Things got out of hand quick. Later work:

* **House of Underground**
* **House of Orange**
* **House of Einherjar**
* **House of Rabbit**
* **House of Botcake**

Learn more:

{% embed url="<https://github.com/shellphish/how2heap>" %}
how2heap
{% endembed %}

## **The Danger of Overlapping Allocations**

Typically, heap metadata corruption is used to confuse the allocator into allocating overlapping memory. As we saw with UAF, this can be extremely dangerous.

If two pointers are pointing to the same memory, and one of the pointers is treated by the program in a security-critical manner, and the other one can be written to or read by an attacker, it's game over!

"Security-critical manner?"

* `authentication` variables
* Function pointers (control flow hijack)
* Program metadata such as length (inducing memory errors)
* Sensitive data (such as the flag)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfwriteup/web2-ctf/pwn.college/dynamic-allocator-misuse/dangers-of-the-heap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
