miércoles, marzo 21, 2018

Metasploit: Cómo extender las funcionalidades de meterpreter

En el artículo de hoy, vengo a hablar del popular meterpreter de Metasploit, y mostrar cómo podemos agregarle funcionalidad. Para ello, como me encanta Python, nos vamos a centrar en el uso de este lenguaje. Me he decidido a escribir este post debido al Trabajo Fin de Máster que estoy realizando junto a mi compañero Antonio Marcos, y que se centra en la creación de una herramienta de explotación de vulnerabilidades locales, donde parte de la funcionalidad correrá en meterpreter.

Figura 1: Metasploit: Cómo extender las funcionalidades de meterpreter

Antes de entrar en materia, vamos a ver cómo se llega a ejecutar meterpreter. Imaginemos que la víctima recibe, por ejemplo, un ataque de phishing, pica el anzuelo, se ejecuta nuestro código y de repente se conecta a la máquina del atacante. Se puede ver el flujo a alto nivel en la siguiente imagen.

Figura 2: Flujo de ejecución de una sesión meterpeter vía Phishing

Cuando el objetivo ejecuta el archivo, se conectará a nuestra máquina, que está a la escucha, se le mandará la longitud del código que le vamos a hacer llegar, y acto seguido se le envía el código, que se ejecutará en la víctima y ya estará meterpreter corriendo. Para ejecutar el código que se envía a través del socket, se utiliza la función exec.

Veamos el código que se ejecutará en el objetivo para hacer las pruebas, lo generaremos con msfvenom, y escogemos el payload python/meterpreter/reverse_tcp:

Figura 3: Payload generado con msfvenom

En la imagen de arriba sacamos el código, pero podemos guardarlo directamente en un archivo añadiendo después de raw > file.py. LHOST es la dirección IP de la máquina a la que se conectará el equipo víctima y LPORT el puerto.

Vemos que tenemos código en Base64. Si obtenemos el lenguaje legible veremos cómo lo primero que hace es esperar la conexión. Cuando esa conexión se establece, se recibe la longitud de los datos que van a llegar, y acto seguido en un bucle recibe el meterpreter, para ser ejecutado con exec, vemos que se le pasa el socket como argumento (que podremos utilizar en nuestro código Python con la variable s).

Figura 4: Código en Python

En este punto, ya podremos cargar nuestro código, haciendo uso del comando load, y aquí es donde se va a centrar el post, ¿cómo hacemos ese código? Tendremos que crear algunos archivos, que veremos después:
• Un “Despachador” de entradas del usuario: escrito en Ruby 
• La extensión: escrita en Ruby 
• Type-Length-Value (TLV): archivo Ruby 
• El código que se va a ejecutar en la máquina objetivo: en este caso Python
Estos archivos se tendrán que incluir en las siguientes rutas, teniendo en cuenta que partimos de la carpeta de Metasploit:
• El “despachador” lo agregaremos en la siguiente carpeta: 
metasploit-framework/lib/rex/post/meterpreter/ui/console/command_dispatcher 
• TLV y extensión dentro de una carpeta con el nombre de la extensión, en este caso boomernix, y que se tiene que crear en la siguiente ruta: 
metasploit-framework/lib/rex/post/meterpreter/extensions 
• El código para el meterpreter va dentro de la ruta:
metasploit-framework/vendor/bundle/ruby/2.3.0/gems/metasploit-payloads-1.3.23/data/meterpreter
A continuación tenemos un pequeño esquema del flujo que sigue la ejecución de código desde meterpreter:

Figura 5: Esquema de flujo

En el esquema no se muestra la respuesta, que serán dos valores. El primero de ellos para indicar si se ha realizado correctamente y el segundo la respuesta.

El despachador

Y ahora vamos a ver algo de código, no es el objetivo explicarlo en detalle, ya que es fácil. Empezaremos por el primer punto, el que recibe nuestra entrada para el meterpreter (command_dispatcher).

Figura 6: Command_dispatcher (parte 1)

