Uso eficiente de Metasploit: resource scripts

Cuando empecé a utilizar Metasploit —hace ya unos cuantos años— era bastante caótico para mi auditar una red en busca de vulnerabilidades o información relevante. No seguía una metodología determinada para llevar a cabo las fases de discovering, reconnaissance, exploitation, etc., si no que me dejaba llevar un poco por la intuición. A la larga, esto significa pérdida de tiempo y muchas veces grandes dolores de cabeza por haber obviado algún paso, olvidado algún servicio, ignorado cierta información, etc., con la que podría haber encontrado alguna vulnerabilidad mucho antes.

Metasploit es una maravilla para hacer auditorias, pero también una locura (debido al elevado número de módulos) si no sigues unas pautas en cierto orden y dedicas gran tiempo a la fase de information gathering.

La idea de esta entrada es mostrar cómo es posible automatizar algunas de estas tareas ahorrándonos mucho tiempo y garantizando seguir siempre una misma metodología sin olvidar ningún paso.

Personalmente, cada vez que quiero auditar una nueva red dedico mucho esfuerzo a la fase de discovering, utilizando diversos escaneos con db_nmap (-sT, -P0, -sS, -P0, -sV, -sA, etc.) y utilizando multitud de módulos auxiliares. Un caso bastante típico es encontrarse máquinas con servicios SMB ejecutándose, así que generalmente utilizo los auxiliary modules en auxiliary/scanner/smb para intentar conseguir la versión del S.O (smb_version), usuarios locales (smb_lookupsid), recursos (smb_enumshares), vulnerabilidades (ms09_050_smb2_negotiate_func_index), etc. Lo mismo para el resto de servicios como smtp, snmp, http, etc.

Obviamente, la idea de todo esto es almacenar toda la información que vayamos consiguiendo en nuestro workspace y en sus tablas asociadas (hosts, services, creds y notes) para posteriormente pasar a la fase de explotación. La pregunta es: si siempre llevo a cabo este modus operandi, ¿por qué no automatizar todo este proceso? Esta es la idea de los resource scripts, disponibles desde la revisión 8876, los cuales son tratados como templates ERB al permitirnos ejecutar bloques de instrucciones en ruby desde los que podremos hacer uso de la API de Metasploit (REX). En mi caso, suelo utilizar muchos de los scripts ya disponibles en $install_dir/scripts/resource, la gran mayoría desarrollados por m-1-k-3 (excelente trabajo, por cierto). Estos scripts nos permiten llevar a cabo, entre otras, gran parte de las tareas comentadas anteriormente.

Comenzaremos con el script basic_discovery.rc, el cual sirve para conseguir máquinas y servicios disponibles utilizando nmap y una gran variedad de módulos auxiliares (smb, imap, pop, http, ftp, vnc, etc.)

Si abrimos el script podemos ver que admite algunos parámetros desde el datastore. Uno de estos parámetros (NMAPOTS) nos permitirá especificar el conjunto de flags con el que deseamos utilizar NMAP; en caso de no definirlo utilizará -PN -P0 -0 -sSV por defecto.

Si en lugar de utilizar NMAP, lo que queremos es utilizar el módulo auxiliar portscan con el conjunto de puertos que se definieron en la variable #{ports} (véase arriba), bastará con fijar la variable NMAP a 0 (o valor distinto de true).

Supongamos, por tanto, que nos encontramos en la red local 192.168.1.0/24 y queremos obtener máquinas activas así como los servicios corriendo en las mismas. Lo único que tendremos que hacer es fijar en el datastore la variable RHOSTS y los parámetros deseados. Posteriormente, para lanzar el script ejecutamos resource basic_discovery.rc:

Si miramos ahora la tabla services obtenemos lo siguiente:

msf > resource port_cleaner.rc 
[*] Processing /opt/framework/msf3/scripts/resource/port_cleaner.rc for ERB directives.
[*] resource (/opt/framework/msf3/scripts/resource/port_cleaner.rc)> Ruby Code (627 bytes)
...
...

msf > services -c name,info 

Services
========

host           name      info
----           ----    	 ----
192.168.1.1    ftp       220 cfr110998 FTP version 1.0 ready at Fri May 
   15 03:22:21 2000\x0d\x0a
