hacktricks/binary-exploitation/heap/double-free.md

6.5 KiB
Raw Permalink Blame History

ダブルフリー

htARTEHackTricks AWS Red Team Expert を通じてゼロからヒーローまでAWSハッキングを学ぶ

HackTricks をサポートする他の方法:

基本情報

メモリブロックを複数回解放すると、割り当て器のデータが狂い、攻撃の隙間が生まれる可能性があります。こうなる理由は次のとおりですメモリブロックを解放すると、それは空きチャンクのリスト「fastbin」に戻ります。同じブロックを2回連続で解放すると、割り当て器はこれを検出してエラーをスローします。しかし、その間に別のチャンクを解放すると、ダブルフリーチェックがバイパスされ、破損が発生します。

そして、新しいメモリを要求すると(mallocを使用)、割り当て器は2回解放されたブロックを提供する可能性があります。これにより、異なる2つのポインタが同じメモリ位置を指すことがあります。攻撃者がそのうちの1つのポインタを制御している場合、そのメモリの内容を変更でき、セキュリティの問題を引き起こすか、コードの実行を許可する可能性があります。

例:

#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 *)i1);

return 0;
}

この例では、tcacheを複数の解放されたチャンクで埋めた後、コードはチャンクh、次にチャンクi、そして再びhを解放し、ダブルフリーエラーを引き起こします。これにより、再割り当て時に重複するメモリアドレスを受け取る可能性が開かれ、つまり2つ以上のポインタが同じメモリ位置を指すことができます。1つのポインタを介してデータを操作することで、他方に影響を与える可能性があり、重大なセキュリティリスクと悪用の可能性が生じます。

実行すると、i1i2が同じアドレスを取得したことに注意してください:

初期割り当て:
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
i1: 0xaaab0f0c23a0
i2: 0xaaab0f0c23a0

参考文献

ゼロからヒーローまでのAWSハッキングを学ぶ htARTEHackTricks AWS Red Team Expert

HackTricksをサポートする他の方法