mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
e234a234ce
A slight typo here probably. Printing i1 would always result in the same address regardless of the double free.
158 lines
7.1 KiB
Markdown
158 lines
7.1 KiB
Markdown
# Double Free
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## Basic Information
|
|
|
|
If you free a block of memory more than once, it can mess up the allocator's data and open the door to attacks. Here's how it happens: when you free a block of memory, it goes back into a list of free chunks (e.g. the "fast bin"). If you free the same block twice in a row, the allocator detects this and throws an error. But if you **free another chunk in between, the double-free check is bypassed**, causing corruption.
|
|
|
|
Now, when you ask for new memory (using `malloc`), the allocator might give you a **block that's been freed twice**. This can lead to two different pointers pointing to the same memory location. If an attacker controls one of those pointers, they can change the contents of that memory, which can cause security issues or even allow them to execute code.
|
|
|
|
Example:
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
int main() {
|
|
// Allocate memory for three chunks
|
|
char *a = (char *)malloc(10);
|
|
char *b = (char *)malloc(10);
|
|
char *c = (char *)malloc(10);
|
|
char *d = (char *)malloc(10);
|
|
char *e = (char *)malloc(10);
|
|
char *f = (char *)malloc(10);
|
|
char *g = (char *)malloc(10);
|
|
char *h = (char *)malloc(10);
|
|
char *i = (char *)malloc(10);
|
|
|
|
// Print initial memory addresses
|
|
printf("Initial allocations:\n");
|
|
printf("a: %p\n", (void *)a);
|
|
printf("b: %p\n", (void *)b);
|
|
printf("c: %p\n", (void *)c);
|
|
printf("d: %p\n", (void *)d);
|
|
printf("e: %p\n", (void *)e);
|
|
printf("f: %p\n", (void *)f);
|
|
printf("g: %p\n", (void *)g);
|
|
printf("h: %p\n", (void *)h);
|
|
printf("i: %p\n", (void *)i);
|
|
|
|
// Fill tcache
|
|
free(a);
|
|
free(b);
|
|
free(c);
|
|
free(d);
|
|
free(e);
|
|
free(f);
|
|
free(g);
|
|
|
|
// Introduce double-free vulnerability in fast bin
|
|
free(h);
|
|
free(i);
|
|
free(h);
|
|
|
|
|
|
// Reallocate memory and print the addresses
|
|
char *a1 = (char *)malloc(10);
|
|
char *b1 = (char *)malloc(10);
|
|
char *c1 = (char *)malloc(10);
|
|
char *d1 = (char *)malloc(10);
|
|
char *e1 = (char *)malloc(10);
|
|
char *f1 = (char *)malloc(10);
|
|
char *g1 = (char *)malloc(10);
|
|
char *h1 = (char *)malloc(10);
|
|
char *i1 = (char *)malloc(10);
|
|
char *i2 = (char *)malloc(10);
|
|
|
|
// Print initial memory addresses
|
|
printf("After reallocations:\n");
|
|
printf("a1: %p\n", (void *)a1);
|
|
printf("b1: %p\n", (void *)b1);
|
|
printf("c1: %p\n", (void *)c1);
|
|
printf("d1: %p\n", (void *)d1);
|
|
printf("e1: %p\n", (void *)e1);
|
|
printf("f1: %p\n", (void *)f1);
|
|
printf("g1: %p\n", (void *)g1);
|
|
printf("h1: %p\n", (void *)h1);
|
|
printf("i1: %p\n", (void *)i1);
|
|
printf("i2: %p\n", (void *)i2);
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
In this example, after filling the tcache with several freed chunks (7), the code **frees chunk `h`, then chunk `i`, and then `h` again, causing a double free** (also known as Fast Bin dup). This opens the possibility of receiving overlapping memory addresses when reallocating, meaning two or more pointers can point to the same memory location. Manipulating data through one pointer can then affect the other, creating a critical security risk and potential for exploitation.
|
|
|
|
Executing it, note how **`i1` and `i2` got the same address**:
|
|
|
|
<pre><code>Initial allocations:
|
|
a: 0xaaab0f0c22a0
|
|
b: 0xaaab0f0c22c0
|
|
c: 0xaaab0f0c22e0
|
|
d: 0xaaab0f0c2300
|
|
e: 0xaaab0f0c2320
|
|
f: 0xaaab0f0c2340
|
|
g: 0xaaab0f0c2360
|
|
h: 0xaaab0f0c2380
|
|
i: 0xaaab0f0c23a0
|
|
After reallocations:
|
|
a1: 0xaaab0f0c2360
|
|
b1: 0xaaab0f0c2340
|
|
c1: 0xaaab0f0c2320
|
|
d1: 0xaaab0f0c2300
|
|
e1: 0xaaab0f0c22e0
|
|
f1: 0xaaab0f0c22c0
|
|
g1: 0xaaab0f0c22a0
|
|
h1: 0xaaab0f0c2380
|
|
<strong>i1: 0xaaab0f0c23a0
|
|
</strong><strong>i2: 0xaaab0f0c23a0
|
|
</strong></code></pre>
|
|
|
|
## Examples
|
|
|
|
* [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/)
|
|
* We can only allocate Fast-Bin-sized chunks except for size `0x70`, which prevents the usual `__malloc_hook` overwrite.
|
|
* Instead, we use PIE addresses that start with `0x56` as a target for Fast Bin dup (1/2 chance).
|
|
* One place where PIE addresses are stored is in `main_arena`, which is inside Glibc and near `__malloc_hook`
|
|
* We target a specific offset of `main_arena` to allocate a chunk there and continue allocating chunks until reaching `__malloc_hook` to get code execution.
|
|
* [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/)
|
|
* Using Tcache bins and a null-byte overflow, we can achieve a double-free situation:
|
|
* We allocate three chunks of size `0x110` (`A`, `B`, `C`)
|
|
* We free `B`
|
|
* We free `A` and allocate again to use the null-byte overflow
|
|
* Now `B`'s size field is `0x100`, instead of `0x111`, so we can free it again
|
|
* We have one Tcache-bin of size `0x110` and one of size `0x100` that point to the same address. So we have a double free.
|
|
* We leverage the double free using [Tcache poisoning](tcache-bin-attack.md)
|
|
|
|
## References
|
|
|
|
* [https://heap-exploitation.dhavalkapil.com/attacks/double\_free](https://heap-exploitation.dhavalkapil.com/attacks/double\_free)
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|