Detection rules › Kusto

Malware attachment delivered

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

Status
available
Severity
medium
Time window
1h
Group by
Recipient, Sender, SenderIPAddress, Subject, TimeGenerated, classification, threatType
Source
github.com/Azure/Azure-Sentinel

'This query identifies a message containing a malware attachment that was delivered.'

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1566.001 Phishing: Spearphishing Attachment

Rule body kusto

id: 0558155e-4556-447e-9a22-828f2a7de06b
name: Malware attachment delivered
description: |
  'This query identifies a message containing a malware attachment that was delivered.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: ProofpointTAPv2
    dataTypes:
      - ProofPointTAPMessagesDeliveredV2_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1566.001
query: |
  ProofPointTAPMessagesDeliveredV2_CL
  | mv-expand todynamic(threatsInfoMap)
  | mv-expand todynamic(messageParts)
  | extend threatType = tostring(threatsInfoMap.threatType), classification = tostring(threatsInfoMap.classification)
  | extend filename = tostring(messageParts.filename)
  | where threatType =~ "attachment" and classification =~ "malware"
  | summarize filenames = make_set(filename), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by TimeGenerated, Sender = sender, SenderIPAddress = senderIP, Recipient = tostring(recipient), threatType, classification, Subject = subject
  | mv-expand todynamic(Recipient)
  | extend RecipientName = tostring(split(Recipient, "@")[0]), RecipientUPNSuffix = tostring(split(Recipient, "@")[1])
  | extend SenderName = tostring(split(Sender, "@")[0]), SenderUPNSuffix = tostring(split(Sender, "@")[1])
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Recipient
      - identifier: Name
        columnName: RecipientName
      - identifier: UPNSuffix
        columnName: RecipientUPNSuffix
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Sender
      - identifier: Name
        columnName: SenderName
      - identifier: UPNSuffix
        columnName: SenderUPNSuffix
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SenderIPAddress
version: 1.0.6
kind: Scheduled

Stages and Predicates

Stage 1: source

ProofPointTAPMessagesDeliveredV2_CL

Stage 2: mv-expand

| mv-expand todynamic(threatsInfoMap)

Stage 3: mv-expand

| mv-expand todynamic(messageParts)

Stage 4: extend

| extend threatType = tostring(threatsInfoMap.threatType), classification = tostring(threatsInfoMap.classification)

Stage 5: extend

| extend filename = tostring(messageParts.filename)

Stage 6: where

| where threatType =~ "attachment" and classification =~ "malware"

Stage 7: summarize

| summarize filenames = make_set(filename), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), count() by TimeGenerated, Sender = sender, SenderIPAddress = senderIP, Recipient = tostring(recipient), threatType, classification, Subject = subject

Stage 8: mv-expand

| mv-expand todynamic(Recipient)

Stage 9: extend

| extend RecipientName = tostring(split(Recipient, "@")[0]), RecipientUPNSuffix = tostring(split(Recipient, "@")[1])

Stage 10: extend

| extend SenderName = tostring(split(Sender, "@")[0]), SenderUPNSuffix = tostring(split(Sender, "@")[1])

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
classificationeq
  • malware
threatTypeeq
  • attachment

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
EndTimesummarize
Recipientsummarize
Sendersummarize
SenderIPAddresssummarize
StartTimesummarize
Subjectsummarize
TimeGeneratedsummarize
classificationsummarize
filenamessummarize
threatTypesummarize
RecipientNameextend
RecipientUPNSuffixextend
SenderNameextend
SenderUPNSuffixextend