9.5 KiB
Подвійне вивільнення
{% hint style="success" %}
Вивчайте та практикуйте хакінг AWS: Навчання AWS Red Team Expert (ARTE) від HackTricks
Вивчайте та практикуйте хакінг GCP: Навчання GCP Red Team Expert (GRTE) від HackTricks
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами на Twitter 🐦 @hacktricks_live.
- Поширюйте хакерські трюки, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
Основна інформація
Якщо ви вивільняєте блок пам'яті більше одного разу, це може спричинити проблеми з даними алокатора та відкрити двері для атак. Ось як це відбувається: коли ви вивільняєте блок пам'яті, він повертається до списку вільних частин (наприклад, "швидкий бін"). Якщо ви вивільнюєте той самий блок двічі поспіль, алокатор виявляє це і видає помилку. Але якщо вивільнити інший блок між ними, перевірка подвійного вивільнення обходиться, що призводить до порушень.
Тепер, коли ви просите нову пам'ять (використовуючи malloc
), алокатор може дати вам блок, який був вивільнений двічі. Це може призвести до того, що два різні вказівники вказують на ту саму область пам'яті. Якщо зловмисник контролює один з цих вказівників, він може змінити вміст цієї пам'яті, що може призвести до проблем з безпекою або навіть дозволити виконати код.
Приклад:
#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 кількома вивільненими частинами (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 та переповнення нульовим байтом, ми можемо досягти ситуації подвійного вивільнення:
- Ми виділяємо три частини розміром
0x110
(A
,B
,C
). - Ми вивільняємо
B
. - Ми вивільняємо
A
та виділяємо знову, щоб використати переповнення нульовим байтом. - Тепер розмір поля
B
-0x100
, а не0x111
, тому ми можемо знову його вивільнити. - У нас є один бін Tcache розміром
0x110
та один розміром0x100
, які вказують на ту саму адресу. Таким чином, ми маємо подвійне вивільнення. - Ми використовуємо подвійне вивільнення за допомогою забруднення Tcache
Посилання
{% hint style="success" %}
Вивчайте та практикуйте взлом AWS:Навчання HackTricks AWS Red Team Expert (ARTE)
Вивчайте та практикуйте взлом GCP: Навчання HackTricks GCP Red Team Expert (GRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами на Twitter 🐦 @hacktricks_live.
- Поширюйте хакерські трюки, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.