Buffer overflow: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Errore di battitura |
Funzionalità collegamenti suggeriti: 3 collegamenti inseriti. Etichette: Modifica visuale Modifica da mobile Modifica da web per mobile Modifica da mobile avanzata Attività per i nuovi utenti Suggerito: aggiungi collegamenti |
||
(12 versioni intermedie di 6 utenti non mostrate) | |||
Riga 1:
{{Nota disambigua|il buffer overflow legato alle telecomunicazioni|Buffer overflow (telecomunicazioni)}}
[[File:Buffer overflow basicexample.svg|alt=Esempio di buffer overflow|miniatura|Esempio di buffer overflow|300x300px]]
'''Buffer overflow''' (o '''buffer overrun'''), in [[informatica]], è una condizione di errore che si verifica a [[runtime]] quando in un [[buffer]] di una data dimensione vengono scritti dati di dimensioni maggiori.
== Storia ==
I buffer
Il primo clamoroso esempio di attacco basato su buffer overflow fu il [[Morris worm|Morris Worm]] (noto anche come Internet Worm), che nel 1988 portò al crash di più di 6.000 sistemi connessi a Internet in poche ore, sfruttando il buffer overflow nel processo demone ''finger'' di UNIX per propagare attraverso la rete.<ref>{{Cita web|url=https://www.sans.org/reading-room/whitepapers/securecode/buffer-overflow-attack-mechanism-method-prevention-386|titolo=Inside the Buffer Overflow Attack:Mechanism, Method, & Prevention}}</ref>
Più tardi, nel 1995, Thomas Lopatic pubblicò sulla [[mailing list]] di Bugtraq un exploit basato sullo stack smashing nel web server NCSA HTTPD su sistema operativo [[HP-UX]], e un anno dopo, nel 1996, Elias Levy (anche noto come Aleph One) pubblicò un articolo intitolato "Smashing the Stack for Fun and Profit" sull'''ezine'' [[Phrack]], una guida step-by-step alle tecniche di exploiting degli stack buffer overflows.<ref>{{Cita web|url=https://rdist.root.org/2010/05/03/why-buffer-overflow-exploitation-took-so-long-to-mature/|titolo=Why buffer overflow exploitation took so long to mature|sito=rdist|data=3 maggio 2010|accesso=5 settembre 2016}}</ref><ref>{{Cita web|url=http://seclists.org/bugtraq/1995/Feb/109|titolo=Bugtraq: Vulnerability in NCSA HTTPD 1.3|cognome=Lopatic|nome=Thomas|sito=seclists.org|accesso=5 settembre 2016}}</ref>
In seguito i buffer
Nonostante sia una delle vulnerabilità note da più tempo, ancora oggi il buffer overflow rappresenta una falla di sicurezza diffusa ed estremamente attuale: organizzazioni come [[CERT|CERT/CC]] e [[SANS]] pubblicano ancora oggi avvisi relativi alla sicurezza informatica che includono un numero rilevante di exploit basati su buffer overflow; inoltre diversi elementi della lista “CWE/SANS Top 25 Most Dangerous Software Error” sono varianti del buffer overflow.<ref>{{Cita web|url=https://cwe.mitre.org/top25/|titolo=CWE -
2011 CWE/SANS Top 25 Most Dangerous Software Errors|sito=cwe.mitre.org|accesso=17 agosto 2016}}</ref>
Nel febbraio 2016 i ricercatori di Google e di Red Hat scoprirono la presenza di una vulnerabilità di tipo stack buffer overflow nella funzione ''getaddrinfo'' della libreria ''[[glibc]]'' (tutte le versioni a partire dalla 2.9). Tale libreria è utilizzata da centinaia di applicazioni e dalla maggior parte delle distribuzioni Linux (incluse quelle installate nei [[router]] e in altro tipo di hardware): la funzione interessata è quella che si occupa del DNS lookup (risoluzione nomi degli host e indirizzi IP) e la vulnerabilità può permettere a un attaccante l'invio di domini o DNS server malevoli, oltre che attacchi ''[[Attacco man in the middle|man-in-the-middle]]'' fino all'esecuzione di codice arbitrario sulla macchina della vittima.<ref>{{Cita web|url=https://security.googleblog.com/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html|titolo=CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow|lingua=en|accesso=6 settembre 2016}}</ref><ref>{{Cita web|url=https://access.redhat.com/it/node/2171131|titolo=Falla di sicurezza critica: glibc stack-based buffer overflow in getaddrinfo() (CVE-2015-7547) - Red Hat Customer Portal|sito=access.redhat.com|accesso=6 settembre 2016}}</ref>
== Descrizione ==
Quando, per errore o per malizia, vengono inviati più dati della capienza del buffer destinato a contenerli (che per errore, malizia o superficialità non è stato progettato a dovere), i dati ''extra'' vanno a sovrascrivere le variabili interne del programma, o il suo stesso [[Pila (informatica)|stack]]; come conseguenza di ciò, a seconda di cosa è stato sovrascritto e con quali valori, il programma può dare risultati errati o imprevedibili, bloccarsi, o (se è un driver di sistema o lo stesso sistema operativo) bloccare il [[computer]]. Conoscendo molto bene il programma in questione, il sistema operativo e il tipo di computer su cui gira, si può precalcolare una serie di dati ''malevoli'' che inviati per provocare un buffer overflow consenta ad un malintenzionato di prendere il controllo del programma (e a volte, tramite questo, dell'intero computer).
Non tutti i programmi sono vulnerabili a questo tipo di inconveniente. Per i linguaggi di basso livello, come l’assembly, i dati sono semplici array di byte, memorizzati in registri o in memoria centrale: la corretta interpretazione di questi dati (indirizzi, interi, caratteri, istruzioni, ecc…) è affidata alle funzioni e alle istruzioni che li accedono e manipolano; utilizzando linguaggi di basso livello si ha dunque un maggiore controllo delle risorse della macchina, ma è richiesta una maggiore attenzione in fase di programmazione in modo da assicurare
Non tutti i programmi sono vulnerabili a questo tipo di inconveniente, infatti perché un dato programma sia a rischio è necessario che:
Riga 30 ⟶ 31:
Il buffer overflow può essere indicato con diversi nomi a seconda della posizione occupata dal buffer all’interno della memoria allocata per il processo. La posizione del buffer è importante in quanto gli effetti del buffer overflow sono principalmente legati a:
* cosa c’è vicino al buffer
* quali dati vanno a sovrascrivere le aree di memoria adiacenti al buffer
Riga 68:
Se i dati in eccesso sovrascrivono frame pointer e return address, al termine dell’esecuzione la funzione tenterebbe di restituire il controllo all’istruzione puntata dal return address che potrebbe contenere:
* L’indirizzo di un’area di memoria non accessibile: i dati in eccesso sono casuali, il programma va in crash restituendo tipicamente un [[errore di segmentazione]]. È un esempio di come lo ''stack buffer overflow'' possa essere utilizzato come attacco del tipo [[Denial of Service|denial
* Un indirizzo di memoria ben preciso: i dati in eccesso sono calcolati in modo da sovrascrivere il return address con l’indirizzo di un’area di memoria a cui l’attaccante vuole avere accesso, o con l’indirizzo in cui si trova il codice che l’attaccante vuole eseguire.
In questo secondo caso rientrano gli attacchi basati sull’iniezione di [[shellcode]]; i dati inseriti all’interno del buffer contengono codice eseguibile in linguaggio macchina ([[assembly]]), e la sovrascrittura del return address viene fatta in modo da rimandare al codice iniettato all’interno del buffer. Compito di tale codice è normalmente quello di richiamare un’interfaccia a riga di comando, ovvero una [[Shell (informatica)|shell]], motivo per cui tale codice è detto shellcode (una chiamata alla funzione ''execve'' che esegue la Bourne shell per i sistemi UNIX, una chiamata a ''system (“command.exe”)'' nei sistemi Windows). In ogni caso il programma in esecuzione viene sostituito dalla shell, che eseguirà con gli stessi privilegi del programma di partenza.
Esiste una variante di questo tipo di attacco che si basa sulla sostituzione solo del frame pointer, e che può essere utilizzata quando l'overflow consentito è limitato e non permette di arrivare alla sovrascrittura del return address. L'attacco consiste nello sfruttare l'overflow per sostituire il frame pointer memorizzato in modo da farlo puntare a uno stack frame fasullo, iniettato all'interno del buffer insieme allo shellcode; in questo ''stack frame'' fasullo l'attaccante ha inserito come return address un puntatore allo shellcode: quando la funzione colpita termina la sua esecuzione, quindi, restituisce correttamente il controllo alla funzione chiamante (il return address infatti non è stato cambiato), ma questa riprenderà l'esecuzione con un contesto fasullo e, quando a sua volta anche lei terminerà di eseguire, il controllo verrà infine trasferito allo shellcode (poiché in questo stack frame è stato alterato il RA in modo da puntare al codice maligno). Gli attacchi [[Off-by-one error|off-by-one]] si basano proprio su questo principio: se per un errore di scrittura il programmatore consente l'immissione all'interno di un buffer anche solo di un byte in più del dovuto (usando ad esempio un <= invece del ''<'' nel test di una condizione di controllo), questo semplice byte in più potrebbe essere utilizzato da un attaccante per modificare il frame pointer memorizzato a sufficienza da farlo puntare ad uno stack frame fasullo, e ottenere quindi indirettamente il trasferimento del controllo al codice maligno iniettato.<ref name=":0" />
Infine bisogna ricordare che [[stack overflow]] e stack buffer overflow non sono sinonimi: il primo indica una situazione per cui si richiede una quantità troppo elevata di memoria nello stack, il secondo una situazione in cui (per varie ragioni) si inserisce in un buffer nello stack una quantità di dati più grande della capacità del buffer stesso.<ref>{{Cita libro|autore=Jon Erickson|titolo=Hacking - The Art of Exploitation|url=https://archive.org/details/hackingartofexpl0000eric_g6n4|anno=2008|editore=No Starch Press|città=|ISBN=978-1-59327-144-2}}</ref>
=== Heap overflow ===
{{Vedi anche|Heap overflow}}
Un programma può richiedere al sistema operativo di allocare dinamicamente una certa quantità di memoria nell'area [[Heap (struttura dati)|heap]], sfruttando chiamate di sistema come ''malloc()'' e ''free''() in C/UNIX. Questi buffer possono ugualmente essere suscettibili a problemi di overflow nel momento in cui vi si possa inserire una quantità di dati superiore alla memoria allocata, e questi dati andrebbero come al solito a sovrascrivere le aree di memoria adiacenti al buffer.
Riga 84 ⟶ 85:
== Contromisure ==
Esistono varie tecniche per prevenire o rivelare il fenomeno del buffer overflow, con vari tradeoff. In generale queste difese possono essere adottate a vari livelli:<ref name=":1">{{Cita web|url=http://www.preserve-it-all.org/emc-plus/rsa-labs/historical/countermeasures-against-buffer-overflow-attacks.htm|titolo=RSA Laboratories - Countermeasures against Buffer Overflow Attacks|accesso=31 agosto 2016|dataarchivio=14 settembre 2016|urlarchivio=https://web.archive.org/web/20160914092946/http://www.preserve-it-all.org/emc-plus/rsa-labs/historical/countermeasures-against-buffer-overflow-attacks.htm|urlmorto=sì}}</ref>
* A livello di linguaggio
* A livello di codice sorgente
Riga 93 ⟶ 94:
La miglior difesa da attacchi basati sul buffer overflow sta nella scelta di un linguaggio di programmazione che fornisca controlli automatici sulla dimensione dei buffer (o a tempo di compilazione o a ''runtime'') come Java, Python o Perl. Se questa opzione può essere presa in considerazione per lo sviluppo di nuovi programmi, resta però difficilmente applicabile nel caso di progetti esistenti, in cui ciò comporterebbe la riscrittura del codice nel nuovo linguaggio.<ref name=":1" />
Un'alternativa consiste nell'utilizzo di ''safe
=== Difese a livello di codice sorgente ===
Riga 109 ⟶ 110:
Approccio differente è invece quello di "StackShield", un'estensione del compilatore ''gcc'' per la protezione dallo stack smashing nei sistemi Linux; anziché inserire a tempo di compilazione i controlli per il ''bounds checking'' dei buffer, l'obiettivo di StackShield è quello di impedire la sovrascrittura dei ''return address'' memorizzandone una copia in una zona sicura non sovrascrivibile (all'inizio del segmento dati) all'inizio di ogni chiamata di funzione, copia che viene poi confrontata al termine dell'esecuzione della funzione con il valore memorizzato nello stack: se i valori non combaciano StackShield può terminare l'esecuzione del programma o tentare di proseguire ignorando l'attacco e rischiando al massimo il crash del programma.<ref>{{Cita web|url=http://www.angelfire.com/sk/stackshield/info.html|titolo=StackShield}}</ref>
Un'altra estensione del compilatore ''gcc'', "StackGuard", consente sia la rivelazione di eventuali ''stack buffer'' overflow sia la prevenzione degli stessi: la prima difesa tuttavia risulta molto più efficiente e portabile della seconda, in generale meno affidabile e sicura. La rivelazione si basa sulla scrittura nello ''stack frame'' di una ''canary
=== Difese a livello di sistema operativo ===
Riga 132 ⟶ 133:
== Voci correlate ==
* [[Heap overflow]]
* [[
* [[
== Collegamenti esterni ==
* {{FOLDOC||buffer overflow}}
* [https://www.sans.org/reading-room/whitepapers/securecode/buffer-overflow-attack-mechanism-method-prevention-386 Inside the Buffer Overflow Attack:Mechanism, Method, & Prevention]
* [https://cwe.mitre.org/top25/ CWE - 2011 CWE/SANS Top 25 Most Dangerous Software Errors]
* [https://www.kb.cert.org/vuls/id/363715 Vulnerability Note VU#363715 - Microsoft Internet Information Server (IIS) vulnerable to heap overflow during processing of crafted ".htr" request by "ISM.DLL" ISAPI filter]
* [https://www.sans.org/reading-room/whitepapers/threats/buffer-overflows-dummies-481 Buffer Overflows for Dummies - SANS Institute]
* [http://www.preserve-it-all.org/emc-plus/rsa-labs/historical/countermeasures-against-buffer-overflow-attacks.htm RSA Laboratories - Countermeasures against Buffer Overflow Attacks] {{Webarchive|url=https://web.archive.org/web/20160914092946/http://www.preserve-it-all.org/emc-plus/rsa-labs/historical/countermeasures-against-buffer-overflow-attacks.htm |date=14 settembre 2016 }}
* [https://www.freebsd.org/doc/en/books/developers-handbook/secure-bufferov.html 3.3. Buffer Overflows]
* [https://directory.fsf.org/wiki/Libsafe Libsafe - Free Software Directory]
Riga 189 ⟶ 159:
* [http://seclists.org/bugtraq/1995/Feb/109 Thomas Lopatic, Bugtraq: Vulnerability in NCSA HTTPD 1.3]
* [https://www.sans.org/reading-room/whitepapers/malicious/code-red-worm-45 What is Code Red Worm?]
* [http://pen-testing.sans.org/resources/papers/gcih/sql-slammer-worm-101033 SQL Slammer worm] {{Webarchive|url=https://web.archive.org/web/20160913082805/http://pen-testing.sans.org/resources/papers/gcih/sql-slammer-worm-101033 |date=13 settembre 2016 }}
* [https://security.googleblog.com/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow]
* [https://access.redhat.com/it/node/2171131 Falla di sicurezza critica: glibc stack-based buffer overflow in getaddrinfo() (CVE-2015-7547) - Red Hat Customer Portal]
|