Listino Supporto Partner Contatti 800 13.40.41

Articoli

Icona delle News


Che cos'è un buffer overflow

23/03/20 CoreTech Blog

×Non sei ancora nostro cliente Acunetix? Diventa Partner CoreTech e visita il nostro configuratore prezzi

Si verifica una vulnerabilità di overflow del buffer quando si forniscono a un programma troppi dati. I dati in eccesso danneggiano lo spazio vicino in memoria e possono alterare altri dati. Di conseguenza, il programma potrebbe segnalare un errore o comportarsi diversamente. Tali vulnerabilità sono anche chiamate sovraccarico del buffer.

Alcuni linguaggi di programmazione sono più suscettibili ai problemi di overflow del buffer, come C e C ++. Questo perché si tratta di linguaggi di basso livello che si affidano allo sviluppatore per allocare memoria. I linguaggi più comuni usati sul web come PHP, Java, JavaScript o Python, sono molto meno inclini agli exploit buffer overflow perché gestiscono l'allocazione di memoria per conto dello sviluppatore. Tuttavia, non sono completamente sicuri: alcuni consentono la manipolazione diretta della memoria e spesso usano funzioni core scritte in C / C ++.

Le vulnerabilità di overflow del buffer sono difficili da trovare e sfruttare. Inoltre non sono così comuni come altre vulnerabilità. Tuttavia, gli attacchi di buffer overflow possono avere conseguenze molto gravi. Tali attacchi spesso consentono all'attaccante di ottenere l'accesso alla shell e quindi il pieno controllo del sistema operativo. Anche se l'attaccante non riesce ad ottenere l'accesso alla shell, gli attacchi di buffer overflow potrebbero interrompere l'esecuzione dei programmi e, di conseguenza, causare un Denial of Service.

Tipi di vulnerabilità di overflow del buffer

Esistono due tipi principali di vulnerabilità di overflow del buffer: overflow dello stack e overflow dell'heap.

Nel caso di overflow del buffer dello stack, il problema si applica allo stack, che è lo spazio di memoria utilizzato dal sistema operativo principalmente per memorizzare le variabili locali e gli indirizzi di ritorno delle funzioni. I dati sullo stack vengono archiviati e recuperati in modo organizzato (last-in-first-out ), l'allocazione dello stack è gestita dal sistema operativo e l'accesso allo stack è rapido.

In caso di overflow del buffer dell'heap, il problema si applica all'heap, che è lo spazio di memoria utilizzato per archiviare i dati dinamici. La quantità di memoria che deve essere riservata viene decisa in fase di esecuzione ed è gestita dal programma, non dal sistema operativo. L'accesso all'heap è più lento ma lo spazio sull'heap è limitato solo dalle dimensioni della memoria virtuale.

Come funziona un overflow del buffer

In un semplice programma, è possibile che l'utente inserisca un indirizzo di posta elettronica. Pertanto, si crea una variabile stringa. Si allocano 64 byte alla variabile perché non si prevede che una stringa di posta elettronica sia più lunga di 64 caratteri. Tuttavia, si considera troppo attendibile l'input dell'utente e non si verifica se la lunghezza della stringa immessa supera la dimensione del buffer.

Di conseguenza, l'utente immette 100 caratteri e i restanti 36 caratteri vengono archiviati nella memoria allocata a un'altra variabile. Questo fa sì che il valore di quella variabile cambi e cambi anche il comportamento del programma. Nella maggior parte dei casi, ciò porta a un semplice errore di segmentazione della memoria, ma può avere conseguenze più gravi. Per capire come ciò possa influenzare l'esecuzione del programma, dovremo supporre che la vulnerabilità sia uno stack overflow e che appaia in un programma C.

Un programma C utilizza lo stack per memorizzare un set di dati per ogni funzione. Il set di dati è denominato stack frame e include l'identificatore di funzione, i valori delle variabili locali e l'indirizzo di ritorno. Ecco un semplice esempio di codice sorgente per spiegare come funziona lo stack:

main() { 

int mv1; 

int mv2; 

func();

}

void func() { 

int fv1; 

int fv2;

}

