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

Phishing link click observed in Network Traffic

Back
Id2fed0668-6d43-4c78-87e6-510f96f12145
RulenamePhishing link click observed in Network Traffic
DescriptionThe purpose of this content is to identify successful phishing links accessed by users. Once a user clicks on a phishing link, we observe successful network activity originating from non-Microsoft network devices. These devices may include Palo Alto Networks, Fortinet, Check Point, and Zscaler devices.
SeverityMedium
TacticsInitialAccess
TechniquesT1566
Required data connectorsCheckPoint
Fortinet
OfficeATP
PaloAltoNetworks
Zscaler
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/PhishinglinkExecutionObserved.yaml
Version1.0.4
Arm template2fed0668-6d43-4c78-87e6-510f96f12145.json
Deploy To Azure
//Finding MDO Security alerts and extracting the Entities user, Domain, Ip, and URL.
let Alert_List= dynamic([
"Phishing link click observed in Network Traffic",
"Phish delivered due to an IP allow policy",
"A potentially malicious URL click was detected",
"High Risk Sign-in Observed in Network Traffic",
"A user clicked through to a potentially malicious URL",
"Suspicious network connection to AitM phishing site",
"Messages containing malicious entity not removed after delivery",
"Email messages containing malicious URL removed after delivery",
"Email reported by user as malware or phish",
"Phish delivered due to an ETR override",
"Phish not zapped because ZAP is disabled"]);
SecurityAlert
|where ProviderName in~ ("Office 365 Advanced Threat Protection", "OATP")
| where AlertName in~ (Alert_List)
//extracting Alert Entities
 | extend Entities = parse_json(Entities)
| mv-apply Entity = Entities on
(
where Entity.Type == 'account'
| extend EntityUPN = iff(isempty(Entity.UserPrincipalName), tostring(strcat(Entity.Name, "@", tostring (Entity.UPNSuffix))), tostring(Entity.UserPrincipalName))
)
| mv-apply Entity = Entities on
(
where Entity.Type == 'url'
| extend EntityUrl = tostring(Entity.Url)
)
| summarize AccountUpn=tolower(tostring(take_any(EntityUPN))),Url=tostring(tolower(take_any(EntityUrl))),AlertTime= min(TimeGenerated)by SystemAlertId, ProductName
// filtering 3pnetwork devices
| join kind= inner (CommonSecurityLog
| where DeviceVendor has_any  ("Palo Alto Networks", "Fortinet", "Check Point", "Zscaler")
| where DeviceAction != "Block"
| where DeviceProduct startswith "FortiGate" or DeviceProduct startswith  "PAN" or DeviceProduct startswith  "VPN" or DeviceProduct startswith "FireWall" or DeviceProduct startswith  "NSSWeblog" or DeviceProduct startswith "URL"
| where isnotempty(RequestURL)
| where isnotempty(SourceUserName)
| extend SourceUserName = tolower(SourceUserName)
| project
3plogTime=TimeGenerated,
DeviceVendor,
DeviceProduct,
Activity,
DestinationHostName,
DestinationIP,
RequestURL=tostring(tolower(RequestURL)),
MaliciousIP,
Name = tostring(split(SourceUserName,"@")[0]),
UPNSuffix =tostring(split(SourceUserName,"@")[1]),
SourceUserName,
IndicatorThreatType,
ThreatSeverity,AdditionalExtensions,
ThreatConfidence)on $left.Url == $right.RequestURL and $left.AccountUpn == $right.SourceUserName
// Applied the condition where alert trigger 1st and then the 3p Network activity execution
| where AlertTime between ((3plogTime - 1h) .. (3plogTime + 1h))
relevantTechniques:
- T1566
name: Phishing link click observed in Network Traffic
requiredDataConnectors:
- dataTypes:
  - SecurityAlert
  connectorId: OfficeATP
- dataTypes:
  - CommonSecurityLog (PaloAlto)
  connectorId: PaloAltoNetworks
- dataTypes:
  - CommonSecurityLog (Fortinet)
  connectorId: Fortinet
