hunt-session – Security skill for AI agents
Hunt Session Management vulnerabilities
Install the hunt-session skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-dc8c6.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /hunt-session – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-dc8c6.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $hunt-session – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-dc8c6.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /hunt-session – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-dc8c6.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /hunt-session – then describe the task you want done.
SKILL.md content
> ⚠️ AUTHORIZED USE ONLY
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.
> Mandatory confirmation gate
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.
Autonomous Testing Priority
Missing HttpOnly on cookies may be detected by separately configured tooling — focus your active testing on lifecycle invalidation (higher impact).
Pattern 1 — Session survives logout (most common high-value finding):
1. Login and note the session token/cookie value
2. Call the logout endpoint (/logout, POST /api/logout, etc.)
3. Try to use the OLD session token to access a protected resource (/api/me, /dashboard, /account)
4. If protected data remains accessible with the old token after confirmed logout, investigate the revocation boundary and expected policy
Pattern 2 — Session not regenerated on login (session fixation):
1. GET any page to receive a pre-authentication session token/cookie
2. POST valid credentials to the login endpoint
3. Compare the session token BEFORE and AFTER login
4. If unchanged, verify an attacker can pre-establish/control the same authenticated session before claiming fixation
Pattern 3 — Session survives password change:
1. Login → record session A value
2. Change the password via the account settings endpoint
3. Replay session A on a protected endpoint
4. If protected data remains accessible, compare the documented session-revocation policy and attack preconditions before assigning impact
Content-type: Login and session endpoints vary — use application/json for REST APIs, application/x-www-form-urlencoded for traditional web forms. Try both if the first returns an unexpected response.
Proof: A protected-resource 200 response (with user data) using a session token that should have been invalidated confirms the finding.
---
HUNT-SESSION — Session Management
Crown Jewel Targets
Session fixation leading to admin hijack = Critical. Session surviving a password change = High-to-Critical (persistent ATO from a stolen cookie that the victim believes they revoked by resetting their password).
Highest-value chains:
- Session fixation — server accepts a session ID set by the client and does NOT regenerate it on login → attacker pre-plants an ID, victim authenticates, attacker rides the now-authenticated session → persistent ATO.
- No invalidation on logout — old token still works after
/logout→ theft window never closes. - No invalidation on password / email change — a stolen session survives the victim's "I think I was hacked, let me reset" → persistent ATO. Impact and bounty eligibility depend on the program and demonstrated threat model.
- Refresh-token reuse without rotation-detection — a leaked refresh token may mint access tokens within its enforced lifetime; no reuse-detection means the legitimate user's later refresh does NOT revoke the attacker's branch.
- Predictable / low-entropy session ID — sequential, timestamp- or userId-derived IDs → brute-force or compute other users' sessions.
- JWT-as-session with no
exp/ no revocation list — inspect server-enforced lifetime and revocation; claims alone do not establish permanent access.
---
Grounding — patterns that shaped each phase
No invented CVE/report IDs below. These are the *named, publicly-documented* patterns this skill encodes:
- Session fixation, login-CSRF, no-regeneration-on-auth — OWASP WSTG-SESS-03 / WSTG-SESS-01; the classic ACROS / Mitja Kolšek session-fixation paper. Highest-impact variant: fixing the session of an SSO/admin user.
- Same-parent-domain CSRF reaching session state — Argo CD CVE-2024-22424 (attacker-controlled HTML on the same parent domain; inspect the advisory’s content-type/CSRF preconditions). Use this when a session cookie relies on
SameSite=Laxas its only CSRF defence. - Refresh-token rotation & automatic reuse-detection — the Auth0/IETF OAuth-Security-BCP model: public-client refresh tokens require rotation with replay detection or sender-constraining; test the implemented protection and replay policy.
- Device Bound Session Credentials (DBSC) — the W3C/Chrome DBSC draft binds a session to a TPM/device key. Test the *downgrade*: does the server still accept a non-bound cookie when the DBSC challenge is stripped?
- Cookie attribute hardening — OWASP WSTG-SESS-02;
__Host-/__Secure-prefixes per RFC 6265bis. MissingHttpOnlycan be a hardening finding; high-impact theft claims require an actual applicable attack path (chain withhunt-xss/hunt-dom). - Entropy — NIST SP 800-63B-4 requires session-binding secrets from an approved random bit generator and at least 64 bits in length. Decodable claims alone are not a finding: signed/encrypted tokens can contain predictable claims while preserving integrity and sufficient unpredictable secrets.
Cross-refs: ATO chaining → hunt-ato; JWT alg/kid tampering → hunt-api-misconfig; OAuth code/state flaws → hunt-oauth; CSRF mechanics → hunt-csrf; cookie-theft sinks → hunt-xss / hunt-dom.
---
Attack Surface Signals
Set-Cookie: session=... # name varies: sid, JSESSIONID, connect.sid,
# PHPSESSID, ASP.NET_SessionId, laravel_session, _csrf
/login /logout /api/login /oauth/token
/auth/refresh /api/token/refresh # refresh-token rotation surface
/account/change-password /settings/email
?sid= ?session= in URL # session-in-URL → leaks via Referer/logs (finding)# Header signals worth flagging immediately:
Set-Cookie: session=abc; Path=/ # no HttpOnly/Secure/SameSite
Set-Cookie: session=abc; SameSite=None # None without Secure = rejected by modern browsers, but flag
Set-Cookie: __Host-sess=...; Secure; Path=/ # GOOD — hard to fixate
Sec-Session-Registration: ... # DBSC in play → test downgrade---
Step-by-Step Hunting Methodology
> Two-session rule. Every invalidation/fixation claim is proven with TWO concrete sessions captured by a real flow — attacker A and victim B — never with hardcoded placeholder strings. Helpers below capture real cookies from curl's Netscape jar.
TARGET=target.com
JAR_A=$(mktemp); JAR_B=$(mktemp)
# Robust session-cookie extractor: handles #HttpOnly_ prefix lines and any
# cookie name (sid/JSESSIONID/connect.sid/PHPSESSID/...). Prints name=value.
get_cookie () { # $1=jar $2=name-regex (default: common session names)
local jar="$1" re="${2:-session|sid|sess|JSESSIONID|connect\.sid|PHPSESSID|laravel_session}"
awk -v re="$re" '
/^#HttpOnly_/ { sub(/^#HttpOnly_/,""); } # strip jar HttpOnly marker
/^#/ { next } # skip remaining comments
NF>=7 && $6 ~ re { print $6"="$7 } # field6=name field7=value
' "$jar" | tail -1
}Phase 1 — Session Fixation (regeneration-on-login)
# Step 1: grab a pre-auth session the SERVER hands an anonymous client.
curl -s -L -c "$JAR_A" "https://$TARGET/login" -o /dev/null
PRE=$(get_cookie "$JAR_A"); echo "pre-auth: $PRE"
# Step 1b (stronger): can we FORCE an arbitrary ID? attacker-chosen value.
FIX="session=AAAAdeadbeefAAAA"
# Step 2: authenticate while CARRYING the pre-auth/forced cookie (reuse same jar).
curl -s -L -c "$JAR_A" -b "$JAR_A" -X POST "https://$TARGET/login" \
-d "[email protected]&password=CorrectHorse1" -o /dev/null
POST=$(get_cookie "$JAR_A"); echo "post-auth: $POST"
# DECISION:
# - If $POST == $PRE (value unchanged across the auth boundary) AND that value
# now returns authenticated data → FIXATION. The server reused the anon ID.
# - If the forced $FIX value is accepted and authenticates → CRITICAL fixation
# (attacker controls the ID; no email/XSS needed to plant it).
AUTH=$(curl -s -L -b "$JAR_A" "https://$TARGET/api/me")
echo "$AUTH" | head -c 200FP guard: a value *change* is not automatically safe — some apps rotate the readable cookie but keep a stable server-side session keyed by a second cookie. Diff the FULL Set-Cookie set and confirm the *old* value is genuinely dead (Phase 2). Also confirm /api/me returns *your* identity, not a generic 200/landing page.
Phase 2 — Invalidation on Logout
# A logs in for real (fresh jar), capture … (full content is in the download package)
Related skills
- hunt-springboot – Hunt Spring Boot specific vulnerabilities
- hunt-sqli – Hunting skill for sqli vulnerabilities.
- hunt-ssrf – Hunting skill for ssrf vulnerabilities.
- hunt-subdomain – Hunting skill for subdomain takeover vulnerabilities.
- hunt-websocket – Hunt WebSocket vulnerabilities
- hunt-xss – Hunting skill for xss vulnerabilities.
- hunt-xxe – Hunting skill for xxe vulnerabilities.
- incident-response – Handle security incidents with IR playbooks and procedures.