Details
| ID | XDome |
|---|---|
| Provider | Claroty |
| Category | Network Security |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10404775 |
| Supported Modules | Agentix XSIAM |
README
Use the xDome integration to manage assets and alerts.
This integration was integrated and tested with version 1.0.0 of XDome.
Configure xDome in Cortex
| Parameter | Description | Required |
|---|---|---|
| XDome public API base URL | True | |
| API Token | The API token to use for connection | True |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| The initial time to fetch from | True | |
| Fetch Only Unresolved Device-Alert Pairs | False | |
| Alert Types Selection | If no alert types are selected, all types will be fetched | 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.
xdome-get-device-alert-relations
Gets all device-alert pairs from xDome. You can apply a query-filter.
Base Command
xdome-get-device-alert-relations
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Fields to return. Possible values are: all, alert_assignees, alert_category, alert_class, alert_id, alert_labels, alert_name, alert_type_name, alert_description, device_alert_detected_time, device_alert_status, device_alert_updated_time, device_assignees, device_category, device_effective_likelihood_subscore, device_effective_likelihood_subscore_points, device_first_seen_list, device_impact_subscore, device_impact_subscore_points, device_insecure_protocols, device_insecure_protocols_points, device_internet_communication, device_ip_list, device_known_vulnerabilities, device_known_vulnerabilities_points, device_labels, device_last_seen_list, device_likelihood_subscore, device_likelihood_subscore_points, device_mac_list, device_manufacturer, device_name, device_network_list, device_purdue_level, device_retired, device_risk_score, device_risk_score_points, device_site_name, device_subcategory, device_type, device_uid, mitre_technique_enterprise_ids, mitre_technique_enterprise_names, mitre_technique_ics_ids, mitre_technique_ics_names. Default is all. | Optional |
| filter_by | A filter_by object, refer to the xDome API documentation. | Optional |
| offset | An offset in the data. This can be used to fetch all data in a paginated manner, by e.g requesting (offset=0, limit=100) followed by (offset=100, limit=100), (offset=200, limit=100), etc. | Optional |
| limit | Maximum amount of items to fetch. | Optional |
| sort_by | Default: [{“field”:”device_uid”,”order”:”asc”},{“field”:”alert_id”,”order”:”asc”}]. Specifies how the returned data should be sorted. If more than one sort clause is passed, additional clauses will be used to sort data that is equal in all previous clauses. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| XDome.DeviceAlert.alert_id | Number | Platform unique Alert ID. |
| XDome.DeviceAlert.alert_name | String | The alert name, such as “Malicious Internet Communication: 62.172.138.35”. |
| XDome.DeviceAlert.alert_type_name | String | An alert type such as “Outdated Firmware”. |
| XDome.DeviceAlert.alert_class | String | The alert class, such as “Pre-Defined Alerts” and “Custom Alerts”. |
| XDome.DeviceAlert.alert_category | String | Alert category such as “Risk” or “Segmentation”. |
| XDome.DeviceAlert.alert_labels | String | The labels added to the alert manually or automatically. |
| XDome.DeviceAlert.alert_assignees | String | The users and or groups the alert is assigned to. |
| XDome.DeviceAlert.alert_description | String | The alert description, such as “SMBv1 Communication was detected by 2 OT Device devices”. |
| XDome.DeviceAlert.device_alert_detected_time | Date | Date and time when the Alert was first detected. |
| XDome.DeviceAlert.device_alert_updated_time | Date | Date and time of last Alert update. |
| XDome.DeviceAlert.device_alert_status | String | Device-Alert relation status (Resolved or Unresolved). |
| XDome.DeviceAlert.device_uid | UUID | A universal unique identifier (UUID) for the device. |
| XDome.DeviceAlert.device_name | String | The Device Name attribute is set automatically based on the priority of the Auto-Assigned Device attribute. You can also set it manually. The Device Name can be the device’s IP, hostname, etc. |
| XDome.DeviceAlert.device_ip_list | List | IP address associated with the device. IPs may be suffixed by a / (annotation), where annotation may be a child device ID or (Last Known IP). |
| XDome.DeviceAlert.device_mac_list | List | MAC address associated with the device. |
| XDome.DeviceAlert.device_network_list | List | The network types, “Corporate” and or “Guest”, that the device belongs to. |
| XDome.DeviceAlert.device_category | String | The device category group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceAlert.device_subcategory | String | The device sub-category group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceAlert.device_type | String | The device type group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceAlert.device_assignees | String | The users and or groups the device is assigned to. |
| XDome.DeviceAlert.device_labels | String | The labels added to the device manually or automatically. |
| XDome.DeviceAlert.device_retired | String | A boolean field indicating if the device is retired or not. |
| XDome.DeviceAlert.device_purdue_level | String | The network layer the device belongs to, based on the Purdue Reference Model for Industrial Control System (ICS). The network segmentation-based model defines OT and IT systems into six levels and the logical network boundary controls for securing these networks. |
| XDome.DeviceAlert.device_site_name | String | The name of the site within the organization the device is associated with. |
| XDome.DeviceAlert.device_first_seen_list | List | The date and time a device’s NIC was first seen. |
| XDome.DeviceAlert.device_last_seen_list | List | The date and time a device’s NIC was last seen. |
| XDome.DeviceAlert.device_risk_score | String | The calculated risk level of a device, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_risk_score_points | Number | The calculated risk points of a device, such as “54.1”. |
| XDome.DeviceAlert.device_effective_likelihood_subscore | String | The calculated effective likelihood subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_effective_likelihood_subscore_points | Number | The calculated effective likelihood subscore points of a device, such as “54.1”. |
| XDome.DeviceAlert.device_likelihood_subscore | String | The calculated likelihood subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_likelihood_subscore_points | Number | The calculated likelihood subscore points of a device, such as “54.1”. |
| XDome.DeviceAlert.device_impact_subscore | String | The calculated impact subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_impact_subscore_points | Number | The calculated impact subscore points of a device, such as “54.1”. |
| XDome.DeviceAlert.device_insecure_protocols | String | The calculated level of the device’s ‘insecure protocols’ likelihood factor, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_insecure_protocols_points | Number | The calculated points for ‘insecure protocols’ likelihood factor of a device, such as “54.1”. |
| XDome.DeviceAlert.device_internet_communication | String | The manner of the device’s communication over the internet. |
| XDome.DeviceAlert.device_known_vulnerabilities | String | The calculated level of the device’s ‘known vulnerabilities’ likelihood factor, such as “Critical”, or “High”. |
| XDome.DeviceAlert.device_known_vulnerabilities_points | Number | The calculated points for ‘known vulnerabilities’ likelihood factor of a device, such as “54.1”. |
| XDome.DeviceAlert.device_manufacturer | String | Manufacturer of the device, such as “Alaris”. |
| XDome.DeviceAlert.mitre_technique_enterprise_ids | List | MITRE ATT&CK® Enterprise technique IDs mapped to the alert. |
| XDome.DeviceAlert.mitre_technique_enterprise_names | List | MITRE ATT&CK® Enterprise technique names mapped to the alert. |
| XDome.DeviceAlert.mitre_technique_ics_ids | List | MITRE ATT&CK® ICS technique IDs mapped to the alert. |
| XDome.DeviceAlert.mitre_technique_ics_names | List | MITRE ATT&CK® ICS technique names mapped to the alert. |
xdome-set-status-for-device-alert-relations
Set device-alert status to resolved or unresolved.
Base Command
xdome-set-status-for-device-alert-relations
Input
| Argument Name | Description | Required |
|---|---|---|
| alert_id | Alert ID, as indicated in the id field of an alert. | Required |
| device_uids | Device UUIDs, as indicated in the uid field of a device. | Optional |
| status | Set the device-alert status to resolve or unresolved. Possible values are: resolved, unresolved. | Required |
Context Output
There is no context output for this command.
xdome-get-device-vulnerability-relations
Get details of devices with their related vulnerabilities from the database. The data returned by this endpoint for each device corresponds to the vulnerabilities table in the single device page.
Base Command
xdome-get-device-vulnerability-relations
Input
| Argument Name | Description | Required |
|---|---|---|
| fields | Fields to return. Possible values are: all, device_network_list, device_category, device_subcategory, device_type, device_uid, device_asset_id, device_mac_list, device_ip_list, device_type_family, device_model, device_os_category, device_serial_number, device_vlan_list, device_retired, device_labels, device_assignees, device_hw_version, device_local_name, device_os_name, device_os_version, device_os_revision, device_os_subcategory, device_combined_os, device_endpoint_security_names, device_equipment_class, device_consequence_of_failure, device_management_services, device_ad_distinguished_name, device_ad_description, device_mdm_ownership, device_mdm_enrollment_status, device_mdm_compliance_status, device_last_domain_user, device_fda_class, device_mobility, device_purdue_level, device_purdue_level_source, device_dhcp_hostnames, device_http_hostnames, device_snmp_hostnames, device_windows_hostnames, device_other_hostnames, device_windows_last_seen_hostname, device_dhcp_last_seen_hostname, device_http_last_seen_hostname, device_snmp_last_seen_hostname, device_ae_titles, device_dhcp_fingerprint, device_note, device_domains, device_battery_level, device_internet_communication, device_financial_cost, device_handles_pii, device_machine_type, device_phi, device_cmms_state, device_cmms_ownership, device_cmms_asset_tag, device_cmms_campus, device_cmms_building, device_cmms_location, device_cmms_floor, device_cmms_department, device_cmms_owning_cost_center, device_cmms_asset_purchase_cost, device_cmms_room, device_cmms_manufacturer, device_cmms_model, device_cmms_serial_number, device_cmms_last_pm, device_cmms_technician, device_edr_is_up_to_date_text, device_mac_oui_list, device_ip_assignment_list, device_protocol_location_list, device_vlan_name_list, device_vlan_description_list, device_connection_type_list, device_ssid_list, device_bssid_list, device_wireless_encryption_type_list, device_ap_name_list, device_ap_location_list, device_switch_mac_list, device_switch_ip_list, device_switch_name_list, device_switch_port_list, device_switch_location_list, device_switch_port_description_list, device_wlc_name_list, device_wlc_location_list, device_applied_acl_list, device_applied_acl_type_list, device_collection_servers, device_edge_locations, device_number_of_nics, device_last_domain_user_activity, device_last_scan_time, device_edr_last_scan_time, device_retired_since, device_os_eol_date, device_last_seen_list, device_first_seen_list, device_wifi_last_seen_list, device_last_seen_on_switch_list, device_is_online, device_network_scope_list, device_ise_authentication_method_list, device_ise_endpoint_profile_list, device_ise_identity_group_list, device_ise_security_group_name_list, device_ise_security_group_tag_list, device_ise_logical_profile_list, device_cppm_authentication_status_list, device_cppm_roles_list, device_cppm_service_list, device_name, device_manufacturer, device_site_name, device_risk_score, device_risk_score_points, device_effective_likelihood_subscore, device_effective_likelihood_subscore_points, device_likelihood_subscore, device_likelihood_subscore_points, device_impact_subscore, device_impact_subscore_points, device_known_vulnerabilities, device_known_vulnerabilities_points, device_insecure_protocols, device_insecure_protocols_points, device_suspicious, device_switch_group_name_list, device_managed_by, device_authentication_user_list, device_collection_interfaces, device_slot_cards, device_cmms_financial_cost, device_software_or_firmware_version, device_enforcement_or_authorization_profiles_list, device_ise_security_group_description_list, device_recommended_firewall_group_name, device_recommended_zone_name, vulnerability_id, vulnerability_name, vulnerability_type, vulnerability_cve_ids, vulnerability_cvss_v2_score, vulnerability_cvss_v2_exploitability_subscore, vulnerability_cvss_v3_score, vulnerability_cvss_v3_exploitability_subscore, vulnerability_adjusted_vulnerability_score, vulnerability_adjusted_vulnerability_score_level, vulnerability_epss_score, vulnerability_sources, vulnerability_description, vulnerability_affected_products, vulnerability_recommendations, vulnerability_exploits_count, vulnerability_is_known_exploited, vulnerability_published_date, vulnerability_labels, vulnerability_assignees, vulnerability_note, vulnerability_last_updated, vulnerability_relevance, vulnerability_relevance_sources, vulnerability_manufacturer_remediation_info, vulnerability_manufacturer_remediation_info_source, vulnerability_overall_cvss_v3_score, device_vulnerability_detection_date, device_vulnerability_resolution_date, device_vulnerability_days_to_resolution, patch_install_date. Default is all. | Optional |
| filter_by | A filter_by object, refer to the xDome API documentation. Input as a string and dont forget to escape quotes ("). | Optional |
| sort_by | Default: [{“field”:”device_uid”,”order”:”asc”}, {“field”:”vulnerability_id”,”order”:”asc”}]. Specifies how the returned data should be sorted. If more than one sort clause is passed, additional clauses will be used to sort data that is equal in all previous clauses. | Optional |
| offset | An offset in the data. This can be used to fetch all data in a paginated manner, by e.g requesting (offset=0, limit=100) followed by (offset=100, limit=100), (offset=200, limit=100), etc. | Optional |
| limit | Maximum amount of items to fetch. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| XDome.DeviceVulnerability.vulnerability_name | String | Name designated by Claroty’s Research team, based on the advisory name or CVE ID. |
| XDome.DeviceVulnerability.vulnerability_type | String | Type such as “Application”, “Clinical”, “IoT” or “Platform”. |
| XDome.DeviceVulnerability.vulnerability_cve_ids | List | Relevant Common Vulnerability Exploits for the selected vulnerability. |
| XDome.DeviceVulnerability.vulnerability_cvss_v3_score | Number | Common Vulnerability Scoring System Version 3 score (0-10). In case of multiple CVEs, the highest Subscore is displayed. |
| XDome.DeviceVulnerability.vulnerability_adjusted_vulnerability_score | Number | The Adjusted Vulnerability Score represents the vulnerability score based on its impact and exploitability. |
| XDome.DeviceVulnerability.vulnerability_adjusted_vulnerability_score_level | String | The calculated Adjusted vulnerability Score (AVS) level of a vulnerability, such as “Critical”, or “High”. |
| XDome.DeviceVulnerability.vulnerability_epss_score | Number | A probability score between 0 to 1 indicating the likelihoodof a vulnerability to be exploited in the wild, based on the Exploit Prediction Scoring System (EPSS) model. |
| XDome.DeviceVulnerability.vulnerability_description | String | Details about the vulnerability. |
| XDome.DeviceVulnerability.vulnerability_exploits_count | Number | An aggregated numeric field of the number of known exploits based on ExploitDB. |
| XDome.DeviceVulnerability.vulnerability_is_known_exploited | Boolean | A boolean field indicating whether a vulnerability is currently exploited in-the-wild, based on the CISA Catalog of Known Exploited Vulnerabilities. |
| XDome.DeviceVulnerability.vulnerability_published_date | Date | The date and time the vulnerability was released. |
| XDome.DeviceVulnerability.vulnerability_relevance | String | The device vulnerability relevance reflects the confidence level of the detection process, corresponding to several components, such as the vulnerability type. |
| XDome.DeviceVulnerability.device_vulnerability_detection_date | Date | The date when the vulnerability was initially detected on the device. A vulnerability is considered detected once marked as “confirmed” or “potentially relevant” for the respective device. |
| XDome.DeviceVulnerability.device_network_list | List | The network types, “Corporate” and or “Guest”, that the device belongs to. |
| XDome.DeviceVulnerability.device_category | String | The device category group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceVulnerability.device_subcategory | String | The device sub-category group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceVulnerability.device_type | String | The device type group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceVulnerability.device_uid | String | A universal unique identifier (UUID) for the device. |
| XDome.DeviceVulnerability.device_asset_id | String | Asset ID. |
| XDome.DeviceVulnerability.device_mac_list | List | MAC address associated with the device. |
| XDome.DeviceVulnerability.device_ip_list | List | IP address associated with the device. IPs may be suffixed by a / (annotation), where annotation may be a child device ID or (Last Known IP). |
| XDome.DeviceVulnerability.device_type_family | String | The device type family group (see “About Device Categorization” in the Knowledge Base). |
| XDome.DeviceVulnerability.device_model | String | The device’s model. |
| XDome.DeviceVulnerability.device_os_category | String | The device’s OS category, such as “Windows”, “Linux” or “Other”. |
| XDome.DeviceVulnerability.device_serial_number | String | The device’s serial number. |
| XDome.DeviceVulnerability.device_vlan_list | List | The virtual LAN to which the device belongs. |
| XDome.DeviceVulnerability.device_labels | List | The labels added to the device manually or automatically. |
| XDome.DeviceVulnerability.device_assignees | List | The users and or groups the device is assigned to. |
| XDome.DeviceVulnerability.device_hw_version | String | The hardware version of the device. |
| XDome.DeviceVulnerability.device_local_name | String | Similar to hostname, the device name identifier is extracted from protocol traffic. |
| XDome.DeviceVulnerability.device_combined_os | String | The aggregated value of OS name, version and revision, such as “Windows XP SP3”. |
| XDome.DeviceVulnerability.device_endpoint_security_names | List | The names of endpoint security applications installed on the device. |
| XDome.DeviceVulnerability.device_equipment_class | String | Determines the equipment class of the device, according to The Joint Commission (TJC). |
| XDome.DeviceVulnerability.device_management_services | String | Defines whether the device is managed by Active Directory, Mobile Device Management, or neither. |
| XDome.DeviceVulnerability.device_purdue_level | String | The network layer the device belongs to, based on the Purdue Reference Model for Industrial Control System (ICS). The network segmentation-based model defines OT and IT systems into six levels and the logical network boundary controls for securing these networks. |
| XDome.DeviceVulnerability.device_http_last_seen_hostname | String | The most recent unique hostname identifier of the device, extracted from HTTP protocol traffic. |
| XDome.DeviceVulnerability.device_snmp_last_seen_hostname | String | The most recent unique hostname identifier of the device, extracted from SNMP protocol traffic. |
| XDome.DeviceVulnerability.device_note | String | The notes added to the device. |
| XDome.DeviceVulnerability.device_domains | List | The domain name of the network that the device belongs to. |
| XDome.DeviceVulnerability.device_internet_communication | String | The manner of the device’s communication over the internet. |
| XDome.DeviceVulnerability.device_edr_is_up_to_date_text | String | Determines whether the endpoint security application installed on the device is up-to-date. |
| XDome.DeviceVulnerability.device_mac_oui_list | List | The vendor of the device’s NIC, according to the OUI (Organizational Unique Identifier) in the MAC address. |
| XDome.DeviceVulnerability.device_ip_assignment_list | List | The device’s IP assignment method, extracted from DHCP protocol traffic, such as “DHCP”, “DHCP (Static Lease)”, or “Static”. |
| XDome.DeviceVulnerability.device_vlan_name_list | List | The name of the VLAN, extracted from switch configurations. |
| XDome.DeviceVulnerability.device_vlan_description_list | List | The description of the VLAN, extracted from switch configurations. |
| XDome.DeviceVulnerability.device_connection_type_list | List | The connection types of a device, such as “Ethernet”. |
| XDome.DeviceVulnerability.device_ssid_list | List | The name of the wireless network the device is connected to, such as “Guest”. |
| XDome.DeviceVulnerability.device_ap_location_list | List | The location of the access point the device is connected to, extracted from Network Management integrations. |
| XDome.DeviceVulnerability.device_switch_port_list | List | The port identifier of the switch the device is connected to. |
| XDome.DeviceVulnerability.device_switch_location_list | List | The location of the switch the device is connected to. |
| XDome.DeviceVulnerability.device_number_of_nics | Number | The number of network interface cards seen on the network. |
| XDome.DeviceVulnerability.device_last_seen_list | List | The date and time a device’s NIC was last seen. |
| XDome.DeviceVulnerability.device_first_seen_list | List | The date and time a device’s NIC was first seen. |
| XDome.DeviceVulnerability.device_is_online | Boolean | A boolean field indicating whether the device is online or not. |
| XDome.DeviceVulnerability.device_network_scope_list | List | The device’s Network Scope - used to differentiate between internal networks that share the same IP subnets. |
| XDome.DeviceVulnerability.device_name | String | The Device Name attribute is set automatically based on the priority of the Auto-Assigned Device attribute. You can also set it manually. The Device Name can be the device’s IP, hostname, etc. |
| XDome.DeviceVulnerability.device_manufacturer | String | Manufacturer of the device, such as “Alaris”. |
| XDome.DeviceVulnerability.device_site_name | String | The name of the site within the healthcare organization the device is associated with. |
| XDome.DeviceVulnerability.device_risk_score | String | The calculated risk level of a device, such as “Critical”, or “High”. |
| XDome.DeviceVulnerability.device_risk_score_points | Number | The calculated risk points of a device, such as “54.1”. |
| XDome.DeviceVulnerability.device_effective_likelihood_subscore | String | The calculated effective likelihood subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceVulnerability.device_effective_likelihood_subscore_points | Number | The calculated effective likelihood subscore points of a device, such as “54.1”. |
| XDome.DeviceVulnerability.device_likelihood_subscore | String | The calculated likelihood subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceVulnerability.device_likelihood_subscore_points | Number | The calculated likelihood subscore points of a device, such as “54.1”. |
| XDome.DeviceVulnerability.device_impact_subscore | String | The calculated impact subscore level of a device, such as “Critical”, or “High”. |
| XDome.DeviceVulnerability.device_impact_subscore_points | Number | The calculated impact subscore points of a device, such as “54.1”. |
| XDome.DeviceVulnerability.device_suspicious | List | The reasons for which the device was marked as suspicious. |
| XDome.DeviceVulnerability.device_authentication_user_list | List | The User name used to authenticate the device to the network using Radius/802.1x is extracted from the NAC integration and the traffic. |
| XDome.DeviceVulnerability.device_software_or_firmware_version | String | The application version running on the device. |
Configuration parameters
isFetch— Fetch incidentsincidentType— Incident typeincidentFetchInterval— Incidents Fetch Intervalurl— XDome API Base URL (required)credentials— (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingsfirst_fetch— Initial Incidents Fetch Timemax_fetch— Maximum number of incidents per fetchfetch_only_unresolved— Fetch Only Unresolved Device-Alert Pairsalert_types— Alert Types Selection
Commands (3)
-
xdome-get-device-alert-relationsGets all device-alert pairs from xDome. You can apply a query-filter.
-
xdome-get-device-vulnerability-relationsGet details of devices with their related vulnerabilities from the database. The data returned by this endpoint for each device corresponds to the vulnerabilities table in the single device page.
-
xdome-set-status-for-device-alert-relationsSet device-alert status to resolved or unresolved.
import abc from collections.abc import Callable, Collection from datetime import datetime, timedelta from typing import Any, TypeAlias import dateparser import demistomock as demisto # noqa: F401 import urllib3 from CommonServerPython import * # noqa: F401 from CommonServerUserPython import * # noqa # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # ISO8601 format with UTC, default in XSOAR SMALLEST_TIME_UNIT = timedelta(seconds=1) MAX_REQUEST_LIMIT = 5_000 DEFAULT_REQUEST_LIMIT = 1_000 MAX_FETCH_LIMIT = 50_000 DEFAULT_FETCH_LIMIT = 50_000 DEVICE_ALERT_FIELDS = { "alert_assignees", "alert_category", "alert_class", "alert_id", "alert_labels", "alert_name", "alert_type_name", "alert_description", "device_alert_detected_time", "device_alert_status", "device_alert_updated_time", "device_assignees", "device_category", "device_effective_likelihood_subscore", "device_effective_likelihood_subscore_points", "device_first_seen_list", "device_impact_subscore", "device_impact_subscore_points", "device_insecure_protocols", "device_insecure_protocols_points", "device_internet_communication", "device_ip_list", "device_known_vulnerabilities", "device_known_vulnerabilities_points", "device_labels", "device_last_seen_list", "device_likelihood_subscore", "device_likelihood_subscore_points", "device_mac_list", "device_manufacturer", "device_name", "device_network_list", "device_purdue_level", "device_retired", "device_risk_score", "device_risk_score_points", "device_site_name", "device_subcategory", "device_type", "device_uid", "mitre_technique_enterprise_ids", "mitre_technique_enterprise_names", "mitre_technique_ics_ids", "mitre_technique_ics_names", } DEVICE_VULNERABILITY_FIELDS = { "device_network_list", "device_category", "device_subcategory", "device_type", "device_uid", "device_asset_id", "device_mac_list", "device_ip_list", "device_type_family", "device_model", "device_os_category", "device_serial_number", "device_vlan_list", "device_retired", "device_labels", "device_assignees", "device_hw_version", "device_local_name", "device_os_name", "device_os_version", "device_os_revision", "device_os_subcategory", "device_combined_os", "device_endpoint_security_names", "device_equipment_class", "device_consequence_of_failure", "device_management_services", "device_ad_distinguished_name", "device_ad_description", "device_mdm_ownership", "device_mdm_enrollment_status", "device_mdm_compliance_status", "device_last_domain_user", "device_fda_class", "device_mobility", "device_purdue_level", "device_purdue_level_source", "device_dhcp_hostnames", "device_http_hostnames", "device_snmp_hostnames", "device_windows_hostnames", "device_other_hostnames", "device_windows_last_seen_hostname", "device_dhcp_last_seen_hostname", "device_http_last_seen_hostname", "device_snmp_last_seen_hostname", "device_ae_titles", "device_dhcp_fingerprint", "device_note", "device_domains", "device_battery_level", "device_internet_communication", "device_financial_cost", "device_handles_pii", "device_machine_type", "device_phi", "device_cmms_state", "device_cmms_ownership", "device_cmms_asset_tag", "device_cmms_campus", "device_cmms_building", "device_cmms_location", "device_cmms_floor", "device_cmms_department", "device_cmms_owning_cost_center", "device_cmms_asset_purchase_cost", "device_cmms_room", "device_cmms_manufacturer", "device_cmms_model", "device_cmms_serial_number", "device_cmms_last_pm", "device_cmms_technician", "device_edr_is_up_to_date_text", "device_mac_oui_list", "device_ip_assignment_list", "device_protocol_location_list", "device_vlan_name_list", "device_vlan_description_list", "device_connection_type_list", "device_ssid_list", "device_bssid_list", "device_wireless_encryption_type_list", "device_ap_name_list", "device_ap_location_list", "device_switch_mac_list", "device_switch_ip_list", "device_switch_name_list", "device_switch_port_list", "device_switch_location_list", "device_switch_port_description_list", "device_wlc_name_list", "device_wlc_location_list", "device_applied_acl_list", "device_applied_acl_type_list", "device_collection_servers", "device_edge_locations", "device_number_of_nics", "device_last_domain_user_activity", "device_last_scan_time", "device_edr_last_scan_time", "device_retired_since", "device_os_eol_date", "device_last_seen_list", "device_first_seen_list", "device_wifi_last_seen_list", "device_last_seen_on_switch_list", "device_is_online", "device_network_scope_list", "device_ise_authentication_method_list", "device_ise_endpoint_profile_list", "device_ise_identity_group_list", "device_ise_security_group_name_list", "device_ise_security_group_tag_list", "device_ise_logical_profile_list", "device_cppm_authentication_status_list", "device_cppm_roles_list", "device_cppm_service_list", "device_name", "device_manufacturer", "device_site_name", "device_risk_score", "device_risk_score_points", "device_effective_likelihood_subscore", "device_effective_likelihood_subscore_points", "device_likelihood_subscore", "device_likelihood_subscore_points", "device_impact_subscore", "device_impact_subscore_points", "device_known_vulnerabilities", "device_known_vulnerabilities_points", "device_insecure_protocols", "device_insecure_protocols_points", "device_suspicious", "device_switch_group_name_list", "device_managed_by", "device_authentication_user_list", "device_collection_interfaces", "device_slot_cards", "device_cmms_financial_cost", "device_software_or_firmware_version", "device_enforcement_or_authorization_profiles_list", "device_ise_security_group_description_list", "device_recommended_firewall_group_name", "device_recommended_zone_name", "vulnerability_id", "vulnerability_name", "vulnerability_type", "vulnerability_cve_ids", "vulnerability_cvss_v2_score", "vulnerability_cvss_v2_exploitability_subscore", "vulnerability_cvss_v3_score", "vulnerability_cvss_v3_exploitability_subscore", "vulnerability_adjusted_vulnerability_score", "vulnerability_adjusted_vulnerability_score_level", "vulnerability_epss_score", "vulnerability_sources", "vulnerability_description", "vulnerability_affected_products", "vulnerability_recommendations", "vulnerability_exploits_count", "vulnerability_is_known_exploited", "vulnerability_published_date", "vulnerability_labels", "vulnerability_assignees", "vulnerability_note", "vulnerability_last_updated", "vulnerability_relevance", "vulnerability_relevance_sources", "vulnerability_manufacturer_remediation_info", "vulnerability_manufacturer_remediation_info_source", "vulnerability_overall_cvss_v3_score", "device_vulnerability_detection_date", "device_vulnerability_resolution_date", "device_vulnerability_days_to_resolution", "patch_install_date", } INCIDENT_TIMESTAMP_FIELD = "device_alert_updated_time" QueryFilterType: TypeAlias = dict[str, Any] """ CLIENT CLASS """ class Client(BaseClient): """Client class to interact with the service API This Client implements API calls, and does not contain any XSOAR logic. Should only do requests and return data. It inherits from BaseClient defined in CommonServer Python. Most calls use _http_request() that handles proxy, SSL verification, etc. For this implementation, no special attributes defined """ def _force_get_all_wrapper( self, paginated_getter_func: Callable, items_name: str, fields: Collection[str], filter_by: QueryFilterType | None = None, sort_by: list[dict] | None = None, stop_after: int | None = None, start_from: int | None = None, ) -> list[dict]: offset = start_from or 0 batch_size = MAX_REQUEST_LIMIT result = paginated_getter_func( fields=fields, filter_by=filter_by, offset=offset, limit=batch_size, sort_by=sort_by, count=True ) last_fetched_items = result.get(items_name, []) all_items = last_fetched_items while (res_cnt := len(last_fetched_items)) >= batch_size and (stop_after is None or len(all_items) < stop_after): offset += res_cnt result = paginated_getter_func( fields=fields, filter_by=filter_by, offset=offset, limit=batch_size, sort_by=sort_by, count=True ) last_fetched_items = result.get(items_name, []) all_items.extend(last_fetched_items) return all_items[:stop_after] if stop_after is not None else all_items def get_device_alert_relations( self, fields: Collection[str], filter_by: QueryFilterType | None = None, offset: int = 0, limit: int = DEFAULT_REQUEST_LIMIT, sort_by: list[dict] | None = None, count: bool = False, ) -> dict: body = {"offset": offset, "limit": limit, "fields": list(fields), "include_count": count} if filter_by: body["filter_by"] = filter_by if sort_by: body["sort_by"] = sort_by return self._http_request("POST", url_suffix="device_alert_relations/", json_data=body) def get_device_vulnerability_relations( self, fields: Collection[str], filter_by: QueryFilterType | None = None, offset: int = 0, limit: int = DEFAULT_REQUEST_LIMIT, sort_by: list[dict] | None = None, count: bool = False, ) -> dict: body = {"offset": offset, "limit": limit, "fields": list(fields), "include_count": count} if filter_by: body["filter_by"] = filter_by if sort_by: body["sort_by"] = sort_by return self._http_request("POST", url_suffix="device_vulnerability_relations/", json_data=body) def force_get_all_device_vulnerability_relations( self, fields: Collection[str], filter_by: QueryFilterType | None = None, sort_by: list[dict] | None = None, stop_after: int | None = None, start_from: int | None = None, ) -> list[dict]: return self._force_get_all_wrapper( paginated_getter_func=self.get_device_vulnerability_relations, items_name="devices_vulnerabilities", fields=fields, filter_by=filter_by, sort_by=sort_by, stop_after=stop_after, start_from=start_from, ) def force_get_all_device_alert_relations( self, fields: Collection[str], filter_by: QueryFilterType | None = None, sort_by: list[dict] | None = None, stop_after: int | None = None, start_from: int | None = None, ) -> list[dict]: return self._force_get_all_wrapper( paginated_getter_func=self.get_device_alert_relations, items_name="devices_alerts", fields=fields, filter_by=filter_by, sort_by=sort_by, stop_after=stop_after, start_from=start_from, ) def set_device_single_alert_relations(self, alert_id: int, device_uids: list[str] | None, status: str) -> dict | None: devices_uids_filter = _simple_filter("uid", "in", device_uids) if device_uids else None return self.set_device_alert_relations([alert_id], devices_uids_filter, status) def set_device_alert_relations(self, alert_ids: list[int], device_filter_by: dict | None, status: str) -> dict: body = {"alerts": {"alert_ids": alert_ids}, "status": status} if device_filter_by: body["devices"] = {"filter_by": device_filter_by} return self._http_request("POST", url_suffix="device-alert-status/set/", json_data=body) """ HELPER FUNCTIONS """ def _device_alert_relation_id(device_alert_relation: dict) -> tuple[int, str]: return device_alert_relation["alert_id"], device_alert_relation["device_uid"] def _device_alert_relation_id_str(device_alert_relation: dict) -> str: dar_id = _device_alert_relation_id(device_alert_relation) return f"{dar_id[0]}↔{dar_id[1]}" def _split_device_alert_relation_id(device_alert_relation_id: str) -> tuple[int, str]: alert_id, device_uid = device_alert_relation_id.split("↔") return int(alert_id), device_uid def _device_alert_relation_name(device_alert_relation: dict) -> str: return f"Alert “{device_alert_relation.get('alert_name', '')}” on Device “{device_alert_relation.get('device_name', '')}”" def _format_date(date: str | datetime, format: str = DATE_FORMAT) -> str: dt = date if isinstance(date, datetime) else dateparser.parse(date) assert dt is not None return dt.strftime(format) def _ascending(field: str) -> dict[str, str]: return {"field": field, "order": "asc"} def _simple_filter(field: str, operation: str, value: Any) -> QueryFilterType: return {"field": field, "operation": operation, "value": value} def _build_alert_types_filter(alert_types: list[str]) -> QueryFilterType: return _simple_filter("alert_type_name", "in", [at.strip() for at in alert_types]) def _compound_filter(op: str, *filters: dict | None) -> QueryFilterType | None: filters = [f for f in filters if f] return None if not filters else filters[0] if len(filters) == 1 else {"operation": op, "operands": filters} def _and(*filters: dict | None) -> QueryFilterType | None: return _compound_filter("and", *filters) def _or(*filters: dict | None) -> QueryFilterType | None: return _compound_filter("or", *filters) def _device_alert_relation_to_incident(device_alert_relation: dict[str, Any]) -> dict[str, Any]: return { "dbotMirrorId": _device_alert_relation_id_str(device_alert_relation), "name": _device_alert_relation_name(device_alert_relation), "occurred": device_alert_relation[INCIDENT_TIMESTAMP_FIELD], "rawJSON": json.dumps(device_alert_relation), } def _next_tick(date_time: str) -> str: parsed_time = dateparser.parse(date_time) assert parsed_time is not None return _format_date(parsed_time + SMALLEST_TIME_UNIT) """ 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. Raises exceptions if something goes wrong. :type client: ``Client`` :param Client: client to use :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ message: str = "" try: # This should validate all the inputs given in the integration configuration panel, # either manually or by using an API that uses them. client.get_device_alert_relations(fields=["device_uid", "alert_id"], limit=1) message = "ok" except DemistoException as e: if "Forbidden" in str(e) or "Authorization" in str(e): message = "Authorization Error: make sure API Key is correctly set" else: raise e return message class XDomeCommand(abc.ABC): retired_field_name: str = "retired" @classmethod @abc.abstractmethod def all_fields(cls) -> set[str]: ... @classmethod def _constant_filter(cls) -> QueryFilterType | None: return None @classmethod def exclude_retired_filter(cls): return _simple_filter(cls.retired_field_name, "in", [False]) def __init__( self, client: Client, fields: str | None, filter_by: str | None, offset: str | None, limit: str | None, sort_by: str | None, ): self._client = client self._raw_args = {"fields": fields, "filter_by": filter_by, "offset": offset, "limit": limit, "sort_by": sort_by} self._fields = self._parse_fields(fields or "all") self._filter_by = self._parse_filter_by(filter_by) self._offset = int(offset or 0) self._limit = int(limit or DEFAULT_REQUEST_LIMIT) self._sort_by = json.loads(sort_by) if sort_by else None def execute(self) -> CommandResults: return self._generate_results(self._get_data()) def _parse_fields(self, raw_fields: str) -> Collection[str]: parsed_fields = [field.strip() for field in raw_fields.split(",")] return self.all_fields() if "all" in parsed_fields else parsed_fields def _parse_filter_by(self, raw_filter_by: str | None) -> QueryFilterType: """parse the raw filter input and make sure to always exclude retired devices""" filter_by = json.loads(raw_filter_by) if raw_filter_by else None filter_by = _and(filter_by, self.exclude_retired_filter(), self._constant_filter()) assert filter_by return filter_by @abc.abstractmethod def _get_data(self) -> list: ... @abc.abstractmethod def _generate_results(self, raw_response: list | dict) -> CommandResults: ... class XDomeGetDeviceAlertRelationsCommand(XDomeCommand): retired_field_name: str = "device_retired" @classmethod def all_fields(cls) -> set[str]: return DEVICE_ALERT_FIELDS def _get_data(self) -> list: return self._client.force_get_all_device_alert_relations( fields=self._fields, filter_by=self._filter_by, sort_by=self._sort_by, stop_after=self._limit if self._raw_args.get("limit") is not None else None, start_from=self._offset if self._raw_args.get("offset") is not None else None, ) def _generate_results(self, raw_response: list | dict) -> CommandResults: device_alert_pairs = raw_response outputs = {"XDome.DeviceAlert(val.device_uid == obj.device_uid && val.alert_id == obj.alert_id)": device_alert_pairs} human_readable_output = tableToMarkdown("xDome device-alert-pairs List", device_alert_pairs) return CommandResults( outputs_prefix="XDome.DeviceAlert", outputs=outputs, readable_output=human_readable_output, raw_response=raw_response, ) class XDomeGetDeviceVulnerabilityRelationsCommand(XDomeCommand): retired_field_name: str = "device_retired" @classmethod def all_fields(cls) -> set[str]: return DEVICE_VULNERABILITY_FIELDS @classmethod def _constant_filter(cls) -> QueryFilterType | None: return _simple_filter("vulnerability_relevance", "in", ["Confirmed", "Potentially Relevant"]) def _get_data(self) -> list: return self._client.force_get_all_device_vulnerability_relations( fields=self._fields, filter_by=self._filter_by, sort_by=self._sort_by, stop_after=self._limit if self._raw_args.get("limit") is not None else None, start_from=self._offset if self._raw_args.get("offset") is not None else None, ) def _generate_results(self, raw_response: list | dict) -> CommandResults: device_vulnerability_pairs = raw_response outputs = { "XDome.DeviceVulnerability(val.device_uid == obj.device_uid " "&& val.vulnerability_id == obj.vulnerability_id)": device_vulnerability_pairs } human_readable_output = tableToMarkdown("xDome device-vulnerability-pairs List", device_vulnerability_pairs) return CommandResults( outputs_prefix="XDome.DeviceVulnerability", outputs=outputs, readable_output=human_readable_output, raw_response=raw_response, ) def get_device_alert_relations_command(client: Client, args: dict) -> CommandResults: cmd = XDomeGetDeviceAlertRelationsCommand( client=client, fields=args.get("fields"), filter_by=args.get("filter_by"), offset=args.get("offset"), limit=args.get("limit"), sort_by=args.get("sort_by"), ) return cmd.execute() def get_device_vulnerability_relations_command(client: Client, args: dict) -> CommandResults: cmd = XDomeGetDeviceVulnerabilityRelationsCommand( client=client, fields=args.get("fields"), filter_by=args.get("filter_by"), sort_by=args.get("sort_by"), offset=args.get("offset"), limit=args.get("limit"), ) return cmd.execute() def set_device_alert_relations_command(client: Client, args: dict) -> CommandResults: alert_id = int(args["alert_id"]) device_uids = args.get("device_uids") if device_uids: device_uids = [field.strip() for field in device_uids.split(",")] status = args["status"] res = client.set_device_single_alert_relations(alert_id, device_uids, status) if res and "details" in res: return CommandResults(readable_output=res["details"][0].get("msg"), raw_response=res) return CommandResults(readable_output="success", raw_response="success") def fetch_incidents( client: Client, last_run: dict, initial_fetch_time: str, fetch_limit: int, alert_types: list[str] | None, fetch_only_unresolved: bool, ): """This function will execute each interval (default is 1 minute)""" start_time = last_run.get("last_fetch", initial_fetch_time) start_time = _format_date(start_time) latest_ids = last_run.get("latest_ids", []) only_unresolved_filter = _simple_filter("device_alert_status", "in", ["Unresolved"]) if fetch_only_unresolved else None alert_types_filter = _build_alert_types_filter(alert_types) if alert_types else None if latest_ids: last_run_alert_id_device_uid_pairs = [_split_device_alert_relation_id(dar_id) for dar_id in latest_ids] not_in_last_fetched_ids_filter = _and( *( _or( _simple_filter("alert_id", "not_in", [alert_id]), _simple_filter("device_uid", "not_in", [device_uid]), ) for alert_id, device_uid in last_run_alert_id_device_uid_pairs ) ) # should be the 'not_equals' or the 'greater' operation, but they're currently not working. # not_last_fetched_time_filter = _simple_filter(INCIDENT_TIMESTAMP_FIELD, "not_equals", start_time) # patch: use the 'greater_or_equal' operation on value 'Time + 1s' not_last_fetched_time_filter = _simple_filter(INCIDENT_TIMESTAMP_FIELD, "greater_or_equal", _next_tick(start_time)) no_last_run_dups_filter = _or(not_in_last_fetched_ids_filter, not_last_fetched_time_filter) else: no_last_run_dups_filter = None start_time_filter = _simple_filter(INCIDENT_TIMESTAMP_FIELD, "greater_or_equal", start_time) sort_by_update_time = [_ascending(INCIDENT_TIMESTAMP_FIELD)] try: device_alert_relations = client.force_get_all_device_alert_relations( fields=DEVICE_ALERT_FIELDS, filter_by=_and( XDomeGetDeviceAlertRelationsCommand.exclude_retired_filter(), only_unresolved_filter, alert_types_filter, no_last_run_dups_filter, start_time_filter, ), sort_by=sort_by_update_time, stop_after=fetch_limit, ) except DemistoException as e: demisto.error(f"An error occurred while fetching xDome incidents:\n{e!s}") return last_run, [] for dar in device_alert_relations: dar[INCIDENT_TIMESTAMP_FIELD] = _format_date(dar[INCIDENT_TIMESTAMP_FIELD]) incidents = [_device_alert_relation_to_incident(dar) for dar in device_alert_relations] if incidents: next_start_time = device_alert_relations[-1][INCIDENT_TIMESTAMP_FIELD] next_latest_ids = [ _device_alert_relation_id_str(dar) for dar in device_alert_relations if dar[INCIDENT_TIMESTAMP_FIELD] == next_start_time ] if next_start_time == start_time: # start_time == next_start_time which means that all the incidents that were fetched have the same # update_time. So I want to keep the current 'latest_ids' for the next run (& extend them with the new IDs) # instead of overriding them. By doing so I make sure we don't fetch those incidents again next run. next_latest_ids = latest_ids + next_latest_ids else: next_start_time = _next_tick(start_time) next_latest_ids = [] next_run = {"last_fetch": next_start_time, "latest_ids": next_latest_ids} return next_run, incidents """ MAIN FUNCTION """ def main() -> None: """main function, parses params and runs command functions :return: :rtype: """ command = demisto.command() params = demisto.params() args = demisto.args() api_key = params.get("credentials", {}).get("password") # get the service API url base_url = urljoin(params["url"], "/api/v1") verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) demisto.debug(f"Command being called is {command}") try: headers: dict = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} client = Client( base_url=base_url, verify=verify_certificate, headers=headers, proxy=proxy, ) if command == "test-module": # This is the call made when pressing the integration Test button. result = test_module(client) return_results(result) elif command == "xdome-get-device-alert-relations": return_results(get_device_alert_relations_command(client, args)) elif command == "xdome-get-device-vulnerability-relations": return_results(get_device_vulnerability_relations_command(client, args)) elif command == "xdome-set-status-for-device-alert-relations": return_results(set_device_alert_relations_command(client, args)) elif command == "fetch-incidents": initial_fetch_time = params.get("first_fetch").strip() fetch_limit = params.get("max_fetch") fetch_limit = int(fetch_limit) if fetch_limit is not None else DEFAULT_FETCH_LIMIT fetch_limit = min(fetch_limit, MAX_FETCH_LIMIT) alert_types = params.get("alert_types") fetch_only_unresolved = params.get("fetch_only_unresolved") next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), initial_fetch_time=initial_fetch_time, fetch_limit=fetch_limit, alert_types=alert_types, fetch_only_unresolved=fetch_only_unresolved, ) demisto.setLastRun(next_run) demisto.incidents(incidents or []) else: raise Exception("Unrecognized command: " + command) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {command} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()