«
‹
HACKAACADEMY
OP-04 // OPERATION SILENT HAND // CSRF
0
XP
R1
RANK
0%
DETECT
↻
RESET
In Operation Iron Gate, Shadow forged a JWT token by exploiting the alg:none vulnerability — the server accepted a token with no signature. The vault was open. MENDAX moved Shadow to the next target.
CAMPAIGN 3 — OPERATION SILENT HAND
CSRF // TARGET: NEXUS BANKING PORTAL
04
OWASP A01:2021 — CSRF / ACCESS CONTROL
CROSS-SITE REQUEST FORGERY
FORGED REQUESTS // TOKEN BYPASS // SESSION RIDING
OPERATION SILENT HAND
📡
SITUATION REPORT
CLASSIFIEDThe Syndicate moves its money through a banking portal fronted by a Bucharest shell company on the Vantage Systems books. GHOST, the Syndicate's operations treasurer, is logged in right now — shuffling breach proceeds between holding accounts before the next payout clears.
We cannot touch GHOST's machine. We cannot steal his password. We don't need to.
The portal has no CSRF protection — it accepts any fund transfer request as long as a valid session cookie is attached. GHOST's browser will attach that cookie automatically to any request — even one we send him through a fake link. We are going to make GHOST's own browser transfer money on our behalf. He won't click anything suspicious. He won't know it happened.
We cannot touch GHOST's machine. We cannot steal his password. We don't need to.
The portal has no CSRF protection — it accepts any fund transfer request as long as a valid session cookie is attached. GHOST's browser will attach that cookie automatically to any request — even one we send him through a fake link. We are going to make GHOST's own browser transfer money on our behalf. He won't click anything suspicious. He won't know it happened.
THE FORGED LETTER FROM YOUR MUM
10-YEAR-OLD LEVEL
Imagine a courier who delivers signed requests on your behalf. Whenever a request appears to come from you, the courier automatically delivers it without asking whether you actually intended it.
Now imagine you are unaware, and someone tricks the system into producing a request that looks like it came from you. The courier does not question it. He delivers it exactly as if it were yours.
Inside the system, that request triggers actions under your identity — even though you never made them. The system confuses identity with intention.
Now imagine you are unaware, and someone tricks the system into producing a request that looks like it came from you. The courier does not question it. He delivers it exactly as if it were yours.
Inside the system, that request triggers actions under your identity — even though you never made them. The system confuses identity with intention.
If your browser automatically attaches your bank cookie to every request — what stops a different website from making your browser send a request to your bank?
INTERCEPTED — GHOST COMMS
11:22 UTC
GHOST
"The Bucharest portal only honours logged-in users. No transfer fires without a live session. The cookie is the lock — and only my browser carries it."
MENDAX
Shadow — that's the whole opening. His browser attaches that cookie to any request to the bank, including one we email him from a page that looks like nothing. We never steal the key. We just get GHOST to turn it for us — fifty thousand into our account, signed by him.
▶ MISSION OBJECTIVES
01
TARGET: GHOST's banking portal at bank.nexus — a /transfer endpoint that trusts the session cookie alone, no anti-CSRF token, no Origin check
02
FORGE: Plant an auto-submitting page that fires a forged transfer from GHOST's logged-in browser — moving 50,000 to our account using his own session
03
SWEEP: Classify GHOST's requests — flag which state-changing actions need CSRF protection and which read-only ones don't
04
WIN: Land the forged transfer, then lock it down — the anti-CSRF token plus SameSite cookie that kills the attack permanently
⚖️
ETHICAL NOTICE: CSRF 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
CSRF tricks the victim's browser into sending a forged request while they are logged in. Host this on your server and get the victim to visit it:
<!-- attacker's page: auto-submits when loaded -->
<form id="f" action="https://bank.com/transfer" method="POST">
<input type="hidden" name="to" value="attacker_account">
<input type="hidden" name="amount" value="5000">
</form>
<script>document.getElementById('f').submit();</script>
The bank sees a valid session cookie and processes the transfer — the victim never saw a form. For GET-based actions (rare but it happens):<img src="https://bank.com/transfer?to=attacker&amount=5000">
COMMON VARIATIONS
1. SameSite=Lax bypass via top-level GET navigation — Lax allows cookies on top-level navigations triggered by links or redirects, so GET endpoints remain vulnerable even with Lax cookies.
2. JSON CSRF via text/plain content type — if the server accepts JSON with no content-type check:
2. JSON CSRF via text/plain content type — if the server accepts JSON with no content-type check:
<form enctype="text/plain" action="https://api.victim.com/settings" method="POST">
<input name='{"email":"attacker@evil.com","dummy":"' value='"}'>
</form>
3. CSRF via Flash or CORS misconfiguration — a lenient CORS policy (Access-Control-Allow-Origin: * with credentials) effectively bypasses same-origin protections.HOW TO DEFEND
Two-pronged defense: CSRF tokens + SameSite cookies:
// Server: generate per-session CSRF token
const csrfToken = crypto.randomBytes(32).toString('hex');
session.csrfToken = csrfToken;
// HTML form: include token as hidden field
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
// Server: validate on every state-changing request
if (req.body._csrf !== req.session.csrfToken) {
return res.status(403).send('CSRF validation failed');
}
Set cookie attributes:Set-Cookie: session=abc123; SameSite=Strict; Secure; HttpOnly
SameSite=Strict is the strongest — the browser never sends the cookie on cross-site requests at all.TARGET
nexus-funds.ghost-capital.int
IP ADDRESS
10.47.0.44
OS / WEB SERVER
Ubuntu 22.04 · nginx/1.18.0
KEY SERVICES
PHP/8.0.20 · MySQL 8.0
ATTACK SCOPE
/portal/transfer — POST endpoint in scope
ATTACKER NODE
shadow@sigma9 · 10.99.0.1
📋 ROOM TASKS
01
✓
Understand why browsers auto-attach cookies cross-origin
02
▶
Forge a fund transfer request via CSRF
03
○
Classify which requests need CSRF protection
04
○
Identify the CSRF token 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
FORGE THE REQUEST
EXPLOIT
SIGMA-9 CAPTURE LOG — HOW WE FOUND IT
02:47 UTC
> replaying GHOST's /transfer request — stripping every header except the session cookie
> server still processes it — no anti-CSRF token in the form, no Origin check
> FOUND: the endpoint trusts the cookie alone — any page can fire this request
MENDAX: "Shadow — the bank only asks 'valid session?' It never asks 'did YOU mean to send this?' That gap is ours. Watch."
MENDAX — HOW THIS IS ACTUALLY DONE
LIVE
MENDAX
First I confirm there's nothing protecting the endpoint — I fetch the transfer form and grep for a token. Nothing comes back:
$ curl -s https://bank.nexus/transfer | grep -i csrf
# no hidden csrf_token field, no per-request secret
(no output)
MENDAX
Confirmed unprotected. Now I plant a page that auto-submits a forged transfer. When GHOST loads it, his browser attaches his cookie and fires it for us:
<form action="https://bank.nexus/transfer" method="POST">
<input name="to" value="nexus_account">
<input name="amount" value="50000">
</form>
<script>document.forms[0].submit()</script>
# GHOST opens our link → browser sends cookie → 50,000 transferred
MENDAX
We never touch his password — we ride his open session. And the fix is almost insulting: one unguessable CSRF token in the form, or a
SameSite cookie, and our forged page can't fire a thing. GHOST shipped neither. We'll wire that defense in later. Now call it: why does GHOST's browser send our forged request?MENDAX
ENCRYPTED
You just planted a page that fired a forged transfer from GHOST's own browser — his cookie rode along and the bank obeyed. Here is the request his browser sent for us:
The server checks the cookie — sees a valid session — and processes the transfer. No other checks. No secret one-time code. No verification that GHOST actually clicked the button.
Simple version: the bank asks "do you have a valid session?" — yes. Then it does whatever the request says. It never asks "did YOU send this request?"
You just made his browser fire it. Now make the call: why did GHOST's browser send our forged request?
POST /transferCookie: session=abc123Body: to=nexus_account&amount=50000The server checks the cookie — sees a valid session — and processes the transfer. No other checks. No secret one-time code. No verification that GHOST actually clicked the button.
Simple version: the bank asks "do you have a valid session?" — yes. Then it does whatever the request says. It never asks "did YOU send this request?"
You just made his browser fire it. Now make the call: why did GHOST's browser send our forged request?
▶ PICK THE CORRECT EXPLANATION
💡 MENDAX — HINT (−20 XP)
Think about what a browser does automatically whenever you visit any website. It sends your cookies for that domain with every request — even if the request was triggered by a completely different website. Which answer describes this automatic browser behaviour?
✓
CSRF MECHANISM UNDERSTOOD
Browsers are built to be helpful. When you visit site-a.com and it triggers a request to bank.com — your browser says "I have cookies for bank.com" and attaches them automatically. It was designed to work this way.
In simple terms: You are logged into your bank. You open a dodgy link in the same browser. That page silently loads an invisible form targeting your bank. Your browser submits it — with your cookie attached — before you even see the page load. The bank sees a valid session and processes the transfer. You see nothing.
GHOST uses the same browser for everything. We just need him to visit one page we control — even for one second.
In simple terms: You are logged into your bank. You open a dodgy link in the same browser. That page silently loads an invisible form targeting your bank. Your browser submits it — with your cookie attached — before you even see the page load. The bank sees a valid session and processes the transfer. You see nothing.
GHOST uses the same browser for everything. We just need him to visit one page we control — even for one second.
Real-world impact: In 2008, a CSRF attack on a Netflix feature allowed attackers to add DVDs to victims' queues and change account settings — just by getting them to visit a webpage. Same technique used against banking portals across multiple countries.
PHASE 02
BUILD THE CSRF PAYLOAD — MAKE GHOST PAY US
TERMINAL
Mechanism confirmed. The browser sends GHOST's credentials automatically. Now study the two requests side by side — spot the fields that make a forged transfer look identical to a real one, then fire it.
MENDAX
ENCRYPTED
Below are two HTTP requests arriving at the NEXUS bank server — one GHOST sent intentionally, one we forged. The server sees both. It has no idea which is real.
Think of it like two letters arriving at the bank — one from GHOST, one from us pretending to be GHOST. The envelope looks identical. The bank opens both and acts on both.
Study the requests carefully. Tap the fields that reveal how the attack works — then fire the forged request.
Think of it like two letters arriving at the bank — one from GHOST, one from us pretending to be GHOST. The envelope looks identical. The bank opens both and acts on both.
Study the requests carefully. Tap the fields that reveal how the attack works — then fire the forged request.
▶ TAP THE HIGHLIGHTED FIELDS TO LEARN HOW THE ATTACK WORKS
Two requests reach the bank server. Tap any underlined field to reveal why CSRF succeeds.
Tap 3 fields
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
Tap each underlined field in the right column (Our Forged Request) — the cookie line, the origin line, and the no-CSRF-token line. Each tap explains one reason the attack works. Tap all three to unlock the fire button.
✓
TRANSFER COMPLETE — GHOST NEVER KNEW
GHOST opened a link. His browser loaded our page. Our hidden form submitted automatically in 200 milliseconds. His bank cookie was attached. USD 50,000 moved — before he even read the page title.
Simple version: We sent GHOST a tripwire disguised as a message. He walked into it. His own browser pulled the trigger. We were never in the room.
Why this works every time without CSRF protection: The browser cannot tell the difference between a form you submitted intentionally and one that submitted itself in JavaScript. Both send the same cookie. Both look identical to the server.
Simple version: We sent GHOST a tripwire disguised as a message. He walked into it. His own browser pulled the trigger. We were never in the room.
Why this works every time without CSRF protection: The browser cannot tell the difference between a form you submitted intentionally and one that submitted itself in JavaScript. Both send the same cookie. Both look identical to the server.
Real impact: In 2012, a CSRF vulnerability in an online banking app in Romania allowed attackers to trigger M-Pesa transfers from logged-in victims just by getting them to visit a link. Same technique. Real money. Real victims.
PHASE 03
CLASSIFY THE REQUESTS — NEEDS CSRF PROTECTION?
TAP & SORT
Transfer fired. CSRF only damages when forging a state-changing action. Identify which portal actions are worth protecting — and which ones an attacker can forge all day without gaining anything.
MENDAX
ENCRYPTED
GHOST's security team is reviewing which NEXUS portal actions need CSRF protection. Some need a token — some don't.
MENDAX: "Shadow — classify each action. Tap it, then mark it NEEDS CSRF TOKEN if forging that request could cause real damage, or SAFE if a forged request does nothing harmful."
Simple rule: does this action CHANGE something — move money, update data, delete records? Then it needs protection. Does it only READ something — load a page, show a balance? A forged read request gets the attacker nothing, because the response goes to the victim's browser, not ours.
Get them all right to proceed.
MENDAX: "Shadow — classify each action. Tap it, then mark it NEEDS CSRF TOKEN if forging that request could cause real damage, or SAFE if a forged request does nothing harmful."
Simple rule: does this action CHANGE something — move money, update data, delete records? Then it needs protection. Does it only READ something — load a page, show a balance? A forged read request gets the attacker nothing, because the response goes to the victim's browser, not ours.
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.
✓ NEEDS CSRF TOKEN
✗ SAFE — READ ONLY
✓
ALL REQUESTS CLASSIFIED — CSRF SURFACE MAPPED
Perfect classification. You now know exactly which endpoints need CSRF tokens.
Simple version: The golden rule — any action that changes data needs a CSRF token. Any action that only reads data is safe to leave unprotected, because even if an attacker forces that request, nothing bad happens.
Actions that change data: transfers, password changes, email changes, deletions. Actions that read data: viewing balances, searching, loading pages.
Simple version: The golden rule — any action that changes data needs a CSRF token. Any action that only reads data is safe to leave unprotected, because even if an attacker forces that request, nothing bad happens.
Actions that change data: transfers, password changes, email changes, deletions. Actions that read data: viewing balances, searching, loading pages.
Why read-only is safe: A CSRF attack forces a request — but the response goes back to the victim's browser, not the attacker's. So reading data gives the attacker nothing. Only state-changing actions cause real damage.
PHASE 04
THE FIX — CLOSE THE DOOR
DEFENSE
Action classified, transfer frozen. The browser's automatic cookie behaviour cannot be changed — the fix lives entirely on the server side. Name the mechanism that breaks the forgery chain permanently.
MENDAX — DEBRIEF
FINAL PHASE
GHOST is being brought in. USD 50,000 recovered.
MENDAX: "Shadow — debrief question. NEXUS's development team is patching the portal right now. Which single fix would have stopped the entire attack? The browser behaviour cannot be changed — we can't stop cookies from being sent automatically. The fix has to be on the server side."
MENDAX: "Shadow — debrief question. NEXUS's development team is patching the portal right now. Which single fix would have stopped the entire attack? The browser behaviour cannot be changed — we can't stop cookies from being sent automatically. The fix has to be on the server side."
▶ WHICH FIX STOPS CSRF?
💡 MENDAX — HINT (−20 XP)
Think about WHY the attack worked: the server had no way to tell the difference between a request GHOST sent intentionally and one his browser sent automatically from our page. The fix gives the server a way to tell the difference. What could be included in the request that only the real banking page would know — but our page could never guess?
► INTEL — OP-04 // OPERATION SILENT HAND
TARGET: NEXUS Bank Transfer API
Classification: TOP SECRET // Campaign 3 Ghost Protocol
MENDAX — CHANNEL BRIEFING
PRE-OP
MENDAX
The transfer form has no CSRF token. Any site can trigger a POST to /transfer on behalf of a logged-in NEXUS user. All parameters come from the attacker-controlled form.
📓
OWASP CLASSIFICATION
INTELA03:2021 — CSRF exploits the trust a site has in a user's browser. The server cannot distinguish a legitimate form from an attacker-crafted one without a secret token.
⚖
GLOSSARY TERMS: CSRF, SameSite Cookie, CSRF Token, Cross-Site Request Forgery, Origin Header. All terms auto-logged to your Field Manual as you encounter them.
▶ ACADEMY — CROSS-SITE REQUEST FORGERY
YOUR BROWSER IS HELPFUL.
CSRF TURNS THAT HELPFULNESS INTO A WEAPON.
CSRF TURNS THAT HELPFULNESS INTO A WEAPON.
Three levels of depth — start at Beginner, go as deep as you want.
BEGINNER
What Is CSRF?
›
CSRF — Cross-Site Request Forgery — is an attack where a website you didn't choose sends a request to a website you trust, using your own identity, without your knowledge.
Here is how it feels from your side: you are logged into your bank. Someone sends you a link — looks innocent. You click it. Nothing seems to happen. But in the background, a form submitted itself to your bank using your session cookie. Money moved. You had no idea.
The three things that make CSRF possible:
• Browsers automatically attach cookies to matching domains — always
• The bank cannot tell if you submitted that form or a foreign page did
• No secret one-time token was required to prove the request was intentional
Here is how it feels from your side: you are logged into your bank. Someone sends you a link — looks innocent. You click it. Nothing seems to happen. But in the background, a form submitted itself to your bank using your session cookie. Money moved. You had no idea.
The three things that make CSRF possible:
• Browsers automatically attach cookies to matching domains — always
• The bank cannot tell if you submitted that form or a foreign page did
• No secret one-time token was required to prove the request was intentional
Real world: In 2008, Netflix had a CSRF vulnerability that let attackers change account settings — email address, DVD queue — by getting victims to visit a webpage. No login. No interaction. Just a visit.
INTERMEDIATE
How CSRF Attacks Are Built
›
Classic CSRF payload (HTML form):
What happens step by step:
1. Victim is logged into bank — session cookie active
2. Victim visits attacker page (phishing link, forum post, ad)
3. Page loads hidden form, JavaScript submits it immediately
4. Browser sends POST to bank.com — with session cookie attached automatically
5. Bank processes transfer — sees valid session, no CSRF token to check
6. Victim never sees a form. Sees a blank page or redirect.
GET-based CSRF (even simpler):
Loading the image triggers the GET request. If the bank uses GET for transfers — instant attack.
<form action="https://bank.com/transfer" method="POST"><input type="hidden" name="to" value="attacker"><input type="hidden" name="amount" value="50000"></form><script>document.forms[0].submit();</script>What happens step by step:
1. Victim is logged into bank — session cookie active
2. Victim visits attacker page (phishing link, forum post, ad)
3. Page loads hidden form, JavaScript submits it immediately
4. Browser sends POST to bank.com — with session cookie attached automatically
5. Bank processes transfer — sees valid session, no CSRF token to check
6. Victim never sees a form. Sees a blank page or redirect.
GET-based CSRF (even simpler):
<img src="https://bank.com/transfer?to=attacker&amount=50000">Loading the image triggers the GET request. If the bank uses GET for transfers — instant attack.
EXPERT
Defences, Bypasses & CVEs
›
CSRF Token — the correct defence:
Server generates a random secret per session. Embeds it in every form as a hidden field. Verifies it on every state-changing request. An attacker on a different origin cannot read this token — same-origin policy blocks it. No token = request rejected.
SameSite cookie attribute:
•
•
•
CSRF token bypass techniques:
• Token not tied to session — reuse a token from your own account
• Token in URL — leaked via Referer header
• Token length too short — brute forceable
• Token not verified server-side — just present in form, never checked
Notable CVEs:
• CVE-2020-17530 — Apache Struts CSRF bypass
• CVE-2019-9978 — WordPress CSRF in Social Warfare plugin
• CVE-2018-6389 — WordPress CSRF via load-scripts.php
Server generates a random secret per session. Embeds it in every form as a hidden field. Verifies it on every state-changing request. An attacker on a different origin cannot read this token — same-origin policy blocks it. No token = request rejected.
SameSite cookie attribute:
•
SameSite=Strict — cookie never sent cross-site. Breaks some flows.•
SameSite=Lax — cookie sent on top-level navigation only. Good default.•
SameSite=None — always sent. Vulnerable to CSRF.CSRF token bypass techniques:
• Token not tied to session — reuse a token from your own account
• Token in URL — leaked via Referer header
• Token length too short — brute forceable
• Token not verified server-side — just present in form, never checked
Notable CVEs:
• CVE-2020-17530 — Apache Struts CSRF bypass
• CVE-2019-9978 — WordPress CSRF in Social Warfare plugin
• CVE-2018-6389 — WordPress CSRF via load-scripts.php
Tiktok 2020: A CSRF + XSS chain allowed attackers to take over any TikTok account by sending the victim a single SMS. One click. Full account takeover. 1 billion potential victims.
▶ REAL-WORLD TOOLS — CSRF
WHAT PROFESSIONALS USE
Every tool here is free, legal, and used in real penetration tests.
🔎
Burp Suite — CSRF PoC Generator
FREE TIER
Right-click any POST request in Burp → Engagement Tools → Generate CSRF PoC. Burp builds the HTML attack page automatically. Open it in a browser to test. Fastest CSRF testing workflow available.
Right-click request → Engagement Tools → Generate CSRF PoC
🌊
OWASP ZAP — Active Scan
FREE / OPEN SOURCE
ZAP's active scanner checks all forms and state-changing endpoints for missing CSRF tokens. Passive scan flags forms without anti-CSRF controls automatically during normal browsing.
Active Scan → Anti CSRF Tokens → View alerts
🐍
csrf-poc-generator (Python)
FREE / OPEN SOURCE
Lightweight Python script that takes a raw HTTP POST request and outputs a ready-to-use CSRF HTML proof-of-concept page. Useful for manual testing when Burp isn't available.
python3 csrf_poc.py --request raw.txt --output poc.html
🛡️
csrf-scanner (npm)
FREE
Node.js package that crawls a web app and reports endpoints that accept state-changing requests without CSRF tokens. Good for developers auditing their own apps before deployment.
npx csrf-scanner --url https://target.com --cookie session=abc