Goal

Deploy the Mythic C2 Framework with Ansible.

Setup

  1. Open up VS Code and connect over SSH to your VM

References

community.general.terraform - Manages a Terraform deployment (and plans) - Ansible Documentation

Official Mythic documentation

Mythic

Mythic

Mythic Overview

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/10a97d68-555c-44f6-a6d7-50dcfd7148e4/Untitled.png

Mythic C2 is primarily a collection of docker containers. With that in mind the documentation and deployment is from a docker Compose file. The Docker Compose used for deployment is here.

Mythic/docker-compose.yml at master ยท its-a-feature/Mythic

Here is the complete docker compose for Mythic C2. It's large be we are going to convert this to Ansible.

services:
  mythic_documentation:
    build: ./documentation-docker
    command: server
    container_name: mythic_documentation
    image: mythic_documentation
    labels:
      name: mythic_documentation
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    ports:
    - ${DOCUMENTATION_PORT}:1313
    restart: always
    volumes:
    - ./documentation-docker/:/src
  mythic_graphql:
    build: ./hasura-docker
    container_name: mythic_graphql
    depends_on:
    - mythic_postgres
    environment:
    - HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    - HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    - HASURA_GRAPHQL_ENABLE_CONSOLE=true
    - HASURA_GRAPHQL_DEV_MODE=true
    - HASURA_GRAPHQL_ADMIN_SECRET=${HASURA_SECRET}
    - HASURA_GRAPHQL_INSECURE_SKIP_TLS_VERIFY=true
    - HASURA_GRAPHQL_SERVER_PORT=${HASURA_PORT}
    - HASURA_GRAPHQL_METADATA_DIR=/metadata
    - HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=500
    - HASURA_GRAPHQL_AUTH_HOOK=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/graphql/webhook
    - MYTHIC_ACTIONS_URL_BASE=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/api/v1.4
    image: mythic_graphql
    labels:
      name: mythic_graphql
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    network_mode: host
    restart: always
    volumes:
    - ./hasura-docker/metadata:/metadata
  mythic_nginx:
    build: ./nginx-docker
    container_name: mythic_nginx
    environment:
    - DOCUMENTATION_HOST=${DOCUMENTATION_HOST}
    - DOCUMENTATION_PORT=${DOCUMENTATION_PORT}
    - NGINX_PORT=${NGINX_PORT}
    - MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}
    - MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}
    - HASURA_HOST=${HASURA_HOST}
    - HASURA_PORT=${HASURA_PORT}
    - NEW_UI_HOST=${MYTHIC_SERVER_HOST}
    - NEW_UI_PORT=3000
    image: mythic_nginx
    labels:
      name: mythic_nginx
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    network_mode: host
    restart: always
    volumes:
    - ./nginx-docker/ssl:/etc/ssl/private
    - ./nginx-docker/config:/etc/nginx
  mythic_postgres:
    build: ./postgres-docker
    command: postgres -c "max_connections=400"
    container_name: mythic_postgres
    environment:
    - POSTGRES_DB=${POSTGRES_DB}
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    image: mythic_postgres
    labels:
      name: mythic_postgres
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    ports:
    - ${POSTGRES_PORT}:5432
    restart: always
    volumes:
    - ./postgres-docker/database:/var/lib/postgresql/data
  mythic_rabbitmq:
    build: ./rabbitmq-docker
    container_name: mythic_rabbitmq
    environment:
    - RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}
    - RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
    - RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST}
    image: mythic_rabbitmq
    labels:
      name: mythic_rabbitmq
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    ports:
    - ${RABBITMQ_PORT}:5672
    restart: always
    volumes:
    - ./rabbitmq-docker/storage:/var/lib/rabbitmq
  mythic_react:
    build: ./mythic-react-docker
    container_name: mythic_react
    image: mythic_react
    labels:
      name: mythic_react
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    network_mode: host
    restart: always
    volumes:
    - ./mythic-react-docker/mythic:/mythic_react
  mythic_redis:
    build: ./redis-docker
    container_name: mythic_redis
    image: mythic_redis
    labels:
      name: mythic_redis
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    ports:
    - ${REDIS_PORT}:6379
    restart: always
  mythic_server:
    build: ./mythic-docker
    command: /bin/bash /Mythic/start_mythic_server.sh
    container_name: mythic_server
    depends_on:
    - mythic_postgres
    environment:
    - MYTHIC_POSTGRES_HOST=${POSTGRES_HOST}
    - MYTHIC_POSTGRES_PORT=${POSTGRES_PORT}
    - MYTHIC_POSTGRES_DB=${POSTGRES_DB}
    - MYTHIC_POSTGRES_USER=${POSTGRES_USER}
    - MYTHIC_POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - MYTHIC_RABBITMQ_HOST=${RABBITMQ_HOST}
    - MYTHIC_RABBITMQ_PORT=${RABBITMQ_PORT}
    - MYTHIC_RABBITMQ_USER=${RABBITMQ_USER}
    - MYTHIC_RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
    - MYTHIC_RABBITMQ_VHOST=${RABBITMQ_VHOST}
    - MYTHIC_JWT_SECRET=${JWT_SECRET}
    - MYTHIC_REDIS_PORT=${REDIS_PORT}
    - MYTHIC_DEBUG
    - MYTHIC_ADMIN_PASSWORD
    - MYTHIC_ADMIN_USER
    - MYTHIC_SERVER_PORT
    - MYTHIC_ALLOWED_IP_BLOCKS=${ALLOWED_IP_BLOCKS}
    - MYTHIC_DEFAULT_OPERATION_NAME=${DEFAULT_OPERATION_NAME}
    - MYTHIC_NGINX_PORT=${NGINX_PORT}
    - MYTHIC_SERVER_HEADER=${SERVER_HEADER}
    - MYTHIC_WEB_LOG_SIZE=${WEB_LOG_SIZE}
    - MYTHIC_WEB_KEEP_LOGS=${WEB_KEEP_LOGS}
    - MYTHIC_SIEM_LOG_NAME=${SIEM_LOG_NAME}
    image: mythic_server
    labels:
      name: mythic_server
    logging:
      driver: json-file
      options:
        max-file: "1"
        max-size: 10m
    network_mode: host
    restart: always
    volumes:
    - ./mythic-docker:/Mythic
version: "2.4"

SSL & Mythic C2 Role

We need some SSL certificates for our Mythic C2 server. I am going to use another public role to get the process started. We are going to use some self-signed certificates for our example.

  1. Install the SSL role by running the following command from your vagrant VM.
ansible-galaxy install akin_ozer.ansible_role_ssl