hunt-session – skill Marketing & SEO cho agent AI
Tìm lỗ hổng quản lý phiên: session fixation (không tái tạo phiên khi đăng nhập), vô hiệu hóa phiên không đầy đủ khi đăng xuất / đổi mật khẩu / đổi email, session ID dễ đoán hoặc entropy thấp, JWT dùng làm phiên không có exp/thu hồi, lỗ hổng trong xoay vòng và phát hiện tái sử dụng refresh-token, liên kết phiên OAuth/SSO, device-bound
Cài skill hunt-session bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-98d1b.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /hunt-session – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-98d1b.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $hunt-session – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-98d1b.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /hunt-session – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-session-98d1b.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /hunt-session – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
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. This is the single highest-paid session bug class.
- Refresh-token reuse without rotation-detection — a leaked refresh token mints fresh access tokens forever; 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 — stolen JWT = permanent access; logout is cosmetic.
---
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.
- SameSite=Lax sibling-subdomain CSRF reaching session state — Argo CD CVE-2024-22424 (Lax cookies sent on top-level cross-site navigations from a sibling subdomain). 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: a rotated refresh token, if replayed, must invalidate the *entire token family*. Absence = the core bug to prove.
- 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. MissingHttpOnlyis only a finding when a real XSS/DOM sink exists (chain withhunt-xss/hunt-dom). - Entropy — NIST SP 800-63B requires ≥64 bits of entropy in a session identifier. Treat anything decodable to a counter/timestamp/userId as a finding regardless of length.
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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 --max-time 30 --connect-timeout 10 -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 A's live session.
curl --max-time 30 --connect-timeout 10 -s -L -c "$JAR_A" -X POST "https://$TARGET/api/login" \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","password":"CorrectHorse1"}' -o /dev/null
A=$(get_cookie "$JAR_A"); echo "A=$A"
# Baseline: what does an authenticated /api/me look like for A? (capture body, not just code)
BEFORE=$(curl --max-time 30 --connect-timeout 10 -s -L -b "$JAR_A" "https://$TARGET/api/me")
# Logout A.
curl --max-time 30 --connect-timeout 10 -s -L -b "$JAR_A" -X POST "https://$TARGET/api/logout" -o /dev/null
# Replay A's OLD cookie value explicitly (do NOT reuse the jar — logout may have
# overwritten it). Compare body + code against the authenticated baseline.
AFTER=$(curl --max-time 30 --connect-timeout 10 -s -L -H "Cookie: $A" "https://$TARGET/api/me" -w '\n[%{http_code}]')
echo "AFTER: $AFTER"FP discipline (mandatory):
- Don't trust the status code. A cached/edge 200 or a generic SPA shell returns 200 for everyone. Body-diff
AFTERagainstBEFORE— the finding is only real ifAFTERstill contains A's *unique identity marker* (email, user-id, CSRF token, account name). - Confirm with a negative control: a random/garbage cookie value must NOT return the same authenticated body. If garbage also yields 200 with user data, the endpoint isn't session-gated and there's no finding here.
- Re-test after a short delay and from a different IP — some servers lazily expire on next access or pin sessions to IP.
Phase 3 — Invalidation on Password / Email Change (persistent-ATO core)
# This is the real two-session flow. A = attacker holding a stolen/old session.
# B = the victim who changes their password believing it revokes access.
# (In a real engagement A is a session you legitimately captured for a TEST account
# that you also control as B — never use a real third party.)
# 1) Log the TEST account in as session A, capture it.
curl --max-time 30 --connect-timeout 10 -s -L -c "$JAR_A" -X POST "https://$TARGET/api/login" \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","password":"OldPass!1"}' -o /dev/null
SESSION_A=$(get_cookie "$JAR_A"); echo "SESSION_A=$SESSION_A"
BEFORE=$(curl --max-time 30 --connect-timeout 10 -s -L -H "Cookie: $SESSION_A" "https://$TARGET/api/profile")
# 2) Log the SAME account in as session B (separate jar = "the victim's browser").
curl --max-time 30 --connect-timeout 10 -s -L -c "$JAR_B" -X POST "https://$TARGET/api/login" \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","password":"OldPass!1"}' -o /dev/null
# 3) Victim (session B) changes the password.
curl --max-time 30 --connect-t… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- seo-audit – Dùng khi người dùng muốn kiểm tra, rà soát hoặc chẩn đoán các vấn đề SEO trên website…
- signup – Dùng khi người dùng muốn tối ưu quy trình đăng ký, tạo tài khoản hoặc kích hoạt dùng…
- email-sequence – Khi người dùng muốn tạo hoặc tối ưu chuỗi email, chiến dịch nhỏ giọt, luồng email tự…
- email-template-builder – Xây dựng hệ thống email giao dịch hoàn chỉnh: template React Email, tích hợp nhà cung…
- social – Khi người dùng muốn tạo, lên lịch hoặc tối ưu nội dung mạng xã hội cho LinkedIn…
- hunt-tls-network – Săn lỗi cấu hình TLS/SSL và DNS: thiếu HSTS (tấn công hạ cấp), bộ mã hóa yếu, chứng chỉ…
- brand-growth-system-builder – Định tuyến yêu cầu qua 13 module thương hiệu và tăng trưởng. Dùng khi một SME cần hỗ trợ…
- form-cro – Khi người dùng muốn tối ưu bất kỳ biểu mẫu nào KHÔNG phải đăng ký tài khoản, bao gồm…