mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
99 lines
5.4 KiB
Markdown
99 lines
5.4 KiB
Markdown
# 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}}
|