«
‹
HACKAACADEMY
OP-03 // OPERATION IRON GATE // JWT FORGERY
0
XP
R1
RANK
0%
DETECT
↻
RESET
In Operation Phantom Script, Shadow planted a stored XSS payload in the NEXUS forum. The payload stole session cookies from every official who read the compromised thread — authenticated access without a single password used.
CAMPAIGN 3 — OPERATION IRON GATE
BROKEN AUTH // TARGET: NEXUS VAULT PLATFORM
03
OWASP TOP 10 #7 — A07:2021
BROKEN AUTHENTICATION
JWT FORGERY // SESSION HIJACKING // CREDENTIAL STUFFING
OPERATION IRON GATE
📡
SITUATION REPORT
CLASSIFIEDThe Syndicate runs Vault — an encrypted ledger platform mirrored across a Reykjavik data-haven, holding the settlement records for every breach Vantage Systems has ever sold. Whoever holds Vault holds the Syndicate's client list. Access requires authentication, and PHANTOM, the platform's security architect, believes that login is impenetrable.
He's wrong. Vault's session tokens are JWT — JSON Web Tokens — and they ship with a fatal misconfiguration. We are going to forge a token that says we are administrator. No password. No brute force. Just math.
He's wrong. Vault's session tokens are JWT — JSON Web Tokens — and they ship with a fatal misconfiguration. We are going to forge a token that says we are administrator. No password. No brute force. Just math.
THE CONCERT WRISTBAND FORGERY
10-YEAR-OLD LEVEL
Imagine a concert where entry is controlled by wristbands. At the entrance, guards check your wristband to decide if you are allowed in.
But there is a hidden problem. The system does not properly verify whether the wristband is truly official or just looks official. It only checks what appears on the surface.
Now imagine someone arrives with a fake wristband. It looks correct. The guard checks it and allows entry. And just like that, someone who was never approved walks inside freely.
But there is a hidden problem. The system does not properly verify whether the wristband is truly official or just looks official. It only checks what appears on the surface.
Now imagine someone arrives with a fake wristband. It looks correct. The guard checks it and allows entry. And just like that, someone who was never approved walks inside freely.
If a server checks your token but never verifies the signature — what stops you from changing the token to say you are an administrator?
INTERCEPTED — PHANTOM COMMS
03:47 UTC
PHANTOM
"Every Vault session carries a signed JWT. The crypto is sound — nobody forges one of my tokens without the secret key, and that key never leaves Reykjavik."
MENDAX
Shadow — he's guarding a key we never need. Vault's tokens accept alg:none: tell the server there's no signature, and it stops checking. PHANTOM locked the safe and left the door unhinged. Strip the signature, set the role to admin, walk in.
▶ MISSION OBJECTIVES
01
Decode a JWT token and identify the fatal misconfiguration in the header
02
Forge an admin JWT using the alg:none exploit — no secret key required
03
Classify authentication mechanisms — strong vs dangerously weak
04
Identify the correct fix — what actually secures session management
⚖️
ETHICAL NOTICE: Broken authentication is covered by CEH, OSCP, and every cybersecurity certification. All interactions here are simulated against fictional infrastructure. Never use these techniques on real systems without explicit written authorisation.
🔧 UNDER THE HOOD▼
THE ATTACK — STEP BY STEP
A JWT has three Base64URL-encoded parts:
header.payload.signature. The alg:none attack removes signature verification entirely:// Original token header: {"alg":"HS256","typ":"JWT"}
// Step 1: decode the three parts with base64url decode
// Step 2: change header to {"alg":"none","typ":"JWT"}
// Step 3: change payload {"sub":"user1"} to {"sub":"admin","role":"admin"}
// Step 4: re-encode header + "." + payload + "." (empty signature)
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiJ9.
RS256 to HS256 confusion: if the server holds an RSA public key, sign with HS256 using that public key as the HMAC secret — the server uses the same key to verify:jwt.sign(payload, rsaPublicKeyAsString, { algorithm: 'HS256' })
COMMON VARIATIONS
1. Weak secret brute force — HS256 tokens can be cracked offline if the secret is weak:
hashcat -a 0 -m 16500 captured_token.txt rockyou.txt
2. kid header path traversal — the kid field selects which key to use; inject to point at a known value:// Set kid to point at /dev/null (empty file), sign with empty string
{"alg":"HS256","kid":"../../dev/null"}
3. jwk header injection — embed your own public key inside the token header so the server uses your key to verify your own forgery:{"alg":"RS256","jwk":{"kty":"RSA","n":"ATTACKER_MODULUS","e":"AQAB"}}
HOW TO DEFEND
Always specify an explicit algorithm whitelist when verifying — never let the token choose:
// Node.js (jsonwebtoken)
jwt.verify(token, SECRET_KEY, { algorithms: ['HS256'] });
// Python (PyJWT)
jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
// NEVER trust the alg field without constraining it:
// jwt.decode(token, key) ← accepts alg:none!
Use strong secrets (at least 256 bits of random entropy) for HS256. Prefer RS256 with asymmetric keys for distributed systems. Set short expiry (<15 min) + refresh token rotation.TARGET
nexus-auth.ghost-capital.int
IP ADDRESS
10.47.0.31
OS / WEB SERVER
Ubuntu 22.04 · Node.js/18.x
KEY SERVICES
Express.js JWT API · Vault port 8443
ATTACK SCOPE
/api/auth/* · /api/vault/* — admin vault in scope
ATTACKER NODE
shadow@sigma9 · 10.99.0.1
📋 ROOM TASKS
01
✓
Understand how alg:none eliminates signature verification
02
▶
Forge a JWT token to access the admin vault
03
○
Classify secure vs vulnerable JWT configurations
04
○
Identify the algorithm-whitelist fix
05
○
Submit the capture-the-flag token
CAPTURE THE FLAG
Complete the exploit lab. The flag appears in the terminal output. Copy and submit it here for +50 XP.
PHASE 01
DECODE THE TOKEN — SPOT THE FLAW
CHOOSE PAYLOAD
SIGMA-9 CAPTURE LOG — HOW WE FOUND IT
02:47 UTC
> tap on vault-api.nexus.int established
> operative logs in — server issues session token
> CAPTURED: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoieyJ1c2VyIjoi...
> MENDAX decoding base64...
MENDAX: "Shadow — I pulled a live token off the wire. I'm decoding it now. Something's wrong with the header. Look at it with me."
MENDAX — HOW THIS IS ACTUALLY DONE
LIVE
MENDAX
Here's how I pulled this off — the real mechanics, so you understand exactly what just happened. I parked a proxy on their wifi and waited for the operative to log in. Their token flew past in the clear:
$ mitmproxy --mode transparent
# operative logs in — token appears in the Authorization header
Authorization: Bearer eyJhbGciOiJub25l...
MENDAX
A JWT is just three base64 chunks split by dots. base64 isn't encryption — it's only packaging. So I decode each part right in the terminal, no key needed:
$ echo $TOKEN.header | base64 -d
{"alg":"none","typ":"JWT"}
$ echo $TOKEN.payload | base64 -d
{"user":"op_shadow","role":"viewer"}
MENDAX
There it is in plain text — the exact token the server issued, and the exact shape it'll accept back. That is the opening. Now you tell me: which field is the way in?
MENDAX
ENCRYPTED
You've seen the decoded token now —
PHANTOM swore this token was cryptographically protected. But it decoded with no key at all. Which field is the open door? Get this right and we forge our own token. No password. No brute force.
{"alg":"none",...} and {"role":"viewer",...}.PHANTOM swore this token was cryptographically protected. But it decoded with no key at all. Which field is the open door? Get this right and we forge our own token. No password. No brute force.
▶ MENDAX NEEDS A CALL — WHICH FIELD GETS US IN?
💡 MENDAX — HINT (−20 XP)
Look at the JWT header:
{"alg":"none"}. The alg field tells the server how to verify the signature. What happens if it says none? Which answer describes this problem directly?✓
FATAL FLAW IDENTIFIED — alg:none ACCEPTED
PHANTOM's Vault accepts JWT tokens where the algorithm is set to
In simple terms: Imagine a bouncer who checks your wristband but never looks at the stamp proving it's real. You can write anything on the wristband. The bouncer will believe it. PHANTOM built a system that checks the content of every token — but forgot to verify whether the token is genuine.
We now know we can craft any payload we want and the server will accept it with no signature.
none — meaning the server skips signature verification entirely.In simple terms: Imagine a bouncer who checks your wristband but never looks at the stamp proving it's real. You can write anything on the wristband. The bouncer will believe it. PHANTOM built a system that checks the content of every token — but forgot to verify whether the token is genuine.
We now know we can craft any payload we want and the server will accept it with no signature.
Real-world impact: CVE-2015-9235 — the alg:none vulnerability affected dozens of JWT libraries including node-jsonwebtoken. Hundreds of production systems accepted forged admin tokens for years before the flaw was widely patched.
PHASE 02
JWT FORGERY — BECOME THE ADMIN
TERMINAL
The flaw is confirmed: NEXUS Vault accepts tokens with no signature. Now use it. Swap the algorithm field to "none", elevate the role to ADMIN, strip the signature — and walk through the door as if you own the building.
MENDAX
ENCRYPTED
We know Vault accepts
A JWT has three parts: Header (what algorithm?), Payload (who are you?), Signature (proof it's real). With
Think of it like printing your own wristband. The stamp was never checked. So we write what we want on it — ADMIN — and walk straight in.
Build the forged token below. Select each value, watch the real Base64 token assemble in real time, then fire it at the server.
alg:none tokens. Now we forge one.A JWT has three parts: Header (what algorithm?), Payload (who are you?), Signature (proof it's real). With
alg:none — there is no proof required.Think of it like printing your own wristband. The stamp was never checked. So we write what we want on it — ADMIN — and walk straight in.
Build the forged token below. Select each value, watch the real Base64 token assemble in real time, then fire it at the server.
▶ BUILD YOUR FORGED JWT — SELECT EACH VALUE
LEAVE MISSION?
Progress is saved. You can resume from the mission select screen at any time.
RESET MISSION?
This wipes all progress for this operation only. XP in other operations is unaffected.
ARE YOU SURE?
Final confirmation -- all progress for this operation will be permanently erased.
💡 MENDAX — ACTIVE HINT
Three steps — one correct choice each. Step 1: Which algorithm makes the server skip signature verification? Look for the word "none". Step 2: We need full access — which role gives that? Step 3: With no verification — what signature do we need? Nothing. Empty.
✓
VAULT BREACHED — ADMIN ACCESS GRANTED
Vault accepted our forged token. We are now administrator. No password. No brute force. No secret key. Just a Base64-encoded JSON object with an empty signature.
Simple version: We wrote "ADMIN — ALL ACCESS" on our own wristband. The bouncer checked the writing but never checked the stamp. So our fake wristband worked perfectly.
Why alg:none is catastrophic: A properly signed JWT requires the server's secret key to forge. Without alg:none, this attack is mathematically impossible. With it — any attacker who can read documentation can become administrator.
Simple version: We wrote "ADMIN — ALL ACCESS" on our own wristband. The bouncer checked the writing but never checked the stamp. So our fake wristband worked perfectly.
Why alg:none is catastrophic: A properly signed JWT requires the server's secret key to forge. Without alg:none, this attack is mathematically impossible. With it — any attacker who can read documentation can become administrator.
Real impact: CVE-2015-9235 affected node-jsonwebtoken — used by millions of Node.js applications. Auth0, a major identity provider, patched an alg:none vulnerability in 2015. Production systems accepted forged admin tokens.
PHASE 03
CLASSIFY THE AUTH METHODS — STRONG OR WEAK?
TAP & SORT
Token forged, vault accessed. The root issue is broken signature verification — not just a JWT problem. Every auth method has its own failure mode. Identify which ones actually hold under pressure and which ones crack.
MENDAX
ENCRYPTED
PHANTOM is auditing authentication methods across NEXUS platforms — trying to work out which ones are actually secure and which ones an attacker like you could defeat.
MENDAX: "Shadow — classify each method. Tap it, then mark it STRONG if it genuinely protects against attack, or WEAK if you could defeat it easily."
Think like an attacker: can I guess it? Can I intercept it? Can I replay it? Can I forge it? If yes to any — it is weak.
Get them all right to proceed.
MENDAX: "Shadow — classify each method. Tap it, then mark it STRONG if it genuinely protects against attack, or WEAK if you could defeat it easily."
Think like an attacker: can I guess it? Can I intercept it? Can I replay it? Can I forge it? If yes to any — it is weak.
Get them all right to proceed.
▶ TAP AN INPUT — THEN TAP A BUCKET
Tap an input chip to select it, then tap SAFE or DANGEROUS to classify it.
✓ STRONG
✗ WEAK
✓
ALL MECHANISMS CLASSIFIED — AUTH SURFACE MAPPED
Perfect classification. You can now evaluate authentication strength on sight.
Simple version: Strong auth requires a secret that is long, random, and impossible to guess or replay. Weak auth uses secrets that are short, predictable, publicly known, or mathematically broken.
The rule: Never use MD5 or SHA1 for passwords. Never rely on security questions. Always use bcrypt, Argon2, or scrypt for password storage — they are designed to be slow, making brute force impractical.
Simple version: Strong auth requires a secret that is long, random, and impossible to guess or replay. Weak auth uses secrets that are short, predictable, publicly known, or mathematically broken.
The rule: Never use MD5 or SHA1 for passwords. Never rely on security questions. Always use bcrypt, Argon2, or scrypt for password storage — they are designed to be slow, making brute force impractical.
Why MD5 is dead: Every MD5 hash of every common password has been pre-computed and stored in rainbow tables. Cracking an MD5 password hash takes seconds — not years. bcrypt with cost factor 12 takes minutes per guess.
PHASE 04
THE FIX — CLOSE THE DOOR
DEFENSE
The vault is open and PHANTOM is exposed. One configuration change would have made this entire operation impossible. Name it, and the briefing is complete.
MENDAX — DEBRIEF
FINAL PHASE
NEXUS Vault is ours. PHANTOM is in custody.
MENDAX: "Shadow — one last brief. PHANTOM's CISO is proposing a fix right now. Which single change would have stopped you from forging the admin token? PHANTOM thought the JWT structure was the protection. Pick what actually secures it."
MENDAX: "Shadow — one last brief. PHANTOM's CISO is proposing a fix right now. Which single change would have stopped you from forging the admin token? PHANTOM thought the JWT structure was the protection. Pick what actually secures it."
▶ WHICH FIX STOPS JWT FORGERY?
💡 MENDAX — HINT (−20 XP)
Think about WHY the forgery worked: the server trusted the
alg field in the token itself. The fix prevents this. Should the server trust what the token claims about its own algorithm — or should the server decide which algorithm to use?► INTEL — OP-03 // OPERATION IRON GATE
TARGET: NEXUS Session Management Server
Classification: TOP SECRET // Campaign 3 Ghost Protocol
MENDAX — CHANNEL BRIEFING
PRE-OP
MENDAX
Session tokens use a weak PRNG seeded with timestamp milliseconds. Cookies have no Secure or HttpOnly flags. JWT tokens use HS256 with a guessable secret.
📓
OWASP CLASSIFICATION
INTELA07:2021 — Auth failures include weak session management, predictable tokens, missing cookie flags, and broken JWT implementation.
⚖
GLOSSARY TERMS: JWT, Session Token, Cookie Hijacking, PRNG, HttpOnly, Secure Flag. All terms auto-logged to your Field Manual as you encounter them.
▶ ACADEMY — BROKEN AUTHENTICATION
AUTHENTICATION IS THE LOCK.
BROKEN AUTH IS A KEY THAT FITS EVERY DOOR.
BROKEN AUTH IS A KEY THAT FITS EVERY DOOR.
Three levels of depth — start at Beginner, go as deep as you want.
BEGINNER
What Is Broken Authentication?
›
Authentication is how a system proves you are who you say you are. Broken authentication means that proof can be faked, guessed, or skipped entirely.
When you log into a website, it gives you a token — a temporary pass that says "we checked this person, trust them." Every page you visit sends that token. If an attacker can forge that token, they become you — without ever knowing your password.
The three failure types you used today:
• JWT alg:none — server accepts tokens with no signature
• Weak credentials — passwords short enough to brute-force
• Broken session management — tokens that never expire or can be reused
When you log into a website, it gives you a token — a temporary pass that says "we checked this person, trust them." Every page you visit sends that token. If an attacker can forge that token, they become you — without ever knowing your password.
The three failure types you used today:
• JWT alg:none — server accepts tokens with no signature
• Weak credentials — passwords short enough to brute-force
• Broken session management — tokens that never expire or can be reused
Real world: In 2016, a researcher discovered that dozens of production APIs accepted JWT tokens with alg:none — including services used by major enterprises. Zero credentials required. Administrator access granted.
INTERMEDIATE
How JWT Forgery Works
›
JWT structure:
Normal verification: Server receives token → decodes header → sees alg:HS256 → computes HMAC of header+payload using secret key → compares to signature → match = valid
alg:none attack: Attacker sets alg:none → server skips signature computation → no comparison → any payload accepted
Credential stuffing:
1. Attacker downloads breach database (billions of username:password pairs)
2. Tries each pair against target login
3. 60-80% of users reuse passwords across sites
4. Rate limiting and MFA are the only defences
Session fixation: Attacker sets a known session ID before login. Victim logs in with that ID. Attacker uses same ID to access authenticated session.
base64(header) . base64(payload) . signatureNormal verification: Server receives token → decodes header → sees alg:HS256 → computes HMAC of header+payload using secret key → compares to signature → match = valid
alg:none attack: Attacker sets alg:none → server skips signature computation → no comparison → any payload accepted
Credential stuffing:
1. Attacker downloads breach database (billions of username:password pairs)
2. Tries each pair against target login
3. 60-80% of users reuse passwords across sites
4. Rate limiting and MFA are the only defences
Session fixation: Attacker sets a known session ID before login. Victim logs in with that ID. Attacker uses same ID to access authenticated session.
EXPERT
Advanced Attacks & CVEs
›
RS256 vs HS256:
• HS256 = shared secret. If you steal the secret, you can forge any token. Stolen from server = full compromise.
• RS256 = asymmetric. Private key signs. Public key verifies. Public key can be shared safely. Attacker cannot forge without private key.
JWT confusion attack (CVE-2022-21449): Java's ECDSA implementation accepted signatures of all zeros — "Psychic Signatures." Affected Java 15-18. Forged JWT, SAML tokens, TLS certificates all accepted.
Password storage failures:
• MD5 — completely broken. Rainbow tables cover all common passwords
• SHA1 — broken. GPU can compute 10 billion SHA1/sec
• bcrypt cost 10 — ~100ms per attempt on modern hardware. Practical
• Argon2id — winner of Password Hashing Competition 2015. Recommended
Notable CVEs:
• CVE-2015-9235 — node-jsonwebtoken alg:none, CVSS 9.8
• CVE-2022-21449 — Java Psychic Signatures, CVSS 7.5
• CVE-2018-0114 — Cisco node-jose alg substitution
• HS256 = shared secret. If you steal the secret, you can forge any token. Stolen from server = full compromise.
• RS256 = asymmetric. Private key signs. Public key verifies. Public key can be shared safely. Attacker cannot forge without private key.
JWT confusion attack (CVE-2022-21449): Java's ECDSA implementation accepted signatures of all zeros — "Psychic Signatures." Affected Java 15-18. Forged JWT, SAML tokens, TLS certificates all accepted.
Password storage failures:
• MD5 — completely broken. Rainbow tables cover all common passwords
• SHA1 — broken. GPU can compute 10 billion SHA1/sec
• bcrypt cost 10 — ~100ms per attempt on modern hardware. Practical
• Argon2id — winner of Password Hashing Competition 2015. Recommended
Notable CVEs:
• CVE-2015-9235 — node-jsonwebtoken alg:none, CVSS 9.8
• CVE-2022-21449 — Java Psychic Signatures, CVSS 7.5
• CVE-2018-0114 — Cisco node-jose alg substitution
RockYou 2009: 32 million passwords stored in plain text. Breached and published. RockYou.txt is now the standard wordlist for every password cracker. 14 years later, it is still used in active attacks.
▶ REAL-WORLD TOOLS — BROKEN AUTHENTICATION
WHAT PROFESSIONALS USE
Every tool here is free, legal, and used in real penetration tests.
🔑
jwt_tool
FREE / OPEN SOURCE
The standard JWT testing toolkit. Decodes tokens, tests alg:none, performs algorithm confusion attacks, brute-forces weak HS256 secrets, and scans for known JWT vulnerabilities.
python3 jwt_tool.py [token] -X a
🔎
Burp Suite — JWT Editor
FREE extension
Burp extension for live JWT manipulation. Intercept requests, decode tokens inline, modify claims, re-sign or strip signatures, send modified tokens. Essential for manual JWT testing.
Burp → Extender → BApp Store → JWT Editor → Intercept → Edit
💧
Hydra
FREE / OPEN SOURCE
Fast online password brute-force tool. Supports HTTP login forms, SSH, FTP, and 50+ protocols. Used to test credential stuffing and weak password attacks in authorised engagements.
hydra -L users.txt -P rockyou.txt target.com http-post-form
🌊
Hashcat
FREE / OPEN SOURCE
GPU-accelerated password hash cracker. Cracks MD5, SHA1, bcrypt, and 300+ hash types. Used to test password storage strength in authorised penetration tests.
hashcat -a 0 -m 0 hashes.txt rockyou.txt