SlideShare a Scribd company logo
1 of 65
Download to read offline
Protostar Format Zero
Studenti:
Gianmarco Beato 0522500782
Francesco Maria D’Auria 0522500752
Sfida CTF:
Università degli Studi di Salerno
Dipartimento di Informatica
Corso di Laurea Magistrale in Informatica
Presentazione per il seminario del corso di “Programmazione Sicura”
Docente:
Prof.ssa Barbara Masucci
Giovedì 20 Maggio 2021
Anno Accademico 2020/2021
(bmasucci@unisa.it)
(g.beato1@studenti.unisa.it)
(f.dauria36@studenti.unisa.it)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
1/63
TEAM
GIANMARCO BEATO FRANCESCO M. D’AURIA
Curriculum
Sicurezza Informatica
Curriculum
Sicurezza Informatica
OBIETTIVO DELLA SFIDA
INTRODUZIONE
FORMATTAZIONE DELLE
STRINGHE
Introduzione alla macchina
virtuale Protostar,
installazione, account
STRATEGIA D’ATTACCO
INDICE DELLA PRESENTAZIONE
01
04
02
05
03
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
06
ANALISI DELLA SFIDA
INDIVIDUAZIONE DELLE DEBOLEZZE
E MITIGAZIONE
Obiettivo, codice
sorgente, suggerimenti,
modus operandi
Raccolta di informazioni,
analisi del codice sorgente,
analisi della memoria
Format Functions e
Format Strings
Preparazione dell’input,
albero di attacco Debolezze e possibili
rimedi degli attacchi
2/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
TIMING
INTRODUZIONE
OBIETTIVO
DELLA SFIDA
ANALISI DELLA
SFIDA
FORMATTAZIONE
DELLE STRINGHE
STRATEGIA
D’ATTACCO
INDIVIDUAZIONE DELLE
DEBOLEZZE E VULNERABILITA’
Gianmarco Beato
Francesco Maria d’Auria
3/63
INTRODUZIONE Introduzione alla macchina virtuale
Protostar, installazione, account
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
4/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
5/63
● Buffer overflow basato su stack;
● Buffer overflow basato su heap;
● Format String;
● Network byte ordering;
INTRODUZIONE (1/5)
Protostar è una macchina virtuale vulnerabile by design contenente esercizi di sicurezza, a scopo didattico,
legati alla corruzione della memoria.
Essa possiede 23 livelli, ciascuno contenente un esercizio, per un totale di 23 esercizi, suddivisi per temi:
1. Stack Zero
2. Stack One
3. Stack Two
4. Stack Three
5. Stack Four
6. Stack Five
7. Stack Six
8. Stack Seven
9. Format Zero
10. Format One
11. Format Two
12. Format Three
13. Format Four
14. Heap Zero
15. Heap One
16. Heap Two
17. Heap Three
18. Net Zero
19. Net One
20. Net Two
21. Final Zero
22. Final One
23. Final Two
I 23 LIVELLI DI PROTOSTAR
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
6/63
La macchina virtuale Protostar è disponibile sul portale di exploit education al link:
http://exploit.education/protostar/
INTRODUZIONE (2/5)
Per l’installazione è necessario eseguire questi semplici passaggi:
● Scaricare l’immagine ISO “exploit-exercises-protostar-2.iso” al link:
http://exploit.education/downloads/
● Successivamente importarla in VirtualBox, creando una nuova macchina virtuale;
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
7/63
Sul PC su cui è stata installata la macchina virtuale, analizzato il sistema e condotto la sfida, così risulta essere
la configurazione:
INTRODUZIONE (3/5)
Oracle VM Virtual Box
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
8/63
INTRODUZIONE (4/5)
Protostar mette a disposizione due account:
Utente che partecipa
alla sfida.
Credenziali:
ATTACCANTE
Utente che amministra il
sistema.
Credenziali:
AMMINISTRATORE
● Username: user
● Password: user
● Username: root
● Password: godmode
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
9/63
INTRODUZIONE (5/5)
Protostar mette a disposizione due account:
Utente che partecipa
alla sfida.
Credenziali:
ATTACCANTE
● Username: user
● Password: user
Questo utente dopo l’autenticazione utilizza le
informazioni contenute nella cartella bin per
eseguire un certo tipo di attacco; la cartella ha il
seguente percorso:
/opt/protostar/bin
OBIETTIVO
DELLA SFIDA
Obiettivo, codice sorgente,
suggerimenti, modus operandi
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
10/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
11/63
OBIETTIVO DELLA SFIDA (1/2)
Sulla relativa pagina web di exploit education (*) viene fornita una descrizione della sfida Format Zero:
“Questo livello introduce le stringhe formattate e di come un attaccante possa dare in input una stringa
formattata per cambiare il flusso di esecuzione di un programma”
(*) http://exploit.education/protostar/format-zero/
Il programma in questione si chiama format0.c ed il suo file eseguibile, format0, ha il seguente percorso:
/opt/protostar/bin/format0
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
12/63
OBIETTIVO DELLA SFIDA (2/2)
format0.c
L’obiettivo della sfida è impostare la variabile target allo
specifico valore 0xdeadbeef a tempo di esecuzione, per
modificare il flusso di esecuzione del programma
Vengono forniti dei piccoli suggerimenti:
● Il livello dovrebbe essere risolto con un input
avente dimensione minore di 10 byte;
● Cercare “Exploiting Format String Vulnerabilities”;
Viene fornito il codice sorgente del programma in
questione; possiamo darne un rapido sguardo:
Il modus operandi è il seguente:
1. Raccogliere quante più informazioni possibili sul
sistema;
2. Aggiornare l’albero d’attacco;
3. Provare l’attacco solo dopo aver individuato un
percorso plausibile;
4. Se l’attacco non è riuscito, tornare al punto 1;
5. Se l’attacco è riuscito, allora sfida vinta!
ANALISI DELLA SFIDA
Raccolta di informazioni, analisi
del codice sorgente, analisi della
memoria
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
13/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
14/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...);
● Sistema Operativo (GNU/Linux, Windows, oppure altro...);
● Metodi di input (locale, remoto, oppure altro...)
ANALISI DELLA SFIDA (1/30)
RACCOLTA DI INFORMAZIONI (1/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
15/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...):
ANALISI DELLA SFIDA (2/30)
Per ottenere informazioni sull’architettura è possibile digitare il seguente comando sul terminale
della macchina precedentemente avviata tramite VirtualBox: arch
Digitando il suddetto comando si scopre che la macchina virtuale Protostar viene eseguita su un
sistema operativo la cui architettura della macchina host è di tipo i686.
Effettuando una ricerca sul Web risulta che i686 è una sigla per indicare la sesta generazione delle
CPU Intel compatibili con l'architettura x86, e che tale architettura utilizza il formato little endian.
RACCOLTA DI INFORMAZIONI (2/8)
1 0 0 1 0 0 1 0
0 1 0 1 0 0 0 1
0 0 0 0 0 1 1 1
0 0 0 0 0 0 1 1
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
16/63
BIG ENDIAN VS LITTLE ENDIAN: COME VENGONO IMMAGAZZINATI I DATI IN MEMORIA? (1/2)
Il modello della memoria RAM
1 0 1 0 1 1 1 0
Una memoria può essere concettualmente
immaginata come una matrice di bit organizzata
in n righe, ciascuna di m colonne.
Il numero n di righe è una potenza di 2.
Il numero m di colonne è un multiplo di 8
(essendo 8 la dimensione in bit del byte).
Una cella è un gruppo di k bit che vengono trattati
come un’unità inscindibile, cioè cui si accede
unitariamente (in genere k = 8, cioè 1byte)
Più celle vengono raggruppate a formare una
parola (word); le dimensioni più comuni per le
parole sono 4 o 8 byte.
Ogni cella/byte viene identificata/o in maniera
univoca mediante il suo indirizzo: se la memoria
contiene N celle, gli indirizzi sono compresi tra 0
e N-1 (si parla di memorie byte-addressable)
:
Memoria da 256bit (32byte)
Byte 0
Indirizzo:
00000000
Byte 1
Indirizzo:
00000001
Byte 2
Indirizzo:
00000010
Byte 3
Indirizzo:
00000011
Byte 31
Indirizzo:
11111111
Ovviamente per memorie molto grandi (es. 4GB) occorrono indirizzi con molti bit (per
una memoria di 4GB occorrono 32bit) e per semplicità tali indirizzi (ma anche il
contenuto dei singoli byte) vengono espressi in notazione esadecimale (prefisso 0x)
e non in notazione binaria, in cui ogni byte viene espresso con due cifre esadecimali:
3970458665 0xECA86429
1110 1100 1010 1000 0110 0100 0010 0000
(Indirizzi bassi)
(Indirizzi alti)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
17/63
BIG ENDIAN VS LITTLE ENDIAN: COME VENGONO IMMAGAZZINATI I DATI IN MEMORIA? (2/2)
Quando il dato da memorizzare (parola) occupa di più di 1byte (più di una cella), un calcolatore può utilizzare una delle due seguenti
modalità per immagazzinare in memoria tali dati, e quindi per accedervi ad esso:
L’ordine dei byte
BIG ENDIAN (da sinistra a
destra):
Il byte più significativo del dato
(della parola) da memorizzare,
cioè quello posto ad estrema
sinistra, ha l’indirizzo di memoria
più basso; mentre quello meno
significativo, cioè quello posto ad
estrema destra, ha l’indirizzo più
alto. In altre parole vuol dire che
l’indirizzo del byte più
significativo viene utilizzato
come indirizzo dell’intera parola,
e quindi per accedervi.
LITTLE ENDIAN (da destra a
sinistra):
Il byte meno significativo del dato
(della parola) da memorizzare,
cioè quello posto ad estrema
destra, ha l’indirizzo di memoria
più basso; mentre quello più
significativo, cioè quello posto ad
estrema sinistra, ha l’indirizzo più
alto. In altre parole vuol dire che
l’indirizzo del byte meno
significativo viene utilizzato come
indirizzo dell’intera parola, e quindi
per accedervi.
0x5C
0x1B
0x12
0x3A
0x5F
0xF4
0x0A
0x0B
:
Byte 0
Indirizzo:
0x00000000
0x12 3A 5F F4
0x5C
0x1B
0xF4
0x5F
0x3A
0x12
:
0x0A
0x0B
(Intero da 32bit=4byte da
memorizzare,
rappresentato in
esadecimale)
Byte 1
Indirizzo:
0x00000001
Byte 2
Indirizzo:
0x00000010
Byte 3
Indirizzo:
0x00000011
Byte 4
Indirizzo:
0x00000100
Byte 5
Indirizzo:
0x00000101
Byte 232
-2
Indirizzo:
0xFFFFFFFE
Byte 232
-1
Indirizzo:
0xFFFFFFFF
(Memoria RAM da 4Gb = 232
byte,
byte-addressable, con celle da
1byte)
0x12 è il
Byte più
significativo
0xF4 è il
Byte meno
significativo
Byte 0
Indirizzo:
0x00000000
Byte 1
Indirizzo:
0x00000001
Byte 2
Indirizzo:
0x00000010
Byte 3
Indirizzo:
0x00000011
Byte 4
Indirizzo:
0x00000100
Byte 5
Indirizzo:
0x00000101
Byte 232
-2
Indirizzo:
0xFFFFFFFE
Byte 232
-1
Indirizzo:
0xFFFFFFFF
(Memoria RAM da 4Gb = 232
byte,
byte-addressable, con celle da
1byte)
(Indirizzi bassi) (Indirizzi bassi)
(Indirizzi alti) (Indirizzi alti)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
18/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...):
ANALISI DELLA SFIDA (5/30)
Per ottenere informazioni sui processori installati sulla macchina host è possibile digitare il
seguente comando sul terminale della macchina: cat /proc/cpuinfo
Digitando il suddetto comando si scopre (tra le tante informazioni che vengono mostrate) che vi è
un solo processore installato e che corrisponde all’ intel Core i7-6700 HQ.
RACCOLTA DI INFORMAZIONI (5/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
19/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Sistema Operativo (GNU/Linux, Windows, oppure altro...):
ANALISI DELLA SFIDA (6/30)
Per ottenere informazioni sul sistema operativo in esecuzione è possibile digitare il seguente
comando sul terminale della macchina: lsb_release -a
Digitando il suddetto comando si scopre che Protostar esegue su un sistema operativo Debian
GNU/Linux v. 6.0.3 (squeeze).
RACCOLTA DI INFORMAZIONI (6/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
20/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Metodi di input (locale, remoto, oppure altro...):
ANALISI DELLA SFIDA (7/30)
Una volta avviata la macchina virtuale tramite virtual box ed aver inserito le credenziali per accedere
all’utente come attaccante, si accede nella cartella di lavoro bin contenente il file eseguibile format0
della sfida digitando il seguente comando sul terminale: cd opt/protostar/bin
Dopodichè, è possibile mandare in esecuzione il programma eseguibile format0 digitando il seguente
comando sul terminale: ./format0
Si può notare che non accade nulla
(viene restituito il terminale) poichè non
è stato passato nessun dato in input.
RACCOLTA DI INFORMAZIONI (7/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
21/63
Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili
sul sistema in questione in termini di:
● Metodi di input (locale, remoto, oppure altro...):
ANALISI DELLA SFIDA (8/30)
Si deduce che il programma format0 accetta esclusivamente input locali, da tastiera o da altro
processo (tramite pipe).
L’input è una stringa generica.
Non sembrano esistere altri metodi per fornire input al programma.
Anche mandando in esecuzione il programma con un input qualsiasi (stringa: abc789 ) si nota che non
accade nulla (viene restituito il terminale, i caratteri vengono memorizzati in buffer[]):
Come procedere?
RACCOLTA DI INFORMAZIONI (8/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
22/63
ANALISI DELLA SFIDA (9/30)
format0.c
ANALISI DEL CODICE SORGENTE (1/2) Analizzando nello specifico il codice sorgente del
programma, è possibile notare che all’interno della
funzione main viene eseguita la funzione vuln che
possiede come parametro argv[1].
All’interno della funzione vuln, invece, vengono
allocate sullo stack due variabili:
volatile int target e char buffer[64]
Viene posta la variabile target al valore 0.
Viene copiato il contenuto di string in buffer
mediante la funzione sprintf(buffer, string).
Se il valore della variabile target risulta uguale al valore
0xdeadbeef, allora viene stampato un messaggio il
quale indica che “il target è stato colpito correttamente”.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
23/63
ANALISI DELLA SFIDA (10/30)
format0.c
ANALISI DEL CODICE SORGENTE (2/2) Inoltre è possibile notare che le variabili target e buffer sono
spazialmente vicine.
Saranno vicine anche in memoria centrale?
E’ necessario analizzare lo stack per capire come sono disposte le
variabili al suo interno.
Perchè? Se le due variabili sono contigue in memoria, è possibile sovrascrivere la
variabile target sfruttando la vicinanza con la variabile buffer.
L’idea è quella di scrivere, mediante una stringa formattata data in input minore di
10 byte (come esplicitamente richiesto), 68 byte all’interno di buffer; poichè
buffer può contenere 64 byte, i primi 64 byte dell’input di 10 byte espanso
riempiranno buffer, mentre i restanti 4 riempiranno target (buffer overflow).
Sarebbe potuto bastare un semplice input di lunghezza maggiore di 64
caratteri per sovrascrivere la variabile target, ma è esplicitamente
richiesto di utilizzare un input minore di 10 byte !
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
24/63
UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (1/3)
Quando viene eseguito un programma il sistema operativo normalmente genera un
nuovo processo e alloca in memoria centrale (RAM) uno spazio di memoria virtuale
riservato al processo stesso.
Tipicamente questa porzione di memoria RAM allocata al processo viene tipicamente
suddivisa in tre parti:
● La prima è il segmento testo che contiene le istruzioni del programma che risiedono
per tutta la durata dell’esecuzione del programma. Tale segmento è posizionato vicino
al limite inferiore (indirizzi bassi) dello spazio di indirizzamento dedicato al processo.
● La seconda parte, collocata immediatamente sopra al segmento testo, è il
segmento dati, che viene ulteriormente suddiviso in due parti:
❖ La sezione dei dati statici, che contiene oggetti di dimensione nota al
compilatore e il cui tempo di vita è il periodo di esecuzione del programma
(es. variabili globali)
❖ La sezione dei dati dinamici (heap), posta immediatamente al di sopra dei dati
statici, contiene dati che vengono allocati dal programma durante la sua
esecuzione (es. malloc()). Questo segmento si espande verso gli indirizzi alti.
● La terza parte è il segmento di stack del programma che è posizionato vicino al limite
superiore (indirizzi alti) dello spazio di indirizzamento dedicato al processo. Come per i
dati dinamici, la dimensione massima di questo segmento non è nota a priori, ed ogni
qualvolta il programma introduce valori (variabili locali e parametri di una funzione), il
sistema operativo espande tale segmento verso gli indirizzi bassi.
Byte 0
Indirizzo:
0x00000000
(Indirizzi bassi)
Byte 232
-1
Indirizzo:
0xFFFFFFFF
(Indirizzi alti)
RAM da 232
byte
Segmento di stack
Segmento testo
Segmento dati
Dati statici
Dati dinamici (heap)
Riservato
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
25/63
UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (2/3)
Byte 0
Indirizzo:
0x00000000
(Indirizzi bassi)
Byte 232
-1
Indirizzo:
0xFFFFFFFF
(Indirizzi alti)
RAM da 232
byte
Segmento di stack
Segmento testo
Segmento dati
Dati statici
Dati dinamici (heap)
Riservato
Il segmento di stack è una zona di memoria di un programma,
organizzata in forma di stack, nella quale sono immagazzinate le
informazioni (i dati oggetto dell’elaborazione) sulle funzioni attive in un
dato momento (le funzioni attive sono quelle che sono state invocate ma
la cui esecuzione non è terminata)
Durante l’esecuzione di un programma, le funzioni hanno la necessità di
archiviare tali dati.
I linguaggi di programmazione moderni hanno il costrutto di procedura
o funzione e quindi l’esecuzione di un programma consiste a sua volta
di diverse “chiamate a funzioni”. Una chiamata a procedura altera il
flusso di controllo come un salto (jump), ma, diversamente da un salto,
una volta finito il proprio compito, una funzione ritorna il controllo
all'istruzione posta appena successivamente alla chiamata.
Quest'astrazione può essere implementata proprio con il supporto di uno
stack; inoltre ciascuna chiamata genera uno stack frame all’interno dello
stack. Questi stack frame vengono impilati sullo stack (allocati) quando
viene chiamata una funzione e spilati quando la funzione ritorna
(deallocati). All’interno di uno stack frame la “funzione chiamata”
generalmente (a seconda dell’architettura) memorizza le variabili locali, i
parametri, l’indirizzo dell’istruzione della funzione chiamante a cui dovrà
restituire il controllo (return address, contenuto nell’instruction pointer o
IP) e il puntatore al frame della funzione chiamante;
:
Segmento di stack
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Variabili locali della
funzione
Parametri della funzione
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
}
}
Stack frame
funzione 2
Stack frame
funzione 1
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Indirizzi alti)
(Top dello stack)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
26/63
UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (3/3)
:
Segmento di stack
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Variabili locali della
funzione
Parametri della funzione
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
}
}
Stack frame
funzione 2
(dimensione 24 byte,
dal byte 1235 al byte
1258)
Stack frame
funzione 1
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Indirizzi alti)
(Top dello stack)
Parametro1
0xaabb89cc
Parametro2
0xacdb17cf
Indirizzo di
ritorno
0x01ab5cff
Puntatore frame
precedente
0x002376cd
Variabile
locale1
0x54ff98cf
Variabile
locale2
0xabcdef00
aa
bb
89
cc
cf
17
db
ac
ff
5c
ab
01
cd
76
23
00
cf
98
ff
54
00
ef
cd
ab
.
esp
Stack
pointer
(0x000004D3)
.
.
.
ebp
Frame
pointer
(0x002376cd)
eax
Valore di
ritorno
(Indirizzi alti)
Da precisare che Il contenuto esatto e
il layout dello stack/stack frame
variano in base all'architettura del
processore e alla convenzione delle
chiamate a funzione. In particolare
nell’architettura Intel x86 gli stack
frame vengono gestiti mediante tre
registri:
Direzione
di
crescita
dello
stack
Byte 1235 (-8 %EBP)
Indirizzo:
0x000004D3
(Indirizzi bassi)
Byte 1238 (-5 %EBP)
Indirizzo:
0x000004D6
Byte 1258 (+15 %EBP)
Indirizzo:
0x000004EA
Byte 1243 (EBP)
Indirizzo:
0x000004DB
ESP: punta al top dello stack, ovvero
contiene l’indirizzo del byte che è
posto al top dello stack.
EBP: contiene l’indirizzo del campo
“puntatore frame precedente” dello
stack frame precedente, e consente di
accedere agli argomenti e alle
variabili locali all’interno del frame
associato alla funzione in esecuzione.
Registri della CPU
EAX: utilizzato per trasferire valori di
ritorno.
BUS INDIRIZZI
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
27/63
ANALISI DELLA SFIDA (14/30)
format0.c
Dunque, in base a ciò che è stato detto, la variabile
buffer[] dovrebbe essere posizionata ad un indirizzo
più basso rispetto alla variabile target.
Ciò dipende dal fatto che le variabili definite per ultime si
posizionano al top dello stack (lo stack cresce verso gli
indirizzi bassi)
E’ necessario, però, ricostruire esattamente il layout dello
stack del programma in esame per determinare
esattamente dove sono posizionati i byte della variabile
target che devono essere sovrascritti mediante
overflow per raggiungere l’obiettivo della sfida, ovvero
modificare il flusso di esecuzione del programma.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
28/63
ANALISI DELLA SFIDA (15/30)
E’ necessario eseguire passo passo il programma format0 mediante un debugger per determinare il layout dello stack.
Lo stack frame da analizzare è quello della funzione vuln().
Lo strumento utilizzato per disassemblare file eseguibili binari è GNU Debugger (gdb).
GDB viene invocato con il comando di shell gdb, seguito dal nome del file binario eseguibile.
L’opzione –q consente di evitare la stampa dei messaggi di copyright.
Una volta avviato, GDB legge i comandi dal terminale, fino a che non si digita quit (q).
Il comando print (p) consente di visualizzare il valore di una espressione.
Verrà simulato ciò che fa un attaccante che non ha a disposizione il codice sorgente, andando a disassemblare la
funzione vuln() e capire cosa fa: per fare ciò verrà utilizzato il comando disassemble di gdb.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
29/63
ANALISI DELLA SFIDA (16/30)
Avvio di gdb digitando il seguente comando sul terminale: gdb -q /opt/protostar/bin/format0
Si può notare che gdb aspetta che viene
digitato un comando.
Viene disassemblata la funzione main() digitando il seguente comando gdb: disassemble main
Si può notare che viene invocata la
funzione vuln che è posta
all’indirizzo 0x80483f4: ora è
possibile disassemblare la funzione
vuln() e vedere in dettaglio
l’evolversi dello stack.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
30/63
ANALISI DELLA SFIDA (17/30)
Viene disassemblata la funzione vuln() digitando il seguente comando gdb: disassemble vuln
Dall’analisi del codice assembly della
funzione vuln() è possibile notare che
sono coinvolti alcuni registri, tra cui quelli
legati allo stack:
● Esp (Stack Pointer): punta al top
dello stack.
● Ebp (Base Pointer): consente di
accedere agli argomenti e alle
variabili locali all’interno di un
frame.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
31/63
ANALISI DELLA SFIDA (18/30)
Viene inserito un breakpoint alla prima istruzione di vuln(), per vedere come viene costruito lo stack, digitando il
seguente comando gdb b seguito dal carattere spazio e poi dal carattere * e dall’indirizzo dell’istruzione in formato
esadecimale: b *0x080483f4
Viene eseguito il programma digitando il comando gdb r (il programma viene eseguito fino all’istruzione immediatamente
precedente al breakpoint precedentemente inserito):
Per capire l’evoluzione dello stack è necessario stampare il valore degli indirizzi puntati dai registri EBP ed ESP ad ogni
passo dell’esecuzione (si digita il comando gdb p seguito dal carattere spazio e poi dal carattere $ e il nome del registro):
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
32/63
ANALISI DELLA SFIDA (19/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffd2c)
ebp
Frame
pointer
(0xbffffd48)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Subito prima dell’esecuzione di
vuln(), l’indirizzo di ritorno è
contenuto nelle cella (di dimensione 4
byte) puntata da ESP, che contiene
l’indirizzo (0xbffffd2c) di tale
cella, ovvero del byte meno
significativo.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
33/63
ANALISI DELLA SFIDA (20/30)
E’ stato appena visto la composizione iniziale dello stack.
Ora si effettuerà una sequenza di istruzioni e si osserverà come si evolve lo stack.
Per eseguire una successiva istruzione assembly passo passo (dopo il breakpoint) si utilizza il
comando si di gdb:
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
34/63
ANALISI DELLA SFIDA (21/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffd2c)
ebp
Frame
pointer
(0xbffffd48)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo push %ebp:
Viene salvato il valore del registro
EBP all’interno dello stack frame. In
tal modo si può risalire allo stack
frame precedente.
Viene aggiornato lo stack pointer
(esp = esp - 4 byte).
Ebp: 0xbffffd48
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
35/63
ANALISI DELLA SFIDA (22/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffd2c)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo mov %esp, %ebp:
Viene impostato un nuovo valore al
registro ebp, che adesso
corrisponde a quello di esp
(ebp = esp).
Ebp: 0xbffffd48
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
36/63
ANALISI DELLA SFIDA (23/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo sub %0x68, %esp:
Lo stack viene allungato di 104 byte
Viene aggiornato lo stack pointer
(esp = esp - 104 byte).
Ebp: 0xbffffd48
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
37/63
ANALISI DELLA SFIDA (24/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo movl $0x0, -0xc(%ebp):
Viene salvato il valore 0 all’interno
dei 4 byte posti all’indirizzo ebp - 12
byte (è la variabile target).
Ebp: 0xbffffd48
8 byte
Target
4 byte
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
38/63
ANALISI DELLA SFIDA (25/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo mov 0x8(%ebp), %eax:
Viene salvato l’indirizzo ebp + 8 byte
all’interno del registro eax
(eax = ebp + 8 byte)
Ebp: 0xbffffd48
8 byte
Target
4 byte
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
39/63
ANALISI DELLA SFIDA (26/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo mov %eax, 0x4(%esp):
Viene salvato il valore del registro
eax all’interno dei 4 byte posti
all’indirizzo esp + 4 byte.
Ebp: 0xbffffd48
8 byte
Target
4 byte
4 byte
4 byte
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
40/63
ANALISI DELLA SFIDA (27/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo lea -0x4c(%ebp), %eax:
Viene salvato l’indirizzo ebp - 76 byte
all’interno del registro eax, che
corrisponde all’indirizzo della
variabile buffer[].
Ebp: 0xbffffd48
8 byte
Target
4 byte
4 byte
Buffer [0, … ,63]
.
.
4 byte
64 byte
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
41/63
ANALISI DELLA SFIDA (28/30)
:
Segmento di stack
Indirizzo di ritorno
libc_start_main
EBP salvato dello stack
frame precedente
Parametri della funzione
main(): argc, argv, envp
Indirizzo di ritorno
Puntatore al frame della
funzione chiamante
Parametri della funzione
Variabili locali della
funzione
{
{
Stack frame
funzione vuln()
Stack frame
funzione main()
Direzione
di
crescita
dello
stack
(Indirizzi bassi)
(Top dello stack)
:
{
Stack frame della
funzione
_libc_start_main()
(che invoca main())
...
esp
Stack
pointer
(0xbffffcc0)
ebp
Frame
pointer
(0xbffffd2c)
eax
Valore di
ritorno
Registri della CPU
BUS INDIRIZZI
(Indirizzi alti)
String
Indirizzo di ritorno
Dopo mov %eax, (%esp):
Lo stack inizia ad essere distrutto;
lo stack pointer adesso punta
all’indirizzo del byte meno
significativo di buffer[].
Ebp: 0xbffffd48
8 byte
Target
Buffer [0, … ,63]
4 byte
64 byte
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
42/63
ANALISI DELLA SFIDA (29/30)
Viene chiamata la funzione
sprintf() che memorizzerà il
risultato all’interno della locazione
puntata da eax, quindi la variabile
buffer[] viene popolata con l’input
che è stato fornito in precedenza.
Poi viene controllato se il valore della
variabile target è uguale al valore
0xdeadbeef.
Infine l’istruzione ret preleva l’indirizzo
di ritorno e lo inserisce in EIP.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
43/63
ANALISI DELLA SFIDA (30/30)
Dunque, dopo aver assistito all’evoluzione dello stack, il piano di attacco diventa più chiaro:
Le variabili buffer[] e target sono contigue in memoria centrale.
E’ necessario costruire un input che vada a sovrascrivere opportunamente i 64 byte della variabile
buffer[] e, successivamente, mediante overflow, i 4 byte della variabile target; questi ultimi
devono avere lo specifico valore 0xdeadbeef per modificare il flusso di esecuzione del programma.
Eseguire il programma format0 con tale input.
Come è possibile quindi, “riempire” 68 byte fornendone in input
al massimo 10? Utilizzando le stringhe formattate!!!
String
Indirizzo di ritorno
Ebp: 0xbffffd48
8 byte
Target
4 byte
4 byte
Buffer [0, … ,63]
.
.
4 byte
64 byte
FORMATTAZIONE
DELLE STRINGHE
Format Functions e Format
Strings
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
44/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
45/63
FORMATTAZIONE DELLE STRINGHE (1/3)
Che cos’è una Format Function?
● E’ una funzione che prende in input differenti parametri, di cui uno è una “Format String”.
● E’ una funzione di conversione, usata per rappresentare tipi di dati primitivi in C in a una
rappresentazione a stringa leggibile da una persona.
https://cs155.stanford.edu/papers/formatstring-1.2.pdf
Esempi di Format Functions:
fprintf() — Stampa in un FILE stream.
printf() — Stampa nello stream “stdout”.
sprintf() — Stampa in una stringa.
snprintf() — Stampa in una stringa e controlla la lunghezza.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
46/63
FORMATTAZIONE DELLE STRINGHE (2/3)
Che cos’è una Format String?
E’ una stringa in ASCIIZ che contiene testo e parametri di formattazione.
https://cs155.stanford.edu/papers/formatstring-1.2.pdf
Esempio: Il seguente codice formatta il valore “1911” come un numero intero.
printf ("The magic number is: %dn", 1911);
Esempi di Parametri di Formattazione:
● %d -- Decimale (int) -- passato come valore
● %u -- Decimale senza segno (unsigned int) -- passato come valore
● %x -- Esadecimale (unsigned int) -- passato come valore
● %s -- Stringa ((const) (unsigned) char *) -- passato come riferimento
● %n -- Numero di bytes scritti, (* int) -- passato come riferimento
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
47/63
FORMATTAZIONE DELLE STRINGHE (3/3)
A cosa bisogna stare attenti?
● Se un attaccante è capace di provvedere una Format String ad una Format Function, in modo
parziale o per intero, è possibile che esista una Format String Vulnerability!
● In base a come usiamo gli specificatori di formato, è possibile perfino leggere e scrivere valori dalla
memoria (con più o meno restrizioni)!
Wrong usage:
int func (char *user) {
printf (user);
}
Ok:
int func (char *user) {
printf ("%s", user);
}
STRATEGIA D’ATTACCO Preparazione dell’input, albero di
attacco
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
48/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
49/63
STRATEGIA D’ATTACCO (1/6)
A questo punto si sa che, tramite un Stack-Based Buffer Overflow, è possibile sovrascrivere la variabile target!
La domanda che sorge è la seguente: è’ possibile anche a livello di codice?
Analizzando la documentazione della funzione sprintf(), scopriamo che non effettua controlli sulla taglia dell’input:
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
50/63
STRATEGIA D’ATTACCO (2/6)
Quindi è possibile scrivere le prime 64 locazioni della variabile buffer con lo specificatore di formattazione “%64x” per poi
aggiungere la stringa “0xdeadbeef” !
Il costo complessivo della stringa è meno di 10 byte e si può automatizzare il tutto con Python digitando il seguente comando sul
terminale:
Python -c “print ‘%64xxefxbexadxde’”
Una volta passato il tutto in input alla funzione sprintf(), lo specificatore di formattazione “%64x” espanderà la stringa!
E’ possibile effettuare un Stack-Based Buffer Overflow! Ma come è possibile riempire 64 locazioni di memoria utilizzando 10 bytes?
La risposta è sempre nella documentazione della funzione sprintf():
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
51/63
STRATEGIA D’ATTACCO (3/6)
ALBERO D’ATTACCO
Sovrascrittura della
variabile target
Login come utente user Preparazione dell’input
Esecuzione di
/opt/protostar/bin/format0
con l’input preparato
Individuazione
formattazione input
Preparazione dell’input
%64 + xefxbexadxde
AND
AND
P
P
P
P
P P
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
52/63
STRATEGIA D’ATTACCO (4/6)
Si entra nella cartella contenente il file
eseguibile del programma.
RISULTATO
Si manda in esecuzione il programma
fornendogli l’input costruito.
Si nota che la variabile target è stata
modificata con successo.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
53/63
STRATEGIA D’ATTACCO (5/6)
SFIDA VINTA
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
54/63
STRATEGIA D’ATTACCO (6/6)
Se, dopo avere eseguito il programma con lo specifico input, si avvia gdb e si disassembla la funzione vuln() con
gli opportuni comandi visti in precedenza, e si stampano i valori delle variabili buffer[] e target, si può
osservare che l’array buffer[] è stato popolato dal valore esadecimale 0x20 corrispondente ad uno spazio
nella tabella ASCII che corrisponde proprio al valore utilizzato dalle funzioni di formattazione!
I valori dalla 57esima alla 63esima cella sono costituiti da valori spazzatura che la funzione sprintf() ha
lasciato avendo ricevuto un input scorretto!
La variabile target, invece, è stata sovrascritta con successo!
CHE COSA E’ SUCCESSO?
INDIVIDUAZIONE DELLE
DEBOLEZZE E
VULNERABILITA’
Debolezze e possibili rimedi degli
attacchi
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
i
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
55/63
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
56/63
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (1/8)
Quali sono le vulnerabilità che sono state riscontrate?
● Il buffer non controlla la size dell’input ricevuto.
● Il buffer permette di leggere e scrivere valori arbitrari dallo stack.
● La funzione “sprintf” non effettua nessun controllo o formattazione sulla stringa in input.
● Ci è stato possibile definire una Format String da input esterno come attaccante!
CWE: Stack-Based Buffer Overflow
https://cwe.mitre.org/data/definitions/121.html
CWE: Use of Externally-Controlled Format String
https://cwe.mitre.org/data/definitions/134.html
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
57/63
POSSIBILI MITIGAZIONI: BUFFER OVERFLOW
IL CWE in “Mitigation” offre diverse soluzioni ma non sono tutte definite
come “complete solutions”.
Soluzioni non complete:
● Architecture & Design: Usare un layer di Astrazione per API rischiose.
● Build & Compilation: Eseguire e compilare il software con estensioni/features con
meccanismi per mitigare o proteggere dai buffer overflow.
● Operation: Usare meccanismi a livello di OS come ASLR (Address Space Layout Randomization).
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (2/8)
Soluzioni più complete:
● Implementation: Implementare controlli sulla lunghezza dell’input.
● Implementation: Usare funzioni capaci di controllare la lunghezza dell’input.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
58/63
IL CWE in “Mitigation” propone mitigazioni semplici ed efficaci:
● Requirement: Quando possibile, non usare linguaggi che possono avere questa debolezza
● Implementation: Far si che alle Format Functions siano passati arguments non modificabili
da un potenziale attaccante. Inoltre bisogna assicurarsi che il numero di arguments passati
sia corretto.
● Build & Compilation: Usare compilatori e linkes capaci di creare warnings per questi casi.
https://cs155.stanford.edu/papers/formatstring-1.2.pdf
POSSIBILI MITIGAZIONI: FORMAT STRING
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (3/8)
● Cosa propone il paper di riferimento nelle Hints:
● Far si che l’utente non possa passare delle Format Strings alle funzioni.
● Usare Specificatori di Formato in modo statico e a priori nelle funzioni.
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
59/63
Stando a quando detto prima, è necessario utilizzare funzioni capaci di
controllare la size dell’input ricevuto!
Pericolosa:
sprintf()
Possibile mitigazione:
snprintf()
POSSIBILI MITIGAZIONI: SNPRINTF
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (4/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
60/63
The functions snprintf() and vsnprintf() do not write more than size
bytes (including the terminating null byte ('0')).
If the output was truncated due to this limit then the return value is the
number of characters (excluding the terminating null byte) which would
have been written to the final string if enough space had been available.
Thus, a return value of size or more means that the output was
truncated. (See also below under NOTES.)
If an output error is encountered, a negative value is returned.
POSSIBILI MITIGAZIONI: SNPRINTF
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (5/8)
int snprintf(char *str, size_t size, const char *format, ...);
*str : Puntatore al Buffer.
size : Numero massimo di bytes (caratteri) scrivibili nel buffer
format : Stringa che contiene una Format String, segue le stesse specifiche di formattazioni della
printf()
Esempio:
int j = snprintf(buffer, 64, stringa_da_scrivere);
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
61/63
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (6/8)
POSSIBILI MITIGAZIONI: BUFFER OVERFLOW
Void vuln(char *string){
…
Char buffer[64];
int length;
…
length = snprintf(buffer, 64, string);
if(length > 64){
printf(“Error: max buffer length exceeded! n”)
exit(-1)
}
...
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
62/63
POSSIBILI MITIGAZIONI: BUFFER OVERFLOW
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (7/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
63/63
INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (8/8)
Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci
Sfida CTF: Protostar Format Zero
Gianmarco Beato e Francesco Maria d’Auria
Giovedì 20 maggio 2021 - a.a. 2020/2021
GRAZIE A TUTTI
PER
L’ATTENZIONE!

More Related Content

Similar to Sfida CTF: Protostar Format Zero

Slide vincenzo masullo
Slide vincenzo masulloSlide vincenzo masullo
Slide vincenzo masullo
vinc3nt83
 
Presentazione Sicurezza Stabile
Presentazione Sicurezza StabilePresentazione Sicurezza Stabile
Presentazione Sicurezza Stabile
Andrea Rossetti
 
La complessità del malware: analisi strutturale ed ambienti di sviluppo
La complessità del malware: analisi strutturale ed ambienti di sviluppoLa complessità del malware: analisi strutturale ed ambienti di sviluppo
La complessità del malware: analisi strutturale ed ambienti di sviluppo
Marco Ferrigno
 

Similar to Sfida CTF: Protostar Format Zero (20)

Slide vincenzo masullo
Slide vincenzo masulloSlide vincenzo masullo
Slide vincenzo masullo
 
Progettazione e Realizzazione di un sistema di sicurezza in ambiente IoT con ...
Progettazione e Realizzazione di un sistema di sicurezza in ambiente IoT con ...Progettazione e Realizzazione di un sistema di sicurezza in ambiente IoT con ...
Progettazione e Realizzazione di un sistema di sicurezza in ambiente IoT con ...
 
Game ratings predictor
Game ratings predictorGame ratings predictor
Game ratings predictor
 
Progetto cluster Ga-vino - Lo sviluppo della piattaforma di montaggio (Massim...
Progetto cluster Ga-vino - Lo sviluppo della piattaforma di montaggio (Massim...Progetto cluster Ga-vino - Lo sviluppo della piattaforma di montaggio (Massim...
Progetto cluster Ga-vino - Lo sviluppo della piattaforma di montaggio (Massim...
 
Presentazione Sicurezza Stabile
Presentazione Sicurezza StabilePresentazione Sicurezza Stabile
Presentazione Sicurezza Stabile
 
Catalogo formativo -V200925
Catalogo formativo -V200925Catalogo formativo -V200925
Catalogo formativo -V200925
 
La copia forense: modalità operative (pt. 2)
La copia forense: modalità operative (pt. 2)La copia forense: modalità operative (pt. 2)
La copia forense: modalità operative (pt. 2)
 
Slide Lavoro di Tesi
Slide Lavoro di TesiSlide Lavoro di Tesi
Slide Lavoro di Tesi
 
Lavoro di Tesi
Lavoro di TesiLavoro di Tesi
Lavoro di Tesi
 
Lavoro di Tesi
Lavoro di TesiLavoro di Tesi
Lavoro di Tesi
 
Grillo manuel
Grillo manuelGrillo manuel
Grillo manuel
 
Untangle piattaforma gateway “modulare”
Untangle piattaforma gateway “modulare”Untangle piattaforma gateway “modulare”
Untangle piattaforma gateway “modulare”
 
Industria 4.0. Lucca, 5 luglio 2017 - Cyber Security in ambiente industriale
Industria 4.0. Lucca, 5 luglio 2017 - Cyber Security in ambiente industrialeIndustria 4.0. Lucca, 5 luglio 2017 - Cyber Security in ambiente industriale
Industria 4.0. Lucca, 5 luglio 2017 - Cyber Security in ambiente industriale
 
Esame di Stato: idee Hardware e Software
Esame di Stato: idee Hardware e SoftwareEsame di Stato: idee Hardware e Software
Esame di Stato: idee Hardware e Software
 
Progettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computerProgettazione e sviluppo di un software applicativo su un single board computer
Progettazione e sviluppo di un software applicativo su un single board computer
 
La complessità del malware: analisi strutturale ed ambienti di sviluppo
La complessità del malware: analisi strutturale ed ambienti di sviluppoLa complessità del malware: analisi strutturale ed ambienti di sviluppo
La complessità del malware: analisi strutturale ed ambienti di sviluppo
 
Seminario blockchain Carrara (1 giugno 2018)
Seminario blockchain Carrara (1 giugno 2018)Seminario blockchain Carrara (1 giugno 2018)
Seminario blockchain Carrara (1 giugno 2018)
 
Giacomo Barbieri - Modulo 5 - Valorizzare lo studio con la tecnologia - Milan...
Giacomo Barbieri - Modulo 5 - Valorizzare lo studio con la tecnologia - Milan...Giacomo Barbieri - Modulo 5 - Valorizzare lo studio con la tecnologia - Milan...
Giacomo Barbieri - Modulo 5 - Valorizzare lo studio con la tecnologia - Milan...
 
Programma il futuro : una scelta Open Source
Programma il futuro : una scelta Open SourceProgramma il futuro : una scelta Open Source
Programma il futuro : una scelta Open Source
 
Data Hiding
Data HidingData Hiding
Data Hiding
 

More from Gianmarco Beato

More from Gianmarco Beato (16)

Acquisizione forense in ambito Web - Gianmarco Beato.pdf
Acquisizione forense in ambito Web - Gianmarco Beato.pdfAcquisizione forense in ambito Web - Gianmarco Beato.pdf
Acquisizione forense in ambito Web - Gianmarco Beato.pdf
 
Documento per la valutazione del progetto del team 2.pdf
Documento per la valutazione del progetto del team 2.pdfDocumento per la valutazione del progetto del team 2.pdf
Documento per la valutazione del progetto del team 2.pdf
 
Documento sul design - SmartPark
Documento sul design - SmartParkDocumento sul design - SmartPark
Documento sul design - SmartPark
 
Documento per l'analisi dei requisiti - SmartPark
Documento per l'analisi dei requisiti - SmartParkDocumento per l'analisi dei requisiti - SmartPark
Documento per l'analisi dei requisiti - SmartPark
 
Presentazione del progetto SmartPark
Presentazione del progetto SmartPark Presentazione del progetto SmartPark
Presentazione del progetto SmartPark
 
Pacman 2D con ML-Agents
Pacman 2D con ML-AgentsPacman 2D con ML-Agents
Pacman 2D con ML-Agents
 
GenerativeMap: visualizzazione ed esplorazione di una density map dinamica tr...
GenerativeMap: visualizzazione ed esplorazione di una density map dinamica tr...GenerativeMap: visualizzazione ed esplorazione di una density map dinamica tr...
GenerativeMap: visualizzazione ed esplorazione di una density map dinamica tr...
 
La mia tesi di laurea triennale - Beato Gianmarco
La mia tesi di laurea triennale  - Beato GianmarcoLa mia tesi di laurea triennale  - Beato Gianmarco
La mia tesi di laurea triennale - Beato Gianmarco
 
La sicurezza nelle reti IEEE 802.15.4
La sicurezza nelle reti IEEE 802.15.4La sicurezza nelle reti IEEE 802.15.4
La sicurezza nelle reti IEEE 802.15.4
 
La sicurezza nelle reti IEEE 802.15.4
La sicurezza nelle reti IEEE 802.15.4 La sicurezza nelle reti IEEE 802.15.4
La sicurezza nelle reti IEEE 802.15.4
 
Relazione progetto Compressione Dati
Relazione progetto Compressione DatiRelazione progetto Compressione Dati
Relazione progetto Compressione Dati
 
Dispensa del corso di Cybersecurity
Dispensa del corso di CybersecurityDispensa del corso di Cybersecurity
Dispensa del corso di Cybersecurity
 
Considerazioni di sicurezza per le reti IEEE 802.15.4
Considerazioni di sicurezza per le reti IEEE 802.15.4 Considerazioni di sicurezza per le reti IEEE 802.15.4
Considerazioni di sicurezza per le reti IEEE 802.15.4
 
Schema di watermarking robusto per un bitstream jpeg cifrato
Schema di watermarking robusto per un bitstream jpeg cifratoSchema di watermarking robusto per un bitstream jpeg cifrato
Schema di watermarking robusto per un bitstream jpeg cifrato
 
Web Application Coronavirus Regione Campania
Web Application Coronavirus Regione CampaniaWeb Application Coronavirus Regione Campania
Web Application Coronavirus Regione Campania
 
Presentazione Tesi di Laurea Triennale
Presentazione Tesi di Laurea Triennale Presentazione Tesi di Laurea Triennale
Presentazione Tesi di Laurea Triennale
 

Sfida CTF: Protostar Format Zero

  • 1. Protostar Format Zero Studenti: Gianmarco Beato 0522500782 Francesco Maria D’Auria 0522500752 Sfida CTF: Università degli Studi di Salerno Dipartimento di Informatica Corso di Laurea Magistrale in Informatica Presentazione per il seminario del corso di “Programmazione Sicura” Docente: Prof.ssa Barbara Masucci Giovedì 20 Maggio 2021 Anno Accademico 2020/2021 (bmasucci@unisa.it) (g.beato1@studenti.unisa.it) (f.dauria36@studenti.unisa.it)
  • 2. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 1/63 TEAM GIANMARCO BEATO FRANCESCO M. D’AURIA Curriculum Sicurezza Informatica Curriculum Sicurezza Informatica
  • 3. OBIETTIVO DELLA SFIDA INTRODUZIONE FORMATTAZIONE DELLE STRINGHE Introduzione alla macchina virtuale Protostar, installazione, account STRATEGIA D’ATTACCO INDICE DELLA PRESENTAZIONE 01 04 02 05 03 Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 06 ANALISI DELLA SFIDA INDIVIDUAZIONE DELLE DEBOLEZZE E MITIGAZIONE Obiettivo, codice sorgente, suggerimenti, modus operandi Raccolta di informazioni, analisi del codice sorgente, analisi della memoria Format Functions e Format Strings Preparazione dell’input, albero di attacco Debolezze e possibili rimedi degli attacchi 2/63
  • 4. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 TIMING INTRODUZIONE OBIETTIVO DELLA SFIDA ANALISI DELLA SFIDA FORMATTAZIONE DELLE STRINGHE STRATEGIA D’ATTACCO INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ Gianmarco Beato Francesco Maria d’Auria 3/63
  • 5. INTRODUZIONE Introduzione alla macchina virtuale Protostar, installazione, account Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 4/63
  • 6. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 5/63 ● Buffer overflow basato su stack; ● Buffer overflow basato su heap; ● Format String; ● Network byte ordering; INTRODUZIONE (1/5) Protostar è una macchina virtuale vulnerabile by design contenente esercizi di sicurezza, a scopo didattico, legati alla corruzione della memoria. Essa possiede 23 livelli, ciascuno contenente un esercizio, per un totale di 23 esercizi, suddivisi per temi: 1. Stack Zero 2. Stack One 3. Stack Two 4. Stack Three 5. Stack Four 6. Stack Five 7. Stack Six 8. Stack Seven 9. Format Zero 10. Format One 11. Format Two 12. Format Three 13. Format Four 14. Heap Zero 15. Heap One 16. Heap Two 17. Heap Three 18. Net Zero 19. Net One 20. Net Two 21. Final Zero 22. Final One 23. Final Two I 23 LIVELLI DI PROTOSTAR
  • 7. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 6/63 La macchina virtuale Protostar è disponibile sul portale di exploit education al link: http://exploit.education/protostar/ INTRODUZIONE (2/5) Per l’installazione è necessario eseguire questi semplici passaggi: ● Scaricare l’immagine ISO “exploit-exercises-protostar-2.iso” al link: http://exploit.education/downloads/ ● Successivamente importarla in VirtualBox, creando una nuova macchina virtuale;
  • 8. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 7/63 Sul PC su cui è stata installata la macchina virtuale, analizzato il sistema e condotto la sfida, così risulta essere la configurazione: INTRODUZIONE (3/5) Oracle VM Virtual Box
  • 9. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 8/63 INTRODUZIONE (4/5) Protostar mette a disposizione due account: Utente che partecipa alla sfida. Credenziali: ATTACCANTE Utente che amministra il sistema. Credenziali: AMMINISTRATORE ● Username: user ● Password: user ● Username: root ● Password: godmode
  • 10. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 9/63 INTRODUZIONE (5/5) Protostar mette a disposizione due account: Utente che partecipa alla sfida. Credenziali: ATTACCANTE ● Username: user ● Password: user Questo utente dopo l’autenticazione utilizza le informazioni contenute nella cartella bin per eseguire un certo tipo di attacco; la cartella ha il seguente percorso: /opt/protostar/bin
  • 11. OBIETTIVO DELLA SFIDA Obiettivo, codice sorgente, suggerimenti, modus operandi Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 10/63
  • 12. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 11/63 OBIETTIVO DELLA SFIDA (1/2) Sulla relativa pagina web di exploit education (*) viene fornita una descrizione della sfida Format Zero: “Questo livello introduce le stringhe formattate e di come un attaccante possa dare in input una stringa formattata per cambiare il flusso di esecuzione di un programma” (*) http://exploit.education/protostar/format-zero/ Il programma in questione si chiama format0.c ed il suo file eseguibile, format0, ha il seguente percorso: /opt/protostar/bin/format0
  • 13. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 12/63 OBIETTIVO DELLA SFIDA (2/2) format0.c L’obiettivo della sfida è impostare la variabile target allo specifico valore 0xdeadbeef a tempo di esecuzione, per modificare il flusso di esecuzione del programma Vengono forniti dei piccoli suggerimenti: ● Il livello dovrebbe essere risolto con un input avente dimensione minore di 10 byte; ● Cercare “Exploiting Format String Vulnerabilities”; Viene fornito il codice sorgente del programma in questione; possiamo darne un rapido sguardo: Il modus operandi è il seguente: 1. Raccogliere quante più informazioni possibili sul sistema; 2. Aggiornare l’albero d’attacco; 3. Provare l’attacco solo dopo aver individuato un percorso plausibile; 4. Se l’attacco non è riuscito, tornare al punto 1; 5. Se l’attacco è riuscito, allora sfida vinta!
  • 14. ANALISI DELLA SFIDA Raccolta di informazioni, analisi del codice sorgente, analisi della memoria Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 13/63
  • 15. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 14/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...); ● Sistema Operativo (GNU/Linux, Windows, oppure altro...); ● Metodi di input (locale, remoto, oppure altro...) ANALISI DELLA SFIDA (1/30) RACCOLTA DI INFORMAZIONI (1/8)
  • 16. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 15/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...): ANALISI DELLA SFIDA (2/30) Per ottenere informazioni sull’architettura è possibile digitare il seguente comando sul terminale della macchina precedentemente avviata tramite VirtualBox: arch Digitando il suddetto comando si scopre che la macchina virtuale Protostar viene eseguita su un sistema operativo la cui architettura della macchina host è di tipo i686. Effettuando una ricerca sul Web risulta che i686 è una sigla per indicare la sesta generazione delle CPU Intel compatibili con l'architettura x86, e che tale architettura utilizza il formato little endian. RACCOLTA DI INFORMAZIONI (2/8)
  • 17. 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 16/63 BIG ENDIAN VS LITTLE ENDIAN: COME VENGONO IMMAGAZZINATI I DATI IN MEMORIA? (1/2) Il modello della memoria RAM 1 0 1 0 1 1 1 0 Una memoria può essere concettualmente immaginata come una matrice di bit organizzata in n righe, ciascuna di m colonne. Il numero n di righe è una potenza di 2. Il numero m di colonne è un multiplo di 8 (essendo 8 la dimensione in bit del byte). Una cella è un gruppo di k bit che vengono trattati come un’unità inscindibile, cioè cui si accede unitariamente (in genere k = 8, cioè 1byte) Più celle vengono raggruppate a formare una parola (word); le dimensioni più comuni per le parole sono 4 o 8 byte. Ogni cella/byte viene identificata/o in maniera univoca mediante il suo indirizzo: se la memoria contiene N celle, gli indirizzi sono compresi tra 0 e N-1 (si parla di memorie byte-addressable) : Memoria da 256bit (32byte) Byte 0 Indirizzo: 00000000 Byte 1 Indirizzo: 00000001 Byte 2 Indirizzo: 00000010 Byte 3 Indirizzo: 00000011 Byte 31 Indirizzo: 11111111 Ovviamente per memorie molto grandi (es. 4GB) occorrono indirizzi con molti bit (per una memoria di 4GB occorrono 32bit) e per semplicità tali indirizzi (ma anche il contenuto dei singoli byte) vengono espressi in notazione esadecimale (prefisso 0x) e non in notazione binaria, in cui ogni byte viene espresso con due cifre esadecimali: 3970458665 0xECA86429 1110 1100 1010 1000 0110 0100 0010 0000 (Indirizzi bassi) (Indirizzi alti)
  • 18. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 17/63 BIG ENDIAN VS LITTLE ENDIAN: COME VENGONO IMMAGAZZINATI I DATI IN MEMORIA? (2/2) Quando il dato da memorizzare (parola) occupa di più di 1byte (più di una cella), un calcolatore può utilizzare una delle due seguenti modalità per immagazzinare in memoria tali dati, e quindi per accedervi ad esso: L’ordine dei byte BIG ENDIAN (da sinistra a destra): Il byte più significativo del dato (della parola) da memorizzare, cioè quello posto ad estrema sinistra, ha l’indirizzo di memoria più basso; mentre quello meno significativo, cioè quello posto ad estrema destra, ha l’indirizzo più alto. In altre parole vuol dire che l’indirizzo del byte più significativo viene utilizzato come indirizzo dell’intera parola, e quindi per accedervi. LITTLE ENDIAN (da destra a sinistra): Il byte meno significativo del dato (della parola) da memorizzare, cioè quello posto ad estrema destra, ha l’indirizzo di memoria più basso; mentre quello più significativo, cioè quello posto ad estrema sinistra, ha l’indirizzo più alto. In altre parole vuol dire che l’indirizzo del byte meno significativo viene utilizzato come indirizzo dell’intera parola, e quindi per accedervi. 0x5C 0x1B 0x12 0x3A 0x5F 0xF4 0x0A 0x0B : Byte 0 Indirizzo: 0x00000000 0x12 3A 5F F4 0x5C 0x1B 0xF4 0x5F 0x3A 0x12 : 0x0A 0x0B (Intero da 32bit=4byte da memorizzare, rappresentato in esadecimale) Byte 1 Indirizzo: 0x00000001 Byte 2 Indirizzo: 0x00000010 Byte 3 Indirizzo: 0x00000011 Byte 4 Indirizzo: 0x00000100 Byte 5 Indirizzo: 0x00000101 Byte 232 -2 Indirizzo: 0xFFFFFFFE Byte 232 -1 Indirizzo: 0xFFFFFFFF (Memoria RAM da 4Gb = 232 byte, byte-addressable, con celle da 1byte) 0x12 è il Byte più significativo 0xF4 è il Byte meno significativo Byte 0 Indirizzo: 0x00000000 Byte 1 Indirizzo: 0x00000001 Byte 2 Indirizzo: 0x00000010 Byte 3 Indirizzo: 0x00000011 Byte 4 Indirizzo: 0x00000100 Byte 5 Indirizzo: 0x00000101 Byte 232 -2 Indirizzo: 0xFFFFFFFE Byte 232 -1 Indirizzo: 0xFFFFFFFF (Memoria RAM da 4Gb = 232 byte, byte-addressable, con celle da 1byte) (Indirizzi bassi) (Indirizzi bassi) (Indirizzi alti) (Indirizzi alti)
  • 19. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 18/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Architettura hardware (32-bit/64-bit, Intel, AMD, oppure altro...): ANALISI DELLA SFIDA (5/30) Per ottenere informazioni sui processori installati sulla macchina host è possibile digitare il seguente comando sul terminale della macchina: cat /proc/cpuinfo Digitando il suddetto comando si scopre (tra le tante informazioni che vengono mostrate) che vi è un solo processore installato e che corrisponde all’ intel Core i7-6700 HQ. RACCOLTA DI INFORMAZIONI (5/8)
  • 20. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 19/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Sistema Operativo (GNU/Linux, Windows, oppure altro...): ANALISI DELLA SFIDA (6/30) Per ottenere informazioni sul sistema operativo in esecuzione è possibile digitare il seguente comando sul terminale della macchina: lsb_release -a Digitando il suddetto comando si scopre che Protostar esegue su un sistema operativo Debian GNU/Linux v. 6.0.3 (squeeze). RACCOLTA DI INFORMAZIONI (6/8)
  • 21. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 20/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Metodi di input (locale, remoto, oppure altro...): ANALISI DELLA SFIDA (7/30) Una volta avviata la macchina virtuale tramite virtual box ed aver inserito le credenziali per accedere all’utente come attaccante, si accede nella cartella di lavoro bin contenente il file eseguibile format0 della sfida digitando il seguente comando sul terminale: cd opt/protostar/bin Dopodichè, è possibile mandare in esecuzione il programma eseguibile format0 digitando il seguente comando sul terminale: ./format0 Si può notare che non accade nulla (viene restituito il terminale) poichè non è stato passato nessun dato in input. RACCOLTA DI INFORMAZIONI (7/8)
  • 22. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 21/63 Prima di addentrarci nel cuore della sfida, è sempre buona norma raccogliere quante più informazioni possibili sul sistema in questione in termini di: ● Metodi di input (locale, remoto, oppure altro...): ANALISI DELLA SFIDA (8/30) Si deduce che il programma format0 accetta esclusivamente input locali, da tastiera o da altro processo (tramite pipe). L’input è una stringa generica. Non sembrano esistere altri metodi per fornire input al programma. Anche mandando in esecuzione il programma con un input qualsiasi (stringa: abc789 ) si nota che non accade nulla (viene restituito il terminale, i caratteri vengono memorizzati in buffer[]): Come procedere? RACCOLTA DI INFORMAZIONI (8/8)
  • 23. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 22/63 ANALISI DELLA SFIDA (9/30) format0.c ANALISI DEL CODICE SORGENTE (1/2) Analizzando nello specifico il codice sorgente del programma, è possibile notare che all’interno della funzione main viene eseguita la funzione vuln che possiede come parametro argv[1]. All’interno della funzione vuln, invece, vengono allocate sullo stack due variabili: volatile int target e char buffer[64] Viene posta la variabile target al valore 0. Viene copiato il contenuto di string in buffer mediante la funzione sprintf(buffer, string). Se il valore della variabile target risulta uguale al valore 0xdeadbeef, allora viene stampato un messaggio il quale indica che “il target è stato colpito correttamente”.
  • 24. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 23/63 ANALISI DELLA SFIDA (10/30) format0.c ANALISI DEL CODICE SORGENTE (2/2) Inoltre è possibile notare che le variabili target e buffer sono spazialmente vicine. Saranno vicine anche in memoria centrale? E’ necessario analizzare lo stack per capire come sono disposte le variabili al suo interno. Perchè? Se le due variabili sono contigue in memoria, è possibile sovrascrivere la variabile target sfruttando la vicinanza con la variabile buffer. L’idea è quella di scrivere, mediante una stringa formattata data in input minore di 10 byte (come esplicitamente richiesto), 68 byte all’interno di buffer; poichè buffer può contenere 64 byte, i primi 64 byte dell’input di 10 byte espanso riempiranno buffer, mentre i restanti 4 riempiranno target (buffer overflow). Sarebbe potuto bastare un semplice input di lunghezza maggiore di 64 caratteri per sovrascrivere la variabile target, ma è esplicitamente richiesto di utilizzare un input minore di 10 byte !
  • 25. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 24/63 UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (1/3) Quando viene eseguito un programma il sistema operativo normalmente genera un nuovo processo e alloca in memoria centrale (RAM) uno spazio di memoria virtuale riservato al processo stesso. Tipicamente questa porzione di memoria RAM allocata al processo viene tipicamente suddivisa in tre parti: ● La prima è il segmento testo che contiene le istruzioni del programma che risiedono per tutta la durata dell’esecuzione del programma. Tale segmento è posizionato vicino al limite inferiore (indirizzi bassi) dello spazio di indirizzamento dedicato al processo. ● La seconda parte, collocata immediatamente sopra al segmento testo, è il segmento dati, che viene ulteriormente suddiviso in due parti: ❖ La sezione dei dati statici, che contiene oggetti di dimensione nota al compilatore e il cui tempo di vita è il periodo di esecuzione del programma (es. variabili globali) ❖ La sezione dei dati dinamici (heap), posta immediatamente al di sopra dei dati statici, contiene dati che vengono allocati dal programma durante la sua esecuzione (es. malloc()). Questo segmento si espande verso gli indirizzi alti. ● La terza parte è il segmento di stack del programma che è posizionato vicino al limite superiore (indirizzi alti) dello spazio di indirizzamento dedicato al processo. Come per i dati dinamici, la dimensione massima di questo segmento non è nota a priori, ed ogni qualvolta il programma introduce valori (variabili locali e parametri di una funzione), il sistema operativo espande tale segmento verso gli indirizzi bassi. Byte 0 Indirizzo: 0x00000000 (Indirizzi bassi) Byte 232 -1 Indirizzo: 0xFFFFFFFF (Indirizzi alti) RAM da 232 byte Segmento di stack Segmento testo Segmento dati Dati statici Dati dinamici (heap) Riservato
  • 26. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 25/63 UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (2/3) Byte 0 Indirizzo: 0x00000000 (Indirizzi bassi) Byte 232 -1 Indirizzo: 0xFFFFFFFF (Indirizzi alti) RAM da 232 byte Segmento di stack Segmento testo Segmento dati Dati statici Dati dinamici (heap) Riservato Il segmento di stack è una zona di memoria di un programma, organizzata in forma di stack, nella quale sono immagazzinate le informazioni (i dati oggetto dell’elaborazione) sulle funzioni attive in un dato momento (le funzioni attive sono quelle che sono state invocate ma la cui esecuzione non è terminata) Durante l’esecuzione di un programma, le funzioni hanno la necessità di archiviare tali dati. I linguaggi di programmazione moderni hanno il costrutto di procedura o funzione e quindi l’esecuzione di un programma consiste a sua volta di diverse “chiamate a funzioni”. Una chiamata a procedura altera il flusso di controllo come un salto (jump), ma, diversamente da un salto, una volta finito il proprio compito, una funzione ritorna il controllo all'istruzione posta appena successivamente alla chiamata. Quest'astrazione può essere implementata proprio con il supporto di uno stack; inoltre ciascuna chiamata genera uno stack frame all’interno dello stack. Questi stack frame vengono impilati sullo stack (allocati) quando viene chiamata una funzione e spilati quando la funzione ritorna (deallocati). All’interno di uno stack frame la “funzione chiamata” generalmente (a seconda dell’architettura) memorizza le variabili locali, i parametri, l’indirizzo dell’istruzione della funzione chiamante a cui dovrà restituire il controllo (return address, contenuto nell’instruction pointer o IP) e il puntatore al frame della funzione chiamante; : Segmento di stack Indirizzo di ritorno Puntatore al frame della funzione chiamante Variabili locali della funzione Parametri della funzione Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione } } Stack frame funzione 2 Stack frame funzione 1 Direzione di crescita dello stack (Indirizzi bassi) (Indirizzi alti) (Top dello stack)
  • 27. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 26/63 UTILIZZO DELLA MEMORIA DA PARTE DI UN PROCESSO (3/3) : Segmento di stack Indirizzo di ritorno Puntatore al frame della funzione chiamante Variabili locali della funzione Parametri della funzione Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione } } Stack frame funzione 2 (dimensione 24 byte, dal byte 1235 al byte 1258) Stack frame funzione 1 Direzione di crescita dello stack (Indirizzi bassi) (Indirizzi alti) (Top dello stack) Parametro1 0xaabb89cc Parametro2 0xacdb17cf Indirizzo di ritorno 0x01ab5cff Puntatore frame precedente 0x002376cd Variabile locale1 0x54ff98cf Variabile locale2 0xabcdef00 aa bb 89 cc cf 17 db ac ff 5c ab 01 cd 76 23 00 cf 98 ff 54 00 ef cd ab . esp Stack pointer (0x000004D3) . . . ebp Frame pointer (0x002376cd) eax Valore di ritorno (Indirizzi alti) Da precisare che Il contenuto esatto e il layout dello stack/stack frame variano in base all'architettura del processore e alla convenzione delle chiamate a funzione. In particolare nell’architettura Intel x86 gli stack frame vengono gestiti mediante tre registri: Direzione di crescita dello stack Byte 1235 (-8 %EBP) Indirizzo: 0x000004D3 (Indirizzi bassi) Byte 1238 (-5 %EBP) Indirizzo: 0x000004D6 Byte 1258 (+15 %EBP) Indirizzo: 0x000004EA Byte 1243 (EBP) Indirizzo: 0x000004DB ESP: punta al top dello stack, ovvero contiene l’indirizzo del byte che è posto al top dello stack. EBP: contiene l’indirizzo del campo “puntatore frame precedente” dello stack frame precedente, e consente di accedere agli argomenti e alle variabili locali all’interno del frame associato alla funzione in esecuzione. Registri della CPU EAX: utilizzato per trasferire valori di ritorno. BUS INDIRIZZI
  • 28. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 27/63 ANALISI DELLA SFIDA (14/30) format0.c Dunque, in base a ciò che è stato detto, la variabile buffer[] dovrebbe essere posizionata ad un indirizzo più basso rispetto alla variabile target. Ciò dipende dal fatto che le variabili definite per ultime si posizionano al top dello stack (lo stack cresce verso gli indirizzi bassi) E’ necessario, però, ricostruire esattamente il layout dello stack del programma in esame per determinare esattamente dove sono posizionati i byte della variabile target che devono essere sovrascritti mediante overflow per raggiungere l’obiettivo della sfida, ovvero modificare il flusso di esecuzione del programma.
  • 29. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 28/63 ANALISI DELLA SFIDA (15/30) E’ necessario eseguire passo passo il programma format0 mediante un debugger per determinare il layout dello stack. Lo stack frame da analizzare è quello della funzione vuln(). Lo strumento utilizzato per disassemblare file eseguibili binari è GNU Debugger (gdb). GDB viene invocato con il comando di shell gdb, seguito dal nome del file binario eseguibile. L’opzione –q consente di evitare la stampa dei messaggi di copyright. Una volta avviato, GDB legge i comandi dal terminale, fino a che non si digita quit (q). Il comando print (p) consente di visualizzare il valore di una espressione. Verrà simulato ciò che fa un attaccante che non ha a disposizione il codice sorgente, andando a disassemblare la funzione vuln() e capire cosa fa: per fare ciò verrà utilizzato il comando disassemble di gdb.
  • 30. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 29/63 ANALISI DELLA SFIDA (16/30) Avvio di gdb digitando il seguente comando sul terminale: gdb -q /opt/protostar/bin/format0 Si può notare che gdb aspetta che viene digitato un comando. Viene disassemblata la funzione main() digitando il seguente comando gdb: disassemble main Si può notare che viene invocata la funzione vuln che è posta all’indirizzo 0x80483f4: ora è possibile disassemblare la funzione vuln() e vedere in dettaglio l’evolversi dello stack.
  • 31. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 30/63 ANALISI DELLA SFIDA (17/30) Viene disassemblata la funzione vuln() digitando il seguente comando gdb: disassemble vuln Dall’analisi del codice assembly della funzione vuln() è possibile notare che sono coinvolti alcuni registri, tra cui quelli legati allo stack: ● Esp (Stack Pointer): punta al top dello stack. ● Ebp (Base Pointer): consente di accedere agli argomenti e alle variabili locali all’interno di un frame.
  • 32. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 31/63 ANALISI DELLA SFIDA (18/30) Viene inserito un breakpoint alla prima istruzione di vuln(), per vedere come viene costruito lo stack, digitando il seguente comando gdb b seguito dal carattere spazio e poi dal carattere * e dall’indirizzo dell’istruzione in formato esadecimale: b *0x080483f4 Viene eseguito il programma digitando il comando gdb r (il programma viene eseguito fino all’istruzione immediatamente precedente al breakpoint precedentemente inserito): Per capire l’evoluzione dello stack è necessario stampare il valore degli indirizzi puntati dai registri EBP ed ESP ad ogni passo dell’esecuzione (si digita il comando gdb p seguito dal carattere spazio e poi dal carattere $ e il nome del registro):
  • 33. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 32/63 ANALISI DELLA SFIDA (19/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffd2c) ebp Frame pointer (0xbffffd48) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Subito prima dell’esecuzione di vuln(), l’indirizzo di ritorno è contenuto nelle cella (di dimensione 4 byte) puntata da ESP, che contiene l’indirizzo (0xbffffd2c) di tale cella, ovvero del byte meno significativo.
  • 34. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 33/63 ANALISI DELLA SFIDA (20/30) E’ stato appena visto la composizione iniziale dello stack. Ora si effettuerà una sequenza di istruzioni e si osserverà come si evolve lo stack. Per eseguire una successiva istruzione assembly passo passo (dopo il breakpoint) si utilizza il comando si di gdb:
  • 35. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 34/63 ANALISI DELLA SFIDA (21/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffd2c) ebp Frame pointer (0xbffffd48) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo push %ebp: Viene salvato il valore del registro EBP all’interno dello stack frame. In tal modo si può risalire allo stack frame precedente. Viene aggiornato lo stack pointer (esp = esp - 4 byte). Ebp: 0xbffffd48
  • 36. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 35/63 ANALISI DELLA SFIDA (22/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffd2c) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo mov %esp, %ebp: Viene impostato un nuovo valore al registro ebp, che adesso corrisponde a quello di esp (ebp = esp). Ebp: 0xbffffd48
  • 37. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 36/63 ANALISI DELLA SFIDA (23/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo sub %0x68, %esp: Lo stack viene allungato di 104 byte Viene aggiornato lo stack pointer (esp = esp - 104 byte). Ebp: 0xbffffd48
  • 38. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 37/63 ANALISI DELLA SFIDA (24/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo movl $0x0, -0xc(%ebp): Viene salvato il valore 0 all’interno dei 4 byte posti all’indirizzo ebp - 12 byte (è la variabile target). Ebp: 0xbffffd48 8 byte Target 4 byte
  • 39. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 38/63 ANALISI DELLA SFIDA (25/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo mov 0x8(%ebp), %eax: Viene salvato l’indirizzo ebp + 8 byte all’interno del registro eax (eax = ebp + 8 byte) Ebp: 0xbffffd48 8 byte Target 4 byte
  • 40. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 39/63 ANALISI DELLA SFIDA (26/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo mov %eax, 0x4(%esp): Viene salvato il valore del registro eax all’interno dei 4 byte posti all’indirizzo esp + 4 byte. Ebp: 0xbffffd48 8 byte Target 4 byte 4 byte 4 byte
  • 41. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 40/63 ANALISI DELLA SFIDA (27/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo lea -0x4c(%ebp), %eax: Viene salvato l’indirizzo ebp - 76 byte all’interno del registro eax, che corrisponde all’indirizzo della variabile buffer[]. Ebp: 0xbffffd48 8 byte Target 4 byte 4 byte Buffer [0, … ,63] . . 4 byte 64 byte
  • 42. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 41/63 ANALISI DELLA SFIDA (28/30) : Segmento di stack Indirizzo di ritorno libc_start_main EBP salvato dello stack frame precedente Parametri della funzione main(): argc, argv, envp Indirizzo di ritorno Puntatore al frame della funzione chiamante Parametri della funzione Variabili locali della funzione { { Stack frame funzione vuln() Stack frame funzione main() Direzione di crescita dello stack (Indirizzi bassi) (Top dello stack) : { Stack frame della funzione _libc_start_main() (che invoca main()) ... esp Stack pointer (0xbffffcc0) ebp Frame pointer (0xbffffd2c) eax Valore di ritorno Registri della CPU BUS INDIRIZZI (Indirizzi alti) String Indirizzo di ritorno Dopo mov %eax, (%esp): Lo stack inizia ad essere distrutto; lo stack pointer adesso punta all’indirizzo del byte meno significativo di buffer[]. Ebp: 0xbffffd48 8 byte Target Buffer [0, … ,63] 4 byte 64 byte
  • 43. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 42/63 ANALISI DELLA SFIDA (29/30) Viene chiamata la funzione sprintf() che memorizzerà il risultato all’interno della locazione puntata da eax, quindi la variabile buffer[] viene popolata con l’input che è stato fornito in precedenza. Poi viene controllato se il valore della variabile target è uguale al valore 0xdeadbeef. Infine l’istruzione ret preleva l’indirizzo di ritorno e lo inserisce in EIP.
  • 44. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 43/63 ANALISI DELLA SFIDA (30/30) Dunque, dopo aver assistito all’evoluzione dello stack, il piano di attacco diventa più chiaro: Le variabili buffer[] e target sono contigue in memoria centrale. E’ necessario costruire un input che vada a sovrascrivere opportunamente i 64 byte della variabile buffer[] e, successivamente, mediante overflow, i 4 byte della variabile target; questi ultimi devono avere lo specifico valore 0xdeadbeef per modificare il flusso di esecuzione del programma. Eseguire il programma format0 con tale input. Come è possibile quindi, “riempire” 68 byte fornendone in input al massimo 10? Utilizzando le stringhe formattate!!! String Indirizzo di ritorno Ebp: 0xbffffd48 8 byte Target 4 byte 4 byte Buffer [0, … ,63] . . 4 byte 64 byte
  • 45. FORMATTAZIONE DELLE STRINGHE Format Functions e Format Strings Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 44/63
  • 46. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 45/63 FORMATTAZIONE DELLE STRINGHE (1/3) Che cos’è una Format Function? ● E’ una funzione che prende in input differenti parametri, di cui uno è una “Format String”. ● E’ una funzione di conversione, usata per rappresentare tipi di dati primitivi in C in a una rappresentazione a stringa leggibile da una persona. https://cs155.stanford.edu/papers/formatstring-1.2.pdf Esempi di Format Functions: fprintf() — Stampa in un FILE stream. printf() — Stampa nello stream “stdout”. sprintf() — Stampa in una stringa. snprintf() — Stampa in una stringa e controlla la lunghezza.
  • 47. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 46/63 FORMATTAZIONE DELLE STRINGHE (2/3) Che cos’è una Format String? E’ una stringa in ASCIIZ che contiene testo e parametri di formattazione. https://cs155.stanford.edu/papers/formatstring-1.2.pdf Esempio: Il seguente codice formatta il valore “1911” come un numero intero. printf ("The magic number is: %dn", 1911); Esempi di Parametri di Formattazione: ● %d -- Decimale (int) -- passato come valore ● %u -- Decimale senza segno (unsigned int) -- passato come valore ● %x -- Esadecimale (unsigned int) -- passato come valore ● %s -- Stringa ((const) (unsigned) char *) -- passato come riferimento ● %n -- Numero di bytes scritti, (* int) -- passato come riferimento
  • 48. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 47/63 FORMATTAZIONE DELLE STRINGHE (3/3) A cosa bisogna stare attenti? ● Se un attaccante è capace di provvedere una Format String ad una Format Function, in modo parziale o per intero, è possibile che esista una Format String Vulnerability! ● In base a come usiamo gli specificatori di formato, è possibile perfino leggere e scrivere valori dalla memoria (con più o meno restrizioni)! Wrong usage: int func (char *user) { printf (user); } Ok: int func (char *user) { printf ("%s", user); }
  • 49. STRATEGIA D’ATTACCO Preparazione dell’input, albero di attacco Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 48/63
  • 50. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 49/63 STRATEGIA D’ATTACCO (1/6) A questo punto si sa che, tramite un Stack-Based Buffer Overflow, è possibile sovrascrivere la variabile target! La domanda che sorge è la seguente: è’ possibile anche a livello di codice? Analizzando la documentazione della funzione sprintf(), scopriamo che non effettua controlli sulla taglia dell’input:
  • 51. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 50/63 STRATEGIA D’ATTACCO (2/6) Quindi è possibile scrivere le prime 64 locazioni della variabile buffer con lo specificatore di formattazione “%64x” per poi aggiungere la stringa “0xdeadbeef” ! Il costo complessivo della stringa è meno di 10 byte e si può automatizzare il tutto con Python digitando il seguente comando sul terminale: Python -c “print ‘%64xxefxbexadxde’” Una volta passato il tutto in input alla funzione sprintf(), lo specificatore di formattazione “%64x” espanderà la stringa! E’ possibile effettuare un Stack-Based Buffer Overflow! Ma come è possibile riempire 64 locazioni di memoria utilizzando 10 bytes? La risposta è sempre nella documentazione della funzione sprintf():
  • 52. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 51/63 STRATEGIA D’ATTACCO (3/6) ALBERO D’ATTACCO Sovrascrittura della variabile target Login come utente user Preparazione dell’input Esecuzione di /opt/protostar/bin/format0 con l’input preparato Individuazione formattazione input Preparazione dell’input %64 + xefxbexadxde AND AND P P P P P P
  • 53. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 52/63 STRATEGIA D’ATTACCO (4/6) Si entra nella cartella contenente il file eseguibile del programma. RISULTATO Si manda in esecuzione il programma fornendogli l’input costruito. Si nota che la variabile target è stata modificata con successo.
  • 54. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 53/63 STRATEGIA D’ATTACCO (5/6) SFIDA VINTA
  • 55. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 54/63 STRATEGIA D’ATTACCO (6/6) Se, dopo avere eseguito il programma con lo specifico input, si avvia gdb e si disassembla la funzione vuln() con gli opportuni comandi visti in precedenza, e si stampano i valori delle variabili buffer[] e target, si può osservare che l’array buffer[] è stato popolato dal valore esadecimale 0x20 corrispondente ad uno spazio nella tabella ASCII che corrisponde proprio al valore utilizzato dalle funzioni di formattazione! I valori dalla 57esima alla 63esima cella sono costituiti da valori spazzatura che la funzione sprintf() ha lasciato avendo ricevuto un input scorretto! La variabile target, invece, è stata sovrascritta con successo! CHE COSA E’ SUCCESSO?
  • 56. INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ Debolezze e possibili rimedi degli attacchi Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci i Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 55/63
  • 57. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 56/63 INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (1/8) Quali sono le vulnerabilità che sono state riscontrate? ● Il buffer non controlla la size dell’input ricevuto. ● Il buffer permette di leggere e scrivere valori arbitrari dallo stack. ● La funzione “sprintf” non effettua nessun controllo o formattazione sulla stringa in input. ● Ci è stato possibile definire una Format String da input esterno come attaccante! CWE: Stack-Based Buffer Overflow https://cwe.mitre.org/data/definitions/121.html CWE: Use of Externally-Controlled Format String https://cwe.mitre.org/data/definitions/134.html
  • 58. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 57/63 POSSIBILI MITIGAZIONI: BUFFER OVERFLOW IL CWE in “Mitigation” offre diverse soluzioni ma non sono tutte definite come “complete solutions”. Soluzioni non complete: ● Architecture & Design: Usare un layer di Astrazione per API rischiose. ● Build & Compilation: Eseguire e compilare il software con estensioni/features con meccanismi per mitigare o proteggere dai buffer overflow. ● Operation: Usare meccanismi a livello di OS come ASLR (Address Space Layout Randomization). INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (2/8) Soluzioni più complete: ● Implementation: Implementare controlli sulla lunghezza dell’input. ● Implementation: Usare funzioni capaci di controllare la lunghezza dell’input.
  • 59. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 58/63 IL CWE in “Mitigation” propone mitigazioni semplici ed efficaci: ● Requirement: Quando possibile, non usare linguaggi che possono avere questa debolezza ● Implementation: Far si che alle Format Functions siano passati arguments non modificabili da un potenziale attaccante. Inoltre bisogna assicurarsi che il numero di arguments passati sia corretto. ● Build & Compilation: Usare compilatori e linkes capaci di creare warnings per questi casi. https://cs155.stanford.edu/papers/formatstring-1.2.pdf POSSIBILI MITIGAZIONI: FORMAT STRING INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (3/8) ● Cosa propone il paper di riferimento nelle Hints: ● Far si che l’utente non possa passare delle Format Strings alle funzioni. ● Usare Specificatori di Formato in modo statico e a priori nelle funzioni.
  • 60. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 59/63 Stando a quando detto prima, è necessario utilizzare funzioni capaci di controllare la size dell’input ricevuto! Pericolosa: sprintf() Possibile mitigazione: snprintf() POSSIBILI MITIGAZIONI: SNPRINTF INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (4/8)
  • 61. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 60/63 The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated. (See also below under NOTES.) If an output error is encountered, a negative value is returned. POSSIBILI MITIGAZIONI: SNPRINTF INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (5/8)
  • 62. int snprintf(char *str, size_t size, const char *format, ...); *str : Puntatore al Buffer. size : Numero massimo di bytes (caratteri) scrivibili nel buffer format : Stringa che contiene una Format String, segue le stesse specifiche di formattazioni della printf() Esempio: int j = snprintf(buffer, 64, stringa_da_scrivere); Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 61/63 INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (6/8) POSSIBILI MITIGAZIONI: BUFFER OVERFLOW
  • 63. Void vuln(char *string){ … Char buffer[64]; int length; … length = snprintf(buffer, 64, string); if(length > 64){ printf(“Error: max buffer length exceeded! n”) exit(-1) } ... Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 62/63 POSSIBILI MITIGAZIONI: BUFFER OVERFLOW INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (7/8)
  • 64. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 63/63 INDIVIDUAZIONE DELLE DEBOLEZZE E VULNERABILITA’ (8/8)
  • 65. Presentazione per il seminario del corso di Programmazione Sicura – prof.ssa Barbara Masucci Sfida CTF: Protostar Format Zero Gianmarco Beato e Francesco Maria d’Auria Giovedì 20 maggio 2021 - a.a. 2020/2021 GRAZIE A TUTTI PER L’ATTENZIONE!