hacktricks/binary-exploitation/libc-heap/off-by-one-overflow.md

139 lines
9.9 KiB
Markdown
Raw Normal View History

# Bir birim aşımı
{% hint style="success" %}
AWS Hacking'i öğrenin ve uygulayın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCP Hacking'i öğrenin ve uygulayın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricks'i Destekleyin</summary>
* [**Abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) katılın veya [**telegram grubuna**](https://t.me/peass) katılın veya bizi **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)** takip edin.**
* **Hacking püf noktalarını paylaşarak PR'ler göndererek** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına katkıda bulunun.
</details>
{% endhint %}
## Temel Bilgiler
Yalnızca 1B aşımına erişim sağlamak, saldırganın bir sonraki parçanın `size` alanını değiştirmesine olanak tanır. Bu, hangi parçaların gerçekten serbest bırakıldığını değiştirmeyi sağlar ve potansiyel olarak başka bir meşru parçayı içeren bir parça oluşturabilir. Sömürü, [çift serbest bırakma](double-free.md) veya parçaların üst üste binmesiyle benzerdir.
Bir birim aşımı zafiyetinin 2 türü vardır:
* Keyfi bayt: Bu tür, o baytı herhangi bir değerle üzerine yazmayı sağlar
* Null baytı (off-by-null): Bu tür, o baytı yalnızca 0x00 ile üzerine yazmayı sağlar
* Bu zafiyetin yaygın bir örneği, `strlen` ve `strcpy` işlevlerinin tutarsız davranışının görüldüğü aşağıdaki kodda görülebilir, bu da bir sonraki parçanın başında 0x00 baytını ayarlamayı mümkün kılar.
* Bu, [House of Einherjar](house-of-einherjar.md) ile sömürülebilir.
* Tcache kullanılıyorsa, bu [çift serbest bırakma](double-free.md) durumuna dönüştürülebilir.
<details>
<summary>Off-by-null</summary>
```c
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}
```
</details>
Diğer kontroller arasında, artık bir parça serbest bırakıldığında önceki boyut, metadatadaki parçanın yapılandırılmış boyutuyla karşılaştırılır, bu saldırı 2.28 sürümden itibaren oldukça karmaşık hale getirir.
### Kod örneği:
* [https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c](https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking\_free\_chunks.c)
* Bu saldırı artık Tcache'lerin kullanımı nedeniyle çalışmıyor.
* Ayrıca, daha büyük parçalar kullanarak (bu durumda Tcache'lerin dahil olmadığı) kötüye kullanmaya çalışırsanız, hata alırsınız: `malloc(): invalid next size (unsorted)`
### Amaç
* Bir parçanın başka bir parçanın içinde bulunmasını sağlamak, böylece ikinci parçanın üzerinde yazma erişimi, içerilen parçayı üzerine yazmamıza olanak tanır
### Gereksinimler
* Boyut metadatası bilgisini değiştirmek için bir fazla bir taşma
### Genel off-by-one saldırısı
* Üç parça `A`, `B` ve `C` (örneğin boyutları 0x20) tahsis edilir ve üst parçayla birleşmeyi önlemek için başka bir parça tahsis edilir.
* `C` serbest bırakılır (0x20 Tcache serbest listesine eklendi).
* Parça `A`yı `B` üzerine taşır. `B`nin `size` alanını 0x21'den 0x41'e değiştirmek için fazla bir taşmayı kötüye kullanın.
* Şimdi `B`, serbest parça `C`yi içeriyor
* `B`'yi serbest bırakın ve 0x40 parça tahsis edin (buraya tekrar yerleştirilecektir)
* Hala serbest olan `C`nin `fd` işaretçisini değiştirebiliriz (Tcache zehirlenmesi)
### Off-by-null saldırısı
* Bellekten üç parça (a, b, c) sırayla ayrılır. Ardından ortadaki parça serbest bırakılır. İlk parça fazla bir taşma açığı içerir ve saldırgan bunu 0x00 ile kötüye kullanır (önceki bayt 0x10 ise, ortadaki parçanın gerçekten olduğundan 0x10 daha küçük olduğunu gösterir).
* Daha sonra, ortadaki serbest bırakılan parçaya (b) 2 daha küçük parça tahsis edilir, ancak `b + b->size` ifadesi c parçasını güncellemez çünkü işaret edilen adres olması gereken adresten daha küçüktür.
* Daha sonra, b1 ve c serbest bırakılır. `c - c->prev_size` hala b'yi (şimdi b1) işaret ettiği için, her ikisi de bir parçada birleştirilir. Ancak, b2 hala b1 ve c arasında içindedir.
* Son olarak, bu bellek alanını geri kazanmak için yeni bir malloc işlemi gerçekleştirilir ve bu aslında b2'yi içerecek şekilde olacaktır, bu da yeni malloc sahibinin b2 içeriğini kontrol etmesine olanak tanır.
Bu resim saldırıyı mükemmel bir şekilde açıklar:
<figure><img src="../../.gitbook/assets/image (1247).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks">https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks</a></p></figcaption></figure>
## Diğer Örnekler ve Referanslar
* [**https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks**](https://heap-exploitation.dhavalkapil.com/attacks/shrinking\_free\_chunks)
* [**Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/bon-nie-appetit/)
* `strlen`'in bir sonraki parçanın `size` alanını düşünerek bir off-by-one hatası oluşturması.
* Tcache kullanılıyor, bu nedenle genel off-by-one saldırıları, Tcache zehirlenmesi ile keyfi yazma işlemine izin vermek için çalışır.
* [**Asis CTF 2016 b00ks**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#1-asis-ctf-2016-b00ks)
* Bir off-by-one'ı kötüye kullanarak bir adres sızdırmak mümkündür çünkü bir dizenin sonundaki 0x00 baytı bir sonraki alan tarafından üzerine yazılır.
* Keyfi yazma, işaretçiyi başka bir yere işaret etmek için off-by-one yazmayı kötüye kullanarak yapılır ve sahte işaretçilerle sahte bir yapı oluşturulur. Daha sonra, bu yapının işaretçisini takip ederek keyfi yazma elde etmek mümkündür.
* Libc adresi sızdırılır çünkü heap, mmap kullanılarak genişletildiğinde, mmap tarafından ayrılan belleğin libc'ten sabit bir ofseti vardır.
* Son olarak, keyfi yazma, \_\_free\_hook adresine bir tane araçla yazmak için kötüye kullanılır.
* [**plaidctf 2015 plaiddb**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off\_by\_one/#instance-2-plaidctf-2015-plaiddb)
* Kullanıcı giriş satırlarını okuyan `getline` işlevinde NULL off-by-one bir zafiyet bulunmaktadır. Bu işlev, içeriğin "anahtarını" okumak için kullanılır.
* 5 başlangıç parçası oluşturulur:
* parça1 (0x200)
* parça2 (0x50)
* parça5 (0x68)
* parça3 (0x1f8)
* parça4 (0xf0)
* parça savunması (0x400), üst parçayla birleşmeyi önlemek için
* Ardından parça 1, 5 ve 3 serbest bırakılır, böylece:
* ```python
[ 0x200 Parça 1 (serbest) ] [ 0x50 Parça 2 ] [ 0x68 Parça 5 (serbest) ] [ 0x1f8 Parça 3 (serbest) ] [ 0xf0 Parça 4 ] [ 0x400 Parça savunması ]
```
* Daha sonra, parça3 (0x1f8) kötüye kullanılarak null off-by-one, prev\_size'ın `0x4e0` olarak yazılmasını sağlar.
* Başlangıçta tahsis edilen parça1, 2, 5 ve 3'ün boyutlarının ve bu parçaların başlıklarının toplamının `0x4e0`'a eşit olduğuna dikkat edin: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
* Ardından, parça 4 serbest bırakılır, tüm parçaları başlangıca kadar tüketen bir parça oluşturur:
* ```python
[ 0x4e0 Parça 1-2-5-3 (serbest) ] [ 0xf0 Parça 4 (bozuk) ] [ 0x400 Parça savunması ]
```
* ```python
[ 0x200 Parça 1 (serbest) ] [ 0x50 Parça 2 ] [ 0x68 Parça 5 (serbest) ] [ 0x1f8 Parça 3 (serbest) ] [ 0xf0 Parça 4 ] [ 0x400 Parça savunması ]
```
* Daha sonra, `0x200` bayt tahsis edilir ve orijinal parça 1 doldurulur
* Ve başka 0x200 bayt tahsis edilir ve parça2 yok edilir ve dolayısıyla hiçbir sızıntı yok ve bu işe yaramaz mı? Belki bunun yapılması gerekmeyebilir
* Daha sonra, 0x58 "a" ile başka bir parça tahsis edilir (parça2'yi üzerine yazarak parça5'e ulaşır) ve parça5'in hızlı bin parçasının `__malloc_hook`'a işaret eden `fd`si değiştirilir
* Son olarak, 0x68'lik yeni bir hızlı bin parçası tahsis edilir ve `__malloc_hook` bir `one_gadget` adresiyle üzerine yazılır
{% hint style="success" %}
AWS Hacking'i öğrenin ve uygulayın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Eğitimi AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
GCP Hacking'i öğrenin ve uygulayın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Eğitimi GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>HackTricks'i Destekleyin</summary>
* [**Abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
* **💬 [Discord grubuna](https://discord.gg/hRep4RUj7f) veya [telegram grubuna](https://t.me/peass) katılın veya** bizi **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)** takip edin.**
* **Hacker hilelerini göndererek PR'ler aracılığıyla paylaşın** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına.
</details>
{% endhint %}