Progetto
Per eseguire: ./script.sh
Repository su GitHub - https://github.com/LaCinquette/practice-22-23
Procedimento
-
Per la ricerca della vulnerabilità ho scelto il progetto FFmpeg. Ho trovato un commit che soddisfacesse i requisiti, ovvero:
- Corrispondeva al tipo CWE-476 - dereferenziazione di un puntatore nullo
-
Ho creato un Dockerfile in cui:
- Ho scelto come immagine base Ubuntu 22.04
- Ho impostato
DEBIAN_FRONTEND=nointeractive per escludere l'interazione con la riga di comando durante l'installazione dei pacchetti e di altri comandi
- Ho installato le dipendenze necessarie indicate nella wiki ufficiale
- Preparo la directory di lavoro (cartella workdir)
- Scarico, decomprimo e sposto il commit con la vulnerabilità non ancora corretta nella directory di lavoro
- Avvio la build del programma tramite l'utility make
- Creo lo script copy_out.sh, che si occupa di trovare il file oggetto necessario con l'errore e di copiarlo nella directory workspace/out
- Lascio l'istruzione per l'esecuzione dello script copy_out.sh, che deve essere eseguita all'avvio del container
-
Per automatizzare creo lo script script.sh, che costruisce l'immagine e avvia il container dal quale poi recupera il file e lo sposta nella directory corrente:
- Elimino la cartella corrente out (se esiste)
- Costruisco l'immagine con il nome ffmpeg_image
- Avvio un container basato sull'immagine costruita, passando i seguenti parametri:
--rm per la rimozione automatica del container al termine
-v $PWD/out:/workspace/out per montare la directory temporanea attraverso cui il file oggetto viene trasferito all'host
- Copio il file necessario dalla cartella out
- Elimino la cartella out
Analisi della vulnerabilità
Fonti:
- Commit con l'errore corretto
- Pagina su GitHub relativa alla vulnerabilità
- Messaggio del ricercatore di sicurezza sulla vulnerabilità
Analisi:
Problema:
- Tramite il comando
ffmpeg -c:v dnxhd -i poc.mov -y output.ts, al programma viene passato in input un file .mov creato appositamente
- Per il parsing del formato DNxHD viene chiamata la funzione dnxhd_parse nel file dnxhd_parser
- Questa a sua volta chiama la funzione dnxhd_find_frame_end (nello stesso file), che in determinate condizioni non trova la fine e restituisce un numero negativo che non è un codice di errore
- Questo numero, insieme ad altri parametri, viene poi passato alla funzione ff_combine_frame (che si trova nel file parser) per unire i frame
- Poiché questo numero non è un codice di errore, ff_combine_frame lo riconosce come uno shift e tenta di rileggere quei byte nel buffer, ma siccome il buffer in quel momento è vuoto, avviene una dereferenziazione del puntatore nullo, che porta a un Segmentation fault
Nell'assembly:
0x08000d4e - inizio della sezione
-
movsxd rcx, dword [rbx + 0xc]
Nel registro rcx otteniamo il riferimento a pc->buffer
-
add rcx, rdi
Aggiungiamo next a pc->buffer
-
add rcx, qword [rbx]
Aggiungiamo pc->last_index a next e pc->buffer
-
movzx edi, byte [rcx]
Calcoliamo il byte all'indirizzo rcx, ma poiché pc->buffer è inizialmente null, otteniamo un Segmentation fault
Soluzione:
Impedire l'accesso a un'area di memoria non allocata, gestendo correttamente il caso eccezionale. Quando viene rilevato un numero negativo di byte rimanenti, continuare l'elaborazione del file saltando il ciclo.