
Exploit Linux ELF x32/x64 per bypass ASLR e DEP/NX con stack-spraying
Exploit Linux ELF x32/x64 con bypass di ASLR e DEP/NX tramite stack-spraying

Proprietà:
Dipendenze:
Limitazioni:
Potresti aver sentito parlare dell'attacco Heap Spraying? Beh, Stack Spraying è simile, tuttavia è stato considerato poco pratico per la maggior parte dei casi, specialmente ASLR su x86-64.
Il mio lavoro dimostrerà il contrario.
Per i 32 bit, ci sono 2^32 (4.294.967.296) indirizzi teorici, ma il kernel permette di controllare solo circa la metà dei bit (2^(32/2) = 65.536) per un'esecuzione in memoria virtualizzata, il che significa che se controlliamo più di 50.000 caratteri nello stack, siamo quasi certi di puntare al nostro shellcode, indipendentemente dall'indirizzo, grazie al reindirizzamento e alla ritraduzione del kernel. Secondo i miei test, anche 100 o 10 caratteri sono sufficienti se la funzione chiamata non contiene altre creazioni di variabili, il che consentirà un attacco stile ROP.
Questo può essere ottenuto utilizzando variabili di shell, che non sono realmente limitate a una lunghezza specifica, ma il limite pratico è circa un centinaio di migliaia, altrimenti satureranno il TTY.
Quindi, per sfruttare con successo qualsiasi shellcode, dobbiamo inserire un NOP sled seguito dallo shellcode in una variabile di shell e sfruttare semplicemente il binario con un indirizzo casuale. Nota che il NOP sled non è necessario, serve solo per universalizzare l'exploit.
In un sistema a 64 bit la situazione è diversa, ma non così tanto secondo la mia scoperta.
Ovviamente, non dovresti coprire tutte le 2^64 possibilità; in effetti, il kernel permette solo 48 bit, più una parte di essi è prevedibile e statica, il che ci lascia con circa 2^(4x8+5) (137.438.953.472) possibilità.
Ho menzionato il limite di dimensione delle variabili di shell, ma c'è anche un limite di conteggio, che sembra essere circa 10, permettendoci così di immagazzinare uno shellcode di 1.000.000 di caratteri, lasciandoci solo con alcune decine di migliaia di possibilità che possono essere testate rapidamente e automaticamente. Questa volta, tuttavia, dovrai usare bruteforce e NOP-sled per rendere le cose più veloci.
Detto questo, ASLR su entrambi i 32 e 64 bit può essere facilmente bypassato in pochi minuti e con poche righe di shell...
Il DEP/NX, d'altra parte, può essere bypassato su x32 usando la tecnica return-to-libc accoppiandola con studi statistici di diversi sistemi operativi, più specificamente, le loro limitazioni e implementazioni di ASLR, che possono portare a uno sfruttamento riuscito per 2 motivi. Il primo è che ASLR non è così casuale nella sua scelta e ha alcune costanti e scarsa entropia (facile indovinare l'indirizzo libC e ogni OS ha le sue costanti). Il secondo è spruzzare l'argomento shell per libC nell'ambiente (facile da trovare e passare a libC).
Per concludere, DEP/NX su 32 bit è indebolito a causa di ASLR.
Una descrizione più dettagliata può essere trovata nel numero Hakin9-12-14.
Se hai sfruttato almeno un buffer overflow nella tua vita, puoi saltare, ma per sicurezza:
apt install gcc libc6-dev-i386 || kill -9 $$
chmod u+x ASLRay.sh
sudo gcc -z execstack test.c -o test
sudo gcc -m32 -z execstack test.c -o test32
sudo chmod +s test test32
source ASLRay.sh test32 1024
source ASLRay.sh test 1024
source ASLRay.sh test 1024 \x31\x80...your_shellcode_here
sudo gcc -m32 test.c -o test32x
sudo chmod +s test test32
source ASLRay.sh test32x 1024
Per dimostrare che il NOP-sled non è necessario per Debian x32:
!!! ATTENZIONE !!! questo modificherà il tuo /etc/passwd e cambierà i permessi di /etc/shadow, esecuzione in VM consigliata
chmod u+x PoC.sh
source PoC.sh
grep ALI /etc/passwd
Se ancora non funziona, aggiungi alcuni NOP (\x90) all'inizio.
Per dimostrare che nemmeno la variabile d'ambiente è necessaria per Debian x32:
chmod u+x PoC2.sh
source PoC2.sh
Così puoi semplicemente mettere il tuo shellcode in una variabile e dare indirizzi casuali ai registri per una shell con ASLR, questo perché il contesto specifico in cui la funzione ha solo una variabile che verrà sovrascritta, quindi lo stack verrà estratto a EIP solo con il nostro shellcode, il che è più simile a un attacco ROP.
Per Arch/Ubuntu dovrai anche disabilitare la protezione stack smashing e il bruteforce potrebbe richiedere molto più tempo (ritardo di esecuzione, probabilmente a causa della syscall brk(NULL/0) e/o del canary):
sudo gcc -z execstack -fno-stack-protector test.c -o test
sudo gcc -m32 -z execstack -fno-stack-protector test.c -o test32
sudo gcc -m32 -fno-stack-protector test.c -o test32x
In Debian 10, questo problema è stato parzialmente corretto, specialmente a causa di AppArmor.
Affidati sempre a più protezioni e non a una sola.
Abbiamo bisogno di nuovi meccanismi di sicurezza del sistema.
"Da dove ci troviamo, la pioggia sembra casuale. Se potessimo stare da qualche altra parte, vedremmo l'ordine in essa. "
Tony Hillerman, Coyote Waits