mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/libc-heap/heap-overflow.md', 'src/b
This commit is contained in:
parent
7bd361cb1a
commit
dad5390547
@ -4,45 +4,77 @@
|
||||
|
||||
## Temel Bilgiler
|
||||
|
||||
Heap overflow, [**stack overflow**](../stack-overflow/index.html) gibi ama heap'te gerçekleşir. Temelde, bazı verileri depolamak için heap'te yer ayrıldığını ve **depolanan verinin ayrılan alandan daha büyük olduğunu** ifade eder.
|
||||
Heap overflow, [**stack overflow**](../stack-overflow/index.html) gibi ama heap'te gerçekleşir. Temelde, bazı verileri depolamak için heap'te ayrılmış bir alanın olduğu ve **depolanan verinin ayrılan alandan daha büyük olduğu** anlamına gelir.
|
||||
|
||||
Stack overflow'larda, bazı kayıtların, örneğin talimat işaretçisi veya stack çerçevesinin, stack'ten geri yükleneceğini biliyoruz ve bunu kötüye kullanmak mümkün olabilir. Heap overflow'larda ise, **varsayılan olarak heap parçasında depolanan herhangi bir hassas bilgi yoktur**. Ancak, hassas bilgiler veya işaretçiler olabilir, bu nedenle bu açığın **kritikliği**, **hangi verilerin üzerine yazılabileceğine** ve bir saldırganın bunu nasıl kötüye kullanabileceğine **bağlıdır**.
|
||||
Stack overflow'larda, talimat işaretçisi veya stack çerçevesi gibi bazı kayıtların stack'ten geri yükleneceğini biliyoruz ve bunu kötüye kullanmak mümkün olabilir. Heap overflow'larda ise, **varsayılan olarak heap parçasında depolanan herhangi bir hassas bilgi yoktur**. Ancak, hassas bilgiler veya işaretçiler olabilir, bu nedenle bu güvenlik açığının **kritikliği** **hangi verilerin üzerine yazılabileceğine** ve bir saldırganın bunu nasıl kötüye kullanabileceğine **bağlıdır**.
|
||||
|
||||
> [!TIP]
|
||||
> Overflow offset'lerini bulmak için [**stack overflow'larda**](../stack-overflow/index.html#finding-stack-overflows-offsets) kullanılan aynı desenleri kullanabilirsiniz.
|
||||
> Overflow offset'lerini bulmak için [**stack overflow'larda**](../stack-overflow/index.html#finding-stack-overflows-offsets) olduğu gibi aynı desenleri kullanabilirsiniz.
|
||||
|
||||
### Stack Overflow'lar vs Heap Overflow'lar
|
||||
|
||||
Stack overflow'larda, açığın tetiklenebileceği anda stack'te bulunacak düzen ve veriler oldukça güvenilirdir. Bunun nedeni, stack'in lineer olması, her zaman çarpışan bellek içinde artması, **programın çalışması sırasında stack belleğinin genellikle benzer türde verileri depolamasıdır** ve her fonksiyon tarafından kullanılan stack parçasının sonunda bazı işaretçilerin bulunmasıdır.
|
||||
Stack overflow'larda, güvenlik açığının tetiklenebileceği anda stack'te bulunacak düzen ve veri oldukça güvenilirdir. Bunun nedeni, stack'in lineer olması, her zaman çarpışan bellek içinde artması, **programın çalışmasının belirli yerlerinde stack belleğinin genellikle benzer türde verileri depolamasıdır** ve her fonksiyon tarafından kullanılan stack parçasının sonunda bazı işaretçilerle belirli bir yapıya sahip olmasıdır.
|
||||
|
||||
Ancak, heap overflow durumunda, kullanılan bellek lineer değildir, **ayrılan parçalar genellikle bellek içinde ayrı konumlarda** (birbirinin yanında değil) bulunur çünkü **boyutlarına göre ayrılan alanları** ayıran **bins ve zonlar** vardır ve **önceki serbest bellek kullanılır** yeni parçalar ayırmadan önce. **Bir heap overflow ile çarpışacak nesneyi bilmek karmaşıktır.** Bu nedenle, bir heap overflow bulunduğunda, **istenen nesnenin, overflow olabilecek nesnenin yanında bellek içinde olmasını sağlamak için güvenilir bir yol bulmak** gerekir.
|
||||
Ancak, heap overflow durumunda, kullanılan bellek lineer değildir, **ayrılan parçalar genellikle bellek içinde ayrı konumlarda** (birbirinin yanında değil) bulunur çünkü **boyutlarına göre ayrılan alanları ayıran kutular ve bölgeler** vardır ve **önceki serbest bırakılan bellek** yeni parçalar ayırmadan önce kullanılır. **Hedef nesnenin, heap overflow'a karşı savunmasız olan nesneyle çarpışacağını bilmek karmaşıktır.** Bu nedenle, bir heap overflow bulunduğunda, **istenen nesnenin, overflow edilebilecek nesneden sonra bellekte gelmesini sağlamak için güvenilir bir yol bulmak** gereklidir.
|
||||
|
||||
Bunun için kullanılan tekniklerden biri **Heap Grooming**'dir, örneğin [**bu yazıda**](https://azeria-labs.com/grooming-the-ios-kernel-heap/) kullanılır. Yazıda, iOS çekirdeğinde bir alanın bellek parçalarını depolamak için bellek kalmadığında, bir çekirdek sayfası ile genişletildiği ve bu sayfanın beklenen boyutlardaki parçalara bölündüğü açıklanmaktadır (iOS sürüm 9.2'ye kadar, ardından bu parçalar bu saldırıların istismarını zorlaştırmak için rastgele bir şekilde kullanılır).
|
||||
Bunun için kullanılan tekniklerden biri **Heap Grooming**'dir, örneğin [**bu yazıda**](https://azeria-labs.com/grooming-the-ios-kernel-heap/) açıklanmaktadır. Yazıda, iOS çekirdeğinde bir bölge bellek parçalarını depolamak için bellek tükendiğinde, bir çekirdek sayfası ile genişletildiği ve bu sayfanın beklenen boyutlardaki parçalara bölündüğü açıklanmaktadır (iOS sürüm 9.2'ye kadar, ardından bu parçalar bu saldırıların istismarını zorlaştırmak için rastgele bir şekilde kullanılır).
|
||||
|
||||
Bu nedenle, önceki yazıda bir heap overflow gerçekleştiğinde, overflow olan nesneyi bir kurban nesnesi ile çarpışmaya zorlamak için, birkaç **`kalloc`'un birkaç iş parçacığı tarafından zorlanması gerekir, böylece tüm serbest parçaların doldurulması ve yeni bir sayfanın oluşturulması sağlanır**.
|
||||
Bu nedenle, önceki yazıda bir heap overflow gerçekleştiğinde, overflow edilen nesneyi bir kurban nesnesiyle çarpışmaya zorlamak için, **tüm serbest parçaların doldurulmasını ve yeni bir sayfanın oluşturulmasını sağlamak için birkaç `kalloc` birkaç iş parçacığı tarafından zorlanır.**
|
||||
|
||||
Belirli bir boyuttaki nesnelerle bu doldurmayı zorlamak için, **iOS mach portu ile ilişkili dışarıdan ayrılan bellek** ideal bir adaydır. Mesajın boyutunu ayarlayarak, `kalloc` ayrımının boyutunu tam olarak belirlemek mümkündür ve ilgili mach portu yok edildiğinde, ilgili ayrım hemen `kfree`'ye geri verilecektir.
|
||||
Belirli bir boyuttaki nesnelerle bu doldurmayı zorlamak için, **iOS mach portu ile ilişkili dışarıdan ayrılan bellek** ideal bir adaydır. Mesajın boyutunu ayarlayarak, `kalloc` tahsisini tam olarak belirlemek mümkündür ve ilgili mach portu yok edildiğinde, ilgili tahsis hemen `kfree`'ye geri verilecektir.
|
||||
|
||||
Sonra, bu yer tutuculardan bazıları **serbest bırakılabilir**. **`kalloc.4096` serbest listesi, son giren ilk çıkar sırasına göre elemanları serbest bırakır**, bu da temelde bazı yer tutucular serbest bırakıldığında ve istismar, overflow'a karşı savunmasız nesneyi ayarlamaya çalışırken birkaç kurban nesnesi ayarlamaya çalıştığında, bu nesnenin bir kurban nesnesi tarafından takip edilme olasılığının yüksek olduğu anlamına gelir.
|
||||
Sonra, bu yer tutuculardan bazıları **serbest bırakılabilir**. **`kalloc.4096` serbest listesi, son giren ilk çıkan sırasına göre elemanları serbest bırakır**, bu da temelde bazı yer tutucular serbest bırakıldığında ve istismar, overflow'a karşı savunmasız nesneyi tahsis etmeye çalışırken birkaç kurban nesnesi tahsis etmeye çalıştığında, bu nesnenin bir kurban nesnesiyle takip edilme olasılığının yüksek olduğu anlamına gelir.
|
||||
|
||||
### Örnek libc
|
||||
|
||||
[**Bu sayfada**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) bir heap overflow emülasyonu bulmak mümkündür; bu emülasyon, bir sonraki parçanın prev in use bitini ve prev boyutunun konumunu üzerine yazarak **kullanılan bir parçayı konsolide etmenin** (kullanılmamış gibi düşünmesini sağlayarak) ve **sonra tekrar ayırmanın** mümkün olduğunu gösterir; böylece farklı bir işaretçide kullanılan verileri de üzerine yazma imkanı sağlar.
|
||||
[**Bu sayfada**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) temel bir Heap overflow emülasyonu bulmak mümkündür; bu emülasyon, bir sonraki parçanın prev in use bitini ve prev boyutunu üzerine yazarak **kullanılan bir parçayı konsolide etmenin** (kullanılmamış gibi düşünmesini sağlayarak) ve **sonra tekrar tahsis etmenin** nasıl mümkün olduğunu gösterir; böylece farklı bir işaretçide kullanılan verileri de üzerine yazma imkanı sağlar.
|
||||
|
||||
[**Protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) örneği, bir **heap overflow**'un istismar edilebileceği çok temel bir CTF örneğini göstermektedir; burada **bayrağı almak için** kazanan fonksiyonu çağırmak mümkündür.
|
||||
[**Protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) adlı başka bir örnek, bir **heap overflow**'un istismar edilebileceği çok temel bir CTF örneğini göstermektedir; bu örnekte **bayrağı almak için** kazanan fonksiyonu çağırmak mümkündür.
|
||||
|
||||
[**Protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) örneğinde, bir buffer overflow istismar edilerek **yakın bir parçaya bir adresin üzerine yazılabileceği** gösterilmektedir; burada **kullanıcıdan rastgele verilerin** yazılacağı bir adres bulunmaktadır.
|
||||
[**Protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) örneğinde, bir buffer overflow istismar edilerek **yakın bir parçaya bir adresin üzerine yazılmasının** mümkün olduğu gösterilmektedir; burada **kullanıcıdan rastgele verilerin** yazılacağı bir adres bulunmaktadır.
|
||||
|
||||
### Örnek ARM64
|
||||
|
||||
Sayfada [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) bir heap overflow örneği bulabilirsiniz; burada yürütülecek bir komut, overflow olan parçanın sonraki parçasında depolanmaktadır. Bu nedenle, yürütülen komutu, kolay bir istismar ile üzerine yazarak değiştirmek mümkündür:
|
||||
[https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) sayfasında, yürütülecek bir komutun overflow edilen parçanın sonraki parçasında depolandığı bir heap overflow örneği bulabilirsiniz. Bu nedenle, yürütülen komutu, aşağıdaki gibi basit bir istismar ile üzerine yazarak değiştirmek mümkündür:
|
||||
```bash
|
||||
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
|
||||
```
|
||||
### Diğer örnekler
|
||||
|
||||
- [**Auth-or-out. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/auth-or-out/)
|
||||
- Bir Heap Overflow elde etmek için bir Integer Overflow zafiyetini kullanıyoruz.
|
||||
- Kod yürütmesi elde etmek için taşan parçanın içindeki bir `struct` içindeki bir işlevin işaretçilerini bozarız ve `system` gibi bir işlev ayarlarız.
|
||||
- Bir Heap Overflow elde etmek için Integer Overflow zafiyetini kullanıyoruz.
|
||||
- Bir `struct` içindeki bir işlevin işaretçilerini bozarız, taşan parçanın içine `system` gibi bir işlev ayarlayıp kod yürütmesi sağlarız.
|
||||
|
||||
### Gerçek Dünya Örneği: CVE-2025-40597 – `__sprintf_chk`'nin Yanlış Kullanımı
|
||||
|
||||
SonicWall SMA100 firmware 10.2.1.15'te ters proxy modülü `mod_httprp.so`, **0x80-byte** boyutunda bir heap parçası ayırır ve ardından içine birkaç dizeyi `__sprintf_chk` ile birleştirir:
|
||||
```c
|
||||
char *buf = calloc(0x80, 1);
|
||||
/* … */
|
||||
__sprintf_chk(buf, /* destination (0x80-byte chunk) */
|
||||
-1, /* <-- size argument !!! */
|
||||
0, /* flags */
|
||||
"%s%s%s%s", /* format */
|
||||
"/", "https://", path, host);
|
||||
```
|
||||
`__sprintf_chk` **_FORTIFY_SOURCE**'un bir parçasıdır. **Pozitif** bir `size` parametresi aldığında, sonuçta oluşan string'in hedef tamponun içine sığdığını doğrular. **`-1` (0xFFFFFFFFFFFFFFFF)** geçirerek, geliştiriciler etkili bir şekilde **sınır kontrolünü devre dışı bıraktılar**, güçlendirilmiş çağrıyı klasik, güvensiz `sprintf`'ye geri döndürdüler.
|
||||
|
||||
Aşırı uzun bir **`Host:`** başlığı sağlamak, bu nedenle bir saldırganın **0x80 baytlık parçayı taşmasına ve sonraki yığın parçasının meta verilerini bozmasına** olanak tanır (tcache / fast-bin / small-bin, ayırıcıya bağlı olarak). Bir çökme şu şekilde yeniden üretilebilir:
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
requests.get(
|
||||
'https://TARGET/__api__/',
|
||||
headers={'Host': 'A'*750},
|
||||
verify=False
|
||||
)
|
||||
```
|
||||
Pratik istismar, kontrol edilebilir bir nesneyi savunmasız parçanın hemen arkasına yerleştirmek için **heap grooming** gerektirecektir, ancak kök neden iki önemli çıkarımı vurgular:
|
||||
|
||||
1. **_FORTIFY_SOURCE gümüş bir mermi değildir** – yanlış kullanım korumayı geçersiz kılabilir.
|
||||
2. Her zaman **doğru tampon boyutunu** `_chk` ailesine iletin (veya daha iyisi, `snprintf` kullanın).
|
||||
|
||||
## References
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
## What is a Stack Overflow
|
||||
|
||||
Bir **stack overflow**, bir programın yığın (stack) için ayrılan alandan daha fazla veri yazdığında meydana gelen bir güvenlik açığıdır. Bu fazla veri, **komşu bellek alanını üzerine yazarak**, geçerli verilerin bozulmasına, kontrol akışının kesilmesine ve potansiyel olarak kötü niyetli kodun çalıştırılmasına yol açar. Bu sorun genellikle, girdi üzerinde sınır kontrolü yapmayan güvensiz fonksiyonların kullanılmasından kaynaklanır.
|
||||
Bir **stack overflow**, bir programın yığın (stack) için ayrılan alandan daha fazla veri yazdığında meydana gelen bir güvenlik açığıdır. Bu fazla veri, **komşu bellek alanını üzerine yazarak**, geçerli verilerin bozulmasına, kontrol akışının kesintiye uğramasına ve potansiyel olarak kötü niyetli kodun çalıştırılmasına yol açar. Bu sorun genellikle, girdi üzerinde sınır kontrolü yapmayan güvensiz fonksiyonların kullanılmasından kaynaklanır.
|
||||
|
||||
Bu üzerine yazmanın ana sorunu, **kaydedilmiş talimat işaretçisi (EIP/RIP)** ve önceki fonksiyona dönmek için **kaydedilmiş temel işaretçi (EBP/RBP)** değerlerinin **yığın üzerinde saklanmasıdır**. Bu nedenle, bir saldırgan bu değerleri üzerine yazarak **programın yürütme akışını kontrol edebilir**.
|
||||
Bu üzerine yazma işleminin ana sorunu, **kayıtlı komut işaretçisi (EIP/RIP)** ve önceki fonksiyona dönmek için **kayıtlı temel işaretçi (EBP/RBP)** değerlerinin **yığın üzerinde saklanmasıdır**. Bu nedenle, bir saldırgan bu değerleri üzerine yazarak **programın yürütme akışını kontrol edebilir**.
|
||||
|
||||
Güvenlik açığı genellikle bir fonksiyonun **yığının içine ayrılan miktardan daha fazla bayt kopyalaması** nedeniyle ortaya çıkar, bu da yığının diğer kısımlarını üzerine yazmasına olanak tanır.
|
||||
Güvenlik açığı genellikle bir fonksiyonun **yığının içine ayrılan miktardan daha fazla bayt kopyalaması** nedeniyle ortaya çıkar ve bu da yığının diğer kısımlarını üzerine yazmasına olanak tanır.
|
||||
|
||||
Buna karşı duyarlı bazı yaygın fonksiyonlar şunlardır: **`strcpy`, `strcat`, `sprintf`, `gets`**... Ayrıca, **`fgets`**, **`read` & `memcpy`** gibi **uzunluk argümanı** alan fonksiyonlar, belirtilen uzunluk ayrılan uzunluktan büyükse, savunmasız bir şekilde kullanılabilir.
|
||||
Bu tür güvenlik açıklarına sahip bazı yaygın fonksiyonlar şunlardır: **`strcpy`, `strcat`, `sprintf`, `gets`**... Ayrıca, **`fgets`**, **`read` & `memcpy`** gibi **uzunluk argümanı** alan fonksiyonlar, belirtilen uzunluk ayrılan uzunluktan büyükse, savunmasız bir şekilde kullanılabilir.
|
||||
|
||||
Örneğin, aşağıdaki fonksiyonlar savunmasız olabilir:
|
||||
```c
|
||||
@ -25,9 +25,9 @@ printf("You entered: %s\n", buffer);
|
||||
|
||||
Stack overflow'ları bulmanın en yaygın yolu, çok büyük bir `A` girişi vermektir (örneğin, `python3 -c 'print("A"*1000)'`) ve **`0x41414141` adresinin erişilmeye çalışıldığını** belirten bir `Segmentation Fault` beklemektir.
|
||||
|
||||
Ayrıca, Stack Overflow zafiyetinin bulunduğunu tespit ettikten sonra, **geri dönüş adresini** geçersiz kılmak için gereken ofseti bulmanız gerekecek; bunun için genellikle bir **De Bruijn dizisi** kullanılır. Verilen bir _k_ boyutundaki alfabede ve _n_ uzunluğundaki alt diziler için, bu, **herhangi bir _n_ uzunluğundaki alt dizinin tam olarak bir kez göründüğü** döngüsel bir dizidir.
|
||||
Ayrıca, Stack Overflow zafiyetini bulduktan sonra, **geri dönüş adresini** yazmanın mümkün olacağı ofseti bulmanız gerekecektir. Bunun için genellikle bir **De Bruijn dizisi** kullanılır. Verilen bir _k_ boyutundaki alfabede ve _n_ uzunluğundaki alt diziler için, bu, **herhangi bir _n_ uzunluğundaki alt dizinin tam olarak bir kez göründüğü döngüsel bir dizidir.**
|
||||
|
||||
Bu şekilde, EIP'yi kontrol etmek için gereken ofseti elle bulmak yerine, bu dizilerden birini dolgu olarak kullanmak ve ardından onu geçersiz kılan baytların ofsetini bulmak mümkündür.
|
||||
Bu şekilde, EIP'yi kontrol etmek için hangi ofsetin gerektiğini elle bulmak yerine, bu dizilerden birini dolgu olarak kullanmak ve ardından onu yazmayı bitiren baytların ofsetini bulmak mümkündür.
|
||||
|
||||
Bunun için **pwntools** kullanılabilir:
|
||||
```python
|
||||
@ -48,24 +48,24 @@ pattern create 200 #Generate length 200 pattern
|
||||
pattern search "avaaawaa" #Search for the offset of that substring
|
||||
pattern search $rsp #Search the offset given the content of $rsp
|
||||
```
|
||||
## Stack Overflow'ların Sömürülmesi
|
||||
## Stack Overflow'ları Sömürmek
|
||||
|
||||
Bir taşma sırasında (taşma boyutunun yeterince büyük olduğunu varsayarsak) **yerel değişkenlerin** değerlerini yığın içinde **EBP/RBP ve EIP/RIP'yi (veya daha fazlasını)** kaydedene kadar **üst üste yazma** işlemi yapabileceksiniz.\
|
||||
Bir taşma sırasında (taşma boyutunun yeterince büyük olduğunu varsayarsak) **stack** içindeki yerel değişkenlerin değerlerini **üzerine yazmak** mümkün olacaktır, ta ki kaydedilmiş **EBP/RBP ve EIP/RIP (veya daha fazlası)** ulaşana kadar.\
|
||||
Bu tür bir güvenlik açığını istismar etmenin en yaygın yolu, **dönüş adresini değiştirmektir**, böylece fonksiyon sona erdiğinde **kontrol akışı kullanıcının bu işaretçide belirttiği yere yönlendirilecektir**.
|
||||
|
||||
Ancak, diğer senaryolarda sadece **yığın içindeki bazı değişkenlerin değerlerini üst üste yazmak** istismar için yeterli olabilir (örneğin, kolay CTF zorluklarında).
|
||||
Ancak, diğer senaryolarda sadece **stack'teki bazı değişken değerlerini üzerine yazmak** istismar için yeterli olabilir (örneğin, kolay CTF zorluklarında).
|
||||
|
||||
### Ret2win
|
||||
|
||||
Bu tür CTF zorluklarında, ikili dosya içinde **asla çağrılmayan** bir **fonksiyon** vardır ve **kazanmak için bu fonksiyonu çağırmanız gerekir**. Bu zorluklar için sadece **dönüş adresini üst üste yazmak için ofseti bulmanız** ve **çağırılacak fonksiyonun adresini bulmanız** gerekir (genellikle [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) devre dışı bırakılmış olacaktır) böylece savunmasız fonksiyon döndüğünde, gizli fonksiyon çağrılacaktır:
|
||||
Bu tür CTF zorluklarında, **asla çağrılmayan** ve **kazanmak için çağırmanız gereken** bir **fonksiyon** **binary** içinde bulunmaktadır. Bu zorluklar için sadece **dönüş adresini üzerine yazmak için ofseti bulmanız** ve **çağırılacak fonksiyonun adresini bulmanız** gerekir (genellikle [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) devre dışı bırakılmış olacaktır) böylece savunmasız fonksiyon döndüğünde, gizli fonksiyon çağrılacaktır:
|
||||
|
||||
{{#ref}}
|
||||
ret2win/
|
||||
{{#endref}}
|
||||
|
||||
### Yığın Shellcode'u
|
||||
### Stack Shellcode
|
||||
|
||||
Bu senaryoda saldırgan, yığında bir shellcode yerleştirebilir ve kontrol edilen EIP/RIP'i kullanarak shellcode'a atlayıp rastgele kod çalıştırabilir:
|
||||
Bu senaryoda, saldırgan stack'te bir shellcode yerleştirebilir ve kontrol edilen EIP/RIP'i kullanarak shellcode'a atlayıp rastgele kod çalıştırabilir:
|
||||
|
||||
{{#ref}}
|
||||
stack-shellcode/
|
||||
@ -73,15 +73,15 @@ stack-shellcode/
|
||||
|
||||
### ROP & Ret2... teknikleri
|
||||
|
||||
Bu teknik, önceki tekniğin ana korumasını aşmak için temel çerçevedir: **Çalıştırılabilir yığın yok (NX)**. Ve mevcut ikili dosyadaki talimatları istismar ederek rastgele komutlar çalıştırmayı sağlayan birkaç başka tekniği (ret2lib, ret2syscall...) gerçekleştirmeye olanak tanır:
|
||||
Bu teknik, önceki tekniğin ana korumasını aşmak için temel çerçevedir: **Çalıştırılamaz stack (NX)**. Ve mevcut talimatları istismar ederek rastgele komutlar çalıştıracak birkaç başka tekniği (ret2lib, ret2syscall...) gerçekleştirmeye olanak tanır:
|
||||
|
||||
{{#ref}}
|
||||
../rop-return-oriented-programing/
|
||||
{{#endref}}
|
||||
|
||||
## Yığın Taşmaları
|
||||
## Heap Taşmaları
|
||||
|
||||
Bir taşma her zaman yığında olmayabilir, örneğin **yığın** içinde de olabilir:
|
||||
Bir taşma her zaman stack'te olmayabilir, örneğin **heap** içinde de olabilir:
|
||||
|
||||
{{#ref}}
|
||||
../libc-heap/heap-overflow.md
|
||||
@ -95,4 +95,32 @@ Güvenlik açıklarının istismarını önlemeye çalışan çeşitli korumalar
|
||||
../common-binary-protections-and-bypasses/
|
||||
{{#endref}}
|
||||
|
||||
### Gerçek Dünya Örneği: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
**`sscanf`'in güvenilmeyecek girdi ayrıştırması için asla güvenilmemesi gerektiğinin** iyi bir gösterimi, 2025 yılında SonicWall’ın SMA100 SSL-VPN cihazında ortaya çıktı. `/usr/src/EasyAccess/bin/httpd` içindeki savunmasız rutin, `/__api__/` ile başlayan herhangi bir URI'den sürüm ve uç noktayı çıkarmaya çalışmaktadır:
|
||||
```c
|
||||
char version[3];
|
||||
char endpoint[0x800] = {0};
|
||||
/* simplified proto-type */
|
||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. İlk dönüşüm (`%2s`) **iki** baytı `version` içine güvenli bir şekilde depolar (örneğin, `"v1"`).
|
||||
2. İkinci dönüşüm (`%s`) **uzunluk belirleyiciye sahip değildir**, bu nedenle `sscanf` **ilk NUL baytına kadar** kopyalamaya devam eder.
|
||||
3. Çünkü `endpoint` **stack** üzerinde yer almakta ve **0x800 bayt uzunluğunda** olduğundan, 0x800 bayttan daha uzun bir yol sağlamak, tamponun ardından gelen her şeyi bozar ‑ **stack canary** ve **kayıtlı dönüş adresi** dahil.
|
||||
|
||||
Kimlik doğrulamasından **önce** çöküşü tetiklemek için tek satırlık bir kanıt konsepti yeterlidir:
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||
requests.get(url, verify=False)
|
||||
```
|
||||
Stack canaries süreci durdurmasına rağmen, bir saldırgan hala bir **Denial-of-Service** primitive kazanır (ve, ek bilgi sızıntıları ile, muhtemelen kod yürütme). Ders basit:
|
||||
|
||||
* Her zaman bir **maksimum alan genişliği** sağlayın (örneğin, `%511s`).
|
||||
* `snprintf`/`strncpy_s` gibi daha güvenli alternatifleri tercih edin.
|
||||
|
||||
## References
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user