Sicurezza del software. Buffer overflow e SQL injection Esercitazione di Sicurezza Informatica, Udine 22/03/2016

Documenti analoghi
Buffer Overflow & SQL Injection

Perché il linguaggio C?

Stack-based buffer overflow

prova.c #include <stdio.h> char funzione(char); codice oggetto del main()

Il linguaggio C. Puntatori e dintorni

Primi passi col linguaggio C

Linguaggi e Ambienti di Programmazione

Format String Vulnerability

Strutture Dati Dinamiche

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Linguaggio C: le funzioni. Visibilità variabili e passaggio parametri

La gestione della memoria dinamica Heap

perror: individuare l errore quando una system call restituisce -1

Lab 01 Introduzione a Codelite

Stringhe e allocazione dinamica della memoria

Linea di comando. Compilazione. Aprire una shell di DOS tramite:

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Informatica Generale 07 - Sistemi Operativi:Gestione dei processi

Corso di Sicurezza Informatica. Sicurezza del software. Ing. Gianluca Caminiti

Laboratorio di Reti, Corsi A e B. Text-Twist. Progetto di Fine Corso A.A. 2016/17

Introduzione al C++ (continua)

Introduzione al linguaggio C Puntatori

Funzioni, Stack e Visibilità delle Variabili in C

Lezione 21 e 22. Valentina Ciriani ( ) Laboratorio di programmazione. Laboratorio di programmazione. Lezione 21 e 22

Documentazione e tutorial

Corso di Sicurezza Informatica

Mini-dispensa sui puntatori in C

Elaborato Shell. Elementi di architettura e sistemi operativi 2016/2017

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2008/2009. formalizzazione degli algoritmi in linguaggio C

Linguaggio C. strutture di controllo: strutture iterative. Università degli Studi di Brescia. Docente: Massimiliano Giacomin

Linguaggio C: introduzione

Il sistema C è formato dal linguaggio C, dal preprocessore, dal compilatore, dalle librerie e da altri strumenti di supporto.

Linguaggi di programmazione

PER UTILIZZARE LCC IN LAB

Linguaggi di Programmazione

Parametri Formali di una Funzione e Record di Attivazione

Allocazione dinamica della memoria

Le basi del linguaggio Java

Compilazione e Makefile

SISTEMI DI ELABORAZIONE

Gestione della memoria

SQL e linguaggi di programmazione. Cursori. Cursori. L interazione con l ambiente SQL può avvenire in 3 modi:

Programmazione Orientata agli Oggetti in Linguaggio Java

Ottenere una modifica del parametro attuale

Gestione dinamica della memoria

Laboratorio di Algoritmi e Strutture Dati

COSTRUZIONE DI UN APPLICAZIONE

Esercizi su. Istruzioni di scelta multipla. Overflow

Unità Didattica 4 Linguaggio C. Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo.

Componenti di un sistema operativo

INTRODUZIONE ALLA PROGRAMMAZIONE

ACSO Programmazione di Sistema e Concorrente

Argomenti Avanzati.! I puntatori! Stack! Visibilità delle Variabili

Esempio. Le istruzioni corrispondono a quelle di sopra, ma sono scritte in modo simbolico. E indipendente dalla machina

Corso sul linguaggio Java

Organizzazione di un SO monolitico

Calcolatori Elettronici Parte VIII: linguaggi assemblativi

Allocazione dinamica della memoria

Il calcolatore. Architettura di un calcolatore (Hardware)

PROGRAMMAZIONE DISCIPLINARE LICEO SCIENTIFICO OPZIONE SCIENZE APPLICATE INFORMATICA CLASSE TERZA

Indice PARTE A. Prefazione Gli Autori Ringraziamenti dell Editore La storia del C. Capitolo 1 Computer 1. Capitolo 2 Sistemi operativi 21 XVII XXIX

La protezione dai memory error exploit

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2009/2010

Esercizi Array. Parte 7. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Lab 1: Marzo 2013

Introduzione a. Funzioni di Ingresso e Uscita. Compilazione

Programmazione (imperativa)

Corso di Laurea Ingegneria Informatica Laboratorio di Informatica

Università degli studi di Roma Tor Vergata Ingegneria Medica Informatica I Programma del Corso

Strutture dati nel supporto a run time

Applicando lo stesso meccanismo al tipo puntatore, possiamo dichiarare un array di puntatori:

Per poter interagire con un database in rete mediante uno script php bisogna. innanzitutto cerare una connessione. Ciò si ottiene mediante la funzione

La Gestione della Memoria. Carla Binucci e Walter Didimo

Architettura dei calcolatori e sistemi operativi. M2 Organizzazione della memoria virtuale Struttura dello spazio virtuale kernel e utente

