Trainman Container Task

You don't get it. I built this place. Down here I make the rules. Down here I make the threats. Down here... I'm God.
- The Trainman in The Matrix Revolutions

Overview

The Trainman container task provides the ability to execute arbitrary commands. This is useful for placing a container inside a network for the sake of testing security controls. For example, launchers generated by a PowerShell Empire container task can be transferred to the local shared directory of a Trainman container task and executed to establish a command and control tunnel to the PowerShell Empire container task. Using this approach, multiple malleable C2 profiles can be tested in fairly rapid succession, allowing for a comprehensive assessment of the environment's security controls' ability to detect and block command and control traffic.

The Trainman container task also comes pre-built with a series of utilities that are useful for performing recon and lateral movement. Any of the listed utilities can be executed via the execute_process instruct_command. Alternatively, if a command and control tunnel is established, the utilities can be executed directly by way of the tunnel, thereby emulating true adversary behaviors. The utilities included in the Trainman container task are as follows:

Nmap
Impacket
Kube-hunter
Minikerberos
LDEEP
BloodHound.py
Altdns
aiodnsbrute
py-wmi-client
CrackMapExec
PyExfil

The source code for the Trainman container task is available here: https://github.com/havocsh/havoc-attack-containers/tree/main/trainman
The container image for the Trainman container task is available here: https://gallery.ecr.aws/havoc_sh/trainman

Launching a Trainman Container Task

To launch a Trainman container task as an ECS task within the AWS account of your ./havoc deployment, use the task_startup or run_task command:

task_startup --task_name=<task_name> --task_type=trainman --task_host_name=<task_host_name> --task_domain_name=<task_domain_name> --portgroups=<portgroup1,portgroup2,...> --end_time=<time_string>

run_task --task_name=<task_name> --task_type=trainman --task_host_name=<task_host_name> --task_domain_name=<task_domain_name> --portgroups=<portgroup1,portgroup2,...> --end_time=<time_string>

To launch a Trainman container task as a remote container task on any system that can run Docker containers, use the docker run command:

sudo docker run -d \
  --name=<container-name> \
  --network host \
  --cap-add SYS_ADMIN \
  -e "LOCAL_IP=$(hostname -I)" \
  -e "CAMPAIGN_ID=<campaign-id>" \
  -e "USER_ID=<campaign-user-id>" \
  -e "TASK_NAME=<task-name>" \
  -e "TASK_CONTEXT=<task-context>" \
  -e "REMOTE_TASK=true" \
  -e "API_KEY=<api-key>" \
  -e "SECRET=<secret>" \
  -e "API_DOMAIN_NAME=<api-domain-name>" \
  -e "API_REGION=<api-region>" \
  public.ecr.aws/havoc_sh/trainman:latest \
  /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

Refer to the Usage Through CLI Console and Usage Through SDK pages for more details about the run_task and docker run commands.

Available Commands

These commands are available to be passed as the instruct_command in the instruct_task method call. The sub-bullets under the commands are the arguments for the command that should be passed in the instruct_args parameter. See the Usage Through CLI Console and Usage Through SDK pages for more details on how to use instruct_args.

  • execute_process - instruct the Trainman container task to execute a local process.
    • file_name - (Required) the name of the file to be executed.
    • options - (Optional) a Python list of parameters that are to be passed as arguments when running the command.
  • kill_process - kill the running process.
  • echo - get an arbitrary response from the container task (can be used to check if the container is responsive to commands).
  • sync_from_workspace - download all files from the Campaign's workspace to the local workspace directory on the container task.

    Note that this will overwrite any existing files with the same name in the container task's local workspace.

  • sync_to_workspace - upload all files from the container task's local workspace directory to the Campaign's workspace.

    Note that this will overwrite any existing files with the same name in the Campaign's workspace.

  • download_from_workspace - download a specific file from the Campaign's workspace to the container task's local workspace directory.
    • file_name - the name of the file to be downloaded.

      Note that this will overwrite any existing file with the same name in the container task's local workspace.

  • upload_to_workspace - upload a specific file from the container task's local workspace directory to the Campaign's workspace.
    • file_name - the name of the file to be uploaded.

      Note that this will overwrite any existing file with the same name in the Campaign's workspace.

  • ls - list files of the container task's local shared directory.
  • del - delete a file from the container task's local shared directory.
    • file_name - the name of the file to be deleted.
  • terminate - instruct the container task to shutdown.