目录

CVE-2022-22947 Spring Cloud Gateway SPEL RCE 简单分析

前言

前段时间刚爆出来的洞,很多师傅都详细分析了各自的思路和想法,不过总要自己亲手去调试分析才能更好的进步,因此有了这篇文章

漏洞版本

1
2
3
4
Spring Cloud Gateway
    3.1.0
    3.0.0 to 3.0.6
    Older, unsupported versions are also affected

环境搭建

地址:https://github.com/spring-cloud/spring-cloud-gateway/tree/v3.1.0

找到GatewaySampleApplication.java启动即可

漏洞分析

先看一下commit删除的漏洞代码

https://github.com/spring-cloud/spring-cloud-gateway/commit/337cef276bfd8c59fb421bfe7377a9e19c68fe1e

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/f542d9a0-76c6-c577-1409-1589b918dae2.png

可以看出这里会执行spel表达式,使用StandardEvaluationContext显然是不安全的在加上参数外部可控导致了spel表达式注入,修复后使用了更安全的GatewayEvaluationContext来解析spel表达式,直接来看一下org.springframework.cloud.gateway.support.ShortcutConfigurable#getValue

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/d5caa3fa-89e8-d88a-0c45-606e11028e4c.png

会对#{}里面的内容进行spel解析,接下来进行回溯看一下哪里使用了getValue()

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/e368d287-233e-83e1-9b51-a22c97155399.png

ShortcutType是个枚举类,类中重写了三个normalize()都调用了getValue(),而在ShortcutConfigurable接口类中有以下代码:

1
2
3
	default ShortcutType shortcutType() {
		return ShortcutType.DEFAULT;
	}

会去调用默认的normalize(),然后对shortcutType()进行回溯

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/ebf051a5-9b7f-13b2-a884-c7820e7c47bc.png

normalizeProperties()中会对filer的属性进行解析,其中this.propertiesExpression expression = parser.parseExpression(entryValue, new TemplateParserContext());中的entryValue,然后一步一步转到getValue()中进入SPEL表达式中触发命令,接着继续对this.properties参数进行回溯

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/16680d3b-d899-718e-0ec9-ebb6e42737a6.png

继续对properties()进行回溯

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/65babf16-c49d-ec59-7e1a-8fae1186b8df.png

这里有两个函数调用了properties()并且进行了传参,一一对其回溯后,最终都回溯到了getRoutes()中的this::convertToRoute

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/ad8862eb-5f71-7cbe-a4b7-fff329f49869.png

到这里后就很容易理解了,在添加新路由后会加载到filter中,其中某个参数最后进入到getValue()中执行了SPEL表达式造成了注入

接下来来看一下官方文档

https://cloud.spring.io/spring-cloud-gateway/multi/multi__actuator_api.html

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/0b36165b-b161-98e7-3b2f-091a5c9424dc.png

接下来就是构造新路由然后去触发漏洞,这里看了Y4er师傅的文章,找到了org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#save,在AbstractGatewayControllerEndpoint.java中对路由进行增删操作

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/f5ee5b3b-622c-4487-b3e7-676cd3c6a579.png

在增加路由时进行了校验,需要与filter进行匹配,也就是说在构造poc时新增已有的filter就可以触发漏洞,这里直接贴一张Y4er师傅的图

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/7d60e656-6070-7d83-266f-36b8af69278e.png

这里贴一下部分堆栈内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
getValue:60, ShortcutConfigurable (org.springframework.cloud.gateway.support)
normalize:94, ShortcutConfigurable$ShortcutType$1 (org.springframework.cloud.gateway.support)
normalizeProperties:140, ConfigurationService$ConfigurableBuilder (org.springframework.cloud.gateway.support)
bind:241, ConfigurationService$AbstractBuilder (org.springframework.cloud.gateway.support)
loadGatewayFilters:144, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)
getFilters:176, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)
convertToRoute:117, RouteDefinitionRouteLocator (org.springframework.cloud.gateway.route)
apply:-1, 1876548582 (org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator$$Lambda$845)
onNext:106, FluxMap$MapSubscriber (reactor.core.publisher)
tryEmitScalar:488, FluxFlatMap$FlatMapMain (reactor.core.publisher)
onNext:421, FluxFlatMap$FlatMapMain (reactor.core.publisher)
drain:432, FluxMergeSequential$MergeSequentialMain (reactor.core.publisher)
innerComplete:328, FluxMergeSequential$MergeSequentialMain (reactor.core.publisher)

看完堆栈后,在org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#loadGatewayFilters中,先进行了properties(definition.getArgs())传参,然后进行了bind()绑定路由

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/725e5944-0be3-8291-6cee-e5f913c450fe.png

漏洞复现

直接通过burp抓包添加路由

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/b89c3e65-8705-eefd-6ceb-31733fa7eb5e.png

然后直接refresh

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/f2f21919-958c-d416-c3dc-cb40e1375e38.png

https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513662/755e6fed-3085-7a2b-bcaf-60fcc18d0389.png

参考链接

  1. https://y4er.com/post/cve-2022-22947-springcloud-gateway-spel-rce-echo-response/