ELEMENTI DI INFORMATICA L-B. Ing. Claudia Chiusoli

Esercizi Programmazione I

Introduzione al Linguaggio C Corso di Informatica Laurea in Fisica

La programmazione in linguaggio C

Creare l array presentato nei lucidi ([pippo, pluto, etc])

Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo.

I puntatori. Un puntatore è una variabile che contiene l indirizzo di un altra variabile. puntatore

Scope delle variabili e passaggio parametri. Danilo Ardagna Politecnico di Milano

IDE DevC

D B M G Il linguaggio HTML

Fortran in pillole : prima parte

Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007

Algoritmo. La programmazione. Algoritmo. Programmare. Procedimento di risoluzione di un problema

liceo B. Russell PROGRAMMAZIONE INDIRIZZO: SCIENTIFICO SCIENZE APPLICATE TRIENNIO: TERZA DISCIPLINA: INFORMATICA

Il linguaggio assembly

Esame Informatica Generale 13/04/2016 Tema A

FAQ. Guida all inserimento di una domanda F.A.Q.

Espressione di chiamata di funzione

Introduzione ai puntatori in C Definizione

Esercitazioni di Informatica (CIV)

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma.

Definizione di classi. Walter Didimo

Linguaggio C: PUNTATORI

Il Sistema Operativo. Informatica Sistema Operativo 1

Compendio sottoinsieme del C++ a comune col C. (Libreria standard, Input/Output, Costanti, Dichiarazioni e typedef, Memoria Dinamica)

GUIDA ALLA REGISTRAZIONE

Transcript:

Sicurezza del software Buffer overflow e SQL injection Esercitazione di Sicurezza Informatica, Udine 22/03/2016

Buffer overflow Lo stack (I) Quando un programma viene eseguito, il sistema operativo riserva una certa quantità di RAM per la sua esecuzione La memoria allocata è divisa in tre sezioni: Data segment o Heap: spazio per variabili globali, statiche e dinamiche non locali Text segment: spazio per il codice macchina da eseguire Stack: spazio per variabili dinamiche locali

Buffer overflow Lo stack (II) Il data segment (heap) cresce da indirizzi più bassi a indirizzi più alti Gestita tramite chiamate a malloc() e free() Lo stack cresce invece in direzione inversa

Buffer overflow Lo stack (III) Lo stack serve per la gestione delle variabili locali nei linguaggi di alto livello (C, C++) È gestito come una pila LIFO (l ultimo elemento aggiunto è il primo ad essere rimosso) Quando in C viene chiamata una funzione viene instanziato un nuovo stack frame

Buffer overflow Lo stack (IV) Ogni stack frame contiene: I parametri passati alla funzione chiamata Le variabili locali dichiarate nel corpo della funzione L indirizzo della prossima istruzione da eseguire (che si trova nel text segment)

Buffer overflow Il problema (I) Consideriamo ora questo codice C void A() { char B[50]; } void main() { A(); printf("done.\n"); } Prima della chiamata ad A, l ultimo stack frame è quello del main

Buffer overflow Il problema (II) void A() { char B[50]; } void main() { A(); printf("done.\n"); } Al momento della chiamata di A, viene allocato il suo stack frame e EIP (Return addr) punta al codice macchina per la chiamata a printf (istruzione successiva dopo l uscita da A)

Buffer overflow Il problema (III) I buffer sono delle locazioni di memoria contigue in cui possono essere archiviati dei dati Gli array in C sono dei buffer In C e C++ non viene effettuato alcun controllo sui buffer Ad esempio è possibile scrivere in un array più elementi di quelli per cui esso è stato dichiarato Cosa succede in memoria se sforiamo la dimensione di un array?

Buffer overflow Il problema (IV) void A() { char B[50]; B[50] = x ; } void main() { A(); printf("done.\n"); } B può contenere 50 elementi, da 0 a 49 Dove viene scritta la x?

Buffer overflow Il problema (V) void A() { char B[50]; B[50] = x ; } void main() { A(); printf("done.\n"); } Lo stack cresce da indirizzi più alti a quelli più bassi Ogni valore di troppo in B sovrascriverà la memoria precedente a B Buffer overflow!

Buffer overflow Il problema (VI) Se prima di B sono state dichiarate altre variabili, queste vengono sovrascritte Poi viene sovrascritto il puntatore allo stack frame precedente Infine viene sovrascritto l indirizzo di ritorno, ovvero l indirizzo della prossima istruzione da eseguire Si può quindi, sovrascrivendo l indirizzo di ritorno, far eseguire al calcolatore del codice arbitrario!! Attacco di Buffer Overflow L obiettivo è di ottenere i privilegi di amministratore sulla macchina bersaglio

