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

Malicious web application requests linked with Microsoft Defender for Endpoint formerly Microsoft Defender ATP alerts

Back
Idfbfbf530-506b-49a4-81ad-4030885a195c
RulenameMalicious web application requests linked with Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts
DescriptionTakes Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts where web scripts are present in the evidence and correlates with requests made to those scripts

in the WCSIISLog to surface new alerts for potentially malicious web request activity.

The lookback for alerts is set to 1h and the lookback for W3CIISLogs is set to 7d. A sample set of popular web script extensions

has been provided in scriptExtensions that should be tailored to your environment.
SeverityMedium
TacticsPersistence
TechniquesT1505
Required data connectorsAzureMonitor(IIS)
MicrosoftDefenderAdvancedThreatProtection
KindScheduled
Query frequency1h
Query period7d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Shells Threat Protection/Analytic Rules/MaliciousAlertLinkedWebRequests.yaml
Version1.0.3
Arm templatefbfbf530-506b-49a4-81ad-4030885a195c.json
Deploy To Azure
let alertTimeWindow = 1h;
let logTimeWindow = 7d;
// Define script extensions that suit your web application environment - a sample are provided below
let scriptExtensions = dynamic([".php", ".jsp", ".js", ".aspx", ".asmx", ".asax", ".cfm", ".shtml"]);
let alertData = materialize(SecurityAlert
| where TimeGenerated > ago(alertTimeWindow)
| where ProviderName == "MDATP"
// Parse and expand the alert JSON
| extend alertData = parse_json(Entities)
| mvexpand alertData);
let fileData = alertData
// Extract web script files from MDATP alerts - our malicious web scripts - candidate webshells
| where alertData.Type =~ "file"
| where alertData.Name has_any(scriptExtensions)
| extend FileName = tostring(alertData.Name), Directory = tostring(alertData.Directory);
let hostData = alertData
// Extract server details from alerts and map to alert id
| where alertData.Type =~ "host"
| project HostName = tostring(alertData.HostName), DnsDomain = tostring(alertData.DnsDomain), SystemAlertId
| distinct HostName, DnsDomain, SystemAlertId;
// Join the files on their impacted servers
let webshellData = fileData
| join kind=inner (hostData) on SystemAlertId
| project TimeGenerated, FileName, Directory, HostName, DnsDomain;
webshellData
| join (
// Find requests that were made to this file on the impacted server in the W3CIISLog table
W3CIISLog
| where TimeGenerated > ago(logTimeWindow)
// Restrict to accesses to script extensions
| where csUriStem has_any(scriptExtensions)
| extend splitUriStem = split(csUriStem, "/")
| extend FileName = splitUriStem[-1], HostName = sComputerName
// Summarize potential attacker activity
| summarize count(), StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), RequestUserAgents=make_set(csUserAgent), ReqestMethods=make_set(csMethod), RequestStatusCodes=make_set(scStatus), RequestCookies=make_set(csCookie), RequestReferers=make_set(csReferer), RequestQueryStrings=make_set(csUriQuery) by AttackerIP=cIP, SiteName=sSiteName, ShellLocation=csUriStem, tostring(FileName), HostName
) on FileName, HostName
| project StartTime, EndTime, AttackerIP, RequestUserAgents, Computer = HostName, SiteName, ShellLocation, ReqestMethods, RequestStatusCodes, RequestCookies, RequestReferers, RequestQueryStrings, RequestCount = count_
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
triggerOperator: gt
queryFrequency: 1h
description: |
  'Takes Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts where web scripts are present in the evidence and correlates with requests made to those scripts
  in the WCSIISLog to surface new alerts for potentially malicious web request activity.
  The lookback for alerts is set to 1h and the lookback for W3CIISLogs is set to 7d. A sample set of popular web script extensions
  has been provided in scriptExtensions that should be tailored to your environment.'  
version: 1.0.3
kind: Scheduled
triggerThreshold: 0
requiredDataConnectors:
- connectorId: MicrosoftDefenderAdvancedThreatProtection
  dataTypes:
  - SecurityAlert
- connectorId: AzureMonitor(IIS)
  dataTypes:
  - W3CIISLog
queryPeriod: 7d
name: Malicious web application requests linked with Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Shells Threat Protection/Analytic Rules/MaliciousAlertLinkedWebRequests.yaml
id: fbfbf530-506b-49a4-81ad-4030885a195c
tactics:
- Persistence
metadata:
  source:
    kind: Scheduled
  author:
    name: Microsoft Security Research
  categories:
    domains:
    - Security - Others
  support:
    tier: Community
relevantTechniques:
- T1505
severity: Medium
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: Computer
  - identifier: HostName
    columnName: HostName
  - identifier: DnsDomain
    columnName: HostNameDomain
  entityType: Host
- fieldMappings:
  - identifier: Address
    columnName: AttackerIP
  entityType: IP
