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

Azure WAF matching for Log4j vulnCVE-2021-44228

Back
Id2de8abd6-a613-450e-95ed-08e503369fb3
RulenameAzure WAF matching for Log4j vuln(CVE-2021-44228)
DescriptionThis query will alert on a positive pattern match by Azure WAF for CVE-2021-44228 log4j vulnerability exploitation attempt. If possible, it then decodes the malicious command for further analysis.

Reference: https://www.microsoft.com/security/blog/2021/12/11/guidance-for-preventing-detecting-and-hunting-for-cve-2021-44228-log4j-2-exploitation/
SeverityHigh
TacticsInitialAccess
TechniquesT1190
Required data connectorsWAF
KindScheduled
Query frequency6h
Query period6h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Apache Log4j Vulnerability Detection/Analytic Rules/AzureWAFmatching_log4j_vuln.yaml
Version1.0.4
Arm template2de8abd6-a613-450e-95ed-08e503369fb3.json
Deploy To Azure
let log4jioc = dynamic(["jndi","ldap","${::"]);
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category in ("ApplicationGatewayFirewallLog", "FrontdoorWebApplicationFirewallLog")
| extend details_data_s = column_ifexists("details_data_s", tostring(AdditionalFields.details_data))
|where requestUri_s has_any (log4jioc) or details_message_s has_any (log4jioc) or details_data_s has_any (log4jioc)
| extend Malicious = iff(isnotempty( details_data_s),details_data_s,iff(isnotempty( requestUri_s),requestUri_s,""))
|parse Malicious with * '${' MaliciousCommand '}' * 
| extend EncodeCmd = iff(MaliciousCommand has 'Base64/', split(split(MaliciousCommand, "Base64/",1)[0], "}", 0)[0], "")
| extend EncodeCmd1 = iff(MaliciousCommand has 'base64/', split(split(MaliciousCommand, "base64/",1)[0], "}", 0)[0], "")
| extend CmdLine = iff( isnotempty(EncodeCmd), EncodeCmd, EncodeCmd1)
| extend DecodedCmdLine = base64_decode_tostring(tostring(CmdLine))
| extend DecodedCmdLine = iff( isnotempty(DecodedCmdLine), DecodedCmdLine, "Unable to decode/Doesn't need decoding")
| project TimeGenerated, Target=column_ifexists("hostname_s", tostring(AdditionalFields.hostname)), MaliciousHost = column_ifexists("clientIp_s", tostring(AdditionalFields.clientIp)) , MaliciousCommand, details_data_s = column_ifexists("details_data_s", tostring(AdditionalFields.details_data)), DecodedCmdLine, Message,
ruleSetType_s = column_ifexists("ruleSetType_s", tostring(AdditionalFields.ruleSetType)), OperationName, SubscriptionId, details_message_s = column_ifexists("details_message_s", tostring(AdditionalFields.details_message)), 
details_file_s = column_ifexists("details_message_s", tostring(AdditionalFields.details_file))
| extend timestamp = TimeGenerated
relevantTechniques:
- T1190
name: Azure WAF matching for Log4j vuln(CVE-2021-44228)
requiredDataConnectors:
- dataTypes:
  - AzureDiagnostics
  connectorId: WAF
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: MaliciousHost
  entityType: IP
triggerThreshold: 0
id: 2de8abd6-a613-450e-95ed-08e503369fb3
tactics:
- InitialAccess
version: 1.0.4
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Apache Log4j Vulnerability Detection/Analytic Rules/AzureWAFmatching_log4j_vuln.yaml
queryPeriod: 6h
kind: Scheduled
tags:
- CVE-2021-44228
- log4j
- log4shell
queryFrequency: 6h
severity: High
status: Available
description: |
  'This query will alert on a positive pattern match by Azure WAF for CVE-2021-44228 log4j vulnerability exploitation attempt. If possible, it then decodes the malicious command for further analysis.
   Reference: https://www.microsoft.com/security/blog/2021/12/11/guidance-for-preventing-detecting-and-hunting-for-cve-2021-44228-log4j-2-exploitation/'  