- dataTypes:
  - CommonSecurityLog (CheckPoint)
  connectorId: CheckPoint
- dataTypes:
  - CommonSecurityLog (Zscaler)
  connectorId: Zscaler
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: SourceUserName
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: DestinationIP
  entityType: IP
- fieldMappings:
  - identifier: DomainName
    columnName: DestinationHostName
  entityType: DNS
triggerThreshold: 0
id: 2fed0668-6d43-4c78-87e6-510f96f12145
tactics:
- InitialAccess
version: 1.0.4
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/PhishinglinkExecutionObserved.yaml
queryPeriod: 1d
kind: Scheduled
metadata:
  categories:
    domains:
    - Security - Threat Protection
  author:
    name: Microsoft Security Research
  support:
    tier: Community
  source:
    kind: Community
queryFrequency: 1d
severity: Medium
description: |
    'The purpose of this content is to identify successful phishing links accessed by users. Once a user clicks on a phishing link, we observe successful network activity originating from non-Microsoft network devices. These devices may include Palo Alto Networks, Fortinet, Check Point, and Zscaler devices.'
query: |
  //Finding MDO Security alerts and extracting the Entities user, Domain, Ip, and URL.
  let Alert_List= dynamic([
  "Phishing link click observed in Network Traffic",
  "Phish delivered due to an IP allow policy",
  "A potentially malicious URL click was detected",
  "High Risk Sign-in Observed in Network Traffic",
  "A user clicked through to a potentially malicious URL",
  "Suspicious network connection to AitM phishing site",
  "Messages containing malicious entity not removed after delivery",
  "Email messages containing malicious URL removed after delivery",
  "Email reported by user as malware or phish",
  "Phish delivered due to an ETR override",
  "Phish not zapped because ZAP is disabled"]);
  SecurityAlert
  |where ProviderName in~ ("Office 365 Advanced Threat Protection", "OATP")
  | where AlertName in~ (Alert_List)
  //extracting Alert Entities
   | extend Entities = parse_json(Entities)
  | mv-apply Entity = Entities on
  (
  where Entity.Type == 'account'
  | extend EntityUPN = iff(isempty(Entity.UserPrincipalName), tostring(strcat(Entity.Name, "@", tostring (Entity.UPNSuffix))), tostring(Entity.UserPrincipalName))
  )
  | mv-apply Entity = Entities on
  (
  where Entity.Type == 'url'
  | extend EntityUrl = tostring(Entity.Url)
  )
  | summarize AccountUpn=tolower(tostring(take_any(EntityUPN))),Url=tostring(tolower(take_any(EntityUrl))),AlertTime= min(TimeGenerated)by SystemAlertId, ProductName
  // filtering 3pnetwork devices
  | join kind= inner (CommonSecurityLog
  | where DeviceVendor has_any  ("Palo Alto Networks", "Fortinet", "Check Point", "Zscaler")
  | where DeviceAction != "Block"
  | where DeviceProduct startswith "FortiGate" or DeviceProduct startswith  "PAN" or DeviceProduct startswith  "VPN" or DeviceProduct startswith "FireWall" or DeviceProduct startswith  "NSSWeblog" or DeviceProduct startswith "URL"
  | where isnotempty(RequestURL)
  | where isnotempty(SourceUserName)
  | extend SourceUserName = tolower(SourceUserName)
  | project
  3plogTime=TimeGenerated,
  DeviceVendor,
  DeviceProduct,
  Activity,
  DestinationHostName,
  DestinationIP,
  RequestURL=tostring(tolower(RequestURL)),
  MaliciousIP,
  Name = tostring(split(SourceUserName,"@")[0]),
  UPNSuffix =tostring(split(SourceUserName,"@")[1]),
  SourceUserName,
  IndicatorThreatType,
  ThreatSeverity,AdditionalExtensions,
  ThreatConfidence)on $left.Url == $right.RequestURL and $left.AccountUpn == $right.SourceUserName
  // Applied the condition where alert trigger 1st and then the 3p Network activity execution
  | where AlertTime between ((3plogTime - 1h) .. (3plogTime + 1h))  
