Adversaries may exploit the SpringShell vulnerability (CVE-2022-22965) by leveraging insecure deserialization in Spring Framework applications to execute arbitrary code. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect and mitigate potential server-side code execution attacks before they escalate.
KQL Query
let spring4shellstring = dynamic(["class.module.classLoader.resources.context.parent.pipeline.first.pattern="]);
AzureDiagnostics
| where Category in ("FrontdoorWebApplicationFirewallLog", "FrontdoorAccessLog", "ApplicationGatewayFirewallLog", "ApplicationGatewayAccessLog")
| extend originalRequestUriWithArgs_s = column_ifexists("originalRequestUriWithArgs_s", ""),
userAgent_s = column_ifexists("userAgent_s", ""),
clientIP_s = column_ifexists("clientIP_s", ""),
clientPort_d = column_ifexists("originalRequestUriWithArgs_s", ""),
host_s = column_ifexists("host_s", ""),
requestUri_s = column_ifexists("requestUri_s", ""),
httpStatus_d = column_ifexists("httpStatus_d",""),
listenerName_s = column_ifexists("listenerName_s", ""),
httpMethod_s = column_ifexists("httpMethod_s", "")
| where httpMethod_s =~ 'POST'
| where originalRequestUriWithArgs_s has_any (spring4shellstring) or requestUri_s has_any (spring4shellstring)
| summarize Total = count() by originalRequestUriWithArgs_s, userAgent_s, clientIP_s,clientPort_d, TimeGenerated, host_s, requestUri_s, httpStatus_d,listenerName_s, httpMethod_s, Category
| extend IPCustomEntity = clientIP_s, timestamp = TimeGenerated, UrlCustomEntity = requestUri_s, HostCustomEntity = host_s
id: 1bb4a007-7d1d-4506-ada9-222604f54ec6
name: Possible SpringShell Exploitation Attempt (CVE-2022-22965)
description: |
'This hunting query looks in Azure Web Application Firewall data to find possible SpringShell Exploitation Attempt (CVE-2022-22965).
The Spring Framework is one of the most widely used lightweight open-source framework for Java. To exploit the vulnerability attackers can
send a specially crafted query to a web server running the Spring Core framework to change the target of logging facility and create a new
malicious JSP file in a location accessible by http requests. Attackers then make requests to the malicious backdoor to run system commands.
Reference: https://www.microsoft.com/security/blog/2022/04/04/springshell-rce-vulnerability-guidance-for-protecting-against-and-detecting-cve-2022-22965/'
requiredDataConnectors:
- connectorId: WAF
dataTypes:
- AzureDiagnostics
tactics:
- InitialAccess
relevantTechniques:
- T1190
tags:
- CVE-2022-22965
- SpringShell
- Spring4Shell
query: |
let spring4shellstring = dynamic(["class.module.classLoader.resources.context.parent.pipeline.first.pattern="]);
AzureDiagnostics
| where Category in ("FrontdoorWebApplicationFirewallLog", "FrontdoorAccessLog", "ApplicationGatewayFirewallLog", "ApplicationGatewayAccessLog")
| extend originalRequestUriWithArgs_s = column_ifexists("originalRequestUriWithArgs_s", ""),
userAgent_s = column_ifexists("userAgent_s", ""),
clientIP_s = column_ifexists("clientIP_s", ""),
clientPort_d = column_ifexists("originalRequestUriWithArgs_s", ""),
host_s = column_ifexists("host_s", ""),
requestUri_s = column_ifexists("requestUri_s", ""),
httpStatus_d = column_ifexists("httpStatus_d",""),
listenerName_s = column_ifexists("listenerName_s", ""),
httpMethod_s = column_ifexists("httpMethod_s", "")
| where httpMethod_s =~ 'POST'
| where originalRequestUriWithArgs_s has_any (spring4shellstring) or requestUri_s has_any (spring4shellstring)
| summarize Total = count() by originalRequestUriWithArgs_s, userAgent_s, clientIP_s,clientPort_d, TimeGenerated, host_s, requestUri_s, httpStatus_d,listenerName_s, httpMethod_s, Category
| extend IPCustomEntity = clientIP_s, timestamp = TimeGenerated, UrlCustomEntity = requestUri_s, HostCustomEntity = host_s
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
- entityType: URL
fieldMappings:
- identifier: Url
columnName: UrlCustomEntity
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: HostCustomEntity
| Sentinel Table | Notes |
|---|---|
AzureDiagnostics | Ensure this data connector is enabled |
Scenario: Legitimate Spring Boot Application with Dynamic Query Parameters
Description: A developer is testing a Spring Boot application that accepts user input in query parameters, which is a normal part of the application’s functionality.
Filter/Exclusion: Exclude requests where the query parameter contains T or t in the context of a legitimate API endpoint (e.g., /api/data?param=value). Use a filter like:
request_uri NOT LIKE '%/api/data%' OR request_uri NOT LIKE '%?param=%'
Scenario: Scheduled Job Execution via Spring Scheduler
Description: An admin is running a scheduled job using Spring’s @Scheduled annotation, which may trigger the rule due to the use of dynamic method calls.
Filter/Exclusion: Exclude requests that originate from internal IP ranges used by the company’s infrastructure (e.g., 10.0.0.0/8) and are associated with known scheduled job endpoints.
source_ip IN ('10.0.0.0/8') OR request_uri NOT LIKE '/scheduler/%'
Scenario: Use of Spring Shell for Administrative Tasks
Description: An admin is using Spring Shell (a command-line interface for Spring applications) to perform routine administrative tasks, which may include executing shell commands.
Filter/Exclusion: Exclude requests that come from known admin workstations and are associated with the Spring Shell endpoint (e.g., /shell).
source_ip IN ('192.168.1.0/24') OR request_uri NOT LIKE '/shell%'
Scenario: Integration with Third-Party APIs Using Spring REST Client
Description: A microservice is making a legitimate REST call to a third-party API using Spring’s RestTemplate