Mythic C2
Un framework cross-platform, orientado a post-exploit y red teaming, diseñado para ofrecer una interfaz colaborativa y fácil de usar para los operators.
What is Mythic?
Mythic es una plataforma multijugador de command and control para operaciones de red teaming. Está diseñada para facilitar una arquitectura plug-n-play donde se pueden incorporar nuevos agents, canales de comunicación y modificaciones on the fly. Algunos de los objetivos principales del proyecto Mythic son mejorar la calidad de vida de los operators, facilitar el mantenimiento de los agents, permitir personalizaciones y ofrecer capacidades más robustas de análisis de datos durante las operaciones.
Fundamentalmente, Mythic utiliza una interfaz web basada en React y contenedores Docker para el back-end. Un servidor escrito en GoLang gestiona la mayoría de las peticiones web mediante GraphQL APIs y WebSockets. Este servidor también maneja las conexiones a la base de datos PostgreSQL y se comunica con los demás contenedores Docker a través de RabbitMQ. Esto permite que los componentes individuales puedan estar en distintos equipos físicos o en diferentes máquinas virtuales si se desea.
Una vista útil del estado actual de los C2 Profiles y Agents de Mythic se puede encontrar aquí: https://mythicmeta.github.io/overview/
VM Instance Configuration on Google Cloud
Para desplegar nuestro servidor Mythic C2 en Google Cloud, primero debemos crear una instancia VM en Compute Engine.
Ingresamos a Compute Engine > VM Instances y damos clic en Create instance:
Luego, seleccionamos una máquina de tipo E2 por costo y desempeño balanceado, por ejemplo, una e2-standard-2
(2 vCPUs, 8GB RAM):
Para el sistema operativo, seleccionamos una imagen minimalista de Ubuntu, específicamente: ubuntu-minimal-2204-jammy-v20250605
Configuramos la imagen con un disco tipo SSD para mejor rendimiento:
Aquí aconsejo escoger 25GB como mínimo si deseas probar varios agentes y profiles.
Luego habilitamos tráfico HTTP y HTTPS para asegurar la accesibilidad web:
Si queremos automatizar el despliegue con Terraform, podemos utilizar este código:
# This code is compatible with Terraform 4.25.0 and versions that are backwards compatible to 4.25.0.
# For information about validating this Terraform code, see https://developer.hashicorp.com/terraform/tutorials/gcp-get-started/google-cloud-platform-build#format-and-validate-the-configuration
resource "google_compute_instance" "mythic-c2-poc" {
boot_disk {
auto_delete = true
device_name = "mythic-c2-poc"
initialize_params {
image = "projects/ubuntu-os-cloud/global/images/ubuntu-minimal-2204-jammy-v20250611"
size = 10
type = "pd-ssd"
}
mode = "READ_WRITE"
}
can_ip_forward = true
deletion_protection = false
enable_display = false
labels = {
goog-ec-src = "vm_add-tf"
goog-ops-agent-policy = "v2-x86-template-1-4-0"
}
machine_type = "e2-standard-2"
metadata = {
enable-osconfig = "TRUE"
}
name = "mythic-c2-poc"
network_interface {
access_config {
network_tier = "PREMIUM"
}
queue_count = 0
stack_type = "IPV4_ONLY"
subnetwork = "projects/local-bastion-462018-h0/regions/us-central1/subnetworks/default"
}
scheduling {
automatic_restart = true
on_host_maintenance = "MIGRATE"
preemptible = false
provisioning_model = "STANDARD"
}
service_account {
email = "391953011745-compute@developer.gserviceaccount.com"
scopes = ["https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append"]
}
shielded_instance_config {
enable_integrity_monitoring = true
enable_secure_boot = false
enable_vtpm = true
}
tags = ["http-server", "https-server"]
zone = "us-central1-f"
}
module "ops_agent_policy" {
source = "github.com/terraform-google-modules/terraform-google-cloud-operations/modules/ops-agent-policy"
project = "local-bastion-462018-h0"
zone = "us-central1-f"
assignment_id = "goog-ops-agent-v2-x86-template-1-4-0-us-central1-f"
agents_rule = {
package_state = "installed"
version = "latest"
}
instance_filter = {
all = false
inclusion_labels = [{
labels = {
goog-ops-agent-policy = "v2-x86-template-1-4-0"
}
}]
}
}
Una vez creada, obtendremos la IP pública de la VM para futuras conexiones:
Luego, debemos configurar la regla de firewall para permitir el puerto que Mythic C2 utiliza (por ejemplo, el puerto 7443):
Finalmente, tendrás lista tu instancia en Google Cloud preparada para instalar Mythic C2, sus perfiles (Apollo HTTP, SMB, TCP y Xenon HTTPX), y comenzar las pruebas operativas.
SSH Configuration (Optional)
Primero actualizamos e instalamos nano
para modificar el archivo authorized_keys
y facilitar el acceso SSH desde otro cliente:
sudo apt-get update
sudo apt-get install nano
cd .ssh/
nano authorized_keys
Generamos un nuevo par de llaves SSH con el siguiente comando:
ssh-keygen -t ed25519 -f ~/.ssh/mythic_key -C "g3kysec@<TEAMSERVER IP>"