triggerOperator: gt
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/2fed0668-6d43-4c78-87e6-510f96f12145')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/2fed0668-6d43-4c78-87e6-510f96f12145')]",
      "properties": {
        "alertRuleTemplateName": "2fed0668-6d43-4c78-87e6-510f96f12145",
        "customDetails": null,
        "description": "'The purpose of this content is to identify successful phishing links accessed by users. Once a user clicks on a phishing link, we observe successful network activity originating from non-Microsoft network devices. These devices may include Palo Alto Networks, Fortinet, Check Point, and Zscaler devices.'\n",
        "displayName": "Phishing link click observed in Network Traffic",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "SourceUserName",
                "identifier": "FullName"
              },
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "DestinationIP",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "DNS",
            "fieldMappings": [
              {
                "columnName": "DestinationHostName",
                "identifier": "DomainName"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/PhishinglinkExecutionObserved.yaml",
        "query": "//Finding MDO Security alerts and extracting the Entities user, Domain, Ip, and URL.\nlet Alert_List= dynamic([\n\"Phishing link click observed in Network Traffic\",\n\"Phish delivered due to an IP allow policy\",\n\"A potentially malicious URL click was detected\",\n\"High Risk Sign-in Observed in Network Traffic\",\n\"A user clicked through to a potentially malicious URL\",\n\"Suspicious network connection to AitM phishing site\",\n\"Messages containing malicious entity not removed after delivery\",\n\"Email messages containing malicious URL removed after delivery\",\n\"Email reported by user as malware or phish\",\n\"Phish delivered due to an ETR override\",\n\"Phish not zapped because ZAP is disabled\"]);\nSecurityAlert\n|where ProviderName in~ (\"Office 365 Advanced Threat Protection\", \"OATP\")\n| where AlertName in~ (Alert_List)\n//extracting Alert Entities\n | extend Entities = parse_json(Entities)\n| mv-apply Entity = Entities on\n(\nwhere Entity.Type == 'account'\n| extend EntityUPN = iff(isempty(Entity.UserPrincipalName), tostring(strcat(Entity.Name, \"@\", tostring (Entity.UPNSuffix))), tostring(Entity.UserPrincipalName))\n)\n| mv-apply Entity = Entities on\n(\nwhere Entity.Type == 'url'\n| extend EntityUrl = tostring(Entity.Url)\n)\n| summarize AccountUpn=tolower(tostring(take_any(EntityUPN))),Url=tostring(tolower(take_any(EntityUrl))),AlertTime= min(TimeGenerated)by SystemAlertId, ProductName\n// filtering 3pnetwork devices\n| join kind= inner (CommonSecurityLog\n| where DeviceVendor has_any  (\"Palo Alto Networks\", \"Fortinet\", \"Check Point\", \"Zscaler\")\n| where DeviceAction != \"Block\"\n| where DeviceProduct startswith \"FortiGate\" or DeviceProduct startswith  \"PAN\" or DeviceProduct startswith  \"VPN\" or DeviceProduct startswith \"FireWall\" or DeviceProduct startswith  \"NSSWeblog\" or DeviceProduct startswith \"URL\"\n| where isnotempty(RequestURL)\n| where isnotempty(SourceUserName)\n| extend SourceUserName = tolower(SourceUserName)\n| project\n3plogTime=TimeGenerated,\nDeviceVendor,\nDeviceProduct,\nActivity,\nDestinationHostName,\nDestinationIP,\nRequestURL=tostring(tolower(RequestURL)),\nMaliciousIP,\nName = tostring(split(SourceUserName,\"@\")[0]),\nUPNSuffix =tostring(split(SourceUserName,\"@\")[1]),\nSourceUserName,\nIndicatorThreatType,\nThreatSeverity,AdditionalExtensions,\nThreatConfidence)on $left.Url == $right.RequestURL and $left.AccountUpn == $right.SourceUserName\n// Applied the condition where alert trigger 1st and then the 3p Network activity execution\n| where AlertTime between ((3plogTime - 1h) .. (3plogTime + 1h))\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1566"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}