Detection rules › Splunk

Microsoft Defender ATP Alerts

This is a third-party alert feed, not a detection over modeled telemetry. Another security product raised the finding; this rule forwards or reshapes it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
production
Severity
medium
Group by
description, id, src
Author
Bryan Pluta, Bhavin Patel, Splunk
Source
github.com/splunk/security_content

The following analytic is to leverage alerts from Microsoft Defender ATP Alerts. This query aggregates and summarizes all alerts from Microsoft Defender ATP Alerts, providing details such as the source, file name, severity, process command line, ip address, registry key, signature, description, unique id, and timestamps. This detection is not intended to detect new activity from raw data, but leverages Microsoft provided alerts to be correlated with other data as part of risk based alerting. The data contained in the alert is mapped not only to the risk object, but also the threat object. This detection filters out evidence that has a verdict of clean from Microsoft. It dynamically maps the MITRE technique at search time to auto populate the annotation field with the value provided in the alert. It also uses a dynamic mapping to set the risk score in Enterprise Security based on the severity of the alert.

Known false positives

  • False positives may vary based on Microsfot Defender configuration; monitor and filter out the alerts that are not relevant to your environment.

Rule body

name: Microsoft Defender ATP Alerts
id: 38f034ed-1598-46c8-95e8-14edf05fdf5d
version: 8
creation_date: '2024-10-30'
modification_date: '2026-05-13'
author: Bryan Pluta, Bhavin Patel, Splunk
status: production
type: TTP
description: The following analytic is to leverage alerts from Microsoft Defender ATP Alerts. This query aggregates and summarizes all alerts from Microsoft Defender ATP Alerts, providing details such as the source, file name, severity, process command line, ip address, registry key, signature, description, unique id, and timestamps. This detection is not intended to detect new activity from raw data, but leverages Microsoft provided alerts to be correlated with other data as part of risk based alerting. The data contained in the alert is mapped not only to the risk object, but also the threat object. This detection filters out evidence that has a verdict of clean from Microsoft. It dynamically maps the MITRE technique at search time to auto populate the annotation field with the value provided in the alert. It also uses a dynamic mapping to set the risk score in Enterprise Security based on the severity of the alert.
data_source:
    - MS Defender ATP Alerts
search: "`ms_defender_atp_alerts` (dest=* OR user=*)\n  | eval tmp_evidence=json_extract(_raw, \"evidence\"), tmp_evidencemv=json_array_to_mv(tmp_evidence), entityType = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"entityType\")), filePath = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"filePath\")), processCommandLine = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"processCommandLine\")), ipAddress = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"ipAddress\")), registryKey = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"registryKey\")), url = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"url\")), fileName = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"fileName\"))\n  | eval tmp_evidencemv=mvfilter(json_extract(tmp_evidencemv, \"entityType\") = \"File\"), fileName = mvmap(tmp_evidencemv, spath(tmp_evidencemv, \"fileName\"))\n  | eval risk_score=case(severity=\"informational\", 5, severity=\"low\", 15, severity=\"medium\", 25, severity=\"high\", 50 , true(), 2)\n  | eval processCommandLine=if(processCommandLine=\"null\", \"\", processCommandLine), ipAddress=if(ipAddress=\"null\", \"\", ipAddress), registryKey=if(registryKey=\"null\", \"\", registryKey), url=if(url=\"null\", \"\", url)\n  | stats count min(_time) as firstTime max(_time) as lastTime values(fileName) as file_name values(severity) as severity values(processCommandLine) as process values(ipAddress) as ip_address values(registryKey) as registry_key values(url) as url values(mitreTechniques{}) as annotations.mitre_attack.mitre_technique_id values(signature) as signature values(user) as user values(risk_score) as risk_score\n    BY id description src\n  | `security_content_ctime(firstTime)`\n  | `security_content_ctime(lastTime)`\n  | `microsoft_defender_atp_alerts_filter`"
how_to_implement: In order to properly run this search, you need to ingest alerts data from Microsoft Defender, specifcally using the Splunk add-on for Microsoft Security. This add-on will collect alerts using the ms:defender:atp:alerts sourcetype. You will need to define the `ms_defender_atp_alerts` macro to point to the proper index that contains the ms:defender:atp:alerts sourcetype.
known_false_positives: False positives may vary based on Microsfot Defender configuration; monitor and filter out the alerts that are not relevant to your environment.
references:
    - https://learn.microsoft.com/en-us/defender-xdr/api-list-incidents?view=o365-worldwide
    - https://learn.microsoft.com/en-us/graph/api/resources/security-alert?view=graph-rest-1.0
    - https://splunkbase.splunk.com/app/6207
    - https://jasonconger.com/splunk-azure-gdi/
finding:
    title: $severity$ alert for $src$ - $signature$
    entity:
        field: user
        type: user
        score: 50
intermediate_findings:
    entities:
        - field: src
          type: system
          score: 50
          message: $severity$ alert for $src$ - $signature$
threat_objects:
    - field: file_name
      type: file_name
    - field: ip_address
      type: ip_address
    - field: process
      type: process_name
    - field: registry_key
      type: registry_path
    - field: url
      type: url
analytic_story:
    - Critical Alerts
asset_type: Endpoint
mitre_attack_id: []
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`ms_defender_atp_alerts` (dest=* OR user=*)

Stage 2: eval

| eval tmp_evidence=json_extract(_raw, "evidence"), tmp_evidencemv=json_array_to_mv(tmp_evidence), entityType = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "entityType")), filePath = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "filePath")), processCommandLine = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "processCommandLine")), ipAddress = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "ipAddress")), registryKey = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "registryKey")), url = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "url")), fileName = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "fileName"))

Stage 3: eval

| eval tmp_evidencemv=mvfilter(json_extract(tmp_evidencemv, "entityType") = "File"), fileName = mvmap(tmp_evidencemv, spath(tmp_evidencemv, "fileName"))

Stage 4: eval

| eval risk_score=case(severity="informational", 5, severity="low", 15, severity="medium", 25, severity="high", 50 , true(), 2)
risk_score =
ifseverity = "informational"5
elifseverity = "low"15
elifseverity = "medium"25
elifseverity = "high"50
else2

Stage 5: eval

| eval processCommandLine=if(processCommandLine="null", "", processCommandLine), ipAddress=if(ipAddress="null", "", ipAddress), registryKey=if(registryKey="null", "", registryKey), url=if(url="null", "", url)
ipAddress =
ifipAddress = "null"""
elseipAddress
processCommandLine =
ifprocessCommandLine = "null"""
elseprocessCommandLine
registryKey =
ifregistryKey = "null"""
elseregistryKey
url =
ifurl = "null"""
elseurl

Stage 6: stats

| stats count min(_time) as firstTime max(_time) as lastTime values(fileName) as file_name values(severity) as severity values(processCommandLine) as process values(ipAddress) as ip_address values(registryKey) as registry_key values(url) as url values(mitreTechniques{}) as annotations.mitre_attack.mitre_technique_id values(signature) as signature values(user) as user values(risk_score) as risk_score
    BY id description src

Stage 7: search

| `security_content_ctime(firstTime)`

Stage 8: search

| `security_content_ctime(lastTime)`

Stage 9: search

| `microsoft_defender_atp_alerts_filter`

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
desteq
  • * corpus 2 (splunk 2)
field:"dest" kind:eq value:"*"
sourcetypeeq
  • ms:defender:atp:alerts
field:"sourcetype" kind:eq value:"ms:defender:atp:alerts"
usereq
  • * corpus 2 (splunk 2)
field:"user" kind:eq value:"*"