
Laboratorio educativo que demuestra CVE-2017-8291 (PIL/GhostScript RCE) mediante la subida de un archivo EPS manipulado con extensión PNG, incluyendo configuración de Docker y ejecución del PoC.
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginsudo apt remove docker docker-engine docker.io containerd runc -ysudo apt updatesudo apt install -y ca-certificates curl gnupg lsb-releasesudo mkdir -p /etc/apt/keyringscurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgecho "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugindocker compose versiongit clone https://github.com/vulhub/vulhub.git
Después de clonar, acceda a la ruta de la vulnerabilidad a explotar
Aquí: /vulhub/python/PIL-CVE-2017-8291
Realice el ejercicio consultando el siguiente archivo yml
docker compose up -d: comando para crear el contenedor y ejecutarlo en segundo plano
Luego acceda a localhost:8000/ para ver la página web donde se pueden subir archivos

Suba el archivo poc.png manipulado que se encuentra en la misma ruta
Al subirlo, podrá ver que aparece lo siguiente

En una funcionalidad normal, después de subir un archivo PNG, se mostrarían las dimensiones (ancho y alto) de la imagen. Sin embargo, dado que el backend clasifica el tipo de imagen basándose en la cabecera del archivo (no en la extensión), es posible ignorar la extensión y subir un archivo EPS que contenga comandos ejecutables cambiándole la extensión a PNG.
Al aprovechar esto, al subir el archivo poc.png se puede ejecutar el comando 'touch /tmp/aaaaa', y si se cambia el comando dentro del archivo POC por un comando de reverse shell, es posible obtener una shell.
Después de subir el archivo, al acceder al contenedor Docker y revisar /tmp, se puede verificar que se ha creado el archivo aaaaa debido al comando.
command = ["gs",
"-q", # modo silencioso (minimizar salida)
"-g%dx%d" % size, # establecer tamaño de imagen de salida (en píxeles)
"-r%fx%f" % res, # establecer resolución de imagen de entrada (DPI)
"-dBATCH", # finalizar automáticamente al completar el trabajo
"-dNOPAUSE", # ejecutar de forma continua sin pausas entre páginas
"-dSAFER", # activar modo seguro
"-sDEVICE=ppmraw", # establecer dispositivo de salida como ppmraw
"-sOutputFile=%s" % outfile, # especificar ruta del archivo de salida
"-c", "%d %d translate" % (-bbox[0], -bbox[1]),
# corregir el origen de la imagen (desplazamiento)
"-f", infile, # especificar archivo de entrada
]
try:
with open(os.devnull, 'w+b') as devnull:
subprocess.check_call(command, stdin=devnull, stdout=devnull)
im = Image.open(outfile)

Esta vulnerabilidad se origina en Python Imaging Library (PIL) y se ha probado contra CVE-2017-8291. La vulnerabilidad se debe a que PIL determina el tipo de imagen basándose en la cabecera del archivo y no en la extensión. Por lo tanto, aunque el archivo sea realmente EPS, si se cambia su extensión a PNG y se sube, el servidor llamará a GhostScript y se podrán ejecutar comandos arbitrarios insertados en el archivo.
Durante el proyecto, al subir el archivo poc.png manipulado se comprobó la creación del archivo /tmp/aaaaa en el servidor, reproduciendo así que la vulnerabilidad puede conducir a una ejecución remota de comandos (RCE, Remote Code Execution). Además, se pudo verificar que esta vulnerabilidad, al explotar la funcionalidad original de procesamiento de imágenes, puede ampliarse a ataques avanzados como una reverse shell.