CVE-2022-22947
https://github.com/vulhub/vulhub/blob/master/spring/CVE-2022-22947/README.zh-cn.md
概述
Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)
Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令。
分析
关键字StandardEvaluationContext
org.springframework.cloud.gateway.support.ShortcutConfigurable#getValue
entryValue 被解析为 spel,然后往上倒追
可以找到ShortcutType的三个枚举值的normalize中调用了getValue 方法,entry 是取自 args 中
在倒追到org.springframework.cloud.gateway.support.ConfigurationService.ConfigurableBuilder#normalizeProperties,上面 args 的传参是this.properties
此时开始分叉,需要追踪两方面,一个是如何触发,一个是如何控制传参,这里明显不是一步到位的。
首先追踪如何触发,可以看到有很多 Controller 可以触发,但是没有找到往上refresh,因为 refresh 对应的是一个事件,可能这个事件可以异步刷新。
gateway/routes/{id}
gateway/routes
gateway/routes/{id}/combinedfilters
然后就是追踪可控点,也就是追踪properties
org.springframework.cloud.gateway.support.ConfigurationService.AbstractBuilder#properties
倒追最后可以到org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getRoutes
但是可以看到它是链式调用,所以实际上传递到 convertToRoute 里面的内容是this.routeDefinitionLocator.getRouteDefinitions()的结果,跟进去看一下
这里实现有很多,我以org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository#getRouteDefinitions为例看一下,可以看到是取的 routes 里面的内容,然后找一下这个值是如何变动的
org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository#save
然后追踪到路由gateway/routes/{id}
org.springframework.cloud.gateway.actuate.AbstractGatewayControllerEndpoint#save
修复分析
自定义一个GatewayEvaluationContext替代StandardEvaluationContext,本质是 SimpleEvaluationContext