Quando si esegue il programma, inizia con la main()funzione. Il programma memorizza i valori delle main()variabili di funzione nella parte superiore dello stack ( mv1mv2). Quindi la main()funzione chiama la func()funzione e memorizza i valori delle sue variabili nella parte superiore dello stack ( fv1fv2). Al func()termine dell'esecuzione della funzione, la parte superiore dello stack viene dimenticata, la funzione corrente torna a main()e il programma ha accesso mv1mv2nuovamente.

Il contenuto dannoso che l'attaccante invia a un programma difettoso è generalmente composto da tre parti:

  • Una catena di byte che rappresentano l' NOPistruzione
  • Un nuovo indirizzo di ritorno che punta ai NOPbyte
  • Codice arbitrario (di solito un codice shell ) situato da qualche parte nel mezzo della catena di NOPbyte

Quando nel nostro esempio si verifica l'overflow del buffer, il programma passa alla catena di NOPbyte (anziché tornare alla main()funzione). I NOPbyte vengono ignorati e il programma incontra il codice shell nel mezzo di essi. Il codice shell esegue una shell del sistema operativo, dando all'autore dell'attacco il pieno accesso al sistema.

Ecco un esempio molto semplice di un programma C che è vulnerabile a un overflow dello stack:

main(int argc, char *argv[]) { 

func(argv[1]);

}

void func(char *v) {  

 char buffer[10]; 

strcpy(buffer, v);

}

La strcpyfunzione nell'esempio precedente copia l'argomento del comando nella variabile del buffer di destinazione senza controllare la lunghezza della stringa. Il programma alloca solo 10 byte alla bufferstringa e quindi strcpyprovoca un overflow del buffer. Se compiliamo questo programma come vulnprog , la seguente chiamata da riga di comando è innocua:

$ vulnprog AAAAAAAAAA

Tuttavia, la seguente chiamata provoca un overflow del buffer:

$ vulnprog AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Come prevenire l'overflow di un buffer

Prevenire gli errori di overflow del buffer non è molto diverso dalla prevenzione di molte altre vulnerabilità. Tutto si riduce a diffidare dell'input dell'utente. Nel caso di vulnerabilità di overflow del buffer, lo sviluppatore deve verificare la lunghezza dell'input prima di utilizzare qualsiasi funzione che potrebbe causare un overflow.

Tuttavia, errare è umano e non è raro che gli sviluppatori dimentichino questa regola di base. Anche i revisori del codice potrebbero perdere tali errori. Ecco perché il metodo di base più sicura in C è quello di evitare i seguenti cinque funzioni non sicure che possono portare ad un Buffer Overflow: printfsprintfstrcatstrcpy, e gets.

Sfortunatamente, il linguaggio C di base fornisce una sola alternativa sicura: fgets (da utilizzare invece di gets). Diverse piattaforme hanno implementazioni non standard. Ad esempio, la versione Microsoft di C include sprintf_sstrcpy_sstrcat_s. Sui sistemi Linux/UNIX, la scelta migliore consiste nel vietare le funzioni non sicure e imporre l'uso della libreria C sicura.

È inoltre possibile proteggersi dagli overflow del buffer utilizzando un'estensione di un compilatore che utilizza canarini. I canarini sono valori speciali che il compilatore inserisce nello stack tra la posizione del buffer e la posizione dei dati del controllo. Quando si verifica un overflow del buffer, è il canarino ad essere danneggiato per primo e questo danneggiamento può essere rilevato immediatamente. Ci sono molte estensioni del compilatore che utilizzano canarini, per esempio, StackGuard e ProPolice.

Meccanismi di protezione dell'overflow del buffer del sistema operativo

Affinché un overflow del buffer sia possibile, l'utente malintenzionato deve sapere esattamente dove si troverà il buffer nella memoria del computer. In passato, questo era semplice come l'esecuzione di un debugger sul computer locale e il controllo degli indirizzi di memoria. Gli attuali sistemi operativi lo rendono molto più difficile.

