import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import urllib3 from CommonServerUserPython import * # noqa: E402 lgtm [py/polluting-import] # IMPORTS from typing import Any import json import dateparser import zipfile import io # Disable insecure warnings urllib3.disable_warnings() # CONSTANTS DATE_FORMAT = "%Y-%m-%dT%H:%M:%S.000Z" DEFAULT_HEADERS_POST_REQUEST = {"accept": "application/json;charset=UTF-8", "Content-Type": "application/json;charset=UTF-8"} class Client(BaseClient): """ Client will implement the service API, and should not contain any Demisto logic. Should only do requests and return data. """ def get_deceptive_users(self, user_type): url_suffix = f"/api/v1/deceptive-entities/users?deceptive_user_type={user_type}" return self._http_request("GET", url_suffix=url_suffix) def get_deceptive_serves(self, server_type): url_suffix = f"/api/v1/deceptive-entities/servers?deceptive_server_type={server_type}" return self._http_request("GET", url_suffix=url_suffix) def add_deceptive_users(self, body): url_suffix = "/api/v1/deceptive-entities/users" return self._http_request("POST", url_suffix=url_suffix, data=json.dumps(body), ok_codes=(200,)) def add_deceptive_servers(self, body): url_suffix = "/api/v1/deceptive-entities/servers" return self._http_request("POST", url_suffix=url_suffix, data=json.dumps(body), ok_codes=(200,)) def assign_host_to_policy(self, policy_name, body): url_suffix = f"/api/v1/policy/domain_hosts/assign?policy_name={policy_name}" return self._http_request("POST", url_suffix=url_suffix, data=json.dumps(body), ok_codes=(200,)) def remove_host_from_policy(self, body): url_suffix = "/api/v1/policy/domain_hosts/remove_assignment" return self._http_request("POST", url_suffix=url_suffix, data=json.dumps(body), ok_codes=(200,)) def get_forensics_timeline(self, incident_id, start_date, end_date): url_suffix = f"/api/v1/forensics/timeline?incident_id={incident_id}" if end_date: url_suffix += f"&end_date={end_date}" if start_date: url_suffix += f"&start_date={start_date}" return self._http_request("GET", url_suffix=url_suffix, ok_codes=(200,)) def get_asm_host_insight(self, hostname_or_ip): url_suffix = f"/api/v1/attack-surface/machine-insights?hostNameOrIp={hostname_or_ip}" return self._http_request("GET", url_suffix=url_suffix) def get_asm_cj_insight(self): url_suffix = "/api/v1/crownjewels/insights" return self._http_request("GET", url_suffix=url_suffix) def run_forensics_on_demand(self, hostname_or_ip): url_suffix = f"/api/v1/event/create-external-event?hostNameOrIp={hostname_or_ip}" return self._http_request("POST", url_suffix=url_suffix) def is_deceptive_user(self, username): url_suffix = f"/api/v1/deceptive-entities/user?userName={username}" return self._http_request("GET", url_suffix=url_suffix, resp_type="text") def is_deceptive_server(self, hostname): url_suffix = f"/api/v1/deceptive-entities/server?hostName={hostname}" return self._http_request("GET", url_suffix=url_suffix, resp_type="text") def delete_deceptive_users(self, deceptive_users): url_suffix = "/api/v1/deceptive-entities/users" url_suffix += "?deceptive_users=" + "&deceptive_users=".join(deceptive_users) return self._http_request("DELETE", url_suffix=url_suffix, resp_type="text") def delete_deceptive_servers(self, deceptive_servers): url_suffix = "/api/v1/deceptive-entities/servers" url_suffix += "?deceptive_hosts=" + "&deceptive_hosts=".join(deceptive_servers) return self._http_request("DELETE", url_suffix=url_suffix, resp_type="text") def get_incident(self, incident_id): url_suffix = f"/api/v2/incidents/incident?incident_id={incident_id}" return self._http_request("GET", url_suffix=url_suffix) def get_event_incident_id(self, event_id): url_suffix = f"/api/v1/incidents/id?event_id={event_id}" return self._http_request("GET", url_suffix=url_suffix, ok_codes=(200,)) def list_all_incidents(self, has_forensics, host_names, limit, offset, start_date): url_suffix = f"/api/v1/incidents?limit={limit}&offset={offset}" if has_forensics is not None: url_suffix += f"&has_forensics={has_forensics}" if start_date: url_suffix += f"&start_date={start_date}" if host_names: url_suffix += "&host_names=" + "&host_names=".join(host_names) return self._http_request("GET", url_suffix=url_suffix) def test_configuration(self): url_suffix = "/api/v1/incidents?limit=10&offset=0" return self._http_request("GET", url_suffix=url_suffix, ok_codes=(200,)) def get_incident_events(self, incident_id, limit, offset): url_suffix = f"/api/v1/incidents/events?incident_id={incident_id}&limit={limit}&offset={offset}" return self._http_request("GET", url_suffix=url_suffix) def get_forensics_artifacts(self, event_id, artifact_type): url_suffix = f"/api/v1/forensics/artifacts?event_id={event_id}&artifacts_type={artifact_type}" return self._http_request("GET", url_suffix=url_suffix, resp_type="content") def get_forensics_analyzers(self, event_id): url_suffix = f"/api/v1/forensics/analyzers?event_id={event_id}" return self._http_request("GET", url_suffix=url_suffix) def get_forensics_triggering_process_info(self, event_id): url_suffix = f"/api/v1/forensics/triggering_process_info?event_id={event_id}" return self._http_request("GET", url_suffix=url_suffix, ok_codes=(200,)) def test_module(client): """ Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Args: client: Illusive Networks client Returns: 'ok' if test passed, anything else will fail the test. """ try: client.test_configuration() return "ok" except DemistoException as e: if "401" in e.args[0]: return f"Test failed, potential reasons might be that the API KEY parameter is incorrect: {e.args[0]}" else: return f"Test failed: {e.args[0]}" def fetch_incidents(client, last_run, first_fetch_time, has_forensics): """ This function will execute each interval (default is 1 minute). """ # Get the last fetch time, if exists last_fetch = last_run.get("last_run") # Handle first time fetch if last_fetch is None: last_fetch, _ = parse_date_range(first_fetch_time, date_format=DATE_FORMAT, utc=True) latest_created_time = last_fetch incidents = [] items = client.list_all_incidents(has_forensics, None, limit=10, offset=0, start_date=latest_created_time) for item in items: incident_created_time = item["incidentTimeUTC"] incident_type = "None" if len(item["incidentTypes"]) > 0: incident_type = str(item["incidentTypes"][0]) incident_create_time_date = dateparser.parse(incident_created_time) assert incident_create_time_date is not None incident = { "name": "Illusive Attack Management detected an incident of type " + incident_type, "occurred": incident_create_time_date.strftime("%Y-%m-%dT%H:%M:%SZ"), "rawJSON": json.dumps(item), } incidents.append(incident) # Update last run and add incident if the incident is newer than last fetch if incident_created_time > latest_created_time: latest_created_time = incident_created_time next_run = {"last_run": latest_created_time} return next_run, incidents def get_deceptive_users_command(client: Client, args: dict) -> tuple: user_type = args.get("type", "ALL") try: result = client.get_deceptive_users(user_type) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive Deceptive Users", result) outputs = {"Illusive.DeceptiveUser(val.userName == obj.userName)": result} return ( readable_output, outputs, result, # raw response - the original response ) def get_deceptive_servers_command(client: Client, args: dict) -> tuple: server_type = args.get("type", "ALL") try: result = client.get_deceptive_serves(server_type) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive Deceptive Servers", result) outputs = {"Illusive.DeceptiveServer(val.host == obj.host)": result} return ( readable_output, outputs, result, # raw response - the original response ) def add_deceptive_users_command(client: Client, args: dict) -> tuple: user_name = args.get("username", None) domain_name = args.get("domain_name", None) password = args.get("password", None) policy_names = argToList(args.get("policy_names")) request_body = [{"domainName": domain_name, "password": password, "policyNames": policy_names, "username": user_name}] try: client.add_deceptive_users(request_body) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") result = { "userName": user_name, "domainName": domain_name, "policyNames": "All Policies" if policy_names == [] else policy_names, "password": password, } readable_output = tableToMarkdown("Illusive Add Deceptive User Succeeded", result) outputs = {"Illusive.DeceptiveUser(val.userName == obj.userName)": result} return ( readable_output, outputs, result, # raw response - the original response ) def add_deceptive_servers_command(client: Client, args: dict) -> tuple: host_name = args.get("host", "") # must be . service_types = argToList(args.get("service_types")) policy_names = argToList(args.get("policy_names"), "All Policies") if len(host_name.split(".")) < 2: raise DemistoException("host name must have the following pattern: .") request_body = [{"host": host_name, "serviceTypes": service_types, "policyNames": policy_names}] try: client.add_deceptive_servers(request_body) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") result = { "host": host_name, "serviceTypes": service_types, "policyNames": "All Policies" if policy_names == [] else policy_names, } readable_output = tableToMarkdown("Illusive Add Deceptive Server Succeeded", result) outputs = {"Illusive.DeceptiveServer(val.host == obj.host)": result} return ( readable_output, outputs, result, # raw response - the original response ) def assign_host_to_policy_command(client: Client, args: dict) -> tuple: policy_name = args.get("policy_name", None) host_names = argToList(args.get("hosts")) host_names = host_names[:1000] request_body = [] for host_name in host_names: host_name_split = host_name.split("@") if len(host_name_split) != 2: raise Exception(f"bad hostname format: {host_name}. Should be @ ") request_body.append({"machineName": host_name_split[0], "domainName": host_name_split[1]}) try: client.assign_host_to_policy(policy_name, request_body) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") result = [] for host in host_names: result.append({"isAssigned": True, "hosts": host, "policy_name": policy_name}) readable_output = tableToMarkdown("Illusive Assign Machines to Policy Succeeded", result) outputs = {"Illusive.DeceptionPolicy.isAssigned(val.hosts == obj.hosts)": result} return ( readable_output, outputs, result, # raw response - the original response ) def remove_host_from_policy_command(client: Client, args: dict) -> tuple: host_names = argToList(args.get("hosts")) host_names = host_names[:1000] request_body = [] for host_name in host_names: host_name_split = host_name.split("@") if len(host_name_split) != 2: raise Exception(f"bad hostname format: {host_name}. Should be @ ") request_body.append({"machineName": host_name_split[0], "domainName": host_name_split[1]}) try: client.remove_host_from_policy(request_body) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") result = [] for host in host_names: result.append({"isAssigned": False, "hosts": host, "policy_name": ""}) readable_output = tableToMarkdown("Illusive Remove Machines from All Policies Succeeded", result) outputs = {"Illusive.DeceptionPolicy.isAssigned(val.hosts == obj.hosts)": result} return ( readable_output, outputs, result, # raw response - the original response ) def get_forensics_timeline_command(client: Client, args: dict) -> tuple: incident_id = args.get("incident_id") start_date = args.get("start_date", None) end_date = args.get("end_date", None) if start_date: start_date, _ = parse_date_range(start_date, date_format=DATE_FORMAT, utc=True) if end_date: end_date, _ = parse_date_range(end_date, date_format=DATE_FORMAT, utc=True) try: result = client.get_forensics_timeline(incident_id, start_date, end_date) for evidence in result: evidence["date"] = evidence.get("details").get("date") readable_output = tableToMarkdown("Illusive Forensics Timeline", result) outputs = { "Illusive.Forensics(val.IncidentId == obj.IncidentId)": { "IncidentId": incident_id, "Status": "Done", "Evidence": result, } } except DemistoException as e: if "404" in e.args[0]: raise DemistoException(f"Incident id {incident_id} doesn't not exist") elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) elif "202" in e.args[0]: readable_output = f"Incident id {incident_id} hasn't been closed yet" outputs = { "Illusive.Forensics(val.IncidentId == obj.IncidentId)": { "IncidentId": incident_id, "Status": "InProgress", "Evidence": [], } } result = [] else: raise DemistoException(f"{e.args[0]}") return ( readable_output, outputs, result, # raw response - the original response ) def get_asm_host_insight_command(client: Client, args: dict) -> tuple: hostname_or_ip = args.get("hostnameOrIp", None) try: result = client.get_asm_host_insight(hostname_or_ip) except DemistoException as e: if "404" in e.args[0]: result = [] elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive ASM Host Insights", result) outputs = {"Illusive.AttackSurfaceInsightsHost(val.ipAddresses == obj.ipAddresses)": result} return ( readable_output, outputs, result, # raw response - the original response ) def get_asm_cj_insight_command(client: Client, args: dict) -> tuple: try: result = client.get_asm_cj_insight() except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive ASM Crown Jewels Insights", result) outputs = {"Illusive.AttackSurfaceInsightsCrownJewel(val.hostname == obj.hostname)": result} return ( readable_output, outputs, result, # raw response - the original response ) def run_forensics_on_demand_command(client: Client, args: dict) -> tuple: fqdn_or_ip = args.get("fqdn_or_ip", None) try: result = client.run_forensics_on_demand(fqdn_or_ip) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive Run Forensics On Demand", result) outputs = {"Illusive.Event(val.eventId == obj.eventId)": result} return ( readable_output, outputs, result, # raw response - the original response ) def is_deceptive_user_command(client: Client, args: dict) -> tuple: username = args.get("username", None) is_deceptive_user = False is_deceptive_user = True if client.is_deceptive_user(username) else is_deceptive_user result = {"Username": username, "IsDeceptiveUser": is_deceptive_user} readable_output = tableToMarkdown("Illusive Is Deceptive", result) outputs = {"Illusive.IsDeceptive(val.Username == obj.Username)": result} return ( readable_output, outputs, None, # raw response - the original response ) def is_deceptive_server_command(client: Client, args: dict) -> tuple: hostname = args.get("hostname", None) is_deceptive_server = False is_deceptive_server = True if client.is_deceptive_server(hostname) else is_deceptive_server result = {"Hostname": hostname, "IsDeceptiveServer": is_deceptive_server} readable_output = tableToMarkdown("Illusive Is Deceptive", result) outputs = {"Illusive.IsDeceptive(val.Hostname == obj.Hostname)": result} return ( readable_output, outputs, None, # raw response - the original response ) def delete_deceptive_users_command(client: Client, args: dict) -> tuple: deceptive_users = argToList(args.get("deceptive_users")) try: client.delete_deceptive_users(deceptive_users) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") if len(deceptive_users) > 1: a, b = "s", "were" else: a, b = "", "was" result = f' {f"Deceptive User{a} {deceptive_users} {b} successfully Deleted"}' readable_output = f"## {result}" outputs: dict[str, Any] = {} return ( readable_output, outputs, None, # raw response - the original response ) def delete_deceptive_servers_command(client: Client, args: dict) -> tuple: deceptive_servers = argToList(args.get("deceptive_hosts")) try: client.delete_deceptive_servers(deceptive_servers) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") if len(deceptive_servers) > 1: a, b = "s", "were" else: a, b = "", "was" result = f' {f"Deceptive Server{a} {deceptive_servers} {b} successfully Deleted"}' readable_output = f"## {result}" outputs: dict[str, Any] = {} return ( readable_output, outputs, None, # raw response - the original response ) def get_incidents_command(client: Client, args: dict) -> tuple: incident_id = args.get("incident_id") has_forensics = args.get("has_forensics", None) host_names = argToList(args.get("hostnames")) limit = args.get("limit", 10) offset = args.get("offset", 0) start_date = args.get("start_date", None) if start_date: start_date, _ = parse_date_range(start_date, date_format=DATE_FORMAT, utc=True) try: if incident_id: incident = client.get_incident(incident_id) else: limit = "100" if int(limit) > 100 else limit incident = client.list_all_incidents(has_forensics, host_names, limit, offset, start_date) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive Incidents", incident) outputs = {"Illusive.Incident(val.incidentId == obj.incidentId)": incident} return ( readable_output, outputs, incident, # raw response - the original response ) def get_event_incident_id_command(client: Client, args: dict) -> tuple: event_id = int(args.get("event_id", None)) status = "Done" try: incident = client.get_event_incident_id(event_id) except DemistoException as e: if "404" in e.args[0]: raise DemistoException(f"Event id {event_id} doesn't not exist") elif "202" in e.args[0]: incident = "-" status = "InProgress" elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") result = [{"eventId": event_id, "incidentId": incident, "status": status}] outputs = {"Illusive.Event(val.eventId == obj.eventId)": result} readable_output = tableToMarkdown("Illusive Get Incident", result) return ( readable_output, outputs, None, # raw response - the original response ) def get_incident_events_command(client: Client, args: dict) -> tuple: incident_id = args.get("incident_id", 0) limit = args.get("limit", 100) limit = "1000" if int(limit) > 1000 else limit offset = args.get("offset", 0) try: events = client.get_incident_events(incident_id, limit, offset) except DemistoException as e: if "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive get incident's events", events, metadata=f"Number of events {len(events)}") outputs = { "Illusive.Incident(val.incidentId == obj.incidentId)": { "eventsNumber": len(events), "incidentId": int(incident_id), "Event": events, } } return ( readable_output, outputs, events, # raw response - the original response ) def get_forensics_analyzers_command(client: Client, args: dict) -> tuple: event_id = args.get("event_id", 0) try: analyzers = client.get_forensics_analyzers(event_id) incident = client.get_event_incident_id(event_id) except DemistoException as e: if "404" in e.args[0]: raise DemistoException(f"Event id {event_id} doesn't not exist") elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") outputs = { "Illusive.Event(val.eventId == obj.eventId)": { "eventId": int(event_id), "incidentId": int(incident), "ForensicsAnalyzers": analyzers, } } readable_output = tableToMarkdown("Illusive Forensics Analyzers", analyzers) return ( readable_output, outputs, incident, # raw response - the original response ) def get_forensics_triggering_process_info_command(client: Client, args: dict) -> tuple: event_id = args.get("event_id") try: processes = client.get_forensics_triggering_process_info(event_id) except DemistoException as e: if "404" in e.args[0]: raise DemistoException(f"failed to get forensics for Event id {event_id}") elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") readable_output = tableToMarkdown("Illusive Triggering Processes Info", processes.get("processes")) outputs = { "Illusive.Event(val.eventId == obj.eventId)": { "eventId": event_id, "ForensicsTriggeringProcess": processes.get("processes"), } } return ( readable_output, outputs, readable_output, # raw response - the original response ) def get_forensics_artifacts_command(client: Client, args: dict) -> tuple: event_id = args.get("event_id") artifact_type = args.get("artifact_type", "DESKTOP_SCREENSHOT") try: client.get_event_incident_id(event_id) # this request is for checking the event exists artifact = client.get_forensics_artifacts(event_id, artifact_type) except DemistoException as e: if "404" in e.args[0]: raise DemistoException(f"failed to get forensics for Event id {event_id}") elif "429" in e.args[0]: raise DemistoException( "The allowed amount of API calls per minute in Illusive Attack Management has exceeded. In case this" " message repeats, please contact Illusive Networks support" ) else: raise DemistoException(f"{e.args[0]}") if len(artifact) == 0: return [], [] zip_file = zipfile.ZipFile(io.BytesIO(artifact)) file_results = [] file_names = [] i = 0 for info in zip_file.infolist(): i = i + 1 file_results.append( fileResult( filename=f"eventId_{event_id}_{artifact_type}_{i}.jpg", data=zip_file.read(info.filename), file_type=entryTypes["image"], ) ) file_names.append(f"eventId_{event_id}_{artifact_type}_{i}.jpg") return file_results, file_names def link_forensics_artifacts_name_command(file_names, client: Client, args: dict) -> CommandResults: event_id = args.get("event_id", 0) if len(file_names) > 0: outputs = {"eventId": int(event_id), "Artifacts": file_names} return CommandResults(outputs_prefix="Illusive.Event", outputs_key_field="eventId", outputs=outputs) else: readable_output = f"### event id {event_id} has no artifacts" return CommandResults( readable_output=readable_output, outputs_prefix="Illusive.Event", outputs_key_field="eventId", outputs={"eventId": int(event_id)}, ) def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ # get the service API token api_token = demisto.params().get("api_token") has_forensics = demisto.params().get("has_forensics") has_forensics = None if has_forensics == "ALL" else has_forensics # get the service API url base_url = demisto.params()["url"] verify_certificate = not demisto.params().get("insecure", False) # How much time before the first fetch to retrieve incidents first_fetch_time = demisto.params().get("fetch_time", "7 days").strip().lower() proxy = demisto.params().get("proxy", False) LOG(f"Command being called is {demisto.command()}") try: headers = DEFAULT_HEADERS_POST_REQUEST headers["Authorization"] = api_token client = Client(base_url=base_url, verify=verify_certificate, headers=headers, 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() == "fetch-incidents": # Set and define the fetch incidents command to run after activated via integration settings. next_run, incidents = fetch_incidents( client=client, last_run=demisto.getLastRun(), first_fetch_time=first_fetch_time, has_forensics=has_forensics ) demisto.setLastRun(next_run) demisto.incidents(incidents) elif demisto.command() == "illusive-get-forensics-timeline": return_outputs(*get_forensics_timeline_command(client, demisto.args())) elif demisto.command() == "illusive-get-asm-host-insight": return_outputs(*get_asm_host_insight_command(client, demisto.args())) elif demisto.command() == "illusive-get-asm-cj-insight": return_outputs(*get_asm_cj_insight_command(client, demisto.args())) elif demisto.command() == "illusive-get-deceptive-users": return_outputs(*get_deceptive_users_command(client, demisto.args())) elif demisto.command() == "illusive-get-deceptive-servers": return_outputs(*get_deceptive_servers_command(client, demisto.args())) elif demisto.command() == "illusive-is-deceptive-user": return_outputs(*is_deceptive_user_command(client, demisto.args())) elif demisto.command() == "illusive-is-deceptive-server": return_outputs(*is_deceptive_server_command(client, demisto.args())) elif demisto.command() == "illusive-get-incidents": return_outputs(*get_incidents_command(client, demisto.args())) elif demisto.command() == "illusive-get-event-incident-id": return_outputs(*get_event_incident_id_command(client, demisto.args())) elif demisto.command() == "illusive-add-deceptive-users": return_outputs(*add_deceptive_users_command(client, demisto.args())) elif demisto.command() == "illusive-add-deceptive-servers": return_outputs(*add_deceptive_servers_command(client, demisto.args())) elif demisto.command() == "illusive-delete-deceptive-users": return_outputs(*delete_deceptive_users_command(client, demisto.args())) elif demisto.command() == "illusive-delete-deceptive-servers": return_outputs(*delete_deceptive_servers_command(client, demisto.args())) elif demisto.command() == "illusive-assign-host-to-policy": return_outputs(*assign_host_to_policy_command(client, demisto.args())) elif demisto.command() == "illusive-remove-host-from-policy": return_outputs(*remove_host_from_policy_command(client, demisto.args())) elif demisto.command() == "illusive-run-forensics-on-demand": return_outputs(*run_forensics_on_demand_command(client, demisto.args())) elif demisto.command() == "illusive-get-forensics-artifacts": try: file_results, file_names = get_forensics_artifacts_command(client, demisto.args()) return_results(file_results) return_results(link_forensics_artifacts_name_command(file_names, client, demisto.args())) except ValueError: return_results(link_forensics_artifacts_name_command([], client, demisto.args())) elif demisto.command() == "illusive-get-forensics-triggering-process-info": return_outputs(*get_forensics_triggering_process_info_command(client, demisto.args())) elif demisto.command() == "illusive-get-forensics-analyzers": return_outputs(*get_forensics_analyzers_command(client, demisto.args())) elif demisto.command() == "illusive-get-incident-events": return_outputs(*get_incident_events_command(client, demisto.args())) # Log exceptions except Exception as e: return_error(f"Failed to execute {demisto.command()} command. Error: {str(e)}") if __name__ in ("__main__", "__builtin__", "builtins"): main()