query: |
  let alertTimeWindow = 1h;
  let logTimeWindow = 7d;
  // Define script extensions that suit your web application environment - a sample are provided below
  let scriptExtensions = dynamic([".php", ".jsp", ".js", ".aspx", ".asmx", ".asax", ".cfm", ".shtml"]);
  let alertData = materialize(SecurityAlert
  | where TimeGenerated > ago(alertTimeWindow)
  | where ProviderName == "MDATP"
  // Parse and expand the alert JSON
  | extend alertData = parse_json(Entities)
  | mvexpand alertData);
  let fileData = alertData
  // Extract web script files from MDATP alerts - our malicious web scripts - candidate webshells
  | where alertData.Type =~ "file"
  | where alertData.Name has_any(scriptExtensions)
  | extend FileName = tostring(alertData.Name), Directory = tostring(alertData.Directory);
  let hostData = alertData
  // Extract server details from alerts and map to alert id
  | where alertData.Type =~ "host"
  | project HostName = tostring(alertData.HostName), DnsDomain = tostring(alertData.DnsDomain), SystemAlertId
  | distinct HostName, DnsDomain, SystemAlertId;
  // Join the files on their impacted servers
  let webshellData = fileData
  | join kind=inner (hostData) on SystemAlertId
  | project TimeGenerated, FileName, Directory, HostName, DnsDomain;
  webshellData
  | join (
  // Find requests that were made to this file on the impacted server in the W3CIISLog table
  W3CIISLog
  | where TimeGenerated > ago(logTimeWindow)
  // Restrict to accesses to script extensions
  | where csUriStem has_any(scriptExtensions)
  | extend splitUriStem = split(csUriStem, "/")
  | extend FileName = splitUriStem[-1], HostName = sComputerName
  // Summarize potential attacker activity
  | summarize count(), StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), RequestUserAgents=make_set(csUserAgent), ReqestMethods=make_set(csMethod), RequestStatusCodes=make_set(scStatus), RequestCookies=make_set(csCookie), RequestReferers=make_set(csReferer), RequestQueryStrings=make_set(csUriQuery) by AttackerIP=cIP, SiteName=sSiteName, ShellLocation=csUriStem, tostring(FileName), HostName
  ) on FileName, HostName
  | project StartTime, EndTime, AttackerIP, RequestUserAgents, Computer = HostName, SiteName, ShellLocation, ReqestMethods, RequestStatusCodes, RequestCookies, RequestReferers, RequestQueryStrings, RequestCount = count_
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)  
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/fbfbf530-506b-49a4-81ad-4030885a195c')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/fbfbf530-506b-49a4-81ad-4030885a195c')]",
      "properties": {
        "alertRuleTemplateName": "fbfbf530-506b-49a4-81ad-4030885a195c",
        "customDetails": null,
        "description": "'Takes Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts where web scripts are present in the evidence and correlates with requests made to those scripts\nin the WCSIISLog to surface new alerts for potentially malicious web request activity.\nThe lookback for alerts is set to 1h and the lookback for W3CIISLogs is set to 7d. A sample set of popular web script extensions\nhas been provided in scriptExtensions that should be tailored to your environment.'\n",
        "displayName": "Malicious web application requests linked with Microsoft Defender for Endpoint (formerly Microsoft Defender ATP) alerts",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "Computer",
                "identifier": "FullName"
              },
              {
                "columnName": "HostName",
                "identifier": "HostName"
              },
              {
                "columnName": "HostNameDomain",
                "identifier": "DnsDomain"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "AttackerIP",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Web Shells Threat Protection/Analytic Rules/MaliciousAlertLinkedWebRequests.yaml",
        "query": "let alertTimeWindow = 1h;\nlet logTimeWindow = 7d;\n// Define script extensions that suit your web application environment - a sample are provided below\nlet scriptExtensions = dynamic([\".php\", \".jsp\", \".js\", \".aspx\", \".asmx\", \".asax\", \".cfm\", \".shtml\"]);\nlet alertData = materialize(SecurityAlert\n| where TimeGenerated > ago(alertTimeWindow)\n| where ProviderName == \"MDATP\"\n// Parse and expand the alert JSON\n| extend alertData = parse_json(Entities)\n| mvexpand alertData);\nlet fileData = alertData\n// Extract web script files from MDATP alerts - our malicious web scripts - candidate webshells\n| where alertData.Type =~ \"file\"\n| where alertData.Name has_any(scriptExtensions)\n| extend FileName = tostring(alertData.Name), Directory = tostring(alertData.Directory);\nlet hostData = alertData\n// Extract server details from alerts and map to alert id\n| where alertData.Type =~ \"host\"\n| project HostName = tostring(alertData.HostName), DnsDomain = tostring(alertData.DnsDomain), SystemAlertId\n| distinct HostName, DnsDomain, SystemAlertId;\n// Join the files on their impacted servers\nlet webshellData = fileData\n| join kind=inner (hostData) on SystemAlertId\n| project TimeGenerated, FileName, Directory, HostName, DnsDomain;\nwebshellData\n| join (\n// Find requests that were made to this file on the impacted server in the W3CIISLog table\nW3CIISLog\n| where TimeGenerated > ago(logTimeWindow)\n// Restrict to accesses to script extensions\n| where csUriStem has_any(scriptExtensions)\n| extend splitUriStem = split(csUriStem, \"/\")\n| extend FileName = splitUriStem[-1], HostName = sComputerName\n// Summarize potential attacker activity\n| summarize count(), StartTime=min(TimeGenerated), EndTime=max(TimeGenerated), RequestUserAgents=make_set(csUserAgent), ReqestMethods=make_set(csMethod), RequestStatusCodes=make_set(scStatus), RequestCookies=make_set(csCookie), RequestReferers=make_set(csReferer), RequestQueryStrings=make_set(csUriQuery) by AttackerIP=cIP, SiteName=sSiteName, ShellLocation=csUriStem, tostring(FileName), HostName\n) on FileName, HostName\n| project StartTime, EndTime, AttackerIP, RequestUserAgents, Computer = HostName, SiteName, ShellLocation, ReqestMethods, RequestStatusCodes, RequestCookies, RequestReferers, RequestQueryStrings, RequestCount = count_\n| extend HostName = tostring(split(Computer, \".\")[0]), DomainIndex = toint(indexof(Computer, '.'))\n| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P7D",
        "severity": "Medium",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence"
        ],
        "techniques": [
          "T1505"
        ],
        "templateVersion": "1.0.3",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}