Aquí se definen los comandos que va a permitir nuestra extensión, hay que tener en cuenta que los comandos que proporcionemos no existan en el meterpreter u otra extensión, porque si no habrá conflictos (por ejemplo, el comando run).

Figura 7: Command_dispatcher (parte 2)

También desde aquí se llama a la extensión, a través de la variable client que nos proporciona Metasploit, y se hace tratamiento de la respuesta que obtenemos, como es un ejemplo, simplemente se pinta por pantalla, sin ningún tratamiento.

La extensión y el TLV (Type-Length-Value)

Vamos a ver la parte de extensión y el archivo de tipo de datos para el intercambio de información con meterpreter.

Figura 8: TLV

La estructura TLV es muy sencilla y permite a meterpreter implementar un protocolo robusto para la comunicación.

Figura 9: La extensión

En la línea 29 se ve cómo se crea un paquete, el parámetro, es el nombre de la función que está en Python. Acto seguido en la línea 30 se agrega un parámetro, y en la siguiente línea se hace la petición. Si miramos en la línea 32, se ve como se extrae el resultado, hay que tener en cuenta los TLV que utilizamos. Todas estas funciones nos las aporta Metasploit.

El código en Python

Hasta aquí hemos visto todo este código que nos vale para cualquier meterpreter, y para cualquier lenguaje como PHP, Python, etcétera. Y ahora por último viene el código de Python, que se encargará de extender meterpreter cuando usemos load.

Figura 10: Código en Python para extender meterpreter

Se puede apreciar que se pueden importar librerías, tener en cuenta que hay librerías que solo existen para un cierto sistema operativo, como puede ser ctypes para Windows, así que toca hacer uso de try. En la línea 24 se obtiene el parámetro que se pasa desde el cliente, se ejecuta el comando en la 25 y se empaqueta en la 26. Se puede ver que se tratan las excepciones, para no alertar de estos errores en la máquina víctima, y tener el máximo control de lo que sucede. Meterpreter puede ejecutarse en cualquier sistema, por ello hay que tener en cuenta dónde corre, para no generar errores visibles por la “víctima”, etcétera.

¡Llega el momento de probar el código, y ver cómo funciona!

1. Ejecutamos Metasploit, cargamos exploit/multi/handler, configuramos el payload y a correr.

Figura 11: Abrimos Metasploit y configuramos el payload

2. Ahora en nuestra víctima se ejecuta el código que se conecta a nuestra máquina.

3. Una vez tenemos meterpreter, hacemos uso de load, y nos informa que se cargó correctamente.

Figura 12: Carga de la extensión con la función load

4. Si usamos el comando help, veremos nuestra funcionalidad.

Figura 13: Ayuda de la funcionalidad

5. Podemos usar la ayuda de la nueva funcionalidad

Figura 14: Pidiendo ayuda de la nueva funcionalidad

6. La usamos, y vemos cómo funciona.
a. Linux
Figura 15: Uso de la nueva funcionalidad en Linux

b. Windows
Figura 16: Uso de la nueva funcionalidad en Windows

Conclusiones

Ahora os toca a vosotros crear vuestra propia funcionalidad. La parte Ruby es igual, aunque es recomendable dividir las funcionalidades en varios archivos, para que su mantenimiento sea más sencillo. En este caso era una simple función. La parte de Python la puedes sustituir, crear una DLL, código PHP, o lo que se te ocurra, cada una funcionara con el tipo de meterpreter correspondiente.

Figura 17: Lanzamiento de exploit desde BoomER

Por último, quiero mostrar cómo se lanza un exploit desde la versión de BoomER que se ha adaptado a meterpreter, el Trabajo Fin de Máster que comente al inicio de este artículo.

¡Hasta la próxima!

Autor: Josué Encinar (@JosueEncinar). Analista de seguridad, autor del blog BoomerNiX.

PD: Quiero dar las gracias a mi tutor y amigo Pablo González, por proponer este tipo de trabajos tan interesantes, desde aquí mandarle un saludo. Y dar las gracias también a Chema Alonso por permitirme aportar este post en su blog.

2 comentarios: