Details
| ID | iot-security-get-raci |
|---|---|
| Language | python |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Tags | iot |
README
IoT RACI model script
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | iot |
| Cortex XSOAR Version | 5.5.0 |
This script is using the device and incident attributes to evaluate the Responsible (R) and Informed (I) parties in the RACI model.
A list variable needs to be created with a fixed format JSON. You can create a new XSOAR list variable under Settings > Advanced > Lists.
By default, the name of the list variable is IOT_CONFIG.
There are three main sections in the JSON: devices, alerts, and groups.
| “devices” is a list of devices mapping to the owners based on the device_id, which is a concatenation of the device’s category, profile, vendor and model delimited by “ | ”. |
- device_id: a regular expression to match
- owner: a group name, which is also defined in the “groups” section
“alerts” is a list of conditions to map a combination of IoT incident type and incident names to the RACI model.
- iot_raw_type: either “IoT Alert” or “IoT Vulnerability”
- name_regex: a list of regular expressions trying to match with the alert/vulnerability names
- raci: a section to define the RACI model for the match. If the value is “IOT_OWNER”, we look up the underlying group using the mapping in “devices” section.
“groups” is all the groups found in the “devices” and “alerts” section.
- email: the email of the group, this is used when setting the incident owner in XSOAR or sending an email through the email integration
- snow: it has three fields, table, fields and custom_fields. Those are the fields when you use the official ServiceNow integration when you create a ServiceNow ticket.
Here is the template of the JSON:
{
"devices": [
{
"device_id": "Audio Streaming|Profusion.*",
"owner": "IT_AUDIO_VIDEO"
},
{
"device_id": "Camera|Avigilon Camera.*",
"owner": "PHYSICAL_SECURITY"
}
],
"alerts": [
{
"iot_raw_type": "IoT Alert",
"name_regex": [
"DOUBLEPULSAR.+",
"ECLIPSEDWING.+",
"ETERNALBLUE.+"
],
"raci": {
"r": "SOC",
"i": ["IOT_OWNER"]
}
},
{
"iot_raw_type": "IoT Vulnerability",
"raci": {
"r": "IOT_OWNER",
"i": ["INFOSEC", "SOC"]
}
}
],
"groups": {
"DEFAULT": {
"email": "default@example.com"
},
"SOC": {
"email": "soc@example.com"
},
"INFOSEC": {
"email": "infosec@example.com"
},
"IT_AUDIO_VIDEO": {
"email": "av@example.com",
"snow": {
"table": "incident",
"fields": {
"assignment_group": "98dae8874fd67348bf547fe24210c7a0"
},
"custom_fields": {
"u_custom_field1": "IT",
"u_category": "05b9e5371b3b08905f28fc43cd4bcbe2"
}
}
},
"PHYSICAL_SECURITY": {
"email": "security@example.com"
}
}
}
Used In
This script is used in the following playbooks and scripts.
- PANW IoT Incident Handling with ServiceNow
Inputs
| Argument Name | Description |
|---|---|
| alert_name | The name of the IoT alert. |
| raw_type | The raw type of the incident. |
| category | The device category. |
| profile | The device profile. |
| vendor | The device vendor. |
| model | The device model. |
| iot_config_list_name | The variable name for IOT_CONFIG. |
Outputs
| Path | Description | Type |
|---|---|---|
| PaloAltoNetworksIoT.RACI | The RACI model of the IoT incident | unknown |
| PaloAltoNetworksIoT.RACI.r | The responsible in the RACI model | string |
| PaloAltoNetworksIoT.RACI.r_email | The email of responsible in the RACI model | string |
| PaloAltoNetworksIoT.RACI.i | The informed in the RACI model | string |
| PaloAltoNetworksIoT.RACI.i_email | The emails of informed in the RACI model delimited by comma | string |
| PaloAltoNetworksIoT.RACI.owner | The IoT owner of the device | string |
| PaloAltoNetworksIoT.RACI.r_snow | The ServiceNow information of the incident responsible | string |
| PaloAltoNetworksIoT.RACI.r_snow.fields | The fields of the ServiceNow ticket | string |
| PaloAltoNetworksIoT.RACI.r_snow.custom_fields | The custom fields of the ServiceNow ticket | string |
| PaloAltoNetworksIoT.RACI.r_snow.table | The table of the ServiceNow ticket | string |
import iot_get_raci from iot_get_raci import get_raci _CONFIG = { "devices": [ {"device_id": "Audio Streaming|Profusion Media Player.*", "owner": "IT_AUDIO_VIDEO"}, {"device_id": "Camera|Avigilon Camera.*", "owner": "WPR_SECURITY"}, {"device_id": "category|profile|vendor|model", "owner": "IT_AUDIO_VIDEO"}, ], "alerts": [ { "iot_raw_type": "IoT Alert", "name_regex": [ "DOUBLEPULSAR.+", "ETERNALBLUE.+", "ETERNALROMANCE.+", "Excessive domain lookup failures with DGA usage", ".+flagged Internet host detected", "NETBIOS SMB ADMIN.+", "NotPetya.+", "PII transmission anomaly", "Remote access.+Windows Security Account Manager.+", "SamSam Testmanware SMB.+", "Win.Ransomware.+", ], "raci": {"r": "SOC", "i": ["IOT_OWNER"]}, }, { "iot_raw_type": "IoT Alert", "name_regex": [ "Excessive .+ server port range detected", ".+ external SMB port connections", "Inbound .+ connections from Internet", "Uncontrolled Internet access", ], "raci": {"r": "INFOSEC", "i": ["IOT_OWNER", "SOC"]}, }, {"iot_raw_type": "IoT Vulnerability", "raci": {"r": "IOT_OWNER", "i": ["INFOSEC", "SOC"]}}, ], "groups": { "DEFAULT": {"email": "default@example.com"}, "INFOSEC": {"email": "infosec@example.com"}, "IT_AUDIO_VIDEO": { "email": "itav@example.com", "snow": { "table": "incident", "fields": {"assignment_group": "itav_group_snow_id"}, "custom_fields": {"u_resolver_department": "IT", "u_category_5": "iot_category_snow_id"}, }, }, "SOC": {"email": "soc@example.com"}, "WPR_SECURITY": {"email": "wpr_security@example.com"}, }, } _CONFIG_WITHOUT_DEFAULT = { "devices": [{"device_id": "Audio Streaming|Profusion Media Player.*", "owner": "IT_AUDIO_VIDEO"}], "alerts": [{"iot_raw_type": "IoT Vulnerability", "raci": {"r": "IOT_OWNER", "i": ["INFOSEC", "SOC"]}}], "groups": {}, } _CONFIG_WITH_DEFAULT = { "devices": [{"device_id": "Audio Streaming|Profusion Media Player.*", "owner": "IT_AUDIO_VIDEO"}], "alerts": [{"iot_raw_type": "IoT Vulnerability", "raci": {"r": "IOT_OWNER", "i": ["INFOSEC", "SOC"]}}], "groups": {"DEFAULT": {"email": "default@example.com"}}, } def test_iot_get_raci_normal(monkeypatch): """ Scenario: getting the raci result in a normal case Given - A device with an IoT alert named "DOUBLEPULSAR Backdoor traffic" When - Calculating the RACI model result Then - Ensure the correct RACI model is calculated """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG) outputs = get_raci( { "alert_name": "DOUBLEPULSAR Backdoor traffic", "raw_type": "IoT Alert", "category": "Audio Streaming", "profile": "Profusion Media Player", } ).outputs assert outputs == { "owner": "IT_AUDIO_VIDEO", "r": "SOC", "r_email": "soc@example.com", "r_snow": None, "i": "IT_AUDIO_VIDEO", "i_email": "itav@example.com", } def test_iot_get_raci_no_default_email(monkeypatch): """ Scenario: checking the responsiblie email is None if a default email is missing in IOT_CONFIG Given - A device with an IoT Vulnerability When - Calculating the RACI model result Then - Ensure the r_email is None even though r is not None """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG_WITHOUT_DEFAULT) outputs = get_raci( {"alert_name": "", "raw_type": "IoT Vulnerability", "category": "Audio Streaming", "profile": "Profusion Media Player"} ).outputs assert outputs == { "owner": "IT_AUDIO_VIDEO", "r": "IT_AUDIO_VIDEO", "r_email": None, "r_snow": None, "i": "INFOSEC, SOC", "i_email": None, } def test_iot_get_raci_default_email(monkeypatch): """ Scenario: checking the responsiblie email is the default one specified in IOT_CONFIG Given - A device with an IoT Vulnerability When - Calculating the RACI model result Then - Ensure the r_email is the default email in IOT_CONFIG """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG_WITH_DEFAULT) outputs = get_raci( {"alert_name": "", "raw_type": "IoT Vulnerability", "category": "Audio Streaming", "profile": "Profusion Media Player"} ).outputs assert outputs == { "owner": "IT_AUDIO_VIDEO", "r": "IT_AUDIO_VIDEO", "r_email": "default@example.com", "r_snow": None, "i": "INFOSEC, SOC", "i_email": "default@example.com, default@example.com", } def test_iot_get_raci_no_name_regex(monkeypatch): """ Scenario: checking the IOT_CONFIG is working without the name regex in the "alerts" section of the JSON Given - A device with an IoT Vulnerability When - Calculating the RACI model result Then - Ensure the r is correct """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG) outputs = get_raci({"alert_name": "FooBar", "raw_type": "IoT Vulnerability", "category": "Foo"}).outputs assert outputs == { "owner": None, "r": None, "r_email": None, "r_snow": None, "i": "INFOSEC, SOC", "i_email": "infosec@example.com, soc@example.com", } outputs = get_raci( {"alert_name": "FooBar", "raw_type": "IoT Vulnerability", "category": "Camera", "profile": "Avigilon Camera"} ).outputs assert outputs == { "owner": "WPR_SECURITY", "r": "WPR_SECURITY", "r_email": "wpr_security@example.com", "r_snow": None, "i": "INFOSEC, SOC", "i_email": "infosec@example.com, soc@example.com", } def test_iot_snow(monkeypatch): """ Scenario: checking the ServiceNow config is returned from the IOT_CONFIG Given - A device with an IoT Vulnerability When - Calculating the RACI model result Then - Ensure the r_snow is returned """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG) outputs = get_raci( { "alert_name": "FooBar", "raw_type": "IoT Vulnerability", "category": "Audio Streaming", "profile": "Profusion Media Player", } ).outputs assert outputs == { "owner": "IT_AUDIO_VIDEO", "r": "IT_AUDIO_VIDEO", "r_email": "itav@example.com", "r_snow": { "custom_fields": "u_resolver_department=IT;u_category_5=iot_category_snow_id", "fields": "assignment_group=itav_group_snow_id", "table": "incident", }, "i": "INFOSEC, SOC", "i_email": "infosec@example.com, soc@example.com", } def test_iot_get_raci_no_raci(monkeypatch): """ Scenario: checking the case of missing the group defined in IOT_CONFIG Given - A device with an owner WPR_SECURITY, and its email is not listed When - Calculating the RACI model result Then - Ensure the code is still returning the raci """ monkeypatch.setattr(iot_get_raci, "get_iot_config", lambda x: _CONFIG) outputs = get_raci( {"alert_name": "FooBar", "raw_type": "IoT Alert", "category": "Camera", "profile": "Avigilon Camera"} ).outputs assert outputs == {"owner": "WPR_SECURITY", "r": None, "r_email": None, "r_snow": None, "i": None, "i_email": None}