192.168.1.1    telnet    Password:
192.168.1.1    ssh       SSH-2.0-OpenSSH_5.8p1 Debian-7ubuntu1
192.168.1.7    netbios   SAW-PC:<00>:U :WORKGROUP:<00>:G 
   :SAW-PC:<20>:U :WORKGROUP:<1e>:G :00:01:aa:02:bb:03
192.168.1.34   ssh        SSH-2.0-OpenSSH_5.8p1 Debian-7ubuntu1
192.168.1.34   dns       BIND 9.7.3
192.168.1.34   domain  	 ISC BIND 9.7.3 
192.168.1.100  netbios   SAW-4F3245E21E:<00>:U :WORKGROUP:<00>:G 
   :SAW-4F3245E21E:<20>:U :WORKGROUP:<1e>:G :00:01:22:22:21:cc
192.168.1.100  ntp       Microsoft NTP
192.168.1.111  ntp     	 NTP v4 (unsynchronized)
192.168.1.111  snmp      
192.168.1.124  dns       BIND 9.4.2
192.168.1.124  netbios   SAW-4F3245E22E:<00>:U :SAW-4F3245E22E:<03>:U 
   :SAW-4F3245E22E:<20>:U :WORKGROUP:<00>:G :WORKGROUP:<1e>:G :01:aa:bb:bb:cc:aa
192.168.1.124  ntp       Microsoft NTP

Veamos otro resource script que puede resultarnos de gran ayuda. Supongamos que conseguimos algunas de las credenciales de acceso a algún servicio y queremos comprobar si las mismas son válidas para algún otro servicio de los disponibles en nuestro workspace. El script auto_cred_checker.rc reutilizará las credenciales disponibles en la tabla creds e intentará hacer logging contra alguno de los servicios previamente identificados.

Como se observa en el ejemplo, el script ha utilizando las credenciales añadidas a creds (user: saw, pass: saw) para intentar autenticarse contra el resto de servicios disponibles en la tabla services, encontrado así un acceso ssh a la máquina 192.168.1.34.

Durante la fase de post-explotación también podemos programar, mediante este tipo de scripts, el conjunto de acciones que queremos llevar a cabo en la equipo objetivo. Supongamos, por ejemplo, que hemos conseguido multitud de sesiones con meterpreter y queremos ejecutar las mismas órdenes en todas las sesiones. Generalmente lo que queremos conseguir son hashes, tokens, etc., así que lo único que tendríamos que hacer es modificar a nuestro gusto el script multi_post.rc y lanzarlo. Utilizando los arrays meterpreter_commands y modules_win podremos añadir y quitar las órdenes que queremos ejecutar desde meterpreter así como los módulos post en los que estamos interesados.

Lo que hará multi_post.rc es recorrer cada una de las sesiones (framework.sessions.each_key) y ejecutar las acciones definidas en ambos arrays:

Veamos un último caso. Imaginemos que necesitamos ejecutar un conjunto de acciones sobre la máquina comprometida una vez conseguimos una sesión de meterpreter. Este generalmente es el caso cuando llevamos a cabo client side attacks, al no saber cuándo vamos a recibir shell (por ej. usando el browser autopwn). En el siguiente ejemplo crearemos un resource script en el que se añadirá el modulo search_dwld con el que conseguiremos los ficheros pdf y doc de la víctima. Para conseguir que se ejecute automáticamente necesitamos fijar la variable AutoRunScript a multi_console_command -rc /root/steal_pdf.rc

El script multi_console_command permitirá ejecutar múltiples comandos bien separados por comas (-cl) o bien definidos en un fichero de texto (-rc). El resultado:

Como puede verse, los resource scripts pueden ahorrarnos multitud de tiempo. Además, son sencillos de escribir, por lo que podemos crear o modificar los script disponibles según nos convenga.

La automatización de tareas desde Metasploit no se reduce únicamente a este tipo de scripts. Utilizando plugins, módulos auxiliares, haciendo uso de la Remote API, etc., es posible también automatizar multitud de acciones en función de las necesidades y de la flexibilidad que necesitemos para ello. Os recomiendo el post de HDM titulado Six Ways to Automate Metasploit donde se explica resumidamente cada una de estas opciones.