zhj123456
- 关注

- 漏洞说明
这个漏洞基于CVE-2010-1622,是该漏洞的补丁绕过,该漏洞即Spring的参数绑定会导致ClassLoader的后续属性的赋值,最终能够导致RCE。
- 漏洞存在条件
1.JDK 9+
2.直接或者间接地使⽤了Spring-beans包(Spring boot等框架都使用了)
3.Controller通过参数绑定传参,参数类型为非常规类型的对象(比如非String等类型的自定义对象)
4.Web应用部署方式必须为Tomcat war包部署
在利用时,存在java.lang.Module.getClassLoader()得到org.apache.catalina.loader.ParallelWebappClassLoader这一步,ParallelWebappClassLoader只能是war包部署时的返回值;如果使用jar包的形式进行部署,则此步获取到的对象是org.springframework.boot.loader.LaunchedURLClassLoader,该类下没有resources成员变量,导致利用链断掉。
- 漏洞原理
- 利用Spring的对象绑定功能将HTTP请求中的参数绑定到应用程序正在使用的某个对象中。
- 与CVE-2010-1622很相似,当时修复此漏洞的方式是检查类名,禁止任何class对象获取classloader,然而JDK9新增的模块化功能使得CVE-2010-1622的补丁被绕过。
- 利用此漏洞,攻击者可以覆写Tomcat日志配置进而上传JSP web shell。
- 漏洞复现
1.首先我们直接将项目源码克隆至本地:
git clone https://github.com/reznok/Spring4Shell-POC.git;
并构建和运行容器;
2.构建并运行容器后,广大研究人员可以通过下列地址来访问Spring4Shell-POC:
3.使用如下命令将运行项目的exploit.py脚本来测试目标站点Spring4Shell漏洞:
Python3 exploit.py --url "http://localhost:8080/helloworld/greeting
4.访问工具创建的webshell,修改命令中的“cmd” GET参数,shell默认路径如下http://localhost:8080/shell.jsp
- 漏洞分析
首先看Controller,参数绑定了Greeting类的对象greeting:
攻击payload:
攻击发起的get请求头:
简单分析一下,相当于发送了以下参数:
1.class.module.classLoader.resources.context.parent.pipeline.first.pattern=带有某前缀和后缀的[jsp webshell]
2.class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
3.class.module.classLoader.resources.context.parent.pipeline.first.directory=shell的文件名(不含后缀)
4.class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell的储存路径(相对路径,默认为webapps/ROOT)
5.class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=(空)
其中的webshell大概为(是个有回显的简单的一句话):
该漏洞中,攻击者可以对绑定对象的class属性进行随意赋值,有点像原型链污染。在exp中,是利用class属性来修改Tomcat的⽇志配置,向⽇志中写⼊shell。
分析流程:
- 在发送了以下参数,首先进行参数绑定,在WebDataBinder#doBind方法中:
继续跟进:
此处,方法被传入当前的待解析参数属性,并且尝试解析嵌套的情况,出现嵌套时,从左边开始挨个递归解析:
比如此处的属性为
class.module.classLoader.resources.context.parent.pipeline.first.suffix,将会解析最左边的class:
我们来对照一下过程:我们现在在解析class.module.classLoader.resources.context.parent.pipeline.first.suffix中的class,而当前绑定参数对象为Greeting类的对象,所以实际上是调用了Greeting.getClass()
然后我们来跟下一层解析,即module.classLoader.resources.context.parent.pipeline.first.suffix中的module的解析。我们再来看解析的入口,即递归处,此时的nestedPa为上一步解析出的java.lang.Object.Class对象,根据前一步的分析,这里会尝试获取该对象的module属性,即会调用java.lang.Object.Class.getModule()
此时获取到的是一个java.lang.Module对象。
此后依次递归~
- 总结
该漏洞是在spring bean解析参数绑定时,对对象的class属性进行了赋值造成
该洞的利用过程是查找一系列的getXXX链,然后可以设置其值为任意字符串,exp中通过设置tomcat日志相关属性以写入webshell。这个链的查找过程应该是很有难度的,除了写日志这条链,还可以尝试去发现其他的利用链,但过程应该很难。
该漏洞与原型链污染有相似的地方(污染现有对象的属性达到利用),与python模板注入也有相似的地方(通过链式的形式在对象成员属性或继承链之间跨越,以达到能够利用的属性处)。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)