Smokescreen IllusionBLACK
Smokescreen IllusionBLACK is a deception-based threat defense platform designed to accurately and efficiently detect targeted threats including reconnaissance, lateral movement, malware-less attacks, social engineering, Man-in-the-Middle attacks, and ransomware in real-time.
Deception & Breach Simulation · Smokescreen IllusionBLACK
Details
| ID | Smokescreen IllusionBLACK |
|---|---|
| Provider | Zscaler |
| Category | Deception & Breach Simulation |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.12042988 |
| Supported Modules | Agentix XSIAM |
README
Smokescreen IllusionBLACK is a deception-based threat defense platform designed to accurately and efficiently detect targeted threats including reconnaissance, lateral movement, malware-less attacks, social engineering, Man-in-the-Middle attacks, and ransomware in real-time.
This integration was integrated and tested with version v3.10.7.4 of Smokescreen IllusionBLACK
Permissions
Configure Smokescreen IllusionBLACK in Cortex
| Parameter | Description | Required |
|---|---|---|
| url | Server URL (e.g. https://example.net) | True |
| client_id | IllusionBLACK API Client Id | True |
| token | IllusionBLACK External API Token | True |
| insecure | Trust any certificate (not secure) | False |
| proxy | Use system proxy settings | False |
| first_fetch | First fetch time for fetching incidents (2 days, 3 weeks, etc) | 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.
illusionblack-get-ad-decoys
Gets a list of Active Directory decoys.
Base Command
illusionblack-get-ad-decoys
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| IllusionBlack.AdDecoy | Unknown | IllusionBLACK AD Decoy users. |
Command Example
##### Context Example
{
“IllusionBlack”: {
“AdDecoy”: {
“first_name”: “felix”,
“last_name”: “hunt”,
“ou”: “mumbai”,
“state”: “added”,
“user_name”: “sqladmin”
}
}
}
##### Human Readable Output
### IllusionBLACK AD Decoys
|First Name|Last Name|Ou|State|User Name|
|---|---|---|---|---|
| felix | hunt | mumbai | added | sqladmin |
### illusionblack-get-network-decoys
***
Gets a list of Network decoys.
##### Base Command
`illusionblack-get-network-decoys`
##### Input
There are no input arguments for this command.
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.NetworkDecoy | Unknown | IllusionBLACK Network decoys. |
##### Command Example
```!illusionblack-get-network-decoys```
##### Context Example
{
“IllusionBlack”: {
“NetworkDecoy”: [
{
“ip”: “10.20.23.61”,
“mac”: “d0:43:1e:cd:cb:c2”,
“name”: “CTX-BACKUPS31”,
“services”: “web”
},
{
“ip”: “10.20.23.64”,
“mac”: “a0:48:1c:ee:08:38”,
“name”: “GCP-CYBERARK”,
“services”: “web”
},
{
“ip”: “10.20.23.63”,
“mac”: “00:fd:45:fa:6f:4d”,
“name”: “NEW-XEN”,
“services”: “web”
},
{
“ip”: “10.20.23.65”,
“mac”: “14:b3:1f:08:84:6d”,
“name”: “PRIM-CYBERARK”,
“services”: “web, shares”
},
{
“ip”: “10.20.23.62”,
“mac”: “20:a6:cd:00:6e:70”,
“name”: “SAP44”,
“services”: “web, shares”
},
{
“ip”: “10.20.23.60”,
“mac”: “90:b1:1c:73:64:fc”,
“name”: “ARCOSNEW”,
“services”: “web”
}
]
}
}
##### Human Readable Output
### IllusionBLACK Network Decoys
|Ip|Mac|Name|Services|
|---|---|---|---|
| 10.20.23.61 | d0:43:1e:cd:cb:c2 | CTX-BACKUPS31 | web |
| 10.20.23.64 | a0:48:1c:ee:08:38 | GCP-CYBERARK | web |
| 10.20.23.63 | 00:fd:45:fa:6f:4d | NEW-XEN | web |
| 10.20.23.65 | 14:b3:1f:08:84:6d | PRIM-CYBERARK | web, shares |
| 10.20.23.62 | 20:a6:cd:00:6e:70 | SAP44 | web, shares |
| 10.20.23.60 | 90:b1:1c:73:64:fc | ARCOSNEW | web |
### illusionblack-get-ti-decoys
***
Gets a list of Threat Intel decoys.
##### Base Command
`illusionblack-get-ti-decoys`
##### Input
There are no input arguments for this command.
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.TIDecoy | Unknown | IllusionBLACK TI Decoys. |
##### Command Example
```!illusionblack-get-ti-decoys```
##### Context Example
{
“IllusionBlack”: {
“TIDecoy”: {
“dataset”: “Finacle”,
“ip”: “10.20.23.67”,
“name”: “dev.smokescreen.io”,
“server_type”: “nginx/1.14.0 (Ubuntu)”
}
}
}
##### Human Readable Output
### IllusionBLACK TI Decoys
|Dataset|Ip|Name|Server Type|
|---|---|---|---|
| Finacle | 10.20.23.67 | dev.smokescreen.io | nginx/1.14.0 (Ubuntu) |
### illusionblack-is-host-decoy
***
Checks if a host or IP address is a network decoy.
##### Base Command
`illusionblack-is-host-decoy`
##### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| host | Hostname or IP address to check. | Required |
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.IsHostDecoy.Host | String | The IP address or hostname submitted to IllusionBLACK to check. |
| IllusionBlack.IsHostDecoy.Value | Boolean | The boolean value whether the host is a decoy or not. |
##### Command Example
```!illusionblack-is-host-decoy host="SAP44"```
##### Context Example
{
“IllusionBlack”: {
“IsHostDecoy”: {
“Host”: “SAP44”,
“Value”: true
}
}
}
##### Human Readable Output
True
### illusionblack-is-user-decoy
***
Checks if an Active Directory user is a decoy.
##### Base Command
`illusionblack-is-user-decoy`
##### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| user | Active Directory user name to check. | Required |
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.IsUserDecoy.User | String | The AD username submitted to IllusionBLACK to check. |
| IllusionBlack.IsUserDecoy.Value | Boolean | The boolean value whether the user is a decoy or not. |
##### Command Example
```!illusionblack-is-user-decoy user="sqladmin"```
##### Context Example
{
“IllusionBlack”: {
“IsUserDecoy”: {
“User”: “sqladmin”,
“Value”: true
}
}
}
##### Human Readable Output
True
### illusionblack-is-subdomain-decoy
***
Checks if a subdomain is a Threat Intel decoy.
##### Base Command
`illusionblack-is-subdomain-decoy`
##### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| subdomain | Subdomain to check. For example: dec.smokescreen.io. | Required |
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.IsSubdomainDecoy.Subdomain | String | The subdomain submitted to IllusionBLACK to check. |
| IllusionBlack.IsSubdomainDecoy.Value | Boolean | The boolean value whether the subdomain is a decoy or not. |
##### Command Example
```!illusionblack-is-subdomain-decoy subdomain="experience.illusionblack.com"```
##### Context Example
{
“IllusionBlack”: {
“IsSubdomainDecoy”: {
“Subdomain”: “experience.illusionblack.com”,
“Value”: false
}
}
}
##### Human Readable Output
False
### illusionblack-get-events
***
Gets events from IllusionBLACK.
##### Base Command
`illusionblack-get-events`
##### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| limit | Number of events. It can be between 1 and 1000. | Optional |
| query | IllusionBLACK query. For example: "attacker.ip is \"1.2.3.4\"" | Optional |
| from | ISO 8601 formatted date string. | Optional |
| to | ISO 8601 formatted date string. | Optional |
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.Event | Unknown | IllusionBLACK Events. |
##### Command Example
```!illusionblack-get-events limit=3```
##### Context Example
{
“IllusionBlack”: {
“Event”: [
{
“attacker.id”: “ADMIN-PC-001\admin”,
“attacker.name”: “ADMIN-PC-001\admin”,
“attacker.score”: 175,
“attacker.threat_parse_ids”: [
“lm_file_open”,
“lm_file_active_monitoring”
],
“decoy.appliance.id”: “cmc”,
“decoy.appliance.name”: “CMC”,
“decoy.client.id”: “experience”,
“decoy.client.name”: “experience”,
“decoy.group”: “Endpoint”,
“decoy.id”: “endpoint:admin-pc-001”,
“decoy.name”: “admin-pc-001”,
“decoy.type”: “endpoint”,
“file.name”: “C:\Users\admin\Desktop\passwords\Passwords.xlsx”,
“file.operation”: “67”,
“file.operation_string”: “Read”,
“file.process.command_line”: “"C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass”,
“file.process.domain_name”: “ADMIN-PC-001”,
“file.process.exit_code”: -1,
“file.process.id”: “10228”,
“file.process.image_name”: “powershell.exe”,
“file.process.user_name”: “admin”,
“file.process.user_sid”: “S-1-5-21-399445878-2258755057-882339928-1000”,
“file.thread_id”: “8588”,
“id”: “2020-02-25T09:49:15Z-76c99a22-03b9-439e-8638-37306c2d8e7f”,
“kill_chain_phase”: “Data Theft”,
“mitre_ids”: [
“T1005”
],
“record_type”: “event”,
“severity”: “high”,
“sub_type”: “file”,
“threat_parse_ids”: [
“lm_file_open”
],
“timestamp”: “2020-04-12T08:57:01Z”,
“type”: “endpoint”,
“whitelisted”: false
},
{
“attacker.id”: “NT AUTHORITY\SYSTEM”,
“attacker.name”: “NT AUTHORITY\SYSTEM”,
“attacker.score”: 250,
“attacker.threat_parse_ids”: [
“filetheft_unattend”,
“lm_file_active_monitoring”,
“lm_file_open”
],
“decoy.appliance.id”: “cmc”,
“decoy.appliance.name”: “CMC”,
“decoy.client.id”: “experience”,
“decoy.client.name”: “experience”,
“decoy.group”: “Endpoint”,
“decoy.id”: “endpoint:admin-pc-001”,
“decoy.name”: “admin-pc-001”,
“decoy.type”: “endpoint”,
“file.name”: “C:\Users\admin\Desktop\passwords\Passwords.xlsx”,
“file.operation”: “67”,
“file.operation_string”: “Read”,
“file.process.command_line”: “”,
“file.process.domain_name”: “NT AUTHORITY”,
“file.process.exit_code”: -1,
“file.process.id”: “2824”,
“file.process.image_name”: “MsMpEng.exe”,
“file.process.user_name”: “SYSTEM”,
“file.process.user_sid”: “S-1-5-18”,
“file.thread_id”: “724”,
“id”: “2020-02-25T09:49:15Z-0950f80f-7571-4382-b4b8-5e04c160c4c0”,
“kill_chain_phase”: “Data Theft”,
“mitre_ids”: [
“T1005”
],
“record_type”: “event”,
“severity”: “high”,
“sub_type”: “file”,
“threat_parse_ids”: [
“lm_file_open”
],
“timestamp”: “2020-04-12T08:57:01Z”,
“type”: “endpoint”,
“whitelisted”: false
},
{
“attacker.id”: “ADMIN-PC-001\admin”,
“attacker.name”: “ADMIN-PC-001\admin”,
“attacker.score”: 175,
“attacker.threat_parse_ids”: [
“lm_file_open”,
“lm_file_active_monitoring”
],
“decoy.appliance.id”: “cmc”,
“decoy.appliance.name”: “CMC”,
“decoy.client.id”: “experience”,
“decoy.client.name”: “experience”,
“decoy.group”: “Endpoint”,
“decoy.id”: “endpoint:admin-pc-001”,
“decoy.name”: “admin-pc-001”,
“decoy.type”: “endpoint”,
“file.name”: “C:\Users\admin\Desktop\docs\vulnerability assessment report\vulnerability assessment report.xlsx”,
“file.operation”: “65”,
“file.operation_string”: “Cleanup”,
“file.process.command_line”: “"C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass”,
“file.process.domain_name”: “ADMIN-PC-001”,
“file.process.exit_code”: -1,
“file.process.id”: “10228”,
“file.process.image_name”: “powershell.exe”,
“file.process.user_name”: “admin”,
“file.process.user_sid”: “S-1-5-21-399445878-2258755057-882339928-1000”,
“file.thread_id”: “0”,
“id”: “2020-02-25T09:45:48Z-fa248a98-bc8a-4275-93c7-e63ff1ee8d34”,
“kill_chain_phase”: “Data Theft”,
“mitre_ids”: [
“T1005”
],
“record_type”: “event”,
“severity”: “high”,
“sub_type”: “file”,
“threat_parse_ids”: [
“lm_file_active_monitoring”
],
“timestamp”: “2020-04-12T08:53:20Z”,
“type”: “endpoint”,
“whitelisted”: false
}
]
}
}
##### Human Readable Output
### IllusionBLACK Events
|attacker.id|attacker.name|attacker.score|attacker.threat_parse_ids|decoy.appliance.id|decoy.appliance.name|decoy.client.id|decoy.client.name|decoy.group|decoy.id|decoy.name|decoy.type|file.name|file.operation|file.operation_string|file.process.command_line|file.process.domain_name|file.process.exit_code|file.process.id|file.process.image_name|file.process.user_name|file.process.user_sid|file.thread_id|id|kill_chain_phase|mitre_ids|record_type|severity|sub_type|threat_parse_ids|timestamp|type|whitelisted|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ADMIN-PC-001\admin | ADMIN-PC-001\admin | 175 | lm_file_open,<br/>lm_file_active_monitoring | cmc | CMC | experience | experience | Endpoint | endpoint:admin-pc-001 | admin-pc-001 | endpoint | C:\Users\admin\Desktop\passwords\Passwords.xlsx | 67 | Read | "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass | ADMIN-PC-001 | -1 | 10228 | powershell.exe | admin | S-1-5-21-399445878-2258755057-882339928-1000 | 8588 | 2020-02-25T09:49:15Z-76c99a22-03b9-439e-8638-37306c2d8e7f | Data Theft | T1005 | event | high | file | lm_file_open | 2020-04-12T08:57:01Z | endpoint | false |
| NT AUTHORITY\SYSTEM | NT AUTHORITY\SYSTEM | 250 | filetheft_unattend,<br/>lm_file_active_monitoring,<br/>lm_file_open | cmc | CMC | experience | experience | Endpoint | endpoint:admin-pc-001 | admin-pc-001 | endpoint | C:\Users\admin\Desktop\passwords\Passwords.xlsx | 67 | Read | | NT AUTHORITY | -1 | 2824 | MsMpEng.exe | SYSTEM | S-1-5-18 | 724 | 2020-02-25T09:49:15Z-0950f80f-7571-4382-b4b8-5e04c160c4c0 | Data Theft | T1005 | event | high | file | lm_file_open | 2020-04-12T08:57:01Z | endpoint | false |
| ADMIN-PC-001\admin | ADMIN-PC-001\admin | 175 | lm_file_open,<br/>lm_file_active_monitoring | cmc | CMC | experience | experience | Endpoint | endpoint:admin-pc-001 | admin-pc-001 | endpoint | C:\Users\admin\Desktop\docs\vulnerability assessment report\vulnerability assessment report.xlsx | 65 | Cleanup | "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass | ADMIN-PC-001 | -1 | 10228 | powershell.exe | admin | S-1-5-21-399445878-2258755057-882339928-1000 | 0 | 2020-02-25T09:45:48Z-fa248a98-bc8a-4275-93c7-e63ff1ee8d34 | Data Theft | T1005 | event | high | file | lm_file_active_monitoring | 2020-04-12T08:53:20Z | endpoint | false |
### illusionblack-get-event-by-id
***
Gets a single event by the event ID.
##### Base Command
`illusionblack-get-event-by-id`
##### Input
| **Argument Name** | **Description** | **Required** |
| --- | --- | --- |
| id | IllusionBLACK Event ID. | Required |
##### Context Output
| **Path** | **Type** | **Description** |
| --- | --- | --- |
| IllusionBlack.Event | Unknown | IllusionBLACK Single Event. |
| IllusionBlack.Event.attacker.id | Unknown | IllusionBLACK Event Attacker ID. |
| IllusionBlack.Event.decoy.id | Unknown | IllusionBLACK Event Decoy ID. |
| IllusionBlack.Event.id | Unknown | IllusionBLACK Event ID. |
| IllusionBlack.Event.severity | Unknown | IllusionBLACK Event Severity. |
| IllusionBlack.Event.type | Unknown | IllusionBLACK Event Attack Type. |
##### Command Example
```!illusionblack-get-event-by-id id="2020-02-25T09:49:15Z-0950f80f-7571-4382-b4b8-5e04c160c4c0"```
##### Context Example
{
“IllusionBlack”: {
“Event”: {
“attacker.id”: “NT AUTHORITY\SYSTEM”,
“attacker.name”: “NT AUTHORITY\SYSTEM”,
“attacker.score”: 250,
“attacker.threat_parse_ids”: [
“filetheft_unattend”,
“lm_file_active_monitoring”,
“lm_file_open”
],
“decoy.appliance.id”: “cmc”,
“decoy.appliance.name”: “CMC”,
“decoy.client.id”: “experience”,
“decoy.client.name”: “experience”,
“decoy.group”: “Endpoint”,
“decoy.id”: “endpoint:admin-pc-001”,
“decoy.name”: “admin-pc-001”,
“decoy.type”: “endpoint”,
“file.name”: “C:\Users\admin\Desktop\passwords\Passwords.xlsx”,
“file.operation”: “67”,
“file.operation_string”: “Read”,
“file.process.command_line”: “”,
“file.process.domain_name”: “NT AUTHORITY”,
“file.process.exit_code”: -1,
“file.process.id”: “2824”,
“file.process.image_name”: “MsMpEng.exe”,
“file.process.user_name”: “SYSTEM”,
“file.process.user_sid”: “S-1-5-18”,
“file.thread_id”: “724”,
“id”: “2020-02-25T09:49:15Z-0950f80f-7571-4382-b4b8-5e04c160c4c0”,
“kill_chain_phase”: “Data Theft”,
“mitre_ids”: [
“T1005”
],
“record_type”: “event”,
“severity”: “high”,
“sub_type”: “file”,
“threat_parse_ids”: [
“lm_file_open”
],
“timestamp”: “2020-04-12T08:57:01Z”,
“type”: “endpoint”,
“whitelisted”: false
}
}
}
```
Human Readable Output
IllusionBLACK Single Event
| attacker.id | attacker.name | attacker.score | attacker.threat_parse_ids | decoy.appliance.id | decoy.appliance.name | decoy.client.id | decoy.client.name | decoy.group | decoy.id | decoy.name | decoy.type | file.name | file.operation | file.operation_string | file.process.command_line | file.process.domain_name | file.process.exit_code | file.process.id | file.process.image_name | file.process.user_name | file.process.user_sid | file.thread_id | id | kill_chain_phase | mitre_ids | record_type | severity | sub_type | threat_parse_ids | timestamp | type | whitelisted |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| NT AUTHORITY\SYSTEM | NT AUTHORITY\SYSTEM | 250 | filetheft_unattend, lm_file_active_monitoring, lm_file_open |
cmc | CMC | experience | experience | Endpoint | endpoint:admin-pc-001 | admin-pc-001 | endpoint | C:\Users\admin\Desktop\passwords\Passwords.xlsx | 67 | Read | NT AUTHORITY | -1 | 2824 | MsMpEng.exe | SYSTEM | S-1-5-18 | 724 | 2020-02-25T09:49:15Z-0950f80f-7571-4382-b4b8-5e04c160c4c0 | Data Theft | T1005 | event | high | file | lm_file_open | 2020-04-12T08:57:01Z | endpoint | false |
Configuration parameters
url— Server URL (e.g. https://example.net) (required)client_id— IllusionBLACK API Client Id (required)token— IllusionBLACK External API Token (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsfirst_fetch— First fetch time for fetching incidents (2 days, 3 weeks, etc)isFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Interval
Commands (8)
-
illusionblack-get-ad-decoysGets a list of Active Directory decoys.
-
illusionblack-get-event-by-idGets a single event by the event ID.
-
illusionblack-get-eventsGets events from IllusionBLACK.
-
illusionblack-get-network-decoysGets a list of Network decoys.
-
illusionblack-get-ti-decoysGets a list of Threat Intel decoys.
-
illusionblack-is-host-decoyChecks if a host or IP address is a network decoy.
-
illusionblack-is-subdomain-decoyChecks if a subdomain is a Threat Intel decoy.
-
illusionblack-is-user-decoyChecks if an Active Directory user is a decoy.
import json from datetime import UTC, datetime from typing import Any import demistomock as demisto # Disable insecure warnings import urllib3 from CommonServerPython import * urllib3.disable_warnings() class Client(BaseClient): """ Client will implement the service API, and should not contain any Demisto logic. Should only do requests and return data. """ def __init__(self, base_url, verify, client_id, token, proxy): """ Constructor which adds the authentication headers required by IllusionBLACK external API Args: base_url: IllusionBLACK URL. For example: https://experience.illusionblack.com verify: Allow insecure SSL client_id: token: proxy: """ headers = {"x-client-id": client_id, "x-client-auth": token} super().__init__(base_url=base_url, verify=verify, proxy=proxy, headers=headers) def ping(self): """ Initiates a HTTP Request to IllusionBLACK test endpoint /ping """ response = self._http_request(method="GET", url_suffix="/ping", ok_codes=(200,)) return response.get("message", "error") def get_ad_decoys(self): """ Gets a list of Active Directory (AD) user decoys from IllusionBLACK Returns: A tuple containing the response in human readable, context data and raw response formats """ response = self._http_request(method="GET", url_suffix="/decoy/users", ok_codes=(200,)) users = response["items"] return ( tableToMarkdown( "IllusionBLACK AD Decoys", users, headerTransform=lambda s: " ".join([w.capitalize() for w in s.split("_")]) ), {"IllusionBlack.AdDecoy(val.user_name==obj.user_name)": users}, users, ) def get_network_decoys(self): """ Gets a list of network decoys from IllusionBLACK and enriches the data with the list of services enabled. Returns:A tuple containing the response in human readable, context data and raw response formats """ response = self._http_request(method="GET", url_suffix="/decoy/hosts", ok_codes=(200,)) hosts: list = response["items"] for h in hosts: h["services"] = ", ".join(h["services"]) return ( tableToMarkdown("IllusionBLACK Network Decoys", hosts, headerTransform=lambda s: s.capitalize()), {"IllusionBlack.NetworkDecoy(val.name==obj.name)": hosts}, hosts, ) def get_ti_decoys(self): """ Gets a list of Threat Intelligence decoys from IllusionBLACK. Returns: A tuple containing the response in human readable, context data and raw response formats """ response = self._http_request(method="GET", url_suffix="/decoy/recon", ok_codes=(200,)) recon_decoys = response["items"] return ( tableToMarkdown( "IllusionBLACK TI Decoys", recon_decoys, headerTransform=lambda s: " ".join([w.capitalize() for w in s.split("_")]), ), {"IllusionBlack.TIDecoy(val.name==obj.name)": recon_decoys}, recon_decoys, ) def is_host_decoy(self, host): """ Checks if the host is an IllusionBLACK network decoy Args: host: The name of the entity For example: SMB-12 Returns: True if host is a decoy else False """ response = self._http_request(method="GET", url_suffix="/decoy/hosts", ok_codes=(200,)) hosts: list = response["items"] for decoy_host in hosts: if host == decoy_host["name"]: return "True", {"IllusionBlack.IsHostDecoy": {"Host": host, "Value": True}} return "False", {"IllusionBlack.IsHostDecoy": {"Host": host, "Value": False}} def is_user_decoy(self, user): """ Checks if the user is an IllusionBLACK AD user decoy Args: user: The user name of the AD user to check Returns: True if user is a decoy else False """ response = self._http_request(method="GET", url_suffix="/decoy/users", ok_codes=(200,)) users: list = response["items"] for decoy_user in users: if user.lower() == decoy_user["user_name"]: return "True", {"IllusionBlack.IsUserDecoy": {"User": user, "Value": True}} return "False", {"IllusionBlack.IsUserDecoy": {"User": user, "Value": False}} return None def is_subdomain_decoy(self, subdomain): """ Checks if the subdomain is an IllusionBLACK TI decoy Args: subdomain: The subdomain to check. For example: experience.illusionblack.com Returns: True if subdomain is a decoy else False """ response = self._http_request(method="GET", url_suffix="/decoy/recon", ok_codes=(200,)) ti_decoys: list = response["items"] for ti_decoy in ti_decoys: if subdomain == ti_decoy["name"]: return "True", {"IllusionBlack.IsSubdomainDecoy": {"Subdomain": subdomain, "Value": True}} return "False", {"IllusionBlack.IsSubdomainDecoy": {"Subdomain": subdomain, "Value": False}} return None def get_events(self, limit=None, query=None, from_time=None, to_time=None): """ Gets Events and corresponding Threat Parse data from IllusionBLACK based on the filtering parameters. Args: limit: Number of events to return per API call. Defaults to 10. query: IllusionBLACK orchestrate engine query string. Refer to IllusionBLACK doc for reference. from_time: ISO-8601 formatted datetime string of the starting time in the filter to_time: ISO-8601 formatted datetime string of the ending time in the filter Returns: A tuple with raw events and threat parse data corresponding to the events """ raw_events, raw_threat_parse, offset = [], {}, 0 # type: ignore while True: response = self._http_request( method="GET", url_suffix="/events", params={"limit": limit, "expfilter": query, "from": from_time, "to": to_time, "offset": offset}, ok_codes=(200,), ) meta: dict = response["meta"] amount = meta["paging"]["amount"] raw_events.extend(response["events"]) for tp in response.get("threat_parse", {}): tp_id = tp["id"] if tp_id not in raw_threat_parse: tp.pop("id", None) raw_threat_parse[tp_id] = tp offset += 1000 if amount < 1000: break return raw_events, raw_threat_parse def test_module(client): """ Returning "ok" indicates that the integration works like it is supposed to. Connection to the service is successful. Args: client: IllusionBLACK client Returns: "ok" if test passed, anything else will fail the test. """ try: message = client.ping() if message == "pong": return "ok" except DemistoException as e: if e.args[0] == "Error in API call [401] - Unauthorized": return_error("Failed to connect to IllusionBLACK. External API Token or Client Id might be invalid.") else: raise e def convert_to_demisto_severity(ib_severity="medium", tp_score_based=False, score=0): """ Converts the IllusionBLACK Threat Parse score for an attacker to demisto incident severity Args: ib_severity: IllusionBLACK severity. Some events do not have threat parse score. tp_score_based: If score is based on Threat Parse cumulative score score: The cumulative Threat Parse score Returns: The demisto incident severity ranging from 1 to 4 """ severity = 1 if tp_score_based: severity = score // 25 severity = max(severity, 1) severity = min(severity, 4) else: if ib_severity == "low": severity = 2 elif ib_severity == "medium": severity = 3 elif ib_severity == "high": severity = 4 return severity def process_events(events, threat_parse): """ Converts raw events and raw threat parse to demisto incidents based on common parameters. Args: events: Raw events from IllusionBLACK threat_parse: Raw Threat Parse from IllusionBLACK Returns: A list of raw incidents with data pertinent to demisto incident format. """ raw_incident_data: dict[str, Any] = {} for event in events: attacker_id = event.get("attacker.id", "") decoy_id = event.get("decoy.id", "") attack_type = event.get("type", "") ib_severity = event.get("severity") incident_id = "-".join(filter(None, [attacker_id, decoy_id, attack_type])).rstrip("-") title = f"{attack_type} activity by {attacker_id} on {decoy_id} decoy" tps = event.get("threat_parse_ids", []) score, is_tp = 0, False for tp in tps: is_tp = True score += threat_parse[tp]["score"] severity = convert_to_demisto_severity(ib_severity=ib_severity, tp_score_based=is_tp, score=score) raw_incident = raw_incident_data.setdefault( incident_id, { "events": [], "threat_parse_ids": [], "title": "", "severity": 1, "attack_type": "illusionblack_event", "attacker_id": "", "decoy_id": "", "source": "IllusionBLACK", }, ) raw_incident["events"].append(event["id"]) raw_incident["threat_parse_ids"].extend(tps) raw_incident["threat_parse_ids"] = list(set(raw_incident["threat_parse_ids"])) raw_incident["title"] = title raw_incident["severity"] = severity raw_incident["attack_type"] = attack_type raw_incident["attacker_id"] = attacker_id raw_incident["decoy_id"] = decoy_id return raw_incident_data def create_incident(raw_incident): """ Creates a demisto incident from a raw incident. Args: raw_incident: The data in the raw incident processed from raw events and Threat Parse from IllusionBLACK Returns: Demisto incident dict """ demisto.info(f"Severity is {raw_incident['severity']}") return {"name": raw_incident["title"], "severity": raw_incident["severity"], "rawJSON": json.dumps(raw_incident)} def fetch_incidents(first_fetch, client): """ Automated fetching of incidents from IllusionBLACK. For first run 2 days is the fixed duration for events. Args: first_fetch: For first fetch the timespan to consider to fetch incidents. Example: 2 days, 5 weeks etc client: IllusionBLACK client Returns: Demisto Incidents """ now = datetime.now(tz=UTC) demisto.info(f"IllusionBLACK: Fetching incidents at {now}") demisto_last_run = demisto.getLastRun() if "last_run" in demisto_last_run: last_run = datetime.fromisoformat(demisto_last_run["last_run"]) else: last_run, _ = parse_date_range(first_fetch) last_run = last_run.replace(tzinfo=UTC) if now - last_run < timedelta(minutes=5): return [] from_time = last_run.replace(microsecond=0).isoformat() to_time = now.replace(microsecond=0).isoformat() demisto.debug(f"IllusionBLACK: Getting raw events from {from_time} to {to_time}") events, all_threat_parse = client.get_events(limit=1000, from_time=from_time, to_time=to_time) raw_incidents = process_events(events, all_threat_parse) incidents = [] for _incident_id, raw_incident in raw_incidents.items(): incidents.append(create_incident(raw_incident)) demisto.setLastRun({"last_run": to_time}) return incidents def main(): client_id = demisto.params().get("client_id") token = demisto.params().get("token") base_url = urljoin(demisto.params()["url"], "/apiv1") verify_certificate = not demisto.params().get("insecure", False) proxy = demisto.params().get("proxy", False) LOG(f"Command being called is {demisto.command()}") try: client = Client(base_url=base_url, verify=verify_certificate, client_id=client_id, token=token, proxy=proxy) if demisto.command() == "test-module": # This is the call made when pressing the integration Test button. result = test_module(client) demisto.results(result) elif demisto.command() == "illusionblack-get-ad-decoys": return_outputs(*client.get_ad_decoys()) elif demisto.command() == "illusionblack-get-network-decoys": return_outputs(*client.get_network_decoys()) elif demisto.command() == "illusionblack-get-ti-decoys": return_outputs(*client.get_ti_decoys()) elif demisto.command() == "illusionblack-is-host-decoy": return_outputs(*client.is_host_decoy(demisto.args()["host"])) elif demisto.command() == "illusionblack-is-user-decoy": return_outputs(*client.is_user_decoy(demisto.args()["user"])) elif demisto.command() == "illusionblack-is-subdomain-decoy": return_outputs(*client.is_subdomain_decoy(demisto.args()["subdomain"])) elif demisto.command() == "illusionblack-get-events": args = demisto.args() events, _ = client.get_events(args.get("limit"), args.get("query"), args.get("from"), args.get("to")) return_outputs( tableToMarkdown("IllusionBLACK Events", events), {"IllusionBlack.Event(val.id==obj.id)": events}, events ) elif demisto.command() == "illusionblack-get-event-by-id": events, _ = client.get_events(query=f"id == \"{demisto.args()['id']}\"") if len(events) != 1: return_error("Invalid event ID") event = events[0] return_outputs( tableToMarkdown("IllusionBLACK Single Event", event), {"IllusionBlack.Event(val.id==obj.id)": event}, event ) elif demisto.command() == "fetch-incidents": demisto.incidents(fetch_incidents(demisto.params().get("first_fetch", "2 days"), client=client)) # Log exceptions except Exception as e: return_error(f"Failed to execute {demisto.command()} command. Error: {e!s}") if __name__ in ("__main__", "builtins"): main()