mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
131 lines
4.9 KiB
Markdown
131 lines
4.9 KiB
Markdown
# Double Free
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Osnovne Informacije
|
|
|
|
Ako oslobodite blok memorije više od jednom, to može poremetiti podatke alokatora i otvoriti vrata napadima. Evo kako se to dešava: kada oslobodite blok memorije, on se vraća u listu slobodnih delova (npr. "brzi bin"). Ako oslobodite isti blok dva puta zaredom, alokator to detektuje i javlja grešku. Ali ako **oslobodite drugi deo između, provera duplog oslobađanja se zaobilazi**, što uzrokuje oštećenje.
|
|
|
|
Sada, kada zatražite novu memoriju (koristeći `malloc`), alokator vam može dati **blok koji je oslobođen dva puta**. To može dovesti do dva različita pokazivača koji upućuju na istu memorijsku lokaciju. Ako napadač kontroliše jedan od tih pokazivača, može promeniti sadržaj te memorije, što može izazvati sigurnosne probleme ili čak omogućiti izvršavanje koda.
|
|
|
|
Primer:
|
|
```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;
|
|
}
|
|
```
|
|
U ovom primeru, nakon popunjavanja tcache-a sa nekoliko oslobođenih delova (7), kod **oslobađa deo `h`, zatim deo `i`, a zatim ponovo `h`, uzrokujući double free** (poznat i kao Fast Bin dup). Ovo otvara mogućnost dobijanja preklapajućih memorijskih adresa prilikom ponovnog alociranja, što znači da dva ili više pokazivača mogu ukazivati na istu memorijsku lokaciju. Manipulacija podacima kroz jedan pokazivač može zatim uticati na drugi, stvarajući kritičan bezbednosni rizik i potencijal za eksploataciju.
|
|
|
|
Izvršavajući to, obratite pažnju na to kako **`i1` i `i2` imaju istu adresu**:
|
|
|
|
<pre><code>Početne alokacije:
|
|
a: 0xaaab0f0c22a0
|
|
b: 0xaaab0f0c22c0
|
|
c: 0xaaab0f0c22e0
|
|
d: 0xaaab0f0c2300
|
|
e: 0xaaab0f0c2320
|
|
f: 0xaaab0f0c2340
|
|
g: 0xaaab0f0c2360
|
|
h: 0xaaab0f0c2380
|
|
i: 0xaaab0f0c23a0
|
|
Nakon ponovnih alokacija:
|
|
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>
|
|
|
|
## Primeri
|
|
|
|
- [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/)
|
|
- Možemo alocirati samo Fast-Bin veličine delove osim za veličinu `0x70`, što sprečava uobičajeno prepisivanje `__malloc_hook`.
|
|
- Umesto toga, koristimo PIE adrese koje počinju sa `0x56` kao cilj za Fast Bin dup (1/2 šansa).
|
|
- Jedno mesto gde se čuvaju PIE adrese je u `main_arena`, koja se nalazi unutar Glibc i blizu `__malloc_hook`.
|
|
- Ciljamo specifičan pomak `main_arena` da bismo alocirali deo tamo i nastavljamo sa alokacijom delova dok ne dođemo do `__malloc_hook` da bismo dobili izvršenje koda.
|
|
- [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/)
|
|
- Koristeći Tcache binove i overflow sa null-bajtom, možemo postići situaciju double-free:
|
|
- Alociramo tri dela veličine `0x110` (`A`, `B`, `C`)
|
|
- Oslobađamo `B`
|
|
- Oslobađamo `A` i ponovo alociramo da bismo iskoristili overflow sa null-bajtom
|
|
- Sada je veličina `B`-ovog polja `0x100`, umesto `0x111`, tako da ga možemo ponovo osloboditi
|
|
- Imamo jedan Tcache-bin veličine `0x110` i jedan veličine `0x100` koji ukazuju na istu adresu. Tako imamo double free.
|
|
- Iskorišćavamo double free koristeći [Tcache poisoning](tcache-bin-attack.md)
|
|
|
|
## Reference
|
|
|
|
- [https://heap-exploitation.dhavalkapil.com/attacks/double_free](https://heap-exploitation.dhavalkapil.com/attacks/double_free)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|