mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
131 lines
5.4 KiB
Markdown
131 lines
5.4 KiB
Markdown
# Double Free
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Temel Bilgiler
|
||
|
||
Eğer bir bellek bloğunu birden fazla kez serbest bırakırsanız, bu, ayırıcı verilerini bozabilir ve saldırılara kapı açabilir. İşte bu nasıl olur: bir bellek bloğunu serbest bıraktığınızda, bu, serbest parçaların bir listesine geri döner (örneğin, "hızlı kutu"). Eğer aynı bloğu ardışık olarak iki kez serbest bırakırsanız, ayırıcı bunu tespit eder ve bir hata fırlatır. Ancak eğer **araya başka bir parça serbest bırakırsanız, çift serbest bırakma kontrolü atlanır**, bu da bozulmaya neden olur.
|
||
|
||
Şimdi, yeni bellek talep ettiğinizde ( `malloc` kullanarak), ayırıcı size **iki kez serbest bırakılmış bir bloğu** verebilir. Bu, iki farklı işaretçinin aynı bellek konumuna işaret etmesine yol açabilir. Eğer bir saldırgan bu işaretçilerden birini kontrol ederse, o bellek içeriğini değiştirebilir, bu da güvenlik sorunlarına neden olabilir veya hatta kod çalıştırmalarına izin verebilir.
|
||
|
||
Örnek:
|
||
```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;
|
||
}
|
||
```
|
||
Bu örnekte, tcache'i birkaç serbest bırakılmış parça (7) ile doldurduktan sonra, kod **`h` parçasını serbest bırakır, ardından `i` parçasını serbest bırakır ve sonra tekrar `h` parçasını serbest bırakır, bu da bir double free'e neden olur** (aynı zamanda Fast Bin dup olarak da bilinir). Bu, yeniden tahsis ederken üst üste binen bellek adresleri alma olasılığını açar, bu da iki veya daha fazla işaretçinin aynı bellek konumuna işaret edebileceği anlamına gelir. Bir işaretçi aracılığıyla verileri manipüle etmek, diğerini etkileyebilir ve bu da kritik bir güvenlik riski ve potansiyel bir istismar olanağı yaratır.
|
||
|
||
Bunu yürütürken, **`i1` ve `i2`'nin aynı adresi aldığını** not edin:
|
||
|
||
<pre><code>Başlangıç tahsisleri:
|
||
a: 0xaaab0f0c22a0
|
||
b: 0xaaab0f0c22c0
|
||
c: 0xaaab0f0c22e0
|
||
d: 0xaaab0f0c2300
|
||
e: 0xaaab0f0c2320
|
||
f: 0xaaab0f0c2340
|
||
g: 0xaaab0f0c2360
|
||
h: 0xaaab0f0c2380
|
||
i: 0xaaab0f0c23a0
|
||
Yeniden tahsislerden sonra:
|
||
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>
|
||
|
||
## Örnekler
|
||
|
||
- [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/)
|
||
- Sadece `0x70` boyutunun dışında Fast-Bin boyutunda parçalar tahsis edebiliriz, bu da olağan `__malloc_hook` üzerine yazmayı engeller.
|
||
- Bunun yerine, Fast Bin dup için hedef olarak `0x56` ile başlayan PIE adreslerini kullanıyoruz (1/2 şansı).
|
||
- PIE adreslerinin saklandığı yerlerden biri `main_arena` içindedir, bu Glibc içindedir ve `__malloc_hook`'a yakındır.
|
||
- Orada bir parça tahsis etmek için `main_arena`'nın belirli bir ofsetini hedef alıyoruz ve `__malloc_hook`'a ulaşana kadar parçalar tahsis etmeye devam ediyoruz.
|
||
- [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/)
|
||
- Tcache kutularını ve bir null-byte taşmasını kullanarak, bir double-free durumu elde edebiliriz:
|
||
- `0x110` boyutunda üç parça tahsis ediyoruz (`A`, `B`, `C`)
|
||
- `B`'yi serbest bırakıyoruz
|
||
- `A`'yı serbest bırakıyoruz ve null-byte taşmasını kullanmak için tekrar tahsis ediyoruz
|
||
- Artık `B`'nin boyut alanı `0x100`, `0x111` yerine, bu yüzden tekrar serbest bırakabiliriz
|
||
- Aynı adrese işaret eden `0x110` boyutunda bir Tcache-bin ve `0x100` boyutunda bir Tcache-binimiz var. Yani bir double free durumumuz var.
|
||
- [Tcache poisoning](tcache-bin-attack.md) kullanarak double free'i değerlendiriyoruz.
|
||
|
||
## Referanslar
|
||
|
||
- [https://heap-exploitation.dhavalkapil.com/attacks/double_free](https://heap-exploitation.dhavalkapil.com/attacks/double_free)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|