Azure WAF matching for Log4j vulnCVE-2021-44228
Id | 2de8abd6-a613-450e-95ed-08e503369fb3 |
Rulename | Azure WAF matching for Log4j vuln(CVE-2021-44228) |
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/ |
Severity | High |
Tactics | InitialAccess |
Techniques | T1190 |
Required data connectors | WAF |
Kind | Scheduled |
Query frequency | 6h |
Query period | 6h |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Apache Log4j Vulnerability Detection/Analytic Rules/AzureWAFmatching_log4j_vuln.yaml |
Version | 1.0.4 |
Arm template | 2de8abd6-a613-450e-95ed-08e503369fb3.json |
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"
}
]
}