cymulate_v2
Multi-Vector Cyber Attack, Breach and Attack Simulation.
Deception & Breach Simulation · Cymulate
Details
| ID | cymulate_v2 |
|---|---|
| Provider | Cymulate |
| Category | Deception & Breach Simulation |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Multi-Vector Cyber Attack, Breach and Attack Simulation.
This integration was integrated and tested with API version 1 of cymulate
This is the default integration for this content pack when configured by the Data Onboarder in Cortex XSIAM.
Configure cymulate_v2 in Cortex
| Parameter | Description | Required |
|---|---|---|
| API token | True | |
| Base URL | False | |
| Fetch incidents | False | |
| Fetch category | Choose one or more categories to fetch. | False |
| Incident type | False | |
| First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) | False | |
| Max Fetch | Maximal number of incidents to fetch. Max value can be no grater than 35. | False |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
Fetch Incidents command
Retrieves new incidents every interval (default is 1 minute).
The fetch incident command will retrieve incidents from all selected modules chosen in the configuration page by the user.
The next run will be calculated by the latest timestamp of all modules, to avoid duplications.
NOTE: We fetch only one module per fetch call.
cymulate-exfiltration-template-list
Retrieve the exfiltration template list.
Base Command
cymulate-exfiltration-template-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Exfiltration.Template.id | String | Template ID. |
| Cymulate.Exfiltration.Template.name | String | Template name. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"Exfiltration": {
"Templates": [
{
"id": "5df0e79b85a00138dc648e75",
"name": "Cymulate Best Practice"
},
{
"id": "5df0e7d585a00138dc648e8f",
"name": "Cloud Services"
},
{
"id": "5df0e80885a00138dc648ea7",
"name": "Network Protocols"
},
{
"id": "5df0e82e85a00138dc648ebb",
"name": "Email"
},
{
"id": "5df25b3696fa2af420a379b9",
"name": "Physical"
}
]
}
}
}
Human Readable Output
Exfiltration templates list
id name 5df0e79b85a00138dc648e75 Cymulate Best Practice 5df0e7d585a00138dc648e8f Cloud Services 5df0e80885a00138dc648ea7 Network Protocols 5df0e82e85a00138dc648ebb 5df25b3696fa2af420a379b9 Physical
cymulate-exfiltration-start
Create a new exfiltration assessment.
Base Command
cymulate-exfiltration-start
Input
| Argument Name | Description | Required |
|---|---|---|
| template_id | The ID of the template to run the exfiltration Assessment with. Can be retrieved using Cymulate’s UI, or using cymulate-exfiltration-template-list command. | Required |
| agent_name | agent name to run simulation attacks. | Required |
| schedule | whether to schedule the automated assessment periodically. Possible values are: true, false. | Required |
| schedule_loop | Loop size of the scheduled agent. For example: to run the agent only once, use the value ‘one-time’. Possible values are: one-time, daily, weekly, monthly. | Required |
| agent_profile_name | agent profile name to run simulation attacks. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Exfiltration.id | String | New exfiltration assessment creation ID. |
| Cymulate.Exfiltration.success | Boolean | New exfiltration assessment creation success status. |
Command Example
!cymulate-exfiltration-start template_id="5df0e79b85a00138dc648e75" agent_name="Cymulate_agent" schedule="false" schedule_loop="one-time"
Context Example
{
"Cymulate": {
"Exfiltration": {
"id": "id_1",
"success": true
}
}
}
Human Readable Output
Starting exfiltration assessment
id success id_1 true
cymulate-exfiltration-stop
Stop a running exfiltration assessment.
Base Command
cymulate-exfiltration-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Exfiltration.data | String | New exfiltration assessment stopping data. |
| Cymulate.Exfiltration.success | Boolean | New exfiltration assessment stopping success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"Exfiltration": {
"data": "ok",
"success": true
}
}
}
Human Readable Output
Stopping exfiltration assessment
data success ok true
cymulate-exfiltration-status
Get exfiltration assessment status.
Base Command
cymulate-exfiltration-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Exfiltration.id | String | New exfiltration assessment stop ID. |
| Cymulate.Exfiltration.inProgress | Boolean | Whether the assessment is in progress. |
| Cymulate.Exfiltration.progress | Number | Percentage of the progress of the assessment. |
| Cymulate.Exfiltration.categories | String | Categories. |
Command Example
!cymulate-exfiltration-status assessment_id="id_2"
Context Example
{
"Cymulate": {
"Exfiltration": {
"categories": [
"http",
"https",
"dns",
"dns-tunneling",
"icmp",
"outlook",
"device",
"telnet",
"sftp",
"slack",
"googledrive",
"onedrive",
"port_scanning",
"msteams",
"gmail",
"gitlab",
"azure_blob",
"aws_s3_bucket",
"github",
"googlestorage",
"browsinghttps",
"browsinghttp"
],
"id": "id_2",
"inProgress": false,
"progress": 0
}
}
}
Human Readable Output
Exfiltration assessment status
categories id inProgress progress http,
https,
dns,
dns-tunneling,
icmp,
outlook,
device,
telnet,
sftp,
slack,
googledrive,
onedrive,
port_scanning,
msteams,
gmail,
gitlab,
azure_blob,
aws_s3_bucket,
github,
googlestorage,
browsinghttps,
browsinghttpid_2 false 0
cymulate-email-gateway-template-list
Retrieve the email gateway template list.
Base Command
cymulate-email-gateway-template-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EmailGateway.Template.id | String | Template ID. |
| Cymulate.EmailGateway.Template.name | String | Template name. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"EmailGateway": {
"Templates": [
{
"id": "5c6920853659191ccf6858fc",
"name": "free assessment"
},
{
"id": "5c6920853659191ccf6858fb",
"name": "cymulate best practice"
},
{
"id": "5db5ab6e79a0bf2feedaf9a7",
"name": "cymulate best practice - high risk"
},
{
"id": "5c6968e43659191ccf685929",
"name": "office payloads"
},
{
"id": "5c6968ec3659191ccf68592a",
"name": "executables payloads"
},
{
"id": "5c73b2ce3febfc300976c6e3",
"name": "exploits"
},
{
"id": "5c7f96963febfc300976c7be",
"name": "malwares"
},
{
"id": "5c7f977bc9545f79ea8b03c0",
"name": "ransomwares"
}
]
}
}
}
Human Readable Output
Email gateway templates list
id name 5c6920853659191ccf6858fc free assessment 5c6920853659191ccf6858fb cymulate best practice 5db5ab6e79a0bf2feedaf9a7 cymulate best practice - high risk 5c6968e43659191ccf685929 office payloads 5c6968ec3659191ccf68592a executables payloads 5c73b2ce3febfc300976c6e3 exploits 5c7f96963febfc300976c7be malwares 5c7f977bc9545f79ea8b03c0 ransomwares
cymulate-email-gateway-start
Create a new email gateway assessment.
Base Command
cymulate-email-gateway-start
Input
| Argument Name | Description | Required |
|---|---|---|
| template_id | The ID of the template to run the email gateway assessment with. Can be retrieved using Cymulate’s UI, or using cymulate-email-gateway-template-list command. | Required |
| agent_email | agent email. | Required |
| schedule | whether to schedule the automated assessment periodically. Possible values are: true, false. | Required |
| schedule_loop | Loop size of the scheduled agent. For example: to run the agent only once, use the value ‘one-time’. Possible values are: one-time, daily, weekly, monthly. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EmailGateway.id | String | New email gateway assessment creation ID. |
| Cymulate.EmailGateway.success | Boolean | New email gateway assessment creation success status. |
Command Example
!cymulate-email-gateway-start template_id="5c6920853659191ccf6858fc" agent_email="test@cymulate.com" schedule="false" schedule_loop="one-time"
Context Example
{
"Cymulate": {
"EmailGateway": {
"id": "id_3",
"success": true
}
}
}
Human Readable Output
Starting email gateway assessment
id success id_3 true
cymulate-email-gateway-stop
Stop a running exfiltration assessment.
Base Command
cymulate-email-gateway-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EmailGateway.data | String | Email gateway assessment stopping data. |
| Cymulate.EmailGateway.success | Boolean | Email gateway assessment stopping success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"EmailGateway": {
"data": "ok",
"success": true
}
}
}
Human Readable Output
Stopping email gateway assessment
data success ok true
cymulate-email-gateway-status
Get the email gateway assessment status.
Base Command
cymulate-email-gateway-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EmailGateway.id | String | Email gateway assessment ID. |
| Cymulate.EmailGateway.success | Boolean | Whether the assessment was successful. |
| Cymulate.EmailGateway.inProgress | Boolean | Whether the assessment is in progress. |
| Cymulate.EmailGateway.progress | Number | Percentage of the progress of the assessment. |
| Cymulate.EmailGateway.addresses | String | Addresses connected to the assessment. |
Command Example
!cymulate-email-gateway-status assessment_id="id_4"
Context Example
{
"Cymulate": {
"EmailGateway": {
"addresses": [
"test@cymulate.com"
],
"categories": [
"worm"
],
"id": "id_4",
"inProgress": false,
"progress": 0
}
}
}
Human Readable Output
Email gateway assessment status
addresses categories id inProgress progress test@cymulate.com worm id_4 false 0
cymulate-endpoint-security-template-list
Retrieve the endpoint security template list.
Base Command
cymulate-endpoint-security-template-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EndpointSecurity.Template.id | String | Template ID. |
| Cymulate.EndpointSecurity.Template.name | String | Template name. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"EndpointSecurity": {
"Templates": [
{
"id": "5c87a26f548a3c7c4c184a5e",
"name": "Free Assessment"
},
{
"id": "5c97a50c5727c58a295d0459",
"name": "Cymulate Best Practice"
},
{
"id": "5e98461d312a740ee4839700",
"name": "DLL Side loading"
},
{
"id": "5c87a314548a3c7c4c184a5f",
"name": "Cymulate Behavior-based"
},
{
"id": "5c87a314548a3c7c4c184a60",
"name": "Cymulate Signature-based"
}
]
}
}
}
Human Readable Output
Endpoint security templates list
id name 5c87a26f548a3c7c4c184a5e Free Assessment 5c97a50c5727c58a295d0459 Cymulate Best Practice 5e98461d312a740ee4839700 DLL Side loading 5c87a314548a3c7c4c184a5f Cymulate Behavior-based 5c87a314548a3c7c4c184a60 Cymulate Signature-based
cymulate-endpoint-security-start
Create a new endpoint security assessment.
Base Command
cymulate-endpoint-security-start
Input
| Argument Name | Description | Required |
|---|---|---|
| template_id | The ID of the template to run the endpoint security assessment with. Can be retrieved using Cymulate’s UI, or using cymulate-endpoint-security-template-list command. | Required |
| agent_name | agent name. | Required |
| schedule | whether to schedule the automated assessment periodically. Possible values are: true, false. | Required |
| schedule_loop | Loop size of the scheduled agent. For example: to run the agent only once, use the value ‘one-time’. Possible values are: one-time, daily, weekly, monthly. | Required |
| agent_profile_name | Agent profile name. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EndpointSecurity.id | String | New endpoint security assessment creation ID. |
| Cymulate.EndpointSecurity.success | Boolean | New endpoint security assessment creation success status. |
Command Example
!cymulate-endpoint-security-start template_id="5e98461d312a740ee4839700" agent_name="Cymulate_agent" schedule="false" schedule_loop="one-time"
Context Example
{
"Cymulate": {
"EndpointSecurity": {
"id": "id_5",
"success": true
}
}
}
Human Readable Output
Starting endpoint security assessment
id success id_5 true
cymulate-endpoint-security-stop
Stop a running endpoint security assessment.
Base Command
cymulate-endpoint-security-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EndpointSecurity.data | String | Endpoint security assessment stopping data. |
| Cymulate.EndpointSecurity.success | Boolean | Endpoint Security assessment stopping success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"EndpointSecurity": {
"data": "ok",
"success": true
}
}
}
Human Readable Output
Stopping endpoint security assessment
data success ok true
cymulate-endpoint-security-status
Get the endpoint security assessment status.
Base Command
cymulate-endpoint-security-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.EndpointSecurity.id | String | Endpoint security assessment ID. |
| Cymulate.EndpointSecurity.inProgress | Boolean | Whether the assessment is in progress. |
| Cymulate.EndpointSecurity.progress | Number | Percentage of the progress of the assessment. |
| Cymulate.EndpointSecurity.categories | String | Assessment categories. |
Command Example
!cymulate-endpoint-security-status assessment_id="id_6"
Context Example
{
"Cymulate": {
"EndpointSecurity": {
"categories": [
"ransomware"
],
"id": "id_6",
"inProgress": true,
"progress": 90
}
}
}
Human Readable Output
Endpoint security assessment status
categories id inProgress progress ransomware id_6 false 0
cymulate-waf-template-list
Retrieve the WAF template list.
Base Command
cymulate-waf-template-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.WAF.Template.id | String | Template ID. |
| Cymulate.WAF.Template.name | String | Template name. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"WAF": {
"Templates": [
{
"id": "5edf7ddfef621bbc252498f3",
"name": "free assessment"
},
{
"id": "5edf7547ef621bbc25248d97",
"name": "Cymulate Best Practice"
},
{
"id": "5ee0726cef621bbc25251d7a",
"name": "SQL Injection"
},
{
"id": "5ee0726cef621bbc25251d7d",
"name": "XSS"
},
{
"id": "5eea1fb754b285889325b818",
"name": "Command Injection"
},
{
"id": "5eea1fb754b285889325b81b",
"name": "File Inclusion"
},
{
"id": "5fb65327f6ce656dbc7f9cf1",
"name": "SSRF"
},
{
"id": "600d258cbd15e73c5882b306",
"name": "david test"
}
]
}
}
}
Human Readable Output
WAF templates list
id name 5edf7ddfef621bbc252498f3 free assessment 5edf7547ef621bbc25248d97 Cymulate Best Practice 5ee0726cef621bbc25251d7a SQL Injection 5ee0726cef621bbc25251d7d XSS 5eea1fb754b285889325b818 Command Injection 5eea1fb754b285889325b81b File Inclusion 5fb65327f6ce656dbc7f9cf1 SSRF 600d258cbd15e73c5882b306 david test
cymulate-waf-start
Create a new web application firewall assessment.
Base Command
cymulate-waf-start
Input
| Argument Name | Description | Required |
|---|---|---|
| template_id | The ID of the template to run the WAF assessment with. Can be retrieved using Cymulate’s UI, or using cymulate-waf-template-list command. | Required |
| sites | Websites to run the assessment on. Can be a single website URL or a list of URLs. | Required |
| schedule | whether to schedule the automated assessment periodically. Possible values are: true, false. | Required |
| schedule_loop | Loop size of the scheduled agent. For example: to run the agent only once, use the value ‘one-time’. Possible values are: one-time, daily, weekly, monthly. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.WAF.id | String | Web application firewall assessment creation ID. |
| Cymulate.WAF.success | Boolean | Web application firewall assessment creation success status. |
Command Example
!cymulate-waf-start template_id="5ee0726cef621bbc25251d7a" sites="http://cymulatelabs.com" schedule="false" schedule_loop="one-time"
Context Example
{
"Cymulate": {
"WAF": {
"id": "604630cbb9eb930a0fa86ab5",
"success": true
}
}
}
Human Readable Output
Starting WAF assessment
id success 604630cbb9eb930a0fa86ab5 true
cymulate-waf-stop
Stop a running web application firewall assessment.
Base Command
cymulate-waf-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.WAF.data | String | Web application firewall assessment stopping data. |
| Cymulate.WAF.success | Boolean | Web application firewall assessment stopping success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"WAF": {
"data": "no running attack",
"success": true
}
}
}
Human Readable Output
Stopping WAF assessment
data success no running attack true
cymulate-waf-status
Get the web application firewall assessment status.
Base Command
cymulate-waf-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.WAF.id | String | Web application firewall assessment ID. |
| Cymulate.WAF.inProgress | Boolean | Whether the assessment is in progress. |
| Cymulate.WAF.progress | Number | Percentage of the progress of the assessment. |
| Cymulate.WAF.categories | String | Assessment categories. |
Command Example
!cymulate-waf-status assessment_id="5ff31ef451647c20338bd235"
Context Example
{
"Cymulate": {
"WAF": {
"categories": [
"XML Injection",
"Command Injection",
"File Inclusion",
"XSS",
"XML Injection",
"SQL Injection"
],
"id": "5ff31ef451647c20338bd235",
"inProgress": false,
"progress": 0
}
}
}
Human Readable Output
WAF assessment status
categories id inProgress progress XML Injection,
Command Injection,
File Inclusion,
XSS,
XML Injection,
SQL Injection5ff31ef451647c20338bd235 false 0
cymulate-immediate-threat-start
Create a new immediate threats assessment.
Base Command
cymulate-immediate-threat-start
Input
| Argument Name | Description | Required |
|---|---|---|
| browsing_address | Browsing address. | Optional |
| mail_address | Agent email address. | Optional |
| edr_address | EDR address. | Optional |
| template_id | The ID of the template to run the immediate threat assessment with. Can be retrieved using Cymulate’s UI. | Required |
| browsing_address_profile_name | Browsing Agent profile name to run the assessment with. | Optional |
| edr_address_profile_name | EDR Agent profile name to run the assessment with. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.ImmediateThreats.id | String | Immediate threats assessment creation ID. |
| Cymulate.ImmediateThreats.success | String | New exfiltration assessment creation success status. |
Command Example
!cymulate-immediate-threat-start edr_address="Cymulate_agent" template_id="603270ce63aa15930631b938"
Context Example
{
"Cymulate": {
"ImmediateThreats": {
"id": [
"id_7"
],
"success": true
}
}
}
Human Readable Output
Starting immediate-threats assessment
id success id_7 true
cymulate-immediate-threat-stop
Stop a running immediate threats assessment.
Base Command
cymulate-immediate-threat-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.ImmediateThreats.data | String | Immediate threats assessment stopping data. |
| Cymulate.ImmediateThreats.success | String | Immediate threats assessment stopping success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"ImmediateThreats": {
"data": "ok",
"success": true
}
}
}
Human Readable Output
Stop immediate-threats assessment
data success ok true
cymulate-immediate-threat-status
Get immediate threats assessment status.
Base Command
cymulate-immediate-threat-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.ImmediateThreats.id | String | Web application firewall assessment ID. |
| Cymulate.ImmediateThreats.categories | String | Assessment categories. |
| Cymulate.ImmediateThreats.inProgress | Boolean | Whether the assessment is in progress. |
| Cymulate.ImmediateThreats.progress | Number | Percentage of the progress of the assessment. |
Command Example
!cymulate-immediate-threat-status assessment_id="id_8"
Context Example
{
"Cymulate": {
"ImmediateThreats": {
"categories": [
"antivirus"
],
"id": "id_8",
"inProgress": true,
"progress": 90
}
}
}
Human Readable Output
Immediate-threats assessment status
categories id inProgress progress antivirus id_8 true 90
cymulate-phishing-awareness-contacts-group-list
Get a list of contact groups.
Base Command
cymulate-phishing-awareness-contacts-group-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Phishing.Groups.id | String | The ID of the phishing content group. |
| Cymulate.Phishing.Groups.name | String | Name of the phishing content group. |
| Cymulate.Phishing.Groups.client | String | The client of the phishing content group. |
| Cymulate.Phishing.Groups.canDelete | Boolean | Whether this group can be deleted. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"Phishing": {
"Groups": [
{
"__v": 0,
"canDelete": true,
"client": "Cymulate",
"id": "id_a",
"name": "qmasters_01"
},
{
"__v": 0,
"canDelete": true,
"client": "Cymulate",
"id": "id_b",
"name": "qmasters_02"
},
{
"__v": 0,
"canDelete": true,
"client": "Cymulate",
"id": "id_c",
"name": "qmasters_03"
},
{
"__v": 0,
"canDelete": true,
"client": "Cymulate",
"id": "id_d",
"name": "new_group_01"
},
{
"__v": 0,
"canDelete": true,
"client": "Cymulate",
"id": "id_e",
"name": "test_group_02"
}
]
}
}
}
Human Readable Output
Phishing awareness contact groups
__v canDelete client id name 0 true Cymulate id_a qmasters_01 0 true Cymulate id_b qmasters_02 0 true Cymulate id_c qmasters_03 0 true Cymulate id_d new_group_01 0 true Cymulate id_e test_group_02
cymulate-phishing-awareness-contacts-group-create
Create new contacts group.
Base Command
cymulate-phishing-awareness-contacts-group-create
Input
| Argument Name | Description | Required |
|---|---|---|
| group_name | The name of the new group to create. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Phishing.Groups.success | Boolean | Whether the creation of the new group was successful. |
| Cymulate.Phishing.Groups.id | String | The ID of the new phishing content group. |
Command Example
!cymulate-phishing-awareness-contacts-group-create group_name="test_group_01"
Context Example
{
"Cymulate": {
"Phishing": {
"Groups": {
"id": "id_9",
"success": true
}
}
}
}
Human Readable Output
Phishing awareness contact group created
id success id_9 true
cymulate-phishing-awareness-contacts-get
Get contacts group using a group ID.
Base Command
cymulate-phishing-awareness-contacts-get
Input
| Argument Name | Description | Required |
|---|---|---|
| group_id | Group ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Phishing.Groups.id | String | The ID of the phishing content group. |
| Cymulate.Phishing.Groups.name | String | Name of the phishing content group. |
| Cymulate.Phishing.Groups.client | String | The client of the phishing content group. |
| Cymulate.Phishing.Groups.canDelete | Boolean | Whether this group can be deleted. |
Command Example
!cymulate-phishing-awareness-contacts-get group_id="id_abcd"
Context Example
{
"Cymulate": {
"Phishing": {
"Groups": [
{
"address": "jamesb@cymulate.com",
"color": "#ffbb00",
"firstName": "James",
"id": "id_1a",
"lastName": "Bond"
},
{
"address": "Billg@cymulate.com",
"color": "#34a853",
"firstName": "Bill",
"id": "id_a2",
"lastName": "Gates"
},
{
"address": "davidb@cymulate.com",
"color": "#00a1f1",
"firstName": "David ",
"id": "id_a3",
"lastName": "Ben-Gurion"
}
]
}
}
}
Human Readable Output
Phishing awareness contact groups
address color firstName id lastName jamesb@cymulate.com #ffbb00 James id_1a Bond Billg@cymulate.com #34a853 Bill id_a2 Gates davidb@cymulate.com #00a1f1 David id_a3 Ben-Gurion
cymulate-lateral-movement-template-list
Retrieve lateral movement template list.
Base Command
cymulate-lateral-movement-template-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.LateralMovement.Template.id | String | Template ID. |
| Cymulate.LateralMovement.Template.name | String | Template name. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"LateralMovement": {
"Templates": [
{
"id": "5e2f0c1054d53d6b115eefa7",
"name": "SMB Pass The Hash"
},
{
"id": "5e2f0c5f54d53d6b115ef0a1",
"name": "Kerberoasting and Cracking on DCOM and WMI"
},
{
"id": "5e2f0c9754d53d6b115ef190",
"name": "LLMNR Poisoning on SMB"
},
{
"id": "5e2f0d2c54d53d6b115ef345",
"name": "SMB And Credentials Harvesting"
},
{
"id": "5e41746171895006ef394607",
"name": "test1"
},
{
"id": "5e44020d3f46e106e9ec706c",
"name": "Prueba completa"
},
{
"id": "5e4a5792b1bdb606ed1f9407",
"name": "lab1"
}
]
}
}
}
Human Readable Output
Lateral movement templates list
id name 5e2f0c1054d53d6b115eefa7 SMB Pass The Hash 5e2f0c5f54d53d6b115ef0a1 Kerberoasting and Cracking on DCOM and WMI 5e2f0c9754d53d6b115ef190 LLMNR Poisoning on SMB 5e2f0d2c54d53d6b115ef345 SMB And Credentials Harvesting 5e41746171895006ef394607 test1 5e44020d3f46e106e9ec706c Prueba completa 5e4a5792b1bdb606ed1f9407 lab1
cymulate-lateral-movement-start
Create a new lateral movement assessment.
Base Command
cymulate-lateral-movement-start
Input
| Argument Name | Description | Required |
|---|---|---|
| agent_name | Agent name to run the assessment with. | Required |
| template_id | The ID of the template to run the lateral movement with. Can be retrieved using Cymulate’s UI, or using cymulate-lateral-movement-template-list command. | Required |
| upload_to_cymulate | Whether to upload the result to Cymulate. Possible values are: true, false. Default is false. | Required |
| schedule | Whether to schedule the automated assessment periodically. Possible values are: true, false. | Required |
| schedule_loop | Loop size of the scheduled agent. For example: to run the agent only once, use the value ‘one-time’. Possible values are: one-time, daily, weekly, monthly. | Required |
| agent_profile_name | Agent profile name to run the assessment with. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.LateralMovement.id | String | Lateral movement assessment creation ID. |
| Cymulate.LateralMovement.success | Boolean | New exfiltration assessment creation success status. |
Command Example
!cymulate-lateral-movement-start agent_name="Cymulate_agent" template_id="5e41746171895006ef394607" upload_to_cymulate="false" schedule="false" schedule_loop="one-time"
Context Example
{
"Cymulate": {
"LateralMovement": {
"id": "id_987",
"success": true
}
}
}
Human Readable Output
Starting lateral movement assessment
id success id_987 true
cymulate-lateral-movement-stop
Stop a running lateral movement assessment.
Base Command
cymulate-lateral-movement-stop
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.LateralMovement.data | String | Lateral movement assessment stopping data. |
| Cymulate.LateralMovement.success | Boolean | Lateral Movement assessment creation success status. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"LateralMovement": {
"data": "ok",
"success": true
}
}
}
Human Readable Output
Stopping lateral movement assessment
data success ok true
cymulate-lateral-movement-status
Get lateral movement assessment status.
Base Command
cymulate-lateral-movement-status
Input
| Argument Name | Description | Required |
|---|---|---|
| assessment_id | Assessment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.LateralMovement.id | String | Lateral movement assessment ID. |
| Cymulate.LateralMovement.inProgress | Boolean | Indicates whether the assessment is in progress. |
Command Example
!cymulate-lateral-movement-status assessment_id="id_876"
Context Example
{
"Cymulate": {
"LateralMovement": {
"id": "id_876",
"inProgress": false
}
}
}
Human Readable Output
Lateral movement assessment status
id inProgress id_876 false
cymulate-agent-list
Retrieve all agents.
Base Command
cymulate-agent-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Agent.agentAddress | String | The agent’s address. |
| Cymulate.Agent.agentMethod | String | The agent’s methods. |
| Cymulate.Agent.agentName | String | Agent name. |
| Cymulate.Agent.comment | String | Comments. |
Command Example
#### Context Example
```json
{
"Cymulate": {
"Agent": [
{
"agentAddress": "test@cymulate.com",
"agentMethod": "smtp",
"comment": ""
},
{
"agentAddress": "Cymulate_agent ",
"agentMethod": "http",
"agentName": "Cymulate_agent",
"comment": ""
}
]
}
}
Human Readable Output
Agents list
agentAddress agentMethod agentName test@cymulate.com smtp Cymulate_agent http Cymulate_agent
cymulate-simulations-list
Retrieve a list of all simulations by ID.
Base Command
cymulate-simulations-list
Input
| Argument Name | Description | Required |
|---|---|---|
| module | Module to retrieve events to. Possible values are: web-gateway, exfiltration, email-gateway, endpoint-security, waf, kill-chain, immediate-threats, phishing-awareness, lateral-movement. | Required |
| attack_id | Attack ID. Can be retrieved using cymulate-simulations-id-list command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Simulations.Attack_Type | String | Attack payload |
| Cymulate.Simulations.Classification | String | Attack classification. |
| Cymulate.Simulations.Content_Type | String | Content type. |
| Cymulate.Simulations.Module | String | Event’s module. |
| Cymulate.Simulations.Phrase | String | Attack description. |
| Cymulate.Simulations.Phrase_Title | String | Attack name. |
| Cymulate.Simulations.Status | String | Attack status |
| Cymulate.Simulations.PrevStatus | String | Attack Previous status |
| Cymulate.Simulations.Risk | String | Attack risk level. |
| Cymulate.Simulations.Source | String | Attack Source |
| Cymulate.Simulations.User | String | User committed the attack ot was attacked. |
| Cymulate.Simulations.Attack_Vector | String | Attack vector |
| Cymulate.Simulations.Source_Email_Address | String | Source email address. |
| Cymulate.Simulations.Md5 | String | MD5 attached to the attack. |
| Cymulate.Simulations.Sha256 | String | Sha256 attached to the attack. |
| Cymulate.Simulations.Sha1 | String | Sha1 attached to the attack. |
| Cymulate.Simulations.Mitigation | String | Mitigation details. |
| Cymulate.Simulations.Mitigation_Details | String | Mitigation details. |
| Cymulate.Simulations.Description | String | Attack description |
| Cymulate.Simulations.Id | String | Attack ID. |
Command Example
!cymulate-simulations-list module="waf" attack_id="id_001"
Context Example
{
"Cymulate": {
"Simulations": {
"Action": " http://Google.com/",
"Category": "SQL Injection",
"Database": "DB Agnostic",
"Display_Url": " http://Google.com/",
"FullRequest": "N/A",
"Id": "id_001",
"Input": "password",
"Method": "post",
"Mitigation": "Create a WAF Security rule to block incoming requests that contains. Validate that the specific input url is protected with the MSSQL Blind signature pack (SQL Injection)",
"Module": "Web Application Firewall",
"Payload": "This is a payload",
"Platform": "OS Agnostic",
"PrevStatus": "blocked",
"Risk": "high",
"Source": " http://Google.com",
"Status": "blocked",
"SubCategoryType": "MSSQL Blind",
"Timestamp": "2021-02-28 16:33:41",
"Url": " http://Google.com/",
"date": "2021-02-28T14:33:41.559Z"
}
}
}
Human Readable Output
Displaying 20/193 simulations
Action Category Database Display_Url FullRequest Id Input Method Mitigation Module Payload Platform PrevStatus Risk Source Status SubCategoryType Timestamp Url date http://Google.com/signup SQL Injection DB Agnostic http://Google.com/signup N/A id_001 password post Create a WAF Security rule to block incoming requests that contains. Validate that the specific input/url is protected with the Oracle SQL Injection signature pack (SQL Injection) Web Application Firewall AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=3)) AND ‘i’=’i OS Agnostic blocked high http://Google.com blocked Oracle SQL Injection 2021-02-28 16:33:41 http://Google.com/signup 2021-02-28T14:33:41.475Z http://Google.com/team/dudi SQL Injection DB Agnostic http://Google.com/team/dudi N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.. The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input url is protected with the Generic Blind Injection signature pack (SQL Injection) Web Application Firewall 1) or benchmark(10000000,MD5(1))# OS Agnostic blocked high http://Google.com blocked Generic Blind Injection 2021-02-28 16:33:41 http://Google.com/team/dudi 2021-02-28T14:33:41.476Z http://Google.com/ SQL Injection DB Agnostic http://Google.com/ N/A id_001 tel post Create a WAF Security rule to block incoming requests that contains:1.The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the General SQL Injection signature pack (SQL Injection) Web Application Firewall 1’ and non_existant_table = ‘1 OS Agnostic blocked high http://Google.com blocked General SQL Injection 2021-02-28 16:33:41 http://Google.com/ 2021-02-28T14:33:41.478Z http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 SQL Injection DB Agnostic http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 N/A id_001 password post Create a WAF Security rule to block incoming requests that contains:..The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall ’ or 1=1 / OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 2021-02-28T14:33:41.478Z http://Google.com/contact SQL Injection DB Agnostic http://Google.com/contact N/A id_001 password post Create a WAF Security rule to block incoming requests that contains..The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall ’ group by userid having 1=1– OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/contact 2021-02-28T14:33:41.476Z http://Google.com/ SQL Injection DB Agnostic http://Google.com/ N/A id_001 tel post Create a WAF Security rule to block incoming requests that contains.The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the MSSQL Injection signature pack (SQL Injection) Web Application Firewall ) waitfor delay ‘0:0:20’ OS Agnostic blocked high http://Google.com blocked MSSQL Injection 2021-02-28 16:33:41 http://Google.com/ 2021-02-28T14:33:41.479Z http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 SQL Injection DB Agnostic http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall ’ or 1=1– OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 2021-02-28T14:33:41.481Z http://Google.com/ SQL Injection DB Agnostic http://Google.com/ N/A id_001 hidden post Create a WAF Security rule to block incoming requests that contains:.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall ’ OR ‘something’ like ‘some%’ OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/ 2021-02-28T14:33:41.480Z http://Google.com/team/ruba SQL Injection DB Agnostic http://Google.com/team/ruba N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall ’ union select from users where login = char(114,111,111,116); OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/team/ruba 2021-02-28T14:33:41.481Z http://Google.com/team/ruba SQL Injection DB Agnostic http://Google.com/team/ruba N/A id_001 password post Create a WAF Security rule to block incoming requests that contains. The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the General SQL Injection signature pack (SQL Injection) Web Application Firewall ’ AND 1=utl_inaddr.get_host_address((SELECT SYS.DATABASE_NAME FROM DUAL)) AND ‘i’=’i OS Agnostic blocked high http://Google.com blocked General SQL Injection 2021-02-28 16:33:41 http://Google.com/team/ruba 2021-02-28T14:33:41.479Z http://Google.com/contact SQL Injection DB Agnostic http://Google.com/contact N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Generic Blind Injection signature pack (SQL Injection) Web Application Firewall ;waitfor delay ‘0:0:TIME’– OS Agnostic blocked high http://Google.com blocked Generic Blind Injection 2021-02-28 16:33:41 http://Google.com/contact 2021-02-28T14:33:41.480Z http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 SQL Injection DB Agnostic http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 N/A id_001 password post Create a WAF Security rule to block incoming requests that contains. The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the MSSQL Injection signature pack (SQL Injection) Web Application Firewall waitfor delay ‘0:0:20’ / OS Agnostic blocked high http://Google.com blocked MSSQL Injection 2021-02-28 16:33:41 http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 2021-02-28T14:33:41.481Z http://Google.com/team/dudi SQL Injection DB Agnostic http://Google.com/team/dudi N/A id_001 password post Create a WAF Security rule to block incoming requests that contains:.Validate that the specific input/url is protected with the Mysql Injection signature pack (SQL Injection) Web Application Firewall 1or1=1 OS Agnostic blocked high http://Google.com blocked Mysql Injection 2021-02-28 16:33:41 http://Google.com/team/dudi 2021-02-28T14:33:41.483Z http://Google.com/team/dudi SQL Injection DB Agnostic http://Google.com/team/dudi N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Generic Blind Injection signature pack (SQL Injection) Web Application Firewall ) or sleep(TIME)=’ OS Agnostic blocked high http://Google.com blocked Generic Blind Injection 2021-02-28 16:33:41 http://Google.com/team/dudi 2021-02-28T14:33:41.483Z http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 SQL Injection DB Agnostic http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Passive SQL Injection signature pack (SQL Injection) Web Application Firewall @var select @var as var into temp end – OS Agnostic blocked high http://Google.com blocked Passive SQL Injection 2021-02-28 16:33:41 http://Google.com/team/%d7%94%d7%9e%d7%a8%d7%a4%d7%90%d7%95%d7%aa-%d7%a9%d7%9c%d7%a0%d7%95 2021-02-28T14:33:41.485Z http://Google.com/team/ruba SQL Injection DB Agnostic http://Google.com/team/ruba N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Oracle SQL Injection signature pack (SQL Injection) Web Application Firewall AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=1)) AND ‘i’=’i OS Agnostic blocked high http://Google.com blocked Oracle SQL Injection 2021-02-28 16:33:41 http://Google.com/team/ruba 2021-02-28T14:33:41.482Z http://Google.com/signup SQL Injection DB Agnostic http://Google.com/signup N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the Mysql Injection signature pack (SQL Injection) Web Application Firewall create table myfile (input TEXT); load data infile filepath into table myfile OS Agnostic blocked high http://Google.com blocked Mysql Injection 2021-02-28 16:33:41 http://Google.com/signup 2021-02-28T14:33:41.484Z http://Google.com/contact SQL Injection DB Agnostic http://Google.com/contact N/A id_001 password post Create a WAF Security rule to block incoming requests that contains. The rule could be a Regular expression that needs to be implemented or an update of your WAF.Validate that the specific input/url is protected with the MSSQL Injection signature pack (SQL Injection) Web Application Firewall and 0=benchmark OS Agnostic blocked high http://Google.com blocked MSSQL Injection 2021-02-28 16:33:41 http://Google.com/contact 2021-02-28T14:33:41.486Z http://Google.com/ SQL Injection DB Agnostic http://Google.com/ N/A id_001 tel post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the MSSQL Injection signature pack (SQL Injection) Web Application Firewall ; exec master..xp_cmdshell ‘ping 1.2.3.4’– OS Agnostic blocked high http://Google.com blocked MSSQL Injection 2021-02-28 16:33:41 http://Google.com/ 2021-02-28T14:33:41.485Z http://Google.com/signup SQL Injection DB Agnostic http://Google.com/signup N/A id_001 password post Create a WAF Security rule to block incoming requests that contains.Validate that the specific input/url is protected with the MSSQL Injection signature pack (SQL Injection) Web Application Firewall insert into mysql.user (user, host, password) values (‘name’, ‘localhost’, password(‘pass123’)) – OS Agnostic N/A high http://Google.com blocked MSSQL Injection 2021-02-28 16:33:41 http://Google.com/signup 2021-02-28T14:33:41.487Z
cymulate-simulations-id-list
Retrieve a list of all simulations IDs.
Base Command
cymulate-simulations-id-list
Input
| Argument Name | Description | Required |
|---|---|---|
| module | Module to retrieve simulations IDs to. Possible values are: web-gateway, exfiltration, email-gateway, endpoint-security, waf, kill-chain, immediate-threats, phishing-awareness, lateral-movement. | Required |
| from_date | From which date to fetch data. Format: YYYY-MM-DD, for example: March 1st 2021 should be written: 2021-03-01. . | Required |
| to_date | End date to fetch data. Format: YYYY-MM-DD, for example: March 1st 2021 should be written: 2021-03-01. If no argument is given, default is now. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Cymulate.Simulations.ID | String | Attack ID. |
| Cymulate.Simulations.Timestamp | String | Attack timestamp |
| Cymulate.Simulations.Agent | String | Agent connected to the attack. |
| Cymulate.Simulations.Template | String | Attack template. |
Command Example
!cymulate-simulations-id-list module="kill-chain" from_date="2021-01-01"
Context Example
{
"Cymulate": {
"Simulations": [
{
"Agent": "Cymulate_agent_2",
"ID": "id_b1",
"Template": "Cobalt Group",
"Timestamp": "2021-03-01 10:15:58.230000"
},
{
"Agent": "Cymulate_agent_2",
"ID": "id_b2",
"Template": "Cobalt Group",
"Timestamp": "2021-02-25 16:56:33.871000"
},
{
"Agent": "info@cymulate.com",
"ID": "id_b3",
"Template": "Cobalt Group",
"Timestamp": "2021-02-23 11:00:50.988000"
}
]
}
}
Human Readable Output
Displaying 3/3 Attack IDs
Agent ID Template Timestamp Cymulate_agent_2 id_b1 Cobalt Group 2021-03-01 10:15:58.230000 Cymulate_agent_2 id_b2 Cobalt Group 2021-02-25 16:56:33.871000 info@cymulate.com id_b3 Cobalt Group 2021-02-23 11:00:50.988000
Configuration parameters
credentials—base_url— Base URLisFetch— Fetch incidentsfetchCategory— Fetch categoryincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalfirst_fetch— First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days)max_fetch— Max Fetchinsecure— Trust any certificate (not secure)proxy— Use system proxy settingsapi_key— API token (Deprecated)
Commands (29)
-
cymulate-agent-listRetrieve all agents.
-
cymulate-email-gateway-startCreate a new email gateway assessment.
-
cymulate-email-gateway-statusGet the email gateway assessment status.
-
cymulate-email-gateway-stopStop a running exfiltration assessment.
-
cymulate-email-gateway-template-listRetrieve the email gateway template list.
-
cymulate-endpoint-security-startCreate a new endpoint security assessment.
-
cymulate-endpoint-security-statusGet the endpoint security assessment status.
-
cymulate-endpoint-security-stopStop a running endpoint security assessment.
-
cymulate-endpoint-security-template-listRetrieve the endpoint security template list.
-
cymulate-exfiltration-startCreate a new exfiltration assessment.
-
cymulate-exfiltration-statusGet exfiltration assessment status.
-
cymulate-exfiltration-stopStop a running exfiltration assessment.
-
cymulate-exfiltration-template-listRetrieve the exfiltration template list.
-
cymulate-immediate-threat-startCreate a new immediate threats assessment.
-
cymulate-immediate-threat-statusGet immediate threats assessment status.
-
cymulate-immediate-threat-stopStop a running immediate threats assessment.
-
cymulate-lateral-movement-startCreate a new lateral movement assessment.
-
cymulate-lateral-movement-statusGet lateral movement assessment status.
-
cymulate-lateral-movement-stopStop a running lateral movement assessment.
-
cymulate-lateral-movement-template-listRetrieve lateral movement template list.
-
cymulate-phishing-awareness-contacts-getGet contacts group using a group ID.
-
cymulate-phishing-awareness-contacts-group-createCreate new contacts group.
-
cymulate-phishing-awareness-contacts-group-listGet a list of contact groups.
-
cymulate-simulations-id-listRetrieve a list of all simulations IDs.
-
cymulate-simulations-listRetrieve a list of all simulations by ID.
-
cymulate-waf-startCreate a new web application firewall assessment.
-
cymulate-waf-statusGet the web application firewall assessment status.
-
cymulate-waf-stopStop a running web application firewall assessment.
-
cymulate-waf-template-listRetrieve the WAF template list.
import copy import json import traceback from datetime import date from typing import Any import urllib3 from CommonServerPython import * # pylint: disable=unused-wildcard-import # Disable insecure warnings urllib3.disable_warnings() DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" CY_GENERAL_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" CY_UNIQUE_DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" MAX_INCIDENTS_TO_FETCH = 35 MAX_EVENTS_TO_DISPLAY = 20 SEVERITIES = ["Low", "Medium", "High", "Critical"] ACCESSED_STATUS = ["penetrated", "accessed", "executed completely", "exfiltrated", "completed"] ENDPOINT_DICT = { "web-gateway": "browsing", "exfiltration": "dlp", "email-gateway": "mail", "endpoint-security": "edr", "waf": "waf", "kill-chain": "apt", "immediate-threats": "immediate-threats", "phishing-awareness": "phishing", "lateral-movement": "hopper", } class Client(BaseClient): """ Client for Cymulate RESTful API. Args: base_url (str): Cymulate server url. token (str): Cymulate access token. verify (bool): Whether the request should verify the SSL certificate. proxy (bool): specifies if to use XSOAR proxy settings. """ def __init__(self, base_url: str, token: str, verify: bool, proxy: bool, **kwargs): super().__init__(base_url=base_url, verify=verify, proxy=proxy, **kwargs) self.headers = {"x-token": token, "accept": "*/*", "Content-Type": "application/json"} def validate(self): """Helper function for test_module that creates a simple API call""" return self._http_request(method="GET", url_suffix="/user/modules", headers=self.headers, resp_type="response") def start_assessment(self, endpoint: str | None, data: dict): """Start new assessment. Args: endpoint (str): Cymulate's endpoint to start the assessment on. data (dict): Dictionary containing all relevant data for running new assessment. """ return self._http_request(method="POST", url_suffix=f"{endpoint}/start", headers=self.headers, data=json.dumps(data)) def stop_assessment(self, endpoint: str | None): """Stop a running assessment. Args: endpoint (str): The Cymulate endpoint to stop the assessment. """ return self._http_request(method="POST", url_suffix=f"/{endpoint}/stop", headers=self.headers) def get_assessment_status(self, endpoint: str | None, assessment_id: str | None): """Retrieve an assessment status. Args: endpoint (str): Cymulate's endpoint to get the assessment status for. assessment_id (str): The assessment ID to get the status to. """ return self._http_request( method="GET", url_suffix=f"/{endpoint}/status", headers=self.headers, params={"id": assessment_id} ) def list_templates(self, endpoint: str | None): """Retrieve a list af all Cymulate templates to run the assessments on. Args: endpoint (str): The Cymulate endpoint templates list. """ return self._http_request(method="GET", url_suffix=f"/{endpoint}/templates", headers=self.headers) def list_phishing_contacts(self): """Retrieve a list af all phishing contacts.""" return self._http_request(method="GET", url_suffix="/phishing/contacts/groups", headers=self.headers) def get_phishing_contacts(self, group_id: str | None): """Retrieve a list of phishing contacts by group ID.""" return self._http_request( method="GET", url_suffix="/phishing/contacts", headers=self.headers, params={"groupId": group_id} ) def create_phishing_contacts(self, group_name: str | None): """Create phishing contacts group.""" return self._http_request( method="POST", url_suffix="/phishing/contacts/group", headers=self.headers, params={"groupName": group_name} ) def get_agents(self): """Retrieve a list af all agents.""" return self._http_request(method="GET", url_suffix="/agents/get/", headers=self.headers, resp_type="json") def list_attacks(self, endpoint: str | None): """Retrieves attacks by module. Args: endpoint (str): Cymulate's endpoint to list attacks by module. """ response = self._http_request(method="GET", url_suffix=f"/{endpoint}/attacks/technical", headers=self.headers) return response.get("data") def list_attack_ids_by_date(self, endpoint: str | None, from_date: str | None, to_date: str | None = None): """Retrieves attack IDs by their dates. Args: endpoint (str): Cymulate's endpoint to list attacks. from_date (str): From which date to fetch data. to_date (str): End date to fetch data. If no argument is given, value will be now. """ to_date = to_date if to_date else date.today().strftime("%Y-%m-%d") response = self._http_request( method="GET", url_suffix=f"/{endpoint}/history/get-ids", params={"fromDate": from_date, "toDate": to_date}, headers=self.headers, ) return dict_safe_get(dict_object=response, keys=["data", "attack"], return_type=list) def list_immediate_threats_ids_by_date(self, from_date: str | None, to_date: str | None): """Retrieves immediate threats attack IDs by their dates. Args: from_date (str): From which date to fetch data. to_date (str): End date to fetch data. If no argument is given, value will be now. """ response = self._http_request( method="GET", url_suffix="/immediate-threats/ids", params={"fromDate": from_date, "toDate": to_date}, headers=self.headers, ) return response.get("data") def list_attack_ids(self, endpoint: str | None): """Retrieves all attack IDs. Args: endpoint (str): The Cymulate endpoint to list attacks. """ response = self._http_request(method="GET", url_suffix=f"/{endpoint}/ids", headers=self.headers) return response.get("data") def get_attack_by_id(self, endpoint: str | None, attack_id: str | None): """Retrieves data regarding an attack by the attack ID. Args: endpoint (str): The Cymulate endpoint to retrieve attacks data from. attack_id (str): ID of the attack to retrieve data to. """ response = self._http_request(method="GET", url_suffix=f"/{endpoint}/attack/technical/{attack_id}", headers=self.headers) return response.get("data") def get_immediate_threat_assessment(self, attack_id: str | None): """Retrieves data regarding immediate threats attack by the attack ID. Args: attack_id (str): ID of the attack to retrieve data to. """ response = self._http_request( method="GET", url_suffix=f"/immediate-threats/attack/technical/{attack_id}", headers=self.headers ).get("data") return response.get("payloads") def get_simulations_by_id(self, endpoint: str | None, attack_id: str | None): """Retrieves all event data.""" return self._http_request( method="GET", url_suffix=f"{endpoint}/history/technical/{attack_id}", headers=self.headers, params={"id": attack_id} ) """ HELPER FUNCTIONS """ def extract_status_commands_output(result: dict) -> dict: """Parse the dictionary returned from the API call to a XSOAR output. Args: result (dict): API call result. """ output = { "id": result.get("id") if result.get("id") else result.get("_id"), "inProgress": result.get("inProgress"), "progress": result.get("progress"), "categories": result.get("categories"), "addresses": result.get("addresses"), } return remove_empty_elements(output) def extract_template_output(raw_response: dict): """Helper function to replace all the `_id` key to `id`. Args: raw_response (dict): Raw response returned from the API. Returns: list[Dict]: The raw response where the `_id` key has replaced with `id`. """ outputs = copy.deepcopy(raw_response) for dictionary in outputs: dictionary["id"] = dictionary.pop("_id", None) return outputs def validate_timestamp(timestamp: Any) -> bool: """ Helper function to validate the input timestamp format. Cymulate API can return empty timestamp or an invalid string (for example the string 'no timestamp'). Args: timestamp: input timestamp Returns: bool: True if the input is in valid format, else False. """ try: if re.match(r"\d{4}-\d{2}-\d{2}", timestamp): return True except Exception: # pylint: disable=broad-except return False return False def get_alerts_by_module(client: Client, module_name: str, last_fetch: int) -> tuple[List[Any], int, int, int]: """Helper function to retrieves raw data from the API according to the module currently fetched, and using format_incidents() function to format the raw data into XSOAR incident format. Args: client (Client): Cymulate client. module_name (str): The module we are currently fetching. last_fetch (int): Timestamp in milliseconds on when to start fetching incidents. Returns: list: incidents, int: event_offset, str: alert_created_time, int: len(events) """ raw_data = [] timestamp_endpoint = None event_offset = get_integration_context().get("offset", 0) if module_name in ("web-gateway", "exfiltration", "endpoint-security"): raw_data = client.list_attacks(ENDPOINT_DICT.get(module_name)) elif module_name == "email-gateway": raw_data = client.list_attacks(ENDPOINT_DICT.get(module_name)) timestamp_endpoint = "Email_Received" elif module_name == "waf": id_data = client.list_attack_ids(module_name) # Extracting the attack data for each site ID. for cur_id in id_data: raw_data.extend(client.get_attack_by_id(ENDPOINT_DICT.get(module_name), cur_id.get("Id"))) elif module_name == "kill-chain": id_data = client.list_attack_ids(ENDPOINT_DICT.get(module_name)) # Kill Chain endpoint returns IDs from all times so filter by time before creating incidents relevant_id_list = [] for cur_id in id_data: alert_created_time = int(date_to_timestamp(cur_id.get("Timestamp"), date_format=CY_GENERAL_DATE_FORMAT)) if alert_created_time >= last_fetch: relevant_id_list.append(cur_id.get("Id")) # Extracting the attack data for each site ID. for cur_id in relevant_id_list: raw_data.extend(client.get_attack_by_id(ENDPOINT_DICT.get(module_name), cur_id)) elif module_name == "immediate-threats": from_date = timestamp_to_datestring(last_fetch, "%Y-%m-%d") id_data = client.list_attack_ids_by_date(ENDPOINT_DICT.get(module_name), from_date) # Immediate threats endpoint returns IDs from all times so filter by time. relevant_id_list = [] for cur_id in id_data: alert_created_time = int(date_to_timestamp(cur_id.get("Timestamp"), date_format=CY_UNIQUE_DATE_FORMAT)) if alert_created_time >= last_fetch: relevant_id_list.append(cur_id.get("Id")) # Extracting the attack data for each site ID. site_id_list = format_id_list(id_data) for cur_id in site_id_list: raw_data.extend(client.get_immediate_threat_assessment(cur_id)) elif module_name in ("phishing-awareness", "lateral-movement"): from_date = timestamp_to_datestring(last_fetch, "%Y-%m-%d") id_data = client.list_attack_ids_by_date(ENDPOINT_DICT.get(module_name), from_date) # Extracting the attack data for each site ID. site_id_list = format_id_list(id_data) for cur_id in site_id_list: raw_data.extend(client.get_attack_by_id(ENDPOINT_DICT.get(module_name), cur_id)) if module_name == "phishing-awareness": timestamp_endpoint = "Campaign_Start_Timestamp" return format_incidents(raw_data, event_offset, last_fetch, module_name, timestamp_endpoint) def format_id_list(id_data_dict: dict) -> list: """Helper function to create an ID list from an ID data dictionary. Args: id_data_dict (dict): Dictionary containing full IDs data. Returns: list: containing IDs only. """ id_list = [] for id_data in id_data_dict: # The API might return ID, Id or id as key, so converting dict keys to be lowercase. data = {k.lower(): v for k, v in id_data.items()} id_list.append(data.get("id", None)) # Remove None objects from ID list, if exists. id_list = [id for id in id_list if id] return id_list def format_incidents( events: list, event_offset: int, last_fetch: int, module_name: str, timestamp_endpoint: str = None ) -> tuple[List[Any], int, int, int]: """ This function loops over the alerts list and create incidents from different events. For `Endpoint Security` and `Kill Chain` modules, if current event name is identical to previous event name, then both are part of the same incident and we will only update the existing incident description and won't create a new incident. Args: events (list): Events list to create incidents from. event_offset (int): Event offset. last_fetch (int): Timestamp in milliseconds on when to start fetching incidents. module_name (str): Module name. timestamp_endpoint(str): What API endpoint represent the event timestamp. If None is given, timestamp endpoint from API can be 'Timestamp' or 'Attack_Timestamp' Returns: list: incidents, int: event_offset, str: alert_created_time, int: len(events) """ incidents: List[Any] = [] event_counter = 0 offset = event_offset alert_created_time = last_fetch max_alert_created_time = alert_created_time for event in events[offset:]: # if current event name is identical to previous, then only update incident description. if (module_name in ("endpoint-security", "kill-chain")) and ( incidents and extract_event_name(event, module_name) == incidents[-1].get("name") ): event_offset += 1 last_incident = incidents[-1] alert_created_time = last_incident.get("occurred") if module_name == "endpoint-security": alert_created_time = int(date_to_timestamp(alert_created_time, date_format=DATE_FORMAT)) elif module_name == "kill-chain": alert_created_time = int(date_to_timestamp(alert_created_time, date_format=CY_GENERAL_DATE_FORMAT)) step_num = event.get("Scenario_Counter") if module_name == "endpoint-security" else event.get("Stage_Phase") data = json.loads(last_incident.get("rawJSON")) current_description = data.get("description") new_description = f"\nStep {step_num}:\n{extract_event_description(event)}" data["description"] = f"{current_description}{new_description}" if current_description else new_description # Insert new description to the previous incident. last_incident["rawJSON"] = json.dumps(data) incidents[-1] = last_incident # Keep track on the latest incident timestamp. Events that are part of an incident are # returned without timestamp so we only use the first the event's timestamp (First step) if alert_created_time > max_alert_created_time: max_alert_created_time = alert_created_time # The current event is new (has new name), then we need to build a new incident. else: if event_counter >= min(MAX_INCIDENTS_TO_FETCH, int(demisto.params().get("max_fetch", MAX_INCIDENTS_TO_FETCH))): break # Incrementing the event offset, regardless of whether new incident will be created. event_offset += 1 # If attack status is identical to previous assessment status, or the current attack was # unsuccessful, we won't create incident. if not event_status_changed(event): continue if timestamp_endpoint is None: t_stamp = event.get("Timestamp") if event.get("Timestamp") else event.get("Attack_Timestamp") else: t_stamp = event.get(timestamp_endpoint) # Validate API timestamp. if validate_timestamp(t_stamp): try: alert_created_time = date_to_timestamp(t_stamp, date_format=CY_GENERAL_DATE_FORMAT) except Exception: alert_created_time = date_to_timestamp(t_stamp, date_format=CY_UNIQUE_DATE_FORMAT) # If current alert was created since last fetch time, create XS0AR incident. if alert_created_time >= last_fetch: incidents.append(build_incident_dict(event, module_name, t_stamp)) event_counter += 1 # Keep track on the latest incident timestamp. if alert_created_time > max_alert_created_time: max_alert_created_time = alert_created_time return incidents, event_offset, max_alert_created_time, len(events) def extract_event_name(event: dict, module_name: str) -> str: """Helper function to extract event name according to the event module. Args: event (dict): Full event data return from API. module_name (str): Module name. """ event_name = f"Cymulate - {module_name} - " if module_name in ("web-gateway", "email-gateway", "immediate-threats"): event_name = f"{event_name}{event.get('Attack_Payload')}" elif module_name == "exfiltration": event_name = f"{event_name}{event.get('Phrase_Title')}-{event.get('Classification')}" elif module_name == "endpoint-security": event_name = f"{event_name}{event.get('Scenario_Title')}" elif module_name == "waf": event_name = f"{event_name}{event.get('Payload')}" elif module_name == "kill-chain": event_name = f"{event_name}{event.get('Template_Name')}" elif module_name == "phishing-awareness": event_name = f"{event_name}{event.get('User')}" elif module_name == "lateral-movement": event_name = f"{event_name}{event.get('Source_Hostname')}-{event.get('Destination_Hostname')}" return event_name def extract_event_description(event) -> Any | None: """Helper function to extract event description. Args: event (dict): Full event data return from API. Returns: str: event description if exists, else: None. """ event_description = None if event.get("Description"): event_description = event.get("Description") elif event.get("Phrase"): event_description = event.get("Phrase") elif event.get("Summery"): event_description = event.get("Summery") return event_description def event_status_changed(event: dict) -> bool: """We only create incidents from penetrated attacks, that were not penetrated in the last attack scenario. This function checks if the event is penetrated for the first time. Args: event (dict): Event dictionary returned from API. Returns: bool: True if the event was penetrated for the first time, else False. """ status_changed = True prev = event.get("PrevStatus") if event.get("PrevStatus") else event.get("Previous_Scenario_Status") if (prev and prev.lower() in ACCESSED_STATUS) or event.get("Previously_Phished"): status_changed = False cur = event.get("Status") if event.get("Status") else event.get("Step_Status") if cur and cur.lower() not in ACCESSED_STATUS: status_changed = False return status_changed def build_incident_dict(event: dict, module_name: str, event_timestamp=None) -> dict: """Helper function for fetch incident that builds the incidents. Args: event (dict): Event dictionary. module_name (str): Module name. event_timestamp: Event timestamp. Returns: dict: XSOAR incident. """ if event is None: return {} incident_data = { "cymulateStatus": event.get("Status"), "module": event.get("Module"), "user": event.get("User"), "lastAction": event.get("Last_Action"), "source": event.get("Source"), "testCase": event.get("Test_Case"), "attackType": event.get("Attack_Type"), "attackVector": event.get("Attack_Vector"), "templateName": event.get("Template_Name"), "inProgress": event.get("InProgress"), "url": event.get("Url"), "input": event.get("Input"), "sourceEmailAddress": event.get("Source_Email_Address"), "agentless": event.get("Agentless"), "analysis": event.get("Analysis"), "command": event.get("Command"), "description": extract_event_description(event), "md5": event.get("MD5") if event.get("MD5") else event.get("Md5"), "sha256": event.get("SHA256") if event.get("SHA256") else event.get("Sha256"), "sha1": event.get("SHA1") if event.get("SHA1") else event.get("Sha1"), } mitigation = event.get("Mitigation_Details") if event.get("Mitigation_Details") else event.get("Mitigation") if mitigation: incident_data["mitigationDetails"] = mitigation attack_payload = event.get("Attack_Payload") if attack_payload and attack_payload.startswith("http"): incident_data["url"] = attack_payload elif attack_payload: incident_data["attackType"] = attack_payload incident = { "name": extract_event_name(event, module_name), "occurred": event_timestamp, "severity": convert_to_xsoar_severity(event.get("Risk")), "rawJSON": json.dumps(remove_empty_elements(incident_data)), } if not event_timestamp: event_timestamp = event.get("Timestamp") if event.get("Timestamp") else event.get("Attack_Timestamp") if validate_timestamp(event_timestamp): try: occurred = datetime.strptime(event_timestamp, CY_GENERAL_DATE_FORMAT).strftime(DATE_FORMAT) # CHANGED except Exception: occurred = datetime.strptime(event_timestamp, CY_UNIQUE_DATE_FORMAT).strftime(DATE_FORMAT) # CHANGED incident["occurred"] = occurred return incident def convert_to_xsoar_severity(severity: Any | None) -> int: """Maps Cymulate severity to Cortex XSOAR severity. Args: severity(str): severity as returned from Cymulate API. If API does not return severity, The function will return 0. Returns: int: Cortex XSOAR Severity (1 to 4) """ if severity: return { "low": IncidentSeverity.LOW, "medium": IncidentSeverity.MEDIUM, "high": IncidentSeverity.HIGH, "critical": IncidentSeverity.CRITICAL, }.get(severity.lower(), IncidentSeverity.UNKNOWN) return IncidentSeverity.UNKNOWN """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """Tests API connectivity and authentication. Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Args: client (Client): Cymulate client. """ test_message = "ok" try: response = client.validate() if not response.ok: raise DemistoException("Authorization Error: make sure API Key is correctly set.", res=response) except DemistoException as err: if "Unauthorized" in str(err): test_message = f"Authorization Error: make sure API Key is correctly set.\n\n{err}" else: raise return test_message def list_exfiltration_template_command(client: Client) -> CommandResults: """Retrieve a list of all exfiltration templates. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all exfiltration templates. """ raw_response = client.list_templates(ENDPOINT_DICT.get("exfiltration")) outputs = extract_template_output(raw_response.get("data")) readable_output = tableToMarkdown("Exfiltration templates list:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Exfiltration.Template", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def start_exfiltration_assessment_command( client: Client, template_id: str, agent_name: str, schedule: bool, schedule_loop: str, agent_profile_name: str = None ) -> CommandResults: """Start a new exfiltration assessment. Args: client (Client): Cymulate client. template_id (str): The ID of the template to run the exfiltration Assessment with. agent_name (str): Agent name to run simulation attacks. agent_profile_name (str): Agent profile name to run simulation attacks on. schedule (bool): Whether to schedule the automated assessment periodically. schedule_loop (str): Loop size of the scheduled agent. For example: to run the agent only once, use the value 'one-time'. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ if agent_profile_name is not None: agent_profile_name = agent_profile_name.replace('"', "") params = { "templateID": template_id, "agentName": agent_name, "agentProfileName": agent_profile_name, "schedule": schedule, "scheduleLoop": schedule_loop, } raw_response = client.start_assessment(ENDPOINT_DICT.get("exfiltration"), params) output = { "id": raw_response.get("data"), "success": raw_response.get("success"), } readable_output = tableToMarkdown("Starting exfiltration assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.Exfiltration", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_exfiltration_assessment_command(client: Client) -> CommandResults: """Stop a running exfiltration assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("exfiltration")) readable_output = tableToMarkdown("Stopping exfiltration assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.Exfiltration", outputs_key_field="id", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_exfiltration_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve exfiltration assessment status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the assessment status. """ raw_response = client.get_assessment_status(ENDPOINT_DICT.get("exfiltration"), assessment_id) outputs = extract_status_commands_output(raw_response) readable_output = tableToMarkdown("Exfiltration assessment status:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Exfiltration", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def list_email_gateway_template_command(client: Client) -> CommandResults: """Retrieve a list of all email gateway templates. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all email-gateway templates. """ raw_response = client.list_templates(ENDPOINT_DICT.get("email-gateway")) outputs = extract_template_output(raw_response) readable_output = tableToMarkdown("Email gateway templates list:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.EmailGateway.Template", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def start_email_gateway_assessment_command( client: Client, template_id: str, agent_email: str, schedule: bool, schedule_loop: str ) -> CommandResults: """Start a new email gateway assessment. Args: client (Client): Cymulate client. template_id (str): The ID of the template to run the assessment with. agent_email (str): Agent email to run simulation attacks. schedule (bool): Whether to schedule the automated assessment periodically. schedule_loop (str): Loop size of the scheduled agent. For example: to run the agent only once, use the value 'one-time'. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ params = {"templateID": template_id, "agentEmail": agent_email, "schedule": schedule, "scheduleLoop": schedule_loop} raw_response = client.start_assessment(ENDPOINT_DICT.get("email-gateway"), params) output = {"id": raw_response.get("data"), "success": raw_response.get("success")} readable_output = tableToMarkdown("Starting email gateway assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.EmailGateway", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_email_gateway_assessment_command(client: Client) -> CommandResults: """Stop a running email gateway assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("email-gateway")) readable_output = tableToMarkdown("Stopping email gateway assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.EmailGateway", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_email_gateway_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve email gateway assessment status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the email gateway assessment status. """ outputs = {} raw_response = client.get_assessment_status(ENDPOINT_DICT.get("email-gateway"), assessment_id) output = copy.deepcopy(raw_response).get("data") if output: outputs = extract_status_commands_output(output[0]) readable_output = tableToMarkdown("Email gateway assessment status:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.EmailGateway", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def list_endpoint_security_template_command(client: Client) -> CommandResults: """Retrieve a list of all endpoint security templates. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all endpoint security templates. """ raw_response = client.list_templates(ENDPOINT_DICT.get("endpoint-security")) outputs = extract_template_output(raw_response) readable_output = tableToMarkdown("Endpoint security templates list:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.EndpointSecurity.Template", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def start_endpoint_security_assessment_command( client: Client, template_id: str, agent_name: str, schedule: bool, schedule_loop: str, agent_profile_name: str = None ) -> CommandResults: """Start a new endpoint security assessment. Args: client (Client): Cymulate client. template_id (str): The ID of the template to run the assessment with. agent_name (str): Agent's name to run simulation attacks with. agent_profile_name (str): Agent profile name to run simulation attacks on schedule (bool): Whether to schedule the automated assessment periodically. schedule_loop (str): Loop size of the scheduled agent. For example: to run the agent only once, use the value 'one-time'. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ if agent_profile_name is not None: agent_profile_name = agent_profile_name.replace('"', "") params = { "templateID": template_id, "agentName": agent_name, "agentProfileName": agent_profile_name, "schedule": schedule, "scheduleLoop": schedule_loop, } raw_response = client.start_assessment(ENDPOINT_DICT.get("endpoint-security"), params) output = {"id": raw_response.get("data"), "success": raw_response.get("success")} readable_output = tableToMarkdown("Starting endpoint security assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.EndpointSecurity", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_endpoint_security_assessment_command(client: Client) -> CommandResults: """Stop a running endpoint security assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("endpoint-security")) readable_output = tableToMarkdown("Stopping endpoint security assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.EndpointSecurity", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_endpoint_security_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve endpoint security assessment status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the assessment status. """ endpoint = ENDPOINT_DICT.get("endpoint-security") raw_response = client.get_assessment_status(endpoint, assessment_id) output = extract_status_commands_output(raw_response) readable_output = tableToMarkdown("Endpoint security assessment status:", output, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.EndpointSecurity", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def list_waf_template_command(client: Client) -> CommandResults: """Retrieve a list of all WAF templates. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all WAF templates. """ raw_response = client.list_templates(ENDPOINT_DICT.get("waf")) output = copy.deepcopy(raw_response).get("data") for dict in output: dict["id"] = dict.pop("_id") readable_output = tableToMarkdown("WAF templates list:", output, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.WAF.Template", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def start_waf_assessment_command(client: Client, template_id: str, sites, schedule: bool, schedule_loop: str) -> CommandResults: """Start a new WAF assessment. Args: client (Client): Cymulate client. template_id (str): The ID of the template to run the assessment with. sites (list[str] or str): Sites to run the assessment on. schedule (bool): Whether to schedule the automated assessment periodically. schedule_loop (str): Loop size of the scheduled agent. For example: to run the agent only once, use the value 'one-time'. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ sites = argToList(sites) params = {"templateID": template_id, "sites": sites, "schedule": schedule, "scheduleLoop": schedule_loop} raw_response = client.start_assessment(ENDPOINT_DICT.get("waf"), params) output = {"id": raw_response.get("data"), "success": raw_response.get("success")} readable_output = tableToMarkdown("Starting WAF assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.WAF", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_waf_assessment_command(client: Client) -> CommandResults: """Stop a running WAF assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("waf")) readable_output = tableToMarkdown("Stopping WAF assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.WAF", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_waf_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve WAF assessment status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the assessment status. """ endpoint = ENDPOINT_DICT.get("waf") raw_response = client.get_assessment_status(endpoint, assessment_id) output = extract_status_commands_output(raw_response) readable_output = tableToMarkdown("WAF assessment status:", output, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.WAF", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def start_immediate_threat_assessment_command( client: Client, template_id: str, browsing_address: str = "", browsing_address_profile_name: str = "", mail_address: str = "", edr_address_profile_name: str = "", edr_address: str = "", ) -> CommandResults: """Start a new immediate threats assessment. Args: client (Client): Cymulate client. template_id (str): The ID of the template to run the assessment with. browsing_address (str): Browsing address. browsing_address_profile_name (str): browsing Agent profile name (Optional - required on SBA only) mail_address (str): Agent email address. edr_address_profile_name (str): EDR Agent profile name (Optional - required on SBA only) edr_address (str): EDR Agent address. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ if browsing_address == "" and mail_address == "" and edr_address == "": raise ValueError("At least one of the addresses arguments should be filled.") params = { "templateID": template_id, "mailAddress": mail_address, "browsingAddress": browsing_address, "browsingAddressProfileName": browsing_address_profile_name, "edrAddressProfileName": edr_address_profile_name, "edrAddress": edr_address, } raw_response = client.start_assessment(ENDPOINT_DICT.get("immediate-threats"), params) output = {"id": raw_response.get("data"), "success": raw_response.get("success")} readable_output = tableToMarkdown("Starting immediate-threats assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.ImmediateThreats", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_immediate_threat_assessment_command(client: Client) -> CommandResults: """Stop the immediate threats assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("immediate-threats")) readable_output = tableToMarkdown("Stop immediate-threats assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.ImmediateThreats", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_immediate_threat_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve the immediate threats status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the assessment status. """ endpoint = ENDPOINT_DICT.get("immediate-threats") raw_response = client.get_assessment_status(endpoint, assessment_id) output = extract_status_commands_output(raw_response) readable_output = tableToMarkdown("Immediate-threats assessment status:", output, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.ImmediateThreats", outputs_key_field="", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def list_lateral_movement_template_command(client: Client) -> CommandResults: """Retrieve a list of all lateral movement templates. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all lateral movement templates. """ raw_response = client.list_templates(ENDPOINT_DICT.get("lateral-movement")) outputs = extract_template_output(raw_response.get("data")) readable_output = tableToMarkdown("Lateral movement templates list:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.LateralMovement.Template", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def start_lateral_movement_assessment_command( client: Client, agent_name: str, template_id: str, upload_to_cymulate: bool, schedule: bool, schedule_loop: str, agent_profile_name: str = None, ) -> CommandResults: """Start a new lateral movement assessment. Args: client (Client): Cymulate client. agent_name (str): Agent name to run the assessment with. agent_profile_name (str): Agent profile name to run simulation attacks on. template_id (str): The ID of the template to run the lateral movement with. upload_to_cymulate (bool): Whether to upload the result to Cymulate. schedule (bool): Whether to schedule the automated assessment periodically. schedule_loop (str): Loop size of the scheduled agent. For example: to run the agent only once, use the value 'one-time'. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the start assessment data. """ if agent_profile_name is not None: agent_profile_name = agent_profile_name.replace('"', "") params = { "agentName": agent_name, "agentProfileName": agent_profile_name, "templateID": template_id, "uploadResultsToCymulate": upload_to_cymulate, "schedule": schedule, "scheduleLoop": schedule_loop, } raw_response = client.start_assessment(ENDPOINT_DICT.get("lateral-movement"), params) output = {"id": raw_response.get("data"), "success": raw_response.get("success")} readable_output = tableToMarkdown("Starting lateral movement assessment:", output) command_results = CommandResults( outputs_prefix="Cymulate.LateralMovement", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def stop_lateral_movement_assessment_command(client: Client) -> CommandResults: """Stop a running lateral movement assessment. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the stop assessment data. """ raw_response = client.stop_assessment(ENDPOINT_DICT.get("lateral-movement")) readable_output = tableToMarkdown("Stopping lateral movement assessment:", raw_response) command_results = CommandResults( outputs_prefix="Cymulate.LateralMovement", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def get_lateral_movement_assessment_status_command(client: Client, assessment_id: str) -> CommandResults: """Retrieve lateral movement assessment status. Args: client (Client): Cymulate client. assessment_id (str): The ID of the assessment to retrieve the status to. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the assessment status. """ endpoint = ENDPOINT_DICT.get("lateral-movement") raw_response = client.get_assessment_status(endpoint, assessment_id) output = extract_status_commands_output(raw_response.get("data")) readable_output = tableToMarkdown("Lateral movement assessment status:", output, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.LateralMovement", outputs_key_field="id", readable_output=readable_output, outputs=output, raw_response=raw_response, ) return command_results def list_phishing_awareness_contact_groups_command(client: Client) -> CommandResults: """Retrieve a list of all phishing awareness contact groups. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all contact groups. """ raw_response = client.list_phishing_contacts() outputs = extract_template_output(raw_response) readable_output = tableToMarkdown("Phishing awareness contact groups:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Phishing.Groups", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def get_phishing_awareness_contact_groups_command(client: Client, group_id: str) -> CommandResults: """Retrieve a list of all phishing awareness contacts list by contact group ID. Args: client (Client): Cymulate client. group_id (str): Group ID. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of contact list by contact group ID. """ raw_response = client.get_phishing_contacts(group_id) outputs = extract_template_output(raw_response) readable_output = tableToMarkdown("Phishing awareness contact groups:", outputs, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Phishing.Groups", outputs_key_field="id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def add_phishing_awareness_contact_groups_command(client: Client, group_name: str) -> CommandResults: """Create phishing awareness contact. Args: client (Client): Cymulate client. group_name (str): New group's name. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of contact list by contact group ID. """ raw_response = client.create_phishing_contacts(group_name) readable_output = tableToMarkdown("Phishing awareness contact group created:", raw_response, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Phishing.Groups", outputs_key_field="id", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def list_agents_command(client: Client) -> CommandResults: """Retrieve a list of all agents. Args: client (Client): Cymulate client. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all agents connected to the current user. """ raw_response = client.get_agents() headers = ["agentAddress", "agentMethod", "agentName", "comment"] readable_output = tableToMarkdown("Agents list:", raw_response, headers=headers, removeNull=True) command_results = CommandResults( outputs_prefix="Cymulate.Agent", outputs_key_field="", readable_output=readable_output, outputs=raw_response, raw_response=raw_response, ) return command_results def list_attack_simulations_command(client: Client, module: str, from_date: str, to_date: str = None) -> CommandResults: """Retrieve a list of all simulations IDs. Args: client (Client): Cymulate client. module (str): Module to retrieve simulations IDs to. from_date (str): From which date to fetch data. to_date (str): End date to fetch data. If no argument is given, value will be now. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all module simulations from a specific ID. """ outputs = [] if not validate_timestamp(from_date) or (to_date and not validate_timestamp(to_date)): raise ValueError("Wrong date format. Year-Month-Day, for example: March 1st 2021 should be written: 2021-03-01.") raw_response = client.list_attack_ids_by_date(ENDPOINT_DICT.get(module), from_date, to_date) num_simulations_to_display = min(MAX_EVENTS_TO_DISPLAY, len(raw_response)) if raw_response: for simulation_id_data in raw_response: data = simulation_id_data data["Timestamp"] = str(parse_date_string(simulation_id_data.get("Timestamp"))) outputs.append(data) readable_output = tableToMarkdown( f"Displaying {num_simulations_to_display}/{len(raw_response)} Attack IDs:", outputs[:num_simulations_to_display] ) command_results = CommandResults( outputs_prefix="Cymulate.Simulations", outputs_key_field="ID", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def list_simulations_command(client: Client, module: str, attack_id: str): """Retrieve a list of all simulations by ID. Args: client (Client): Cymulate client. module (str): Module to retrieve simulations to. attack_id (str): Attack ID. Returns: CommandResults: A CommandResults object that is then passed to 'return_results', containing the list of all module simulations from a specific ID. """ outputs = [] raw_response = client.get_simulations_by_id(ENDPOINT_DICT.get(module), attack_id) raw_response = raw_response.get("data") num_simulations_to_display = min(MAX_EVENTS_TO_DISPLAY, len(raw_response)) if raw_response: outputs = raw_response # Adding the attack ID to the simulation data. for simulation in outputs: simulation["Id"] = attack_id readable_output = tableToMarkdown( f"Displaying {num_simulations_to_display}/{len(raw_response)} simulations:", outputs[:num_simulations_to_display], removeNull=True, ) command_results = CommandResults( outputs_prefix="Cymulate.Simulations", outputs_key_field="Id", readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) return command_results def fetch_incidents( client: Client, last_run: dict[str, int], first_fetch_time: int, fetch_categories: list ) -> tuple[dict[str, int], List[dict]]: """ Retrieves new incidents every interval (default is 1 minute). The function will retrieve incidents from all selected modules chosen in the configuration page by the user. the next run will be calculated by the latest timestamp of all modules, to avoid duplications. NOTE: We fetch only one module per fetch call. Args: client (Client): Cymulate client object last_run (Optional[Dict[str, int]]): Dictionary with a key containing the latest incident created time we got from last fetch. first_fetch_time (Optional[int]): If last_run is None (first time we are fetching), it contains the timestamp in milliseconds on when to start fetching incidents. fetch_categories (list): a list of selected modules chosen in the configuration page. Returns: A tuple containing two elements: next_run (``Dict[str, int]``): Contains the timestamp that will be used in ``last_run`` on the next fetch. incidents (``List[dict]``): List of incidents that will be created in XSOAR """ last_fetch = last_run.get("last_fetch", None) last_fetch = int(last_fetch) if last_fetch else first_fetch_time * 1000 next_run = last_fetch context = get_integration_context() current_module = context.get("current_module", None) if current_module: incidents, offset, creation_time, total_simulated_events = get_alerts_by_module(client, current_module, last_fetch) else: incidents, offset, creation_time, total_simulated_events = [], 0, last_fetch, 0 # current_time will help us save current's module time, and update next_run accordingly. if creation_time > context.get("current_time", last_fetch): current_time = creation_time else: current_time = context.get("current_time", last_fetch) # There are alerts left to fetch if total_simulated_events > offset: integration_context = { "offset": offset, "current_module": context.get("current_module"), "modules": context.get("modules"), "current_time": current_time, } demisto.info(f"Fetching {current_module} module. Offset: {offset}/{total_simulated_events}") # Finished fetching current module, checking if there are more modules to fetch. else: modules = context.get("modules", None) if modules: integration_context = { "offset": 0, "current_module": modules[0], "modules": modules[1:], "current_time": current_time, } # Finished fetching all modules, re-initializing integration context. else: integration_context = {"offset": 0, "current_module": None, "modules": fetch_categories, "current_time": current_time} # Updating next run time after finish fetching all modules, if needed. if current_time >= next_run: next_run = current_time + 1000 else: # Increment by 1 second, only if new incidents were fetched. if incidents: next_run = next_run + 1000 set_integration_context(integration_context) return {"last_fetch": next_run}, incidents def main() -> None: """main function, parses params and runs command functions""" params = demisto.params() api_key = (params.get("credentials") or {}).get("password") or params.get("api_key") if not api_key: raise Exception("API Token must be provided.") base_url = params.get("base_url") verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) # How much time before the first fetch to retrieve incidents first_fetch_time = arg_to_datetime(arg=params.get("first_fetch", "3 days"), arg_name="First fetch time", required=True) first_fetch_timestamp = int(first_fetch_time.timestamp()) if first_fetch_time else None assert isinstance(first_fetch_timestamp, int) command = demisto.command() demisto.debug(f"Command being called is {command}") try: client = Client( base_url=base_url, token=api_key, # type: ignore[arg-type] verify=verify_certificate, proxy=proxy, ) if command == "test-module": return_results(test_module(client)) elif command == "fetch-incidents": fetch_categories = params.get("fetchCategory", None) # Handles first fetch if get_integration_context() is None: set_integration_context( { "offset": 0, "current_module": None, "modules": fetch_categories, } ) next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_timestamp, fetch_categories=fetch_categories, ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif command == "cymulate-simulations-id-list": return_results(list_attack_simulations_command(client, **demisto.args())) elif command == "cymulate-simulations-list": return_results(list_simulations_command(client, **demisto.args())) # exfiltration elif command == "cymulate-exfiltration-template-list": return_results(list_exfiltration_template_command(client)) elif command == "cymulate-exfiltration-start": return_results(start_exfiltration_assessment_command(client, **demisto.args())) elif command == "cymulate-exfiltration-stop": return_results(stop_exfiltration_assessment_command(client)) elif command == "cymulate-exfiltration-status": return_results(get_exfiltration_assessment_status_command(client, **demisto.args())) # email-gateway elif command == "cymulate-email-gateway-template-list": return_results(list_email_gateway_template_command(client)) elif command == "cymulate-email-gateway-start": return_results(start_email_gateway_assessment_command(client, **demisto.args())) elif command == "cymulate-email-gateway-stop": return_results(stop_email_gateway_assessment_command(client)) elif command == "cymulate-email-gateway-status": return_results(get_email_gateway_assessment_status_command(client, **demisto.args())) # endpoint-security elif command == "cymulate-endpoint-security-template-list": return_results(list_endpoint_security_template_command(client)) elif command == "cymulate-endpoint-security-start": return_results(start_endpoint_security_assessment_command(client, **demisto.args())) elif command == "cymulate-endpoint-security-stop": return_results(stop_endpoint_security_assessment_command(client)) elif command == "cymulate-endpoint-security-status": return_results(get_endpoint_security_assessment_status_command(client, **demisto.args())) # waf elif command == "cymulate-waf-template-list": return_results(list_waf_template_command(client)) elif command == "cymulate-waf-start": return_results(start_waf_assessment_command(client, **demisto.args())) elif command == "cymulate-waf-stop": return_results(stop_waf_assessment_command(client)) elif command == "cymulate-waf-status": return_results(get_waf_assessment_status_command(client, **demisto.args())) # immediate_threat elif command == "cymulate-immediate-threat-start": return_results(start_immediate_threat_assessment_command(client, **demisto.args())) elif command == "cymulate-immediate-threat-stop": return_results(stop_immediate_threat_assessment_command(client)) elif command == "cymulate-immediate-threat-status": return_results(get_immediate_threat_assessment_status_command(client, **demisto.args())) # lateral_movement elif command == "cymulate-lateral-movement-template-list": return_results(list_lateral_movement_template_command(client)) elif command == "cymulate-lateral-movement-start": return_results(start_lateral_movement_assessment_command(client, **demisto.args())) elif command == "cymulate-lateral-movement-stop": return_results(stop_lateral_movement_assessment_command(client)) elif command == "cymulate-lateral-movement-status": return_results(get_lateral_movement_assessment_status_command(client, **demisto.args())) # phishing_awareness elif command == "cymulate-phishing-awareness-contacts-group-list": return_results(list_phishing_awareness_contact_groups_command(client)) elif command == "cymulate-phishing-awareness-contacts-get": return_results(get_phishing_awareness_contact_groups_command(client, **demisto.args())) elif command == "cymulate-phishing-awareness-contacts-group-create": return_results(add_phishing_awareness_contact_groups_command(client, **demisto.args())) # General elif command == "cymulate-agent-list": return_results(list_agents_command(client)) except Exception as error: demisto.error(traceback.format_exc()) if "unauthorized" in str(error): return_error( f"Failed to execute {command} command.\nAuthorization Error: make sure API" f" Key is correctly set.\n\nFull error message:\n{error}" ) if "invalid attack id" in str(error): return_error( f"Failed to execute {command} command.\nPlease make sure you " f"entered the correct assessment id.\n\nFull error message:\n{error!s}" ) return_error(f"Failed to execute {command} command.\n\nFull error message:\n{error!s}") if __name__ in ("__main__", "__builtin__", "builtins"): main()