Detection rules › Kusto

ProofpointPOD - Multiple protected emails to unknown recipient

Status
available
Severity
medium
Time window
30m
Group by
SrcUserUpn, commcol
Source
github.com/Azure/Azure-Sentinel

'Detects when multiple protected messages where sent to early not seen recipient.'

MITRE ATT&CK coverage

TacticTechniques
Exfiltration

Rule body

id: f8127962-7739-4211-a4a9-390a7a00e91f
name: ProofpointPOD - Multiple protected emails to unknown recipient
description: |
  'Detects when multiple protected messages where sent to early not seen recipient.'
severity: Medium
status: Available 
requiredDataConnectors:
  - connectorId: ProofpointPOD
    dataTypes:
      - ProofpointPOD_message_CL
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
relevantTechniques:
- T1567
query: |
  let lbtime = 30m;
  let lbperiod = 14d;
  let knownrecipients = ProofpointPOD
  | where TimeGenerated > ago(lbperiod)
  | where EventType == 'message'
  | where NetworkDirection == 'outbound'
  | where SrcUserUpn != ''
  | where array_length(todynamic(DstUserUpn)) == 1
  | summarize recipients = make_set(tostring(todynamic(DstUserUpn)[0])) by SrcUserUpn
  | extend commcol = SrcUserUpn;
  ProofpointPOD
  | where TimeGenerated between (ago(lbtime) .. now())
  | where EventType == 'message'
  | where NetworkDirection == 'outbound'
  | extend isProtected = todynamic(MsgParts)[0]['isProtected']
  | extend mimePgp = todynamic(MsgParts)[0]['detectedMime']
  | where isProtected == 'true' or mimePgp == 'application/pgp-encrypted'
  | extend DstUserMail = tostring(todynamic(DstUserUpn)[0])
  | extend commcol = tostring(todynamic(DstUserUpn)[0])
  | join knownrecipients on commcol
  | where recipients !contains DstUserMail
  | project SrcUserUpn, DstUserMail
  | extend AccountCustomEntity = SrcUserUpn
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountCustomEntity
version: 1.1.1
kind: Scheduled

Stages and Predicates

Parameters

let lbtime = 30m;
let lbperiod = 14d;

Let binding: knownrecipients used in Stage 10

let knownrecipients = ProofpointPOD
| where TimeGenerated > ago(lbperiod)
| where EventType == 'message'
| where NetworkDirection == 'outbound'
| where SrcUserUpn != ''
| where array_length(todynamic(DstUserUpn)) == 1
| summarize recipients = make_set(tostring(todynamic(DstUserUpn)[0])) by SrcUserUpn
| extend commcol = SrcUserUpn;

Stage 1: source

ProofpointPOD

Stage 2: where

| where TimeGenerated between (ago(lbtime) .. now())

Stage 3: where

| where EventType == 'message'

Stage 4: where

| where NetworkDirection == 'outbound'

Stage 5: extend

| extend isProtected = todynamic(MsgParts)[0]['isProtected']

Stage 6: extend

| extend mimePgp = todynamic(MsgParts)[0]['detectedMime']

Stage 7: where

| where isProtected == 'true' or mimePgp == 'application/pgp-encrypted'

Stage 8: extend

| extend DstUserMail = tostring(todynamic(DstUserUpn)[0])

Stage 9: extend

| extend commcol = tostring(todynamic(DstUserUpn)[0])

Stage 10: join

| join knownrecipients on commcol

Stage 11: where

| where recipients !contains DstUserMail

Stage 12: project

| project SrcUserUpn, DstUserMail

Stage 13: extend

| extend AccountCustomEntity = SrcUserUpn

Stage 14: summarize aggregation inside the join branch

summarize by SrcUserUpn

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
SrcUserUpnsummarize