Getting started with the mantis CLI
Installation
To install M&NTIS CLI in a virtualenv, use the following commands:
$ mkdir venv
$ virtualenv venv/
$ source venv/bin/activate
(venv) $ pip install mantis_api_client
(...)
Authentication
In order to authenticate the CLI with M&NTIS Platform, use account login
command:
$ mantis account login
A web browser should been opened for 'mantis-platform.io'
Waiting callback for 60s
Access granted
Group `amossys` activated
You can see that you are correctly logged with:
$ mantis account info
[+] Connected to mantis-platform.io
[+] Username: jde
[+] Email: john.doe@amossys.fr
[+] Group membership: amossys
[+] Scopes: dataset:read, dataset:write, email, groups, offline_access, openid, profile, scenario:run
Accessing the threat catalogs
Two threat catalogs are available:
- Unit attacks (TTPs)
- Scenarios (killchains)
You can list the unit attack catalog contents with:
$ mantis attack list
[+] Available attacks (90):
[+] NAME - DESCRIPTION
[+] wordpress_tatsubuilder_rce - RCE on Wordpress with Tatsu Builder (T1190)
[+] mimikatz_logonpasswords - Dump Credentials from Memory with Mimikatz (T1003.001)
[+] list_local_process - Discover Local Processes (T1518)
(...)
And for listing the available scenarios:
$ mantis scenario list
[+] Available scenarios (6):
[+] aetheris: Starts with a Log4shell attack on a server, then ARP poisoning (...)
Launching a lab
If you want to launch an attack in a lab, for example the unit attack list_local_process
, use the attack run
command:
$ mantis attack run list_local_process
[+] Going to execute attack: list_local_process
Needed argument --scenario_config_name, in order to choose the unit scenario to run
Available unit scenarios:
[+] windows10
[+] linux
You should receive a message telling you that you need to select one of the available unit scenarios, here either windows10
or linux
. You can do it with the command:
$ mantis attack run list_local_process --scenario_config_name linux
Here is a complete log of an attack execution. This log displays each scenario step executed (provisioning steps, user activity steps, attack steps, etc.), and also returns the lab ID which can be used afterwards to interact with the lab.
$ mantis attack run list_local_process --scenario_config_name linux
[+] Going to execute attack: list_local_process
[+] Scenario lab ID: 2f603ea7-98aa-40dd-8f21-e2ee299a02e9
[+] Notifications:
⚡ 2024-07-25 20:34:27 - Initialization
⚡ 2024-07-25 20:34:27 - Reserve Cyber Range instance
⚡ 2024-07-25 20:34:38 - Start Cyber Range
⚡ 2024-07-25 20:36:09 - Initialize Cyber Range
⚡ 2024-07-25 20:38:18 - Create simulation from topology '/cyber-range-catalog/redteam_topologies/ubuntu'
⚡ 2024-07-25 20:38:18 - Fetch required baseboxes
⚡ 2024-07-25 20:38:37 - Simulation started. You can use the Interactive view.
⚡ 2024-07-25 20:38:38 - Deploying 'os_set_hostname' playbook
⚡ 2024-07-25 20:39:31 - Playing 'operating_system/open_session' activity
⚡ 2024-07-25 20:40:29 - Begin attack 'Deploy an nginx web server'
⚡ 2024-07-25 20:40:31 - Finished attack 'Deploy an nginx web server'
⚡ 2024-07-25 20:40:32 - Begin attack 'Deploys a C&C'
⚡ 2024-07-25 20:40:36 - Finished attack 'Deploys a C&C'
⚡ 2024-07-25 20:40:48 - Playing 'operating_system/activate_payload_linux' activity
⚡ 2024-07-25 20:41:53 - Begin attack 'Discover Local Processes'
(...)
[========================================] in 7:41.1
[+] Scenario ended
Several kind of content can be launched in a lab. Here are the available contents:
- See attack reference documentation.
- See scenario reference documentation.
- See basebox reference documentation.
- See topology reference documentation.
Configuring a lab
When launching a lab, you can configure it with the option --scenario_run_config
which expects a YAML configuration file as parameter.
See scenario_run_config reference documentation.
The CLI usage when passing a scenario_run_config YAML file is as follow:
$ mantis attack run list_local_process --scenario_config_name linux --scenario_run_config config.yaml
(...)
In the next subchapters, we illustrate the use of the scenario_run_config data structure to control scenario execution, and to configure defense.
Configuring scenario execution
There are four ways of managing scenario execution:
automatic
: the various attack steps are executed one after the other without pause (default behavior).step_by_step
: a pause occurs between each attack step.custom
: a list of attack steps for which a pause is required as defined in thestep_waiting_list
attribute.
A paused scenario can either require a user action to resume (default behavior), or wait for a random duration chosen between two values (random_waiting_minutes
). Pauses are performed before and after the attack step.
In order to resume a scenario execution, the resume
command should be entered:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 resume
The following example runs a step-by-step scenario, stopping before and after each step:
$ cat config.yaml
---
scenario_execution_mode: "step_by_step"
This example pauses on a scenario's "api_control" attack step:
$ cat config.yaml
---
scenario_execution_mode: "custom"
step_waiting_list: ["api_control"]
Thie next example waits between 1 and 3 minutes before and after each attack rather than waiting for a user to resume the scenario:
$ cat config.yaml
---
random_waiting_minutes: [1, 3]
Configuring defense
Defense log collection can be configured through the log_collectors attribute
of the scenario_run_config
data structure.
The following extract illustratres a scenario_run_config
data structure used to configure the log collection chain Winlogbeat that emits logs towards a logstash log aggregator. Logs are then stored in a Elasticsearch database, and are then accessible through an analyst machine connecting to a Kibana instance.
$ cat config_collect.yaml
---
config_name: "config_collect_auditbeat"
log_collectors:
- instance_name: auditbeat
collector_name: auditbeat
collector_type: agent
location:
- location_type: system_type
value: linux
output:
- instance_name: logstash
collector_name: logstash
collector_type: aggregator
- instance_name: logstash
collector_name: logstash
collector_type: aggregator
location:
- location_type: new_node
value: logstash
output:
- instance_name: elasticsearch
collector_name: elasticsearch
collector_type: aggregator
- instance_name: elasticsearch
collector_name: elasticsearch
collector_type: aggregator
location:
- location_type: new_node
value: elasticsearch
- instance_name: kibana
collector_name: kibana
collector_type: visualization
location:
- location_type: new_node
value: kibana
- instance_name: analyst_machine
collector_name: analyst_machine
collector_type: visualization
location:
- location_type: new_node
value: analyst_machine
user_config:
nb_machines: 1
Accessing lab information
Several lab commands are available with the CLI, as shown by the --help
message:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 --help
(...)
info Get information about a lab
api Get API URLs to directly access the lab
topology Get scenario topology on current lab
nodes Get scenario nodes on current lab
assets Get scenario assets on current lab
attack-report Get scenario attack report on current lab
attack-infras Get scenario attack infras on current lab
attack-sessions Get scenario attack sessions on current lab
attack-knowledge Get scenario attack knowledge on current lab
notifications Get scenario notifications on current lab
scenario-run-config Get scenario run config on current lab
get-remote-access Get info for remote access to lab VMs
(...)
Lab metadata
In order to retrieve lab metadata, the info
command is available:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 info
[+] Lab information:
[+] Id: 2f603ea7-98aa-40dd-8f21-e2ee299a02e9
[+] Name: list_local_process
[+] Type: UNIT_ATTACK
[+] Status: RUNNING
[+] Start time: 2024-07-29 07:29:13
[+] Elapsed time (minutes): 8.01
[+] Created by: jde
See lab info reference documentation.
Lab nodes
To fetch the nodes metadata, use the nodes
subcommand.
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 nodes
This subcommand allows to display nodes information as JSON with the --json
option. This option is usefull when looking for a specific piece of information with the tool jq
:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 nodes --json | jq
[
{
"simulation_id": 1,
"basebox_id": "AMOSSYS/linux/ubuntu_20.04_gnome_chrome_firefox",
"id": 1,
"name": "TARGET",
"node_start_time": "2024-07-29T07:33:07",
"status": "RUNNING",
"nb_proc": 2,
"memory_size": 4096,
"type": "virtual_machine",
"username": "alex",
"password": "123456;!",
"admin_username": "root",
"admin_password": "Beezh35;",
"vnc_port": 5901,
"spice_port": 6901,
"remote_password": "sXi-KRj8wjXtLucCMtPi6zenm8Ph7Y4U",
"active": true,
"roles": [
"client"
],
"network_interfaces": [
{
"mac_address": "00:21:1b:96:1b:14",
"ip_address_runtime": "192.168.33.11",
(...)
}
],
},
(...)
For example, to list all the node names, you can use this command:
$ mantis lab cbf18e0c-f870-4048-9e42-413167bcd789 nodes|jq '.[] | .name'
"TARGET"
"Router1"
"switchinternet"
"SwitchMonitoring"
"SwitchGateway"
"RouterGateway"
"PhysicalGateway"
"internetproxy"
"provAgentSimu1"
"logstash"
"nginxserver"
"apicontrol"
See lab nodes reference documentation.
Deploying a software on a node
Deployment of software can be done with ansible which has been integrated in M&NTIS Platform.
Here is an example of an ansible playbook, that installs and starts an nginx server.
$ cat ./deploy-nginx/playbook.yaml
---
tasks:
- name: apt-get update
ansible.builtin.apt:
update_cache: true
environment:
http_proxy: "{{ proxy_address }}"
- name: ensure nginx is at the latest version
ansible.builtin.apt:
name: nginx
state: latest
environment:
http_proxy: "{{ proxy_address }}"
- name: start nginx
service:
name: nginx
state: started
As you can see, you have to set the proxy address in order to use this playbook for internet related activities. The proxy address expects a URL of the form http://xxx.xxx.xxx.xxx:3128
. If a proxy is available on a topology, its IP address can be retrieved with the following command:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 nodes --json | jq '.[] | select(.name == "internetproxy") | .network_interfaces[0].ip_address_runtime'
"192.168.250.1"
Then, in order to run the playbook on a specific target node (here on the machine named TARGET
), use this command:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 provisioning ansible --id 1 --stream-ansible -c ./deploy-nginx/ -n TARGET -e "proxy_address=http://192.168.250.1:3128"
2024-07-29 13:49:08.450 | INFO | [+] Starting provisioning ansible playbook(s) ./deploy-nginx/ on simulation ID '1'
2024-07-29 13:49:08.522 | INFO | [+] Provisioning task ID: f73f740f-c464-465f-a644-25093bf86850
2024-07-29 13:49:09.587 | INFO | [+] Provisioning task starting...
2024-07-29 13:49:10.644 | INFO | [+] Execute playbook: '/data_ansible/2024_07_29_11_49_08-/playbooks/2024_07_29_11_49_08/playbook.yaml'
2024-07-29 13:49:10.644 | INFO | [+]
2024-07-29 13:49:10.644 | INFO | [+] PLAY [TARGET] ******************************************************************
2024-07-29 13:49:10.644 | INFO | [+]
2024-07-29 13:49:10.644 | INFO | [+] TASK [apt-get update] **********************************************************
2024-07-29 13:49:13.854 | INFO | [+]
2024-07-29 13:49:13.855 | INFO | [+] TASK [ensure nginx is at the latest version] ***********************************
2024-07-29 13:49:14.926 | INFO | [+]
2024-07-29 13:49:14.926 | INFO | [+] TASK [start nginx] *************************************************************
2024-07-29 13:49:15.989 | INFO | [+]
2024-07-29 13:49:15.990 | INFO | [+] PLAY RECAP *********************************************************************
2024-07-29 13:49:15.990 | INFO | [+] TARGET : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2024-07-29 13:49:15.990 | INFO | [+]
2024-07-29 13:49:16.128 | INFO | [+] Provisioning was correctly executed in 7 seconds
The provisioning ansible
command parameters are:
--id
: to precise the simulation ID on which the targeted machine is running (1 by default).--stream-ansible
: to display real time logs of ansible.-c
: expects a path to a directory containing a ansible file namedplaybook.yaml
.-n
: allows to specify the target name (multiple use of this option are allowed in order to run the ansible playbook on several targets).-e
: allows to pass extra args to the ansible playbook.
See provisioning ansible reference documentation.
Accessing attack report
Once a scenario is finished (or during scenario execution), you can fetch information related to the attack execution:
$ mantis lab 2f603ea7-98aa-40dd-8f21-e2ee299a02e9 mantis attack-report
(...)
{
"id": 24,
"source_id": 10,
"worker": {
"id": "1518_000_001",
"name": "list_local_process",
"title": "Discover Local Processes",
"title_fr": "Liste les processus locaux",
"description": "Lists all running processes on the local workstation.",
"version": "1.1",
"cve": [],
"stability": "CRASH_SAFE",
"reliability": null,
"side_effect": "",
"killchain_step": "DISCOVERY",
"topics": "attack_session",
"repeatable": true,
"mitre_data": {
"technique": {
"id": "T1518",
"name": "Software Discovery"
},
"subtechnique": {},
"tactics": [
{
"id": "TA0007",
"name": "Discovery"
}
]
},
"attack_mode": "INDIRECT"
},
"status": "success",
"started_date": "2024-07-29T11:25:23+00:00",
"last_update": "2024-07-29T11:25:29+00:00",
"target_nodes": [
{
"node_type": "ATTACK_SESSION",
"node_info": {
"ip": "192.168.33.11",
"type_session": "sh",
"privilege_level": "user",
"session_id": "2101d27b-9870-4af8-b999-dcb642181dbd",
"username": "adurand"
},
"attack_process_graph": [
{
"sh": {
"encoded_command": "cABzACAAYQB4AGMAbwAgAGMAbwBtAG0AYQBuAGQA",
"decoded_command": "ps axco command"
}
}
]
}
],
},
(...)
See attack-report reference documentation.