hunt-jwt-crypto
Skill2 starsChanged 2 months agoMITView on GitHub
Hunt JWT cryptographic failures — alg:none signature-stripping and RS256→HS256 key-confusion that let an attacker forge a token for any identity (e.g. an admin) without knowing a secret. Use when the app authenticates with a JSON Web Token (an `eyJ...` Bearer token in the Authorization header, a cookie, or a login response). This skill OWNS JWT signature/crypto forgery (alg:none, key confusion, kid/jku header injection); hunt-ato covers JWT as one ATO path, hunt-auth-bypass covers SSO/SAML token trust, hunt-api-misconfig covers non-crypto JWT handling. Critical when a forged token grants access to another user's data or an admin-only endpoint.
2 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- murrtada/bug-bounty-agent-skillsedited, first seen Nov 15, 2026
- elementalsouls/Claude-BugHunterword for word, first seen Jul 1, 2026
Other versions2 projects use a version of this.
Word for word · 1
- elementalsouls/Claude-BugHunter★ 6.1k100% same
Edited · 1
- murrtada/bug-bounty-agent-skills★ 7100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository255 other files it gives its agents.
- ad-acl-abuseSkill
- ad-adcs-access-and-relaySkill
- ad-adcs-persistenceSkill
- ad-adcs-template-abuseSkill
- ad-ad-discoverySkill
- ad-ad-persistenceSkill
- ad-auth-coercion-relaySkill
- ad-credential-dumpingSkill
- ad-gpo-abuseSkill
- ad-kerberos-delegationSkill
- ad-kerberos-roastingSkill
- ad-kerberos-ticket-forgingSkill
- ad-pass-the-hashSkill
- ad-sccm-exploitationSkill
- ad-trust-attacksSkill
- hunt-ntlm-infoSkill
- offensive-active-directorySkill
- hunt-llm-aiSkill
- hunt-rag-vectorSkill
- offensive-ai-securitySkill
- cloud-iam-deepSkill
- hunt-cloud-misconfigSkill
- hunt-k8sSkill
- m365-entra-attackSkill
- network-container-escapesSkill
- offensive-cloudSkill
- offensive-container-escapeSkill
- offensive-k8s-attacksSkill
- okta-attackSkill
- vmware-vcenter-attackSkill
- credential-password-sprayingSkill
- hunt-brute-forceSkill
- hunt-forgot-passwordSkill
- post-exploit-credential-recoverySkill
- meme-coin-auditSkill
- offensive-crypto-attacksSkill
- web3-auditSkill
- ctfSkill
- advisory-miningSkill
- auth-bypassSkill
- code-injection-codegenSkill
- command-injectionSkill
- cross-pollinationSkill
- cve-hunting-methodologySkill
- decompression-bombSkill
- entity-expansionSkill
- fp-checkSkill
- method-clobberingSkill
- path-traversalSkill
- prototype-pollutionSkill
- recursion-dosSkill
- redosSkill
- sandbox-escapeSkill
- target-reconSkill
- web2-vuln-classesSkill
- evasion-av-edr-evasionSkill
- offensive-anti-forensicsSkill
- offensive-edr-evasionSkill
- offensive-keylogger-archSkill
- offensive-mitigationsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 40
Use a purpose-built tool so encoding/signing is correct: jwt_tool (jwt_tool <token> -T to tamper interactively, -X a for alg:none, -X k -pk …
- Distinctive: line 115
If the token is HS256 (HMAC-based) and the secret is weak or reused from a known password list:
- Distinctive: line 129
Use purpose-built JWT attack suites to run all known forgery modes in parallel:
- Distinctive: line 137
Run these early in JWT recon.
- Very specific: line 154
When /admin returns 200 (you'll see admin controls / a delete link), perform the admin action with the SAME forged token — a typical one is …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
HUNT-JWT-CRYPTO — Forgeable JSON Web Tokens (A04 Cryptographic Failures)
What actually pays
A JWT is header.payload.signature, each base64url. The signature is the only
thing stopping you from editing the payload (your identity/role) and replaying
it. It pays High/Critical when the verifier can be tricked into accepting a
token you forged — so you become another user or an admin without their secret.
Two classic, generic verifier flaws:
alg:none— the verifier trusts the token's ownalgheader. Setalg:"none", drop the signature, edit the payload (e.g.role:"admin", another user'sid/email). A broken verifier skips signature checking.- RS256 → HS256 key confusion — the token is signed RS256 (asymmetric). The RSA public key is, by definition, public. If the verifier lets you choose HS256, it will use that public key as the HMAC secret — which you also know. Sign an edited payload with HS256 using the public key and it validates.
Recon — is this app JWT-based?
Login/token responses containing "token":"eyJ..." or Set-Cookie: token=eyJ...
Authorization: Bearer eyJ... on authenticated requests
A JWKS / public-key endpoint: /.well-known/jwks.json, /jwks, public-key in the JS bundleDecode the header (base64url the first segment). "alg":"RS256" → try key
confusion. Any alg → always try alg:none first; it's free.
Forging the token (never hand-encode base64 — use a JWT tool)
Use a purpose-built tool so encoding/signing is correct: jwt_tool
(jwt_tool <token> -T to tamper interactively, -X a for alg:none, -X k -pk
public.pem for key confusion), Burp's JWT Editor extension, or a few lines
of PyJWT. Each forge below is the concept plus the claim to edit.
alg:none — become admin / another user
header: {"alg":"none","typ":"JWT"}
payload: {"data":{"id":1,"email":"admin@target.example","role":"admin"}}
signature: (empty — keep the trailing dot: header.payload. )Some verifiers reject lowercase none but accept None/NONE/nOnE — try case variants.
RS256 → HS256 key confusion — once you have the RSA public key
1. Obtain the server's RSA public key as PEM. Sources: /jwks.json or
/.well-known/jwks.json (convert the JWK to PEM), a public-key file in the JS
bundle, or recover it from two captured tokens (e.g. jwt_tool / rsa_sign2n).
2. Re-sign an EDITED payload with HS256, using that PEM as the HMAC secret:
jwt_tool <token> -X k -pk public.pem
payload edit: {"sub":"administrator"} (or role:"admin" / another user's id)kid header injection — verifier loads the HMAC key from a FILE named by kid
header: {"alg":"HS256","kid":"../../../../../../../dev/null"}
secret: "" (contents of /dev/null = empty string → sign HS256 with an empty secret)
payload: {"sub":"administrator"}Traverse out of the keys directory first. kid can also carry SQLi / command
injection / SSRF if the key lookup hits a DB / shell / URL — same idea: kid is
attacker-controlled and reaches a dangerous sink.
jku / x5u header injection (RS256) — verifier fetches the public key from a URL in the token
1. Host a JWKS containing a public key you control, on a server the verifier can reach.
2. Set the token's `jku` (or `x5u`) header to that URL and sign the edited payload
with YOUR matching private key.
3. If the verifier allowlists jku hosts, chain an open-redirect or SSRF-reachable
path on the target's OWN domain so the fetch resolves to your JWKS.jwk header self-signed key injection (RS256) — embed an attacker-controlled public key in the token
header: {"alg":"RS256","jwk":{"kty":"RSA","n":"<your_rsa_modulus>","e":"AQAB"}}
payload: {"sub":"administrator"}
signature: (sign with your matching private key)Some verifiers incorrectly trust a jwk (JSON Web Key) claim in the header and use it to validate the signature. Generate your own RSA keypair, embed the public key in the token header, sign with your private key, and send. Works when the verifier does not verify the key's provenance or allowlist.
Expiry / time-based claim manipulation
Remove "exp" (expiration) claim entirely — many validators skip the check if absent.
Or set "nbf" (not before) to the past and "exp" (expiration) to far future (e.g. year 2099).
Edit payload: {"sub":"administrator","nbf":1000000000,"exp":4102444800}Combined with any forging technique above (alg:none, key confusion, jwk injection), this bypasses time-based validation when the verifier does not enforce strict expiry rules.
Cross-tenant claim injection — escalate to another tenant's data via claim swaps
Identify tenant-related claims in a decoded real token: "org_id", "tenant", "account_id",
"workspace_id", "customer_id". Edit the target claim to another tenant's value.
Example: {"sub":"victim@org.com","org_id":1234} → change org_id to an admin's org (e.g. 9999).This is systematic IDOR via claims — if authorization logic trusts the token claims without checking ownership server-side, you cross into another tenant's resources. Works especially well combined with alg:none or weak-secret attacks.
Match the payload shape to a REAL token from the app (decode one first) — keep
its claim names, only change identity/role. A payload the app can't parse fails
for the wrong reason and wastes the attempt.
Offline attacks — weak HMAC secret cracking
If the token is HS256 (HMAC-based) and the secret is weak or reused from a known password list:
# Hashcat: mode 16500 = JWT
hashcat -a 0 -m 16500 <jwt_file> rockyou.txt
# jwt_tool: built-in wordlist cracking
jwt_tool <token> -C -d wordlist.txtOnce the secret is cracked, forge any token using HS256 with that secret (via jwt_tool or PyJWT).
Automated attack automation
Use purpose-built JWT attack suites to run all known forgery modes in parallel:
# jwt_tool: auto-try alg:none, key confusion, kid injection, etc.
jwt_tool <token> -X a
# Nuclei: automated JWT vuln scanning
nuclei -u <target_url> -t jwt/ -timeout 10sRun these early in JWT recon; they often find the vulnerability faster than manual chaining of individual techniques.
Drive to the ADMIN objective — do not stop at a working forge
A forge that loads YOUR own /my-account is NOT the goal — it just proves the
forge mechanism works. The objective is almost always admin (reach an
admin-only page and perform an admin action, e.g. delete a user). Once any forge
is accepted, IMMEDIATELY escalate — change identity to admin AND aim at the admin
endpoint. Do not keep re-forging /my-account or re-logging-in; that is drift.
Fixed escalation sequence (run it in order, do not loop on earlier steps):
- Forge admin identity and hit the admin page (try these claim names — match a
decoded real token:
sub,role,isAdmin,username), e.g. an HS256 token withkidpointed at/dev/nulland an empty secret, payload{"sub":"administrator"}, sent toGET /admin. - When
/adminreturns 200 (you'll see admin controls / a delete link), perform the admin action with the SAME forged token — a typical one is deleting a target user account, e.g.GET /admin/delete?username=<victimuser>(some apps usePOST /admin/delete— read the admin page for the exact form/verb).
A 401 on /admin means the forge/claim is wrong — change ONE thing (the kid
depth, the claim name/value, or alg) and retry /admin. Never retreat to a bare
unauthenticated GET /admin (no token) — that always 401s and wastes effort.
Proof of impact
Point the forged token at a protected/admin endpoint and prove you read data you should not: an account/user listing (multiple users' emails), another user's object, or a completed admin action (the deleted-user confirmation). Reading the admin user list or performing the admin action with a forged token IS the exploit. A 200 that returns only your own data, or a 401, is not proof.
Validation discipline
- Decode and confirm the token you sent actually carries the edited claims.
- The win is cross-identity data access, not merely a 200. Show the foreign user data (e.g. other users' emails) in the response.
alg:nonerejected (401) just means that flaw is patched — try key confusion before concluding the app is safe.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