Visualizamos y copiamos la llave pública generada:
cat .ssh/mythic_key.pub
ssh-ed25519 AAAAC3NzaC1lZDI<SNIPPED>jmauSFBuwVFkFt g3kysec@<TEAMSERVER IP>
Pegamos la llave pública en la sesión SSH de la instancia VM:
Con esto podremos acceder fácilmente a través de SSH usando:
ssh -i ~/.ssh/mythic_key g3kysec@<TEAMSERVER-IP>
Opcionalmente, podemos agregar persistencia de la llave ingresada desde el dashboard de Google Compute Engine.
Installation of Mythic C2
Ejecutamos los siguientes comandos para instalar Mythic y sus dependencias:
sudo apt install -y git curl unzip make
git clone https://github.com/its-a-feature/Mythic --depth 1
cd Mythic
sudo ./install_docker_ubuntu.sh
sudo make
Habilitamos el acceso externo configurando Mythic para no enlazar solamente localhost:
sudo ./mythic-cli config set mythic_server_bind_localhost_only false
sudo ./mythic-cli config set rabbitmq_bind_localhost_only false
sudo ./mythic-cli config set nginx_bind_localhost_only false
Installation of C2 Profile and MythicAgent Apollo
Para instalar Apollo y los perfiles HTTP, SMB y TCP ejecutamos:
sudo ./mythic-cli install github https://github.com/MythicAgents/Apollo.git
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/http.git
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/smb.git
sudo ./mythic-cli install github https://github.com/MythicC2Profiles/tcp.git
Reiniciamos Mythic para cargar los nuevos perfiles y agentes:
sudo ./mythic-cli restart
Comprobamos el estado de los servicios:
sudo ./mythic-cli status
MYTHIC SERVICE WEB ADDRESS BOUND LOCALLY
Nginx (Mythic Web UI) https://127.0.0.1:7443 false
Mythic Backend Server http://127.0.0.1:17443 false
Hasura GraphQL Console http://127.0.0.1:8080 true
Jupyter Console http://127.0.0.1:8888 true
Internal Documentation http://127.0.0.1:8090 true
ADDITIONAL SERVICES ADDRESS BOUND LOCALLY
Postgres Database postgresql://mythic_user:password@127.0.0.1:5432/mythic_db true
React Server http://127.0.0.1:3000/new true
RabbitMQ amqp://mythic_user:password@127.0.0.1:5672 false
Mythic Main Services
CONTAINER NAME STATE STATUS MOUNT PORTS
mythic_documentation running Up About a minute (healthy) local 8090/tcp -> 127.0.0.1:8090
mythic_graphql running Up 39 seconds (healthy) N/A 8080/tcp -> 127.0.0.1:8080
mythic_jupyter running Up About a minute (healthy) local 8888/tcp -> 127.0.0.1:8888
mythic_nginx running Up About a minute (healthy) local 7443/tcp -> :::7443, 7443
mythic_postgres running Up About a minute (healthy) local 5432/tcp -> 127.0.0.1:5432
mythic_rabbitmq running Up About a minute (health: starting) local 5672/tcp -> :::5672, 5672
mythic_react running Up About a minute (healthy) local 3000/tcp -> 127.0.0.1:3000
mythic_server running Up About a minute (health: starting) local 7000/tcp -> 127.0.0.1:7000, 7001/tcp -> 127.0.0.1:7001, 7002/tcp -> 127.0.0.1:7002, 7003/tcp -> 127.0.0.1:7003, 7004/tcp -> 127.0.0.1:7004, 7005/tcp -> 127.0.0.1:7005, 7006/tcp -> 127.0.0.1:7006, 7007/tcp -> 127.0.0.1:7007, 7008/tcp -> 127.0.0.1:7008, 7009/tcp -> 127.0.0.1:7009, 7010/tcp -> 127.0.0.1:7010, 17443/tcp -> :::17443, 17444/tcp -> :::17444, 17443, 17444
Installed Services
CONTAINER NAME STATE STATUS MOUNT
apollo running Up About a minute local
http running Up About a minute local
smb running Up About a minute local
tcp running Up About a minute local
2025/06/19 03:54:56 [*] If you are using a remote PayloadType or C2Profile, they will need certain environment variables to properly connect to Mythic.
2025/06/19 03:54:56 Use 'sudo ./mythic-cli config service' for configs for these services.
Verificamos la configuración actual:
cat .env

