Double Free
Reading time: 5 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Basic Information
Якщо ви звільняєте блок пам'яті більше ніж один раз, це може порушити дані аллокатора і відкрити двері для атак. Ось як це відбувається: коли ви звільняєте блок пам'яті, він повертається до списку вільних частин (наприклад, "швидкий бін"). Якщо ви звільняєте той самий блок двічі підряд, аллокатор виявляє це і видає помилку. Але якщо ви звільняєте іншу частину між цим, перевірка на подвійне звільнення обходиться, що призводить до пошкодження.
Тепер, коли ви запитуєте нову пам'ять (використовуючи malloc
), аллокатор може надати вам блок, який був звільнений двічі. Це може призвести до того, що два різні вказівники вказують на одне й те саме місце в пам'яті. Якщо зловмисник контролює один з цих вказівників, він може змінити вміст цієї пам'яті, що може викликати проблеми з безпекою або навіть дозволити йому виконати код.
Example:
#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
, що викликає подвійне звільнення (також відоме як Fast Bin dup). Це відкриває можливість отримання перекриваючих адрес пам'яті під час повторного виділення, що означає, що два або більше вказівників можуть вказувати на одне й те саме місце в пам'яті. Маніпулювання даними через один вказівник може вплинути на інший, створюючи критичний ризик безпеки та потенціал для експлуатації.
Виконуючи це, зверніть увагу, як i1
і i2
отримали ту ж адресу:
Початкові виділення:
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
Приклади
- Dragon Army. Hack The Box
- Ми можемо виділяти лише частини розміру Fast-Bin, за винятком розміру
0x70
, що запобігає звичайному переписуванню__malloc_hook
. - Натомість ми використовуємо адреси PIE, які починаються з
0x56
, як ціль для Fast Bin dup (1/2 шанс). - Одне з місць, де зберігаються адреси PIE, знаходиться в
main_arena
, яка є частиною Glibc і знаходиться поруч з__malloc_hook
. - Ми націлюємося на конкретний зсув
main_arena
, щоб виділити частину там і продовжити виділення частин, поки не досягнемо__malloc_hook
, щоб отримати виконання коду. - zero_to_hero. PicoCTF
- Використовуючи Tcache bins і переповнення нульовим байтом, ми можемо досягти ситуації подвійного звільнення:
- Ми виділяємо три частини розміру
0x110
(A
,B
,C
) - Ми звільняємо
B
- Ми звільняємо
A
і знову виділяємо, щоб використати переповнення нульовим байтом - Тепер поле розміру
B
становить0x100
, замість0x111
, тому ми можемо звільнити його знову - У нас є один Tcache-bin розміру
0x110
і один розміру0x100
, які вказують на ту ж адресу. Отже, у нас є подвійне звільнення. - Ми використовуємо подвійне звільнення за допомогою Tcache poisoning
Посилання
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.