Saltar a contenido

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: selecciona Binary. (En mi caso, el tuyo puede ser distinto)
  • output_type: selecciona Shellcode 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.

  1. Ejecutamos el comando link en un INTERACT

    link
    

  2. Registramos el agente remoto que tiene el payload SMB

  3. Ingresamos el nombre del host remoto y seleccionamos el payload SMB

  4. Validamos los parámetros SMB: pipename, AESPSK, killdate, etc.

  5. Ejecutamos la tarea y se establece el link SMB con el agente remoto:

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 ACTIONSGenerate 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/


Resources

  1. Webinar copy of Mythic Apollo
  2. TheSpecterOps Videolist using Mythic
  3. Mythic Apollo Webinar
  4. Official DOC