Tutti i sistemi operativi moderni includono un meccanismo di protezione chiamato ASLR (Address Space Layout Randomization). Grazie a questo meccanismo, il file eseguibile può essere caricato in molte posizioni di memoria diverse. Pertanto, l'utente malintenzionato non può prevedere facilmente l'indirizzo di memoria a cui passare e molti tentativi di attacco di overflow del buffer falliscono.

Un'altra tecnica che aiuta a prevenire gli attacchi di overflow del buffer è la protezione dello spazio eseguibile (su Windows: prevenzione dell'esecuzione dei dati – Protezione esecuzione programmi). Grazie a questa tecnica, l'utente malintenzionato non può eseguire il codice se si trova nello spazio di memoria assegnato allo stack o heap e, in alcuni casi, anche in altre aree. Questo rende impossibile chiamare direttamente un shell code, ma gli aggressori possono utilizzare trucchi avanzati come la programmazione orientata al ritorno.

Tuttavia, un utente malintenzionato potrebbe tentare di eludere entrambi questi meccanismi di protezione su architetture x86 utilizzando un attacco ret2reg. Quello che devono fare è trovare un modulo (DLL) che non è protetto da ASLR o PROTEZIONE esecuzione programmi. Se in tale modulo è possibile trovare un'istruzione JMP ESP (salto allo stack, combinazione di byte, FF \FF\E4), è possibile utilizzare il percorso di questa istruzione come indirizzo di ritorno. Il programma salterà a questa posizione, eseguirà l'istruzione di salto (JMP ESP) e salterà alla posizione corrente dello stack, che si trova subito dopo l'indirizzo di ritorno (prima del codice shell).

Rilevamento di overflow del buffer correlati al Web

Le applicazioni Web e le pagine Web sono raramente soggette a vulnerabilità di overflow del buffer perché non sono scritte in C o in C++. Tuttavia, questi errori si verificano in software sottostanti, ad esempio server web, server applicazioni web o interpreti.

Lo scanner di vulnerabilità web Acunetix controlla tali errori nel software web e l'integrazione con OpenVAS consente di espandere l'elenco dei controlli per includere il software relativo alla reteFai una demo e scopri di più su come eseguire scansioni sul tuo server web.

 


Articoli su Acunetix e Hacking

Introduzione alle web shell - parte 1Iniezioni di NoSQL e come evitarleDebunking 5 miti sulla postura della sicurezza informaticaConfigurazione passo passo di Acunetix con JenkinsAnche il più forte cade: un'iniezione SQL in Sophos XG FirewallCosa sono i riferimenti a oggetti diretti non sicuriAcunetix rilascia Business Logic RecorderCome recuperare da un evento del sito Web compromessoCome difendersi dagli hacker Black Hat durante la pandemia COVID-19Che cos'è l'inclusione remota dei file (RFI)?Apache Security - 10 consigli per un'installazione sicuraUn nuovo sguardo sugli attacchi correlati al proxy inversoVulnerabilità delle entità esterne XML in Internet ExplorerVulnerabilità delle password comuni e come evitarleChe cosa sono le iniezioni HTMLTutto quello che devi sapere sugli attacchi Man-in-the-MiddleTesta le tue competenze XSS utilizzando siti vulnerabiliRed Teaming – 5 consigli su come farlo in modo sicuroPratiche di codifica sicura – I tre principi chiavePerché hacker malintenzionati hanno messo gli occhi sugli ospedaliMutation XSS nella ricerca GoogleLa maledizione delle vecchie librerie JavaIgnorare SOP utilizzando la cache del browserDirottamento di sessione e altri attacchi di sessioneCome e perché evitare reindirizzamenti e inoltri non convalidati?Come abbiamo trovato un altro XSS in Google con AcunetixChe cos'è un buffer overflowChe cos'è l'overflow di IntegerChe cos'è HSTS e perché dovrei usarlo?Che cosa è OS Command InjectionCoreTech assicura protezione dei siti Web con AcunetixCoreTech distributore Acunetix a fianco dei partner per la CyberSecurityCyberSecurity applicativa, nuova opportunità per voi!

Knowledge Base su Acunetix e Hacking

Il Pen Testing applicativo con Acunetix
Ripe Ncc Member
vmware
CloudLinux
Plesk
HP
Microsoft