query: |
  let log4jioc = dynamic(["jndi","ldap","${::"]);
  AzureDiagnostics
  | where ResourceProvider == "MICROSOFT.NETWORK" and Category in ("ApplicationGatewayFirewallLog", "FrontdoorWebApplicationFirewallLog")
  | extend details_data_s = column_ifexists("details_data_s", tostring(AdditionalFields.details_data))
  |where requestUri_s has_any (log4jioc) or details_message_s has_any (log4jioc) or details_data_s has_any (log4jioc)
  | extend Malicious = iff(isnotempty( details_data_s),details_data_s,iff(isnotempty( requestUri_s),requestUri_s,""))
  |parse Malicious with * '${' MaliciousCommand '}' * 
  | extend EncodeCmd = iff(MaliciousCommand has 'Base64/', split(split(MaliciousCommand, "Base64/",1)[0], "}", 0)[0], "")
  | extend EncodeCmd1 = iff(MaliciousCommand has 'base64/', split(split(MaliciousCommand, "base64/",1)[0], "}", 0)[0], "")
  | extend CmdLine = iff( isnotempty(EncodeCmd), EncodeCmd, EncodeCmd1)
  | extend DecodedCmdLine = base64_decode_tostring(tostring(CmdLine))
  | extend DecodedCmdLine = iff( isnotempty(DecodedCmdLine), DecodedCmdLine, "Unable to decode/Doesn't need decoding")
  | project TimeGenerated, Target=column_ifexists("hostname_s", tostring(AdditionalFields.hostname)), MaliciousHost = column_ifexists("clientIp_s", tostring(AdditionalFields.clientIp)) , MaliciousCommand, details_data_s = column_ifexists("details_data_s", tostring(AdditionalFields.details_data)), DecodedCmdLine, Message,
  ruleSetType_s = column_ifexists("ruleSetType_s", tostring(AdditionalFields.ruleSetType)), OperationName, SubscriptionId, details_message_s = column_ifexists("details_message_s", tostring(AdditionalFields.details_message)), 
  details_file_s = column_ifexists("details_message_s", tostring(AdditionalFields.details_file))
  | extend timestamp = TimeGenerated  
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/2de8abd6-a613-450e-95ed-08e503369fb3')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/2de8abd6-a613-450e-95ed-08e503369fb3')]",
      "properties": {
        "alertRuleTemplateName": "2de8abd6-a613-450e-95ed-08e503369fb3",
        "customDetails": null,
        "description": "'This query will alert on a positive pattern match by Azure WAF for CVE-2021-44228 log4j vulnerability exploitation attempt. If possible, it then decodes the malicious command for further analysis.\n Reference: https://www.microsoft.com/security/blog/2021/12/11/guidance-for-preventing-detecting-and-hunting-for-cve-2021-44228-log4j-2-exploitation/'\n",
        "displayName": "Azure WAF matching for Log4j vuln(CVE-2021-44228)",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "MaliciousHost",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Apache Log4j Vulnerability Detection/Analytic Rules/AzureWAFmatching_log4j_vuln.yaml",
        "query": "let log4jioc = dynamic([\"jndi\",\"ldap\",\"${::\"]);\nAzureDiagnostics\n| where ResourceProvider == \"MICROSOFT.NETWORK\" and Category in (\"ApplicationGatewayFirewallLog\", \"FrontdoorWebApplicationFirewallLog\")\n| extend details_data_s = column_ifexists(\"details_data_s\", tostring(AdditionalFields.details_data))\n|where requestUri_s has_any (log4jioc) or details_message_s has_any (log4jioc) or details_data_s has_any (log4jioc)\n| extend Malicious = iff(isnotempty( details_data_s),details_data_s,iff(isnotempty( requestUri_s),requestUri_s,\"\"))\n|parse Malicious with * '${' MaliciousCommand '}' * \n| extend EncodeCmd = iff(MaliciousCommand has 'Base64/', split(split(MaliciousCommand, \"Base64/\",1)[0], \"}\", 0)[0], \"\")\n| extend EncodeCmd1 = iff(MaliciousCommand has 'base64/', split(split(MaliciousCommand, \"base64/\",1)[0], \"}\", 0)[0], \"\")\n| extend CmdLine = iff( isnotempty(EncodeCmd), EncodeCmd, EncodeCmd1)\n| extend DecodedCmdLine = base64_decode_tostring(tostring(CmdLine))\n| extend DecodedCmdLine = iff( isnotempty(DecodedCmdLine), DecodedCmdLine, \"Unable to decode/Doesn't need decoding\")\n| project TimeGenerated, Target=column_ifexists(\"hostname_s\", tostring(AdditionalFields.hostname)), MaliciousHost = column_ifexists(\"clientIp_s\", tostring(AdditionalFields.clientIp)) , MaliciousCommand, details_data_s = column_ifexists(\"details_data_s\", tostring(AdditionalFields.details_data)), DecodedCmdLine, Message,\nruleSetType_s = column_ifexists(\"ruleSetType_s\", tostring(AdditionalFields.ruleSetType)), OperationName, SubscriptionId, details_message_s = column_ifexists(\"details_message_s\", tostring(AdditionalFields.details_message)), \ndetails_file_s = column_ifexists(\"details_message_s\", tostring(AdditionalFields.details_file))\n| extend timestamp = TimeGenerated\n",
        "queryFrequency": "PT6H",
        "queryPeriod": "PT6H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "tags": [
          "CVE-2021-44228",
          "log4j",
          "log4shell"
        ],
        "techniques": [
          "T1190"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}