131 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ダブルフリー
{{#include ../../banners/hacktricks-training.md}}
## 基本情報
メモリのブロックを複数回解放すると、アロケータのデータが混乱し、攻撃の扉が開かれる可能性があります。これは次のように発生しますメモリのブロックを解放すると、それはフリーチャンクのリスト「ファストビン」に戻ります。同じブロックを連続して2回解放すると、アロケータはこれを検出し、エラーをスローします。しかし、**その間に別のチャンクを解放すると、ダブルフリーのチェックがバイパスされ**、破損が発生します。
今、新しいメモリを要求すると(`malloc`を使用)、アロケータは**2回解放されたブロック**を返す可能性があります。これにより、2つの異なるポインタが同じメモリ位置を指すことになります。攻撃者がそのポインタの1つを制御している場合、彼らはそのメモリの内容を変更でき、これがセキュリティ問題を引き起こしたり、コードを実行させたりする可能性があります。
例:
```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;
}
```
この例では、tcacheをいくつかの解放されたチャンク7で埋めた後、コードは**チャンク`h`を解放し、次にチャンク`i`を解放し、再び`h`を解放することでダブルフリーを引き起こします**ファストビンの重複とも呼ばれます。これにより、再割り当て時に重複したメモリアドレスを受け取る可能性が生じ、2つ以上のポインタが同じメモリ位置を指すことができます。1つのポインタを通じてデータを操作すると、他のポインタにも影響を与え、重大なセキュリティリスクと悪用の可能性を生み出します。
実行すると、**`i1``i2`が同じアドレスを取得したことに注意してください**
<pre><code>初期割り当て:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
d: 0xaaab0f0c2300
e: 0xaaab0f0c2320
f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
再割り当て後:
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>
## 例
- [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/)
- サイズ`0x70`を除いて、ファストビンサイズのチャンクしか割り当てられず、通常の`__malloc_hook`の上書きを防ぎます。
- 代わりに、`0x56`で始まるPIEアドレスをファストビンの重複のターゲットとして使用します1/2の確率
- PIEアドレスが保存される場所の1つは`main_arena`で、これはGlibc内にあり、`__malloc_hook`の近くにあります。
- 特定のオフセットの`main_arena`をターゲットにして、そこにチャンクを割り当て、`__malloc_hook`に到達するまでチャンクを割り当て続けてコード実行を取得します。
- [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/)
- Tcacheビンとヌルバイトオーバーフローを使用して、ダブルフリーの状況を達成できます
- サイズ`0x110`のチャンクを3つ`A``B``C`)割り当てます。
- `B`を解放します。
- `A`を解放し、ヌルバイトオーバーフローを使用するために再度割り当てます。
- 現在、`B`のサイズフィールドは`0x100`であり、`0x111`ではないため、再度解放できます。
- サイズ`0x110`のTcacheビンとサイズ`0x100`のTcacheビンが同じアドレスを指しているため、ダブルフリーが発生します。
- [Tcache poisoning](tcache-bin-attack.md)を使用してダブルフリーを利用します。
## 参考文献
- [https://heap-exploitation.dhavalkapil.com/attacks/double_free](https://heap-exploitation.dhavalkapil.com/attacks/double_free)
{{#include ../../banners/hacktricks-training.md}}