Abnormal Security Event Collector
Abnormal Security Event Collector integration for XSIAM.
Analytics & SIEM · Abnormal Security
Details
| ID | Abnormal Security Event Collector |
|---|---|
| Provider | Abnormal Security |
| Category | Analytics & SIEM |
| From Version | 6.8.0 |
| Docker Image | demisto/python3:3.12.13.10404775 |
| Supported Modules | Agentix XSIAM |
README
Abnormal Security Event Collector integration for XSIAM.
This integration was integrated and tested with version 01 of Abnormal Security Event Collector
This is the default integration for this content pack when configured by the Data Onboarder in Cortex XSIAM.
Configure Abnormal Security Event Collector in Cortex
| Parameter | Required |
|---|---|
| Token | True |
| First fetch time interval | False |
| Use system proxy settings | False |
| Trust any certificate (not secure) | 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.
abnormal-security-event-collector-get-events
Manual command to fetch events and display them.
Base Command
abnormal-security-event-collector-get-events
Input
| Argument Name | Description | Required |
|---|---|---|
| should_push_events | Set this argument to True in order to create events, otherwise the command will only display them. Possible values are: True, False. Default is False. | Required |
Context Output
There is no context output for this command.
Note
This integration only fetches threats.
Configuration parameters
token— (required)proxy— Use system proxy settingsverify— Trust any certificate (not secure)after— First fetch time interval
Commands (1)
-
abnormal-security-event-collector-get-eventsManual command to fetch events.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 VENDOR = "Abnormal_Security" PRODUCT = "Email_Protection" FETCH_LIMIT = 9000 DEFAULT_PAGE_SIZE = 1000 class Client(BaseClient): def list_threats(self, params): return self._http_request("GET", params=params, url_suffix="threats") def get_threat(self, threat_id): return self._http_request("GET", url_suffix=f"threats/{threat_id}") def format_messages(messages: list): """change the messages into the desired form 1. change the toAddresses value to a list. Args: messages(list): the messages list to check. Returns: list: the reorganised messages. """ for message in messages: to_addresses = message.get("toAddresses") if isinstance(to_addresses, str): message["toAddresses"] = argToList(to_addresses) return messages def get_events(client: Client, after: str, before: str, next_page_number: int): """Retrieves messages by time range & ordered by datetime Args: client (Client): Abnormal Security client. after (str): the start datetime to search messages. before (str): the end datetime to search messages. next_page_number (int): the page number of the next page to search threats. Returns: list: messages ordered by datetime. str: the last run to be set for the next run. """ if not before: before = arg_to_datetime(arg="now", arg_name="before", required=True).strftime("%Y-%m-%dT%H:%M:%SZ") # type: ignore demisto.debug(f"Calling get_list_threats with: {after=}, {before=}, {next_page_number=}") next_page_number, threats_ids = get_list_threats(client, after, before, next_page_number) last_run = {"before": before, "after": after, "next_page_number": next_page_number} messages = [] if threats_ids: for threat in reversed(threats_ids): messages += format_messages(get_messages_by_datetime(client, threat.get("threatId"), after, before)) ordered_messages = sorted(messages, key=lambda d: d["receivedTime"]) return ordered_messages, last_run return [], last_run def get_messages_by_datetime(client: Client, threat_id: str, after: str, before: str): """get messages from a threat and return only the messages that are in the time range Args: client (Client): Abnormal Security client. threat_id (str): the threat to get messages. after (str): the datetime to search messages after that. before (str): the datetime to search messages before that. Returns: list: messages filtered by the time range. """ messages = [] res = client.get_threat(threat_id) for message in res.get("messages"): # messages are ordered from newest to oldest received_time = message.get("receivedTime") if before >= received_time >= after: messages.append(message) elif received_time < after: break return messages def get_list_threats(client: Client, after: str, before: str, next_page_number: int): """get list of all threats ids in the time range Args: client (Client): Abnormal Security client. after (str): the datetime to search threats after that. before (str): the datetime to search threats before that. next_page_number (int): the page number of the next page to search threats. Returns: list: list of threats ids. """ threats: List[dict[str, Any]] = [] is_next_page = True while len(threats) < FETCH_LIMIT and is_next_page: page_size = min(DEFAULT_PAGE_SIZE, FETCH_LIMIT - len(threats)) demisto.debug(f"fetching events: epoch {next_page_number}, {page_size=}") params = assign_params(pageSize=page_size, filter=f"receivedTime gte {after} lte {before}", pageNumber=next_page_number) demisto.debug(f"calling list_threats with {params=}") res = client.list_threats(params) demisto.debug(f"fetched {len(res.get('threats'))} events") threats += res.get("threats") if res.get("nextPageNumber"): next_page_number = res.get("nextPageNumber") demisto.debug(f"There are more events to fetch. {next_page_number=}") else: demisto.debug("no more events to fetch") is_next_page = False return (next_page_number, threats) if is_next_page else (1, threats) def main(): # pragma: no cover # Args is always stronger. Get last run even stronger params = demisto.params() token = params["token"]["password"] verify = params.get("verify", False) proxy = params.get("proxy", False) after = arg_to_datetime(arg="1 minute").strftime("%Y-%m-%dT%H:%M:%SZ") # type: ignore before: str = "" next_page_number = 1 client = Client( base_url="https://api.abnormalplatform.com/v1", verify=verify, proxy=proxy, headers={"Authorization": f"Bearer {token}"} ) last_run = demisto.getLastRun() demisto.debug(f"{last_run=}") if last_run: next_page_number = last_run.get("next_page_number", 1) if next_page_number > 1: after = last_run.get("after") before = last_run.get("before") else: after = last_run.get("before") command = demisto.command() demisto.debug(f"Command being called is {command}") try: threats, last_run = get_events(client, after, before, next_page_number) if command == "test-module": return_results("ok") elif command == "fetch-events": send_events_to_xsiam(threats, VENDOR, PRODUCT) demisto.debug(f"calling setLastRun: {last_run=}") demisto.setLastRun(last_run) elif command == "abnormal-security-event-collector-get-events": command_results = CommandResults( readable_output=tableToMarkdown(f"{VENDOR} - {PRODUCT} events", threats), raw_response=threats, ) return_results(command_results) if argToBoolean(demisto.args().get("should_push_events", False)): send_events_to_xsiam(threats, VENDOR, PRODUCT) except Exception as e: return_error(str(e)) if __name__ in ("__main__", "__builtin__", "builtins"): main()