microsoft / msticpy

Microsoft Threat Intelligence Security Tools
Other
1.72k stars 310 forks source link

Return Extended Properties for sentinel alerts #782

Open BWC-TomW opened 2 weeks ago

BWC-TomW commented 2 weeks ago

Is your feature request related to a problem? Please describe.

I would like a way to pull more details from the sentinel incident alerts so that I can process the query results.

currently when retrieving incidents you can specify alerts=True however the data returned here is currently heavily limited.

https://github.com/microsoft/msticpy/blob/c0ef238db4ddeaec5b038401c09b28855b88d50b/msticpy/context/azure/sentinel_incidents.py#L116

We have a use case that is currently not using msticpy that retrieves the associated events for a given alert by extracting the query and timeframe from the extended properties. This is currently how it's functioning.

def _get_alert_events(self, alert, limit=None):
    # type: (dict) -> list
    """
    Get event list for alert
    @param alert: Alert
    @param limit {int}: Limit for results
    @return: List of Events
    """
    extended_properties = json.loads(alert.get('ExtendedProperties'))
    start_time = convert_string_to_datetime(extended_properties.get('Query Start Time UTC'), "UTC")\
        .strftime(TIME_FORMAT)
    end_time = convert_string_to_datetime(extended_properties.get('Query End Time UTC'), "UTC")\
        .strftime(TIME_FORMAT)

    query = extended_properties.get('Query')
    timespan = '{}/{}'.format(start_time, end_time)

Describe the solution you'd like

Either a new method for retrieval of alert details for a given alert id or expand the param alerts=True on get_incident to return the entire alert object.

ianhelle commented 3 days ago

Are you using the API to get the additional alert properties or retrieving them via log analytics query? Can you include the full code of the function?

Maybe we change the parameter to also accept a string like alerts="full" or add another parameter "all_alert_details=True"

BWC-TomW commented 3 days ago

Are you using the API to get the additional alert properties or retrieving them via log analytics query? Can you include the full code of the function?

Maybe we change the parameter to also accept a string like alerts="full" or add another parameter "all_alert_details=True"

It's included in the API response, the current behavior is to only return ID, Name when alerts=True

We've made an override like this that dumps all the properties into "OtherProps" as a quick fix

`class MicrosoftSentinelOverides(MicrosoftSentinel): """ Function to overide functionality of MicrosoftSentinel class""" def init(self, kwargs) -> None: super().init(kwargs)

def get_incident_alerts(self, incident: str) -> list:
    """
    Get the alerts from an incident.

    Parameters
    ----------
    incident : str
        Incident GUID or Name.

    Returns
    -------
    list
        A list of alerts.

    """
    self.check_connected()  # type: ignore
    incident_id = self._get_incident_id(incident)
    alerts_url = self.sent_urls["incidents"] + f"/{incident_id}/alerts"  # type: ignore
    alerts_parameters = {"api-version": "2021-04-01"}
    alerts_resp = httpx.post(
        alerts_url,
        headers=get_api_headers(self._token),  # type: ignore
        params=alerts_parameters,
        timeout=get_http_timeout(),
    )
    return (
        [
            {
                "ID": alrts["properties"]["systemAlertId"],
                "Name": alrts["properties"]["alertDisplayName"],
                "OtherProps": alrts["properties"]
            }
            for alrts in alerts_resp.json()["value"]
        ]
        if alerts_resp.status_code == 200
        else []
    )

`

ianhelle commented 1 day ago

thx I've changed the code slightly - it puts the alert properties into a key called "AlertProperties", which I thought sounded a bit more "official". Hope that doesn't mess you up. I will try to publish a new version when this branch gets merged.