Buffer overflow L attacco (I) Bisogna anzitutto individuare un software vulnerabile Ad esempio i programmi che utilizzano strcpy, perché la funzione strcpy non effettua nessuna verifica sulla lunghezza delle stringhe sorgente e destinazione Sulla vostra macchina virtuale è presente il programma vulnerable.c che stampa in output la stringa ricevuta in input usando la strcpy. Il programma vulnerable.c può essere compilato con: gcc -z execstack -fno-stack-protector -o vulnerable vulnerable.c Può essere eseguito con il comando:./vulnerable testo_in_input Se testo_in_input rientra nella dimensione del buffer, otterrete in output il testo stesso Altrimenti il programma incontrerà un buffer overflow e terminerà con un errore di Segmentation fault

Buffer overflow L attacco (II) Il programma exploit.c sfrutta la vulnerabilità di vulnerable per eseguire del codice malevolo in grado di restituire una shell da amministratore. Il funzionamento di exploit è il seguente: genera un ambiente di esecuzione per il programma vulnerable, contenente, sotto forma di stringa, il codice macchina per ottenere lo uid 0 (l indentità dell amministatore) e aprire una shell genera un parametro per vulnerable più lungo di quello ammesso, la cui porzione finale è riempita con l indirizzo di ritorno del codice macchina eseguibile invoca vulnerable passando l ambiente e il parametro generato

Buffer overflow L attacco (III) Ci sono però alcune limitazioni all attacco per eseguire setuid(0), il programma vulnerabile deve essere di proprietà dell amministratore (root) i moderni compilatori utilizzano dei meccanismi di protezione contro gli attacchi di questo tipo, quindi se il programma vulnerabile è compilato senza particolari opzioni, non sarà vulnerabile (per questo usiamo z execstack -fno-stack-protector) i moderni sistemi operativi utilizzano dei meccanismi di protezione della memoria, che devono essere disabilitati per poter far funzionare questo esempio Per semplificare questa procedura useremo un Makefile che automatizzerà la procedura di compilazione disabilitando le protezioni e rendendo vulnerable di proprietà dell utente root. Per compilare l esempio sarà quindi sufficiente digitare: make Per effettuare un vero attacco di questo tipo è necessario individuare un programma sul sistema che sia già di proprietà di root e che soffra della vulnerabilità a buffer overflow

Buffer overflow L attacco (IV) A questo punto, per eseguire l attacco è sufficiente mandare in esecuzione exploit: $ whoami guy $./exploit AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... # whoami root # I caratteri A sono quelli con cui abbiamo riempito il parametro fino alla lunghezza del buffer, i caratteri seguenti (non stampabili) sono i codici delle operazioni necessarie (a basso livello) ad aprire la shell.

Buffer overflow L attacco (V) Come si fa a costruire il codice macchina per assumere l identità dell amministratore e aprire la shell? La procedura è un po macchinosa e complicata e consiste nelle seguenti fasi: Si scrive un programma C che esegua setuid(0) e execve("/bin/sh") lo si compila sull architettura target con linking statico si decompila il codice e si legge il codice assembly si converte l assembly in codice macchina eliminando eventuali caratteri nulli, che spezzerebbero la stringa C che lo contiene. Ci sono dei software che automatizzano questa procedura (un esempio è generator.c che trovate nella vostra VM)

Buffer overflow Contromisure I moderni compilatori e sistemi operativi hanno diverse contromisure e sistemi di protezione dagli attacchi di buffer overflow. Ecco i principali: Executable space protection: il contenuto dello stack viene marcato in modo tale che non possa essere eseguito, questi metodi possono essere implementati nel sistema operativo o sul processore stesso Address space layout randomization (ASLR): gli indirizzi della memoria di un processo vengono assegnati in modo casuale, impedendo quindi di fare assunzioni sulle posizioni delle variabili, rende l attacco improbabile ma non impossibile Canarini (StackGuard, ProPolice) implementati nei compilatori (GCC, Visual Studio,... ), sono dei valori di guardia che vengono messi attorno ai buffer, il principio è che se il valore del canarino cambia c è in atto un buffer overflow. Il valore iniziale del canarino è solitamente casuale o dipendente dal programma in esecuzione (altrimenti sarebbe possibile sfondare i limiti dei buffer riconoscendo e saltando i canarini).

Buffer overflow All attacco! Compilare vulnerable.c ed exploit.c usando il Makefile Eseguire vulnerable.exe con input di varia lunghezza Eseguire exploit.exe Provare a compilare vulnerable.c senza l opzione -fno-stackprotector, cosa succede? Perché? Provare a compilare vulnerable.c senza l opzione z executestack, cosa succede? Perché? Provare a compilare generator.c ed eseguire./generator comando (es: comando = ls -la). Utilizzare la stringa in output da generator come shellcode in exploit.c.

