SymantecICDM
Query the Symantec Endpoint Security Cloud Portal (ICDM).
Data Enrichment & Threat Intelligence · SymantecICDM
Details
| ID | SymantecICDM |
|---|---|
| Provider | Broadcom |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Query the Symantec Endpoint Security Cloud Portal (ICDM).
This integration was integrated and tested with version 1 of SymantecICDM.
Configure Symantec Endpoint Security (ICDM) in Cortex
| Parameter | Description | Required |
|---|---|---|
| Source Reliability | Reliability of the source providing the intelligence data. | True |
| Server URL (e.g. https://api.sep.securitycloud.symantec.com) | True | |
| Fetch incidents | False | |
| Incident type | False | |
| Maximum number of incidents per fetch | False | |
| API Key | True | |
| First fetch time | False | |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| Incidents Fetch Interval | False | |
| Ignore Domains (e.g. domain.local) | Comma-separated list of domains that shall be ignored for Urls and (Sub-)Domains reputation lookup | False |
| Ignore Private IPs (e.g. 192.168.0.1) | 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.
file
Get file reputation for given SHA256.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | List of files. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| File.SHA256 | String | The SHA256 hash of the file. |
ip
Get ip reputation.
Base Command
ip
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | List of IPs. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| IP.Address | String | IP address. |
url
Get reputation for given url.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | List of URLs. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| URL.Data | String | The URL. |
domain
Get reputation for given domain.
Base Command
domain
Input
| Argument Name | Description | Required |
|---|---|---|
| domain | List of domains. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| Domain.Name | String | The domain name. |
symantec-protection-file
Get information whether a given file has been blocked by any Symantec technologies.
Base Command
symantec-protection-file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | Comma-separated list of file Sha256 hashes. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Symantec.Protection.File.file | String | input file sha256. |
| Symantec.Protection.File.state.technology | String | Symantec technology providing protection. |
| Symantec.Protection.File.state.firstDefsetVersion | String | The first definition version with protection. |
| Symantec.Protection.File.state.threatName | String | The name of the threat the file is detected as. |
symantec-protection-network
Get information whether given domain or ip has been blocked by any Symantec technologies.
Base Command
symantec-protection-network
Input
| Argument Name | Description | Required |
|---|---|---|
| network | Comma-separated list of domains or IPs. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Symantec.Protection.Network.network | String | input domain or ip. |
| Symantec.Protection.Network.state.technology | String | Symantec technology providing protection. |
| Symantec.Protection.Network.state.firstDefsetVersion | String | The first definition version with protections. |
| Symantec.Protection.Network.state.threatName | String | The name of the threat the domain or is detected as. |
symantec-protection-cve
Get returns information whether a given CVE has been blocked by any Symantec technologies.
Base Command
symantec-protection-cve
Input
| Argument Name | Description | Required |
|---|---|---|
| cve | Comma-separated list of CVEs. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Symantec.Protection.CVE.cve | String | input CVE. |
| Symantec.Protection.CVE.state.technology | String | Symantec technology providing protection. |
| Symantec.Protection.CVE.state.firstDefsetVersion | String | The first definition version with protections. |
| Symantec.Protection.CVE.state.threatName | String | The name of the threat the domain or is detected as. |
Configuration parameters
integrationReliability— Source Reliability (required)url— Server URL (e.g. https://api.sep.securitycloud.symantec.com) (required)isFetch— Fetch incidentsincidentType— Incident typemax_fetch— Maximum number of incidents per fetchcredentials— (required)first_fetch— First fetch timeinsecure— Trust any certificate (not secure)proxy— Use system proxy settingsincidentFetchInterval— Incidents Fetch Intervalignored_domains— Ignore Domains (e.g. domain.local)ignore_private_ip— Ignore Private IPs (e.g. 192.168.0.1)
Commands (7)
-
domainGet reputation for given domain.
-
fileGet file reputation for given SHA256.
-
ipGet ip reputation.
-
symantec-protection-cveGet returns information whether a given CVE has been blocked by any Symantec technologies.
-
symantec-protection-fileGet information whether a given file has been blocked by any Symantec technologies.
-
symantec-protection-networkGet information whether given domain or ip has been blocked by any Symantec technologies.
-
urlGet reputation for given url.
"""Symantec Endpoint Security Threat Intel- Unit Tests file Pytest Unit Tests: all function names must start with "test_" """ import json import pytest from CommonServerPython import * from datetime import datetime, timedelta from freezegun import freeze_time from SymantecICDM import ( Client, icdm_fetch_incidents_command, fetch_incidents_command, ensure_max_age, file_reputation_command, url_reputation_command, domain_reputation_command, ip_reputation_command, ensure_argument, is_filtered, symantec_protection_file_command, symantec_protection_cve_command, symantec_protection_network_command, get_network_indicator_by_type, ) BASE_RELIABILITY = DBotScoreReliability.B FREEZE_TIME = "2026-04-18T03:00:00Z" DATE_TIME = datetime.strptime(FREEZE_TIME, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc) AN_HOUR_AGO = DATE_TIME - timedelta(hours=1) TWO_MONTHS_AGO = DATE_TIME - timedelta(days=60) def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) @freeze_time(FREEZE_TIME) @pytest.mark.parametrize( "value, output", [ (AN_HOUR_AGO, AN_HOUR_AGO), (TWO_MONTHS_AGO, DATE_TIME - timedelta(days=29, hours=23, minutes=59)), ], ) def test_ensure_max_age(value: datetime, output: datetime): """ Given: - Mocked date When: - sent to ensure_max_age Then: - ensure the age matches the expected output """ value = value.replace(second=0, microsecond=0) result = ensure_max_age(value) result = result.replace(second=0, microsecond=0) assert result == output def test_icdm_fetch_incidents_command(mocker): client = Client("", "") incidents = util_load_json("test_data/icdm_incidents_without_events.json") mocker.patch.object(Client, "_http_request", return_value=incidents) result = icdm_fetch_incidents_command(client, 100, datetime(2023, 4, 26, 0, 0, 0, tzinfo=timezone.utc)) assert result.outputs == incidents.get("incidents") expected_hr = ( "### Symantec Endpoint Security EDR Incidents\n" "|ref_incident_uid|type|conclusion|created|modified|\n" "|---|---|---|---|---|\n" "| 102106 | INCIDENT_UPDATE | Suspicious Activity | 2023-04-26T15:44:19.345+00:00 | 2023-04-26T23:38:48.634+00:00 |\n" "| 102109 | INCIDENT_CREATION | Suspicious Activity | 2023-04-26T21:28:00.467+00:00 | 2023-04-26T21:52:51.550+00:00 |\n" "| 102110 | INCIDENT_CREATION | Suspicious Activity | 2023-04-26T21:46:10.400+00:00 | 2023-04-26T22:01:58.648+00:00 |\n" ) assert result.readable_output == expected_hr def test_fetch_incidents_command(mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/icdm_incidents_without_events.json"), ) last_run, incidents = fetch_incidents_command(client, 100, datetime(2023, 4, 26, 0, 0, 0, tzinfo=timezone.utc)) expected_incidents = util_load_json("test_data/outputs/icdm_incidents_output.json") assert last_run == {"last_fetch": 1682545570.4} assert incidents == expected_incidents @pytest.mark.parametrize("response, result", [({"access_token": "YXNhbXBsZWFjY2Vzc3Rva2VudGNvZGU="}, True)]) def test_client_authenticate(response, result, mocker): client = Client("", "") mocker.patch.object(Client, "_http_request", return_value=response) assert client.authenticate() == result assert client._session_token == response.get("access_token") @pytest.mark.parametrize( "file, output", [ ( "eec3f761f7eabe9ed569f39e896be24c9bbb8861b15dbde1b3d539505cd9dd8d", { "indicator": "eec3f761f7eabe9ed569f39e896be24c9bbb8861b15dbde1b3d539505cd9dd8d", "reputation": "BAD", "actors": ["Waterbug"], }, ) ], ) def test_file_reputation_command(file, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/file_insight_reputation_response.json"), ) response = file_reputation_command(client, {"file": file}, BASE_RELIABILITY) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "url, output", [ ( "elblogdeloscachanillas.com.mx%2Fs3sy8rq10%2Fophn.png", { "indicator": "elblogdeloscachanillas.com.mx%2Fs3sy8rq10%2Fophn.png", "reputation": "BAD", "risk_level": 10, "categories": ["Malicious Sources/Malnets"], "first_seen": None, "last_seen": None, }, ) ], ) def test_url_reputation_command(url, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/url_insight_reputation_response.json"), ) response = url_reputation_command(client, {"url": url}, BASE_RELIABILITY) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "domain, output", [ ( "elblogdeloscachanillas.com.mx", { "indicator": "elblogdeloscachanillas.com.mx", "reputation": "BAD", "risk_level": 10, "categories": ["Malicious Sources/Malnets"], "first_seen": "2019-08-30", "last_seen": "2024-01-24", }, ) ], ) def test_domain_reputation_command(domain, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/domain_insight_reputation_response.json"), ) response = domain_reputation_command(client, {"domain": domain}, BASE_RELIABILITY) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "ip, output", [ ( "8.8.8.8", { "indicator": "8.8.8.8", "reputation": "GOOD", "risk_level": 2, "categories": ["Web Infrastructure"], "first_seen": "2023-07-10", "last_seen": "2023-12-18", }, ) ], ) def test_ip_reputation_command(ip, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/ip_insight_reputation_response.json"), ) response = ip_reputation_command(client, {"ip": ip}, BASE_RELIABILITY) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "file, output", [ ( "eec3f761f7eabe9ed569f39e896be24c9bbb8861b15dbde1b3d539505cd9dd8d", util_load_json("test_data/file_protection_response.json"), ) ], ) def test_symantec_protection_file_command(file, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/file_protection_response.json"), ) response = symantec_protection_file_command(client, {"file": file}) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "network, output", [ ( "eec3f761f7eabe9ed569f39e896be24c9bbb8861b15dbde1b3d539505cd9dd8d", util_load_json("test_data/network_protection_response.json"), ) ], ) def test_symantec_protection_network_command(network, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/network_protection_response.json"), ) response = symantec_protection_network_command(client, {"network": network}) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize( "cve, output", [ ( "eec3f761f7eabe9ed569f39e896be24c9bbb8861b15dbde1b3d539505cd9dd8d", util_load_json("test_data/cve_protection_response.json"), ) ], ) def test_symantec_protection_cve_command(cve, output, mocker): client = Client("", "") mocker.patch.object( Client, "_http_request", return_value=util_load_json("test_data/cve_protection_response.json"), ) response = symantec_protection_cve_command(client, {"cve": cve}) assert len(response) == 1 assert response[0].outputs == output @pytest.mark.parametrize("args, name, output", [({"ip": "8.8.8.8"}, "ip", ["8.8.8.8"])]) def test_ensure_argument(args, name, output): assert ensure_argument(args, name) == output @pytest.mark.parametrize("args, name", [({}, "ip"), ({"ip": ""}, "ip")]) def test_ensure_argument_exception(args, name): with pytest.raises(ValueError): ensure_argument(args, name) @pytest.mark.parametrize( "value, filters, output", [("support.paloaltonetworks.com", ["paloaltonetworks.com"], True)], ) def test_is_filtered(value: str, filters: list[str], output: bool): assert is_filtered(value, filters) == output @pytest.mark.parametrize( "arg_type, indicator, score", [ ( DBotScoreType.IP, "8.8.8.8", Common.DBotScore.GOOD, ), ( DBotScoreType.URL, "https://google.com", Common.DBotScore.GOOD, ), ( DBotScoreType.DOMAIN, "google.com", Common.DBotScore.GOOD, ), ], ) def test_get_network_indicator_by_type(arg_type: str, indicator: str, score: int): dbot_score = Common.DBotScore( indicator=indicator, indicator_type=arg_type, integration_name="INTEGRATION_NAME", score=score, reliability=DBotScoreReliability.A, malicious_description=None, ) assert isinstance(get_network_indicator_by_type(type=arg_type, indicator=indicator, dbot_score=dbot_score), Common.Indicator) @pytest.mark.parametrize( "type, indicator, score", [ ( "", "", Common.DBotScore.GOOD, ) ], ) def test_get_network_indicator_by_type_exception(type: str, indicator: str, score: Common.DBotScore): with pytest.raises(DemistoException): get_network_indicator_by_type(type, indicator, score)