Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Red Sift - New email with URL from previously unseen source

Back
Id6084dfd8-830b-4839-9a9c-5f08cc984729
RulenameRed Sift - New email with URL from previously unseen source
DescriptionDetects email forensics events that contain one or more URLs where the sender is using a source IP address not seen in the previous 14 days, which may indicate suspicious infrastructure changes or phishing activity.
SeverityMedium
TacticsInitialAccess
TechniquesT1566
Required data connectorsRedSiftPush
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Red Sift/Analytic Rules/RedSiftEmailUrlFromNewSource.yaml
Version1.0.0
Arm template6084dfd8-830b-4839-9a9c-5f08cc984729.json
Deploy To Azure
let lookback = 14d;
let recentWindow = 1h;
let historicalSources = RedSiftEmailForensics_CL
| extend
    EmailFrom = tostring(column_ifexists("EmailFrom", "")),
    SrcIp = tostring(column_ifexists("SrcIp", ""))
| where TimeGenerated between (ago(lookback) .. ago(recentWindow))
| where isnotempty(EmailFrom) and isnotempty(SrcIp)
| summarize by EmailFrom, SrcIp;
RedSiftEmailForensics_CL
| extend
    EmailFrom = tostring(column_ifexists("EmailFrom", "")),
    EmailSubject = tostring(column_ifexists("EmailSubject", "")),
    EmailReturnPath = tostring(column_ifexists("EmailReturnPath", "")),
    EmailMessageUid = tostring(column_ifexists("EmailMessageUid", "")),
    SrcIp = tostring(column_ifexists("SrcIp", "")),
    DstHostname = tostring(column_ifexists("DstHostname", "")),
    Severity = tostring(column_ifexists("Severity", "")),
    Message = tostring(column_ifexists("Message", "")),
    CorrelationUid = tostring(column_ifexists("CorrelationUid", "")),
    EmailUrls = todynamic(column_ifexists("EmailUrls", "[]"))
| where TimeGenerated >= ago(recentWindow)
| where isnotempty(EmailFrom) and isnotempty(SrcIp)
| extend UrlCount = array_length(EmailUrls)
| where UrlCount > 0
| mv-apply Url = EmailUrls on (
    summarize UrlSet = make_set(tostring(Url.url_string), 50)
  )
| extend UrlList = strcat_array(UrlSet, ", ")
| join kind=leftanti (historicalSources) on EmailFrom, SrcIp
| project
    TimeGenerated,
    EmailFrom,
    EmailSubject,
    EmailReturnPath,
    EmailMessageUid,
    SrcIp,
    DstHostname,
    UrlCount,
    UrlList,
    Severity,
    Message,
    CorrelationUid
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: EmailFrom
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIp
- entityType: DNS
  fieldMappings:
  - identifier: DomainName
    columnName: DstHostname
tactics:
- InitialAccess
suppressionEnabled: false
suppressionDuration: PT1H
requiredDataConnectors:
- dataTypes:
  - RedSiftEmailForensics_CL
  connectorId: RedSiftPush
alertDetailsOverride:
  alertDisplayNameFormat: RedSift - New URL-bearing email source for {{EmailFrom}}
  alertDescriptionFormat: Email from {{EmailFrom}} contains {{UrlCount}} URL(s) and originated from previously unseen source IP {{SrcIp}}.
incidentConfiguration:
  groupingConfiguration:
    reopenClosedIncident: false
    lookbackDuration: P1D
    groupByEntities:
    - Account
    - IP
    groupByCustomDetails:
    - EmailSubject
    enabled: true
    matchingMethod: Selected
  createIncident: true
id: 6084dfd8-830b-4839-9a9c-5f08cc984729
severity: Medium
eventGroupingSettings:
  aggregationKind: AlertPerResult
status: Available
customDetails:
  EmailSubject: EmailSubject
  UrlCount: UrlCount
  CorrelationUid: CorrelationUid
  UrlList: UrlList
  ReturnPath: EmailReturnPath
query: |
  let lookback = 14d;
  let recentWindow = 1h;
  let historicalSources = RedSiftEmailForensics_CL
  | extend
      EmailFrom = tostring(column_ifexists("EmailFrom", "")),
      SrcIp = tostring(column_ifexists("SrcIp", ""))
  | where TimeGenerated between (ago(lookback) .. ago(recentWindow))
  | where isnotempty(EmailFrom) and isnotempty(SrcIp)
  | summarize by EmailFrom, SrcIp;
  RedSiftEmailForensics_CL
  | extend
      EmailFrom = tostring(column_ifexists("EmailFrom", "")),
      EmailSubject = tostring(column_ifexists("EmailSubject", "")),
      EmailReturnPath = tostring(column_ifexists("EmailReturnPath", "")),
      EmailMessageUid = tostring(column_ifexists("EmailMessageUid", "")),
      SrcIp = tostring(column_ifexists("SrcIp", "")),
      DstHostname = tostring(column_ifexists("DstHostname", "")),
      Severity = tostring(column_ifexists("Severity", "")),
      Message = tostring(column_ifexists("Message", "")),
      CorrelationUid = tostring(column_ifexists("CorrelationUid", "")),
      EmailUrls = todynamic(column_ifexists("EmailUrls", "[]"))
  | where TimeGenerated >= ago(recentWindow)
  | where isnotempty(EmailFrom) and isnotempty(SrcIp)
  | extend UrlCount = array_length(EmailUrls)
  | where UrlCount > 0
  | mv-apply Url = EmailUrls on (
      summarize UrlSet = make_set(tostring(Url.url_string), 50)
    )
  | extend UrlList = strcat_array(UrlSet, ", ")
  | join kind=leftanti (historicalSources) on EmailFrom, SrcIp
  | project
      TimeGenerated,
      EmailFrom,
      EmailSubject,
      EmailReturnPath,
      EmailMessageUid,
      SrcIp,
      DstHostname,
      UrlCount,
      UrlList,
      Severity,
      Message,
      CorrelationUid  
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Red Sift/Analytic Rules/RedSiftEmailUrlFromNewSource.yaml
kind: Scheduled
queryPeriod: 14d
version: 1.0.0
name: Red Sift - New email with URL from previously unseen source
queryFrequency: 1h
triggerThreshold: 0
relevantTechniques:
- T1566
description: |
    'Detects email forensics events that contain one or more URLs where the sender is using a source IP address not seen in the previous 14 days, which may indicate suspicious infrastructure changes or phishing activity.'
triggerOperator: gt