SQL Injection Cos è (I) A differenza dell attacco buffer overflow, gli attacchi di tipo SQL injection sono tuttora molto diffusi Supponiamo di essere i gestori di un sito web a registrazione. Ogni utente può sottoscrivere un abbonamento specificando un indirizzo e-mail, uno user name e una password. Il database relazionale del nostro sito conterrà quindi una tabella di questo tipo:

SQL Injection Cos è (II) Tipicamente i siti come questo forniscono una pagina di lost password nel caso di smarrimento dei dati di accesso. Inserendo il proprio username, in un apposito modulo, l utente riceve un messaggio di posta elettronica con le istruzioni per la generazione di una nuova password, o addirittura la password stessa Supponiamo che l utente gdavid abbia smarrito la password e venga quindi rediretto sulla pagina del servizio di reinvio password. Il sistema dovrà richiedere al database, tramite una query SQL, l indirizzo e-mail dell utente e la password fornita al momento della registrazione SELECT email FROM tblusers WHERE username = "$uname";

SQL Injection Cos è (III) Se non viene fatto alcun controllo sui dati (pratica molto comune), e quindi sul valore della variabile $uname, è possibile inserire codice SQL al posto del nome utente, ad esempio: whatever"; TRUNCATE TABLE tblusers -- Poichè la query viene costruita per sostituzione, il comando che verrà inviato al server SQL sarà: SELECT email FROM tblusers WHERE username = "whatever"; TRUNCATE TABLE tblusers -- "

SQL Injection Cos è (IV) TRUNCATE TABLE tblusers è il codice SQL per lo svuotamento totale di una tabella, e ; è, in SQL, l operatore per concatenare due query -- indica un commento nella sintassi SQL, e serve all attaccante ad evitare che le virgolette finali causino un errore di sintassi impedendo alla query di essere eseguita Il risultato è che la tabella tblusers viene cancellata da un utente qualsiasi del sito (neppure necessariamente autenticato) Il problema è che alcuni dei caratteri utilizzabili nei moduli su Internet sono anche presenti nella sintassi SQL e poichè spesso i dati di input vengono sostituiti all interno delle query SQL, è possibile modificare il significato delle query.

SQL Injection Esercitiamoci A questo indirizzo è possibile trovare una demo interattiva che spiega l SQL Injection https://www.hacksplaining.com/exercises/sql-injection Nella vostra macchina virtuale è disponibile una sandbox in cui è possibile provare gli effetti dell attacco http://localhost/sqlinjection

SQL Injection Contromisure Escaping: consiste nel convertire ogni carattere in una sua rappresentazione testuale che non abbia alcun significato in SQL. Per esempio, al posto delle doppie virgolette " viene messo il carattere \". Per semplificare queste procedure i linguaggi di programmazione di alto livello forniscono funzioni di conversione apposite (e.g., in PHP mysql_real_escape_string()) Disable query concatenation: per evitare attacchi come quello appena visto alcuni linguaggi impediscono di concatenare le query. In questo modo non sarà possibile, ad esempio, appendere una TRUNCATE ad una SELECT, però non viene garantita l integrità della SELECT stessa.

SQL Injection All attacco! Provare a ottenere lo svuotamento della tabella. Reinserire qualche utente dal modulo apposito. Provare ad ottenere l inserimento di un utente senza passare dal modulo apposito (e.g. evitando un controllo sulla validità dell indirizzo e-mail). (Avanzato) c è un altro oggetto della pagina a rischio SQL injection, quale? Provare a svuotare la tabella sfruttando questa vulnerabilità. (Avanzato) ottenere l eliminazione (non svuotamento) della tabella.

SQL Injection Per ridere

SQL Injection Sul serio (I)

SQL Injection Sul serio (II)

SQL Injection Sul serio (III)

Conclusioni I dati in input possono generare famiglie di attacchi molto difficili da prevedere e individuare, per questo motivo nessun input può essere considerato "sicuro" a priori. Ogni dato proveniente dagli utenti dovrebbe essere controllato e validato, soprattutto se il software è esposto ad accessi dalla rete Non dobbiamo mai pensare che l utente si comporterà nel modo in cui noi pensiamo debba comportarsi!

Rosario Lombardo E: rosario.lombardo@innovactors.it T: +39 0432 1841425 innov@ctors s.r.l. spin-off dell Università di Udine P.IVA, C.F., R.I. 02614070304 REA UD 274523 C.S. 11.500 euro i.v. Sede Legale: Via Vittorio Veneto 31-33100 Udine UD Sede Operativa: Via Jacopo Linussio 51 33100 Udine UD Tel. +39 0432 1841425 Fax +39 0432 1841866 E-Mail innov@ctors.it Web: www.innovactors.it