Getting Started with Mythic
Podemos obtener rápidamente las credenciales para acceder mediante estos comandos:
sudo ./mythic-cli config get mythic_admin_user
sudo ./mythic-cli config get mythic_admin_password
Accedemos desde nuestro navegador web utilizando estas credenciales:
https://<TEAMSERVER-IP>:7443/
Your connection is not private Warning
Si estás utilizando Chrome y un certificado autofirmado generado por defecto por Mythic, probablemente verás una advertencia como esta al intentar conectarte:
Esto es normal y esperado, ya que no estamos utilizando un certificado válido de Let's Encrypt ni un certificado de dominio adecuado. Para omitir esta advertencia, simplemente haz clic en cualquier parte de la ventana y escribe thisisunsafe
. Tu navegador ahora aceptará temporalmente el certificado y te permitirá continuar.
El alcance de este tutorial no contempla el uso de certificados válidos como Let's Encrypt ni de DNS propio.
Operations
What is an operation?
Las operaciones son colecciones de operators, payloads, tasks, artifacts, callbacks y files. Mientras que los tipos de payload y los C2 profiles se comparten a lo largo de toda una instancia de Mythic, las operaciones permiten un control detallado sobre la visibilidad y el acceso durante una evaluación.
Where are operations?
La información de las operaciones se puede encontrar haciendo clic en el ícono de menú (hamburger) en la esquina superior izquierda y luego seleccionando "Operations" → "Modify Operations". Si eres un Mythic admin global, verás todas las operaciones aquí. De lo contrario, solo verás las operaciones asociadas a tu cuenta.
Y realizar cambios estéticos y organizacionales:
Operators
Mythic está diseñado para ser utilizado por múltiples operators trabajando en conjunto para llevar a cabo operaciones. Esto normalmente significa que hay un lead operator, varios otros operators, y potencialmente personas que solo están observando (spectators). Veamos cómo los operators participan dentro de Mythic.
Cada usuario tiene su propia contraseña para autenticarse en Mythic. En el inicio inicial, se crea una cuenta con una contraseña especificada a través de la variable de entorno MYTHIC_ADMIN_PASSWORD
o creando un archivo Mythic/.env
con la entrada MYTHIC_ADMIN_PASSWORD=passwordhere
. Esta cuenta puede luego ser utilizada para crear otras cuentas (también pueden crearse mediante la capacidad de scripting). Si la contraseña de admin no se especifica mediante la variable de entorno ni mediante el archivo Mythic/.env
, entonces se genera una contraseña aleatoria. Esta contraseña solo se utiliza durante la configuración inicial para crear el primer usuario; después de eso, este valor ya no se utiliza.
Operator Permissions
Hay varios tipos de permisos para los operators dentro de Mythic:
-
Admin: Es una configuración global que otorga a los usuarios la capacidad de ver todas las operaciones, desbloquear todos los callbacks e interactuar con todo dentro de Mythic. La única cuenta que tiene este permiso inicialmente es la primera que se crea, y solo las cuentas con permisos de Admin pueden otorgar este nivel a otras cuentas. De igual forma, solo los Admin pueden remover permisos de Admin a otros usuarios.
-
Operation Admin: Es el lead de una operación específica. El Operation Admin puede desbloquear los callbacks de cualquier otro usuario, omitir cualquier verificación de opsec, y tiene control total sobre esa operación.
-
Operator: Son los permisos normales de un usuario. Pueden ser añadidos a una operación por un Admin o por el Operation Admin, y dentro de esa operación pueden omitir verificaciones de opsec para otros operators, y solo pueden desbloquear los callbacks que ellos mismos bloquearon.
-
Spectator: Este tipo de cuenta no tiene permisos para realizar modificaciones dentro de Mythic en una operación. Sin embargo, pueden consultar y visualizar todas las tasks, responses, artifacts, etc., pero no pueden emitir tasks, bloquear callbacks, crear payloads, etc.
Para mejorar la seguridad operativa, creamos un nuevo operador y evitamos usar la cuenta admin predeterminada. Accedemos a la configuración desde:
https://<TEAMSERVER-IP>:7443/new/settings
Finalmente, configuramos el nuevo usuario operador:
Ahora podemos asignar al nuevo operador en la operación Prism
.
C2 Profile
Existen dos tipos de C2 profiles: los egress profiles, que se comunican directamente hacia fuera de la red objetivo, y los peer-to-peer (p2p) profiles, que se comunican con agents vecinos.
Egress Profiles
Los perfiles default HTTP, dynamicHTTP y HTTPX son ejemplos de egress profiles. Se comunican directamente hacia fuera de la red objetivo. Los egress profiles tienen contenedores Docker asociados que permiten hacer la traducción entre tu perfil C2 personalizado y las solicitudes web RESTful normales al servidor principal de Mythic. Más información sobre cómo funciona esto y cómo crear tu propio perfil se puede encontrar aquí: C2 Related Development.
P2P Profiles
Los peer-to-peer profiles, en general, son un poco diferentes. No se comunican directamente con Internet; en su lugar, permiten que los agents se comuniquen entre sí. Esta distinción entre P2P y Egress en Mythic se define mediante un simple valor booleano que indica el propósito del contenedor C2.
HTTP C2 Profile Configuration
Para configurar un perfil HTTP con Apollo:
Accede a la sección de perfiles C2:
https://<TEAMSERVER-IP>:7443/new/payloadtypes
Edita el perfil HTTP haciendo clic en el ícono de configuración:
El perfil HTTP, por defecto, escucha en el puerto 80. Si deseas conectarte al puerto 443 con SSL, necesitas ir a la página de administración del perfil C2 (haz clic en el ícono de audífonos en la parte superior) y ajustar la configuración del perfil HTTP.
{
"instances": [
{
"port": 443, // Default port: 80
"key_path": "privkey.pem",
"cert_path": "fullchain.pem",
"debug": true,
"use_ssl": true,
"ServerHeaders": {
"Cache-Control": "max-age=0, no-cache",
"Connection": "keep-alive",
"Content-Type": "application/javascript; charset=utf-8",
"Pragma": "no-cache",
"Server": "NetDNA-cache/2.2"
},
"error_file_path": "",
"error_status_code": 404,
"payloads": {}
}
]
}
Establece los parámetros personalizados del perfil HTTP:
La configuración utilizada es:
{
"c2profile_name": "http",
"c2_instance": {
"callback_host": "https://<TEAMSERVER-IP>",
"callback_interval": "5",
"callback_jitter": "60",
"callback_port": "443", //Default port: 80
"AESPSK": "aes256_hmac",
"get_uri": "static/js/runtime-main.2b3f1a4c.js",
"headers": {
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "es-CL,es;q=0.9,en-US;q=0.8,en;q=0.7",
"Cache-Control": "no-cache",
"Cookie": "session_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.; Secure; HttpOnly; SameSite=Lax",
"Host": "cdn.prism-assets.com",
"Referer": "https://app.prism-assets.com/dashboard",
"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",
"X-Forwarded-For": "198.51.100.23"
},
"killdate": "2026-06-19",
"query_path_name": "v",
"post_uri": "api/user/notifications",
"encrypted_exchange_check": "true"
},
"instance_name": "prism_https_instance"
}
SMB/TCP C2 Profile Configuration
Para configurar estos perfiles ve donde se indica en las flechas:
SMB
Configuración personalizada SMB:
TCP
Configuración personalizada TCP:
Payloads
Creating a Payload
Necesitas un payload para utilizar. Haz clic en el ícono de advertencia en la parte superior y luego selecciona "New Payload" en la esquina superior derecha de la nueva pantalla. También puedes llegar a esta sección haciendo clic en el ícono de menú (hamburger) en la esquina superior izquierda y seleccionando "Create" → "Create Payload".
Se te pedirá que selecciones el sistema operativo. Esto se utiliza para filtrar los payloads posibles a generar. Luego, selecciona el tipo de payload que deseas construir y completa los parámetros de compilación necesarios para el agent. Selecciona los commands que deseas incluir inicialmente en el payload. Verás los comandos aún no seleccionados a la izquierda y los ya seleccionados a la derecha. Algunos pueden estar preseleccionados por el desarrollador del agent (algunos son integrados y no pueden ser removidos, otros son sugeridos, etc). Si pasas el cursor sobre algún comando, podrás ver información descriptiva sobre él. También es posible cargar comandos más adelante, pero para este walkthrough selecciona todos. Haz clic en Next
.
En la barra lateral izquierda, haz clic en Payloads
, luego selecciona Generate New Payload
desde el menú ACTIONS
.
En el primer paso del asistente, selecciona el sistema operativo de destino para tu payload. En este caso, seleccionamos Windows
.
Escribe y selecciona el agente apollo
. Asegúrate de configurar correctamente los siguientes parámetros:
debug
: puedes activarlo si estás en fase de testing.shellcode_format
: seleccionaBinary
. (En mi caso, el tuyo puede ser distinto)output_type
: seleccionaShellcode
si quieres un payload en formato .bin (ideal para inyección directa).
Aquí puedes seleccionar qué comandos vendrán integrados desde el principio. Usa >>
para incluirlos todos o selecciona solo los necesarios para mantener OPSEC. Puedes revisar la descripción de cada uno al hacer clic sobre ellos.
Elige el perfil C2 previamente configurado, por ejemplo prism_https_instance
.
Una vez construido, verás tu payload en la lista. Podrás descargarlo desde el icono de descarga.
Los pasos para generar los Payloads de los otros C2-Profiles es idéntica.
Using the HTTP Payload
Haz clic nuevamente en el ícono de advertencia en la parte superior para ir a la página de payloads creados. Aquí podrás ver todos los payloads generados para la operación actual. Puedes eliminar un payload, ver su configuración o descargarlo. Para este walkthrough, descarga el payload (ícono verde de descarga).
Al ejecutar el payload, si realizaste los pasos como se indicaron en el walkthrough deberías obtener el callback.
Using the TCP/SMB Payload
Este perfil de C2 SMB/TCP funciona como un canal P2P (Peer-to-Peer) entre agentes Mythic, permitiendo comunicación lateral sin necesidad de que todos los agentes tengan salida directa a internet.
El protocolo define que se deben transferir mensajes base64 de Mythic, conocidos como messageA
, en bloques de 1KB a través del wire.
El contenido de messageA
es:
- El uuid del agente + los datos del mensaje
- Todo codificado en base64
Dependiendo de desde dónde venga el mensaje, el agente que lo recibe debe actuar distinto:
-
Si el mensaje viene desde un agente más alejado del punto de salida (egress): debe encapsular el mensaje (
delegate
) y reenviarlo hacia el siguiente hop más cercano a Mythic. -
Si el mensaje viene desde el lado de Mythic (egress): es un mensaje para este agente, por lo tanto debe ser procesado normalmente.
Este diseño simple pero robusto permite que cualquier agente Mythic pueda interoperar mediante este C2 profile.
Link SMB Agent:
-
Ejecutamos el comando
link
en unINTERACT
link
-
Ingresamos el nombre del host remoto y seleccionamos el payload SMB
-
Validamos los parámetros SMB:
pipename
,AESPSK
,killdate
, etc. -
Ejecutamos la tarea y se establece el link SMB con el agente remoto:
Link TCP Agent:
Se repite el mismo procedimiento, esta vez seleccionando un payload TCP:
Callback Interaction
Aquí es donde podrás interactuar con cualquier callback dentro de la operación. Haz clic en el botón correspondiente a la fila de tu nuevo agent para mostrar la información en el panel inferior, donde podrás escribir comandos y enviárselos al agent.
Recomiendo leer la documentación y también usar el comando help
.
La documentación la puedes encontrar integrada en tu Mythic:
https://TEAMSERVER-IP:7443/docs/agents/apollo/commands/
C2 Profile Testing
Se puede probar la configuración del C2 Profile
, dirgiendonos a ACTIONS
→ Generate Sample Message
.
Esto genera ejemplos de tráfico HTTP (GET
y POST
) que permiten revisar en detalle cómo se verá la comunicación real, incluyendo:
- Headers
- Cookies
- User-Agent
- URIs
- Payload codificado en base64
Es OPSEC hacer pruebas de evasión o análisis estático antes de desplegar el perfil en producción.
What's Next?
Existen distintos tipos de agentes para Mythic, conocidos como MythicAgents
, así como diferentes perfiles de comunicación llamados MythicC2Profiles
. Para verificar compatibilidad entre versiones, sistemas operativos y C2 profiles soportados, puedes revisar la siguiente tabla oficial:
https://mythicmeta.github.io/overview/agent_matrix.html
Esta tabla permite identificar: Las versiones compatibles entre Mythic y sus agentes, los sistemas operativos soportados por cada agente y los C2 Profiles compatibles con cada agente (por ejemplo: http
, httpx
, github
, freya.tcp
, websocket
, etc).
Para más información técnica actualizada: https://mythicmeta.github.io/overview/