Corso di Sicurezza Informatica Sicurezza del software Ing. Gianluca Caminiti
Software Sicuro Privo di errori (logici) che comportino un comportamento inatteso. Tali bug possono minare la sicurezza dell intero sistema creando vulnerabilità. Approccio classico penetrate and patch non soddisfacente. 2
Problemi delle patch L analisi è limitata alla correzione veloce del problema e non alla ricerca di problemi di progettazione. Gli effetti collaterali del problema spesso non sono visibili. Soluzioni quick & dirty introducono spesso ulteriori bug. A volte la soluzione del bug non può essere completa nel senso che pregiudica funzionalità o efficienza del sistema. 3
Errori tipici Errori che causano accesso non controllato ai dati. Errori che causano alterazione del flusso di esecuzione del programma. Mancanza di verifiche sui permessi di accesso alle funzioni oppure ai dati (controlli inadeguati o incompleti). Errori sulle condizioni limite (primo o ultimo caso). Altri errori logici. 4
Errori tipici Errori che causano accesso non controllato ai dati. Errori che causano alterazione del flusso di esecuzione del programma. Mancanza di verifiche sui permessi di accesso alle funzioni oppure ai dati (controlli inadeguati o incompleti). Errori sulle condizioni limite (primo o ultimo caso). Altri errori logici. 5
Buffer Overflow
Sommario Gestione della memoria nell invocazione di funzioni per i linguaggi ad alto livello. Richiami su call-stack (record di attivazione). Definizione di Buffer Overflow. Descrizione della tecnica che sfrutta la vulnerabilità (exploit). Tecniche per contrastare il B.O. 7
Call-Stack Stuttura dati organizzata a stack per gestire le chiamate a funzioni nei linguaggi ad alto livello. Ad ogni chiamata a funzione è associata la creazione di un frame sul call-stack. Ogni frame contiene sia il contesto della funzione (parametri di ingresso, variabili locali) che le informazioni (return address, frame pointer) per la gestione del frame stesso, es. per restituire il controllo alla funzione chiamante al termine di quella corrente. 8
Call-Stack Funzione DrawLine invocata da DrawSquare *1 Verso di crescita dello stack per ogni chiamata a funzione *2 *1 Return Address (RA1) & Saved Frame Pointer (SFP1) di DrawLine *2 Return Address (RA2) & Saved Frame Pointer (SFP2) di DrawSquare 9
Call-Stack Al termine di DrawLine, lo stack di DrawSquare è ripristinato (sfruttando il Saved Frame Pointer SFP1) e l esecuzione riprende dal Return Address (RA1). Top of stack Return value (if any) Stack Pointer Frame Pointer 10
Definizione (Stack-based) Buffer Overflow: vulnerabilità di sicurezza del codice. Causa: Un programma contiene funzioni che non verificano la dimensione dei dati in ingresso, limitandosi a copiarli in un buffer (variabile locale alla funzione) di dimensione prestabilita, confidando che l'utente non immetta più dati di quanti il buffer ne possa contenere. Scenario: Ciò può accadere se il programma sfrutta funzioni di libreria di I/O che non fanno controlli sulle dimensioni dei dati trasferiti (es. strcpy del C). 11
Definizione Causa: Quando (per errore o per malizia) il buffer è riempito con una quantità di dati superiore alla sua capienza Effetto: i dati extra possono sovrascrivere le strutture presenti nel record di attivazione della funzione corrente (es. le variabili locali, il return address, ecc.). Il programma può dare risultati errati o imprevedibili, bloccarsi, o (se è un driver di sistema o lo stesso sistema operativo) causare il blocco del computer. 12
Definizione Sfruttamento malevolo della vulnerabilità: Conoscendo bene il programma, il S.O. e l hardware su cui è eseguito, si può precalcolare una sequenza di dati che, inviata per provocare un buffer overflow, consenta di prendere il controllo del programma (e a volte, tramite questo, dell intero sistema). 13
Esempio di codice non sicuro #include <string.h> void foo (char *bar) { char c[12]; } memcpy(c, bar, strlen(bar)); // no bounds checking... int main (int argc, char **argv) { foo(argv[1]); } 14
Lo stack prima dell inserimento 15
Inserimento di hello 16
"A A A A A A A A A A A A A A A A AA A A \x08 \x35 \xc0 \x80" 17
Descrizione dell Exploit In presenza di un parametro di ingresso avente dimensione maggiore di 11 caratteri (byte), i dati che eccedono la dimensione della variabile sovrascrivono il frame, comprese le altre variabili locali, il SFP ed il RA. Quando foo() restituisce il controllo alla funzione chiamante, preleva il RA dal frame e prosegue l esecuzione a partire da quell indirizzo. L attaccante ha sovrascritto RA con un indirizzo arbitrario (in questo caso quello di inizio della variabile c[12]). Nel caso di un vero attacco la stringa di A sarebbe rimpiazzata da codice macchina in grado di cedere il controllo ad un programma esterno (es. una shell). 18
Exploit Possibili 1. Modifica di RA per dirottare il flusso del programma (di solito sul buffer stesso) al termine della funzione. 2. Modifica dei valori contenuti nelle variabili locali vicine per alterare il comportamento del programma ed ottenere effetti vantaggiosi. 3. Modifica di un puntatore a funzione o di un gestore di eccezioni. 19
Contromisure Linguaggio di programmazione: C e C++ non offrono metodi built-in sicuri (rispetto l accesso a dati esterni ad un array), il programmatore si deve occupare delle necessarie verifiche. Linguaggi sicuri (verificano che non si eccedano i confini dell array) sono ad es. Java,.NET ed altri. Uso di funzioni di libreria sicure (non meramente basate su strcpy e similari). Pointer protection: es. codificare gli indirizzi per nascondere i valori effettivi. Protezione contro l esecuzione: uso del bit NX ( No execute ) o anche XD ( execute Disabled ), per marcare aree di memoria in cui l esecuzione di codice è disabilitata. Address space layout randomization (ASLR). 20
Mediazione Incompleta Situazione in cui un provider non controlla il tipo o la quantità di dati ricevuti in input. La conseguenza è che l utente è libero di comporre input di lunghezza e tipologia arbitrari (funzionanti a meno di B.O.). Effetto: alterazione del funzionamento del servizio. Il provider non riesce a distinguere un caso di richiesta prodotta dall interfaccia del servizio da quello in cui è l utente a comporre tale richiesta. Esempio: sito web con uso di parametri passati con metodo GET. 21
Esempio Facciamo acquisti su www.things.com. Al termine degli acquisti confermiamo l ordine e si ottiene la URL seguente: http://www.things.com/order.asp?custid=101&part=555a& qy=20&price =10&ship=boat&shipcost=5&total=205 Allora, perché non provare a modificarla? ;) http://www.things.com/order.asp?custid=101&part=555a& qy=20&price =1&ship=boat&shipcost=5&total=25 22
Contromisure Limitare le scelte dell utente quando possibile. Offuscare (tramite codifica) i parametri passati. Nel caso del web: NON usare il metodo GET (ma il POST). 23
Errori Time-to-check to Time-to-use Si verificano quando è richiesto un certo controllo per potere svolgere una determinata azione, in presenza di problemi di sincronizzazione fra la fase di controllo e l azione corrispondente. Scenario: quando passa troppo tempo fra il momento del controllo e quello in cui tale controllo diventa significativo. 24
Esempio Metafora del venditore anziano Time-of-check Mio_file cambiare il carattere A in B Time-of-use Administrator s_file cancellare il file 25
Contromisure Fare in modo di collegare i due momenti (es. attraverso l uso di checksum per garantire che il controllo sia valido anche in momenti successivi). Time-of-check Mio_file cambiare il carattere A in B 26
Contromisure Fare in modo di collegare i due momenti (es. attraverso l uso di checksum per garantire che il controllo sia valido anche in momenti successivi). Time-of-check Mio_file cambiare il carattere A in B Hash H 27
Contromisure Fare in modo di collegare i due momenti (es. attraverso l uso di checksum per garantire che il controllo sia valido anche in momenti successivi). Time-of-use Administrator s_file cancellare il file Hash H1 28
Contromisure Fare in modo di collegare i due momenti (es. attraverso l uso di checksum per garantire che il controllo sia valido anche in momenti successivi). Time-of-use Administrator s_file cancellare il file Hash H1 H1!= H Verifica fallita: l operazione non è consentita!!! 29