99 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Stack Overflow
{{#include ../../banners/hacktricks-training.md}}
## 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.
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**.
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.
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.
Örneğin, aşağıdaki fonksiyonlar savunmasız olabilir:
```c
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Stack Overflow ofsetlerini Bulma
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.
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.
Bunun için **pwntools** kullanılabilir:
```python
from pwn import *
# Generate a De Bruijn sequence of length 1000 with an alphabet size of 256 (byte values)
pattern = cyclic(1000)
# This is an example value that you'd have found in the EIP/IP register upon crash
eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")
```
ve **GEF**:
```bash
#Patterns
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
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.\
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).
### 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:
{{#ref}}
ret2win/
{{#endref}}
### Yığın Shellcode'u
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:
{{#ref}}
stack-shellcode/
{{#endref}}
### 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:
{{#ref}}
../rop-return-oriented-programing/
{{#endref}}
## Yığın Taşmaları
Bir taşma her zaman yığında olmayabilir, örneğin **yığın** içinde de olabilir:
{{#ref}}
../libc-heap/heap-overflow.md
{{#endref}}
## Koruma Türleri
Güvenlik açıklarının istismarını önlemeye çalışan çeşitli korumalar vardır, bunları kontrol edin:
{{#ref}}
../common-binary-protections-and-bypasses/
{{#endref}}
{{#include ../../banners/hacktricks-training.md}}