Already a member?
Your cart

Your cart is empty.

CMWAP example plans & reports

Learn the expected format: example plans (what you submit in your 90-minute window) and example reports and findings. These are illustrative β€” your exam deliverables are your own work.

← Back to CMWAP

Worked example plan β€” RatCTF

CMWAP Pentest Plan β€” Worked Example: RatCTF

A full plan for ratctf.com inside an 8-hour window β€” 300 testable minutes, 11 endpoints IN, the rest OUT or DEFERRED with reasons. Source for [EXAMPLE] Pentest Plan - RatCTF - 010.pdf. The XSS Rat Β· CMWAP Β· Authorized testing only.


Pentest Plan β€” RatCTF

ratctf.com in an 8-hour window. Five testable hours, and a written reason for every endpoint that does not get them.

Read this beside the template. Same sections, same clock, filled in against a target far larger than the window. That is the point: the platform has roughly 96 challenge machines, eight multi-machine ranges and a portal, and this plan tests eleven endpoints. The other rows are not missing β€” they are marked OUT or DEFERRED, each with a reason and, where it applies, the condition that would pull it forward.

FieldValue
CandidateA. Candidate
Target / engagementratctf.com β€” RatCTF training platform
Window opens (T+0:00)Mon 09:00 CET
Plan due (T+0:45)Mon 09:45 CET β€” submitted 09:41
Report + debrief due (T+8:00)Mon 17:00 CET
AuthorizationEngagement letter dated 2026-08-07. The platform rules at /rules apply as the baseline and are not overridden by this plan. Disclosure route: /.well-known/security.txt.
Plan versionv1.0

1 Β· Objective (0:00 – 0:10)

Determine whether a free-tier RatCTF account can obtain content or standing it has not earned β€” premium or retired machines, another user's progress, or leaderboard position from challenges it never solved β€” and state what that would cost RatCTF in subscription revenue and leaderboard credibility.

One question, answerable in five hours. Not β€œassess the security of RatCTF”, which is a six-week engagement and would have produced a plan I could not deliver.

2 Β· Time budget (0:10 – 0:15)

Fixed cost β€” comes off the topHours
Total window8.00
This planβˆ’0.75
Report β€” ring-fenced, never borrowed fromβˆ’1.50
Debrief video: record, review, uploadβˆ’0.50
Setup, access, evidence adminβˆ’0.25
ACTUAL TESTABLE TIME5.00 h Β =Β  300 min
Wall clockBlockBudgetWhat must be true when it ends
09:00–09:45Plan β€” write and send45 minSubmitted at 09:41
09:45–10:45Recon and mapping60 minTwo free accounts and the premium account live; Burp proxying; endpoint table confirmed against the real app
10:45–13:00IN Β· MUST β€” rows 1–5135 minEntitlement and scoring questions answered either way
13:00–14:15IN Β· SHOULD β€” rows 6–1175 minSupporting rows tested or explicitly parked
14:15–14:45Verify and capture proof30 minEvery finding re-run from its own written steps on a clean session
14:45–16:15Report90 minRing-fenced
16:15–16:45Debrief video30 minRecorded and uploaded
16:45–17:00Submit and buffer15 minBoth deliverables in
Testing subtotal300 min= 5.00 h

3 Β· Endpoint inventory and disposition (0:15 – 0:35)

IN β€” authorized, relevant, affordable. OUT β€” not authorized. Never tested. DEFERRED β€” authorized and relevant, does not fit 300 minutes.

#Endpoint / functionMethodRole(s)WSTG ID(s)Disp.Why this dispositionBudget
1/challenges/{slug} β€” premium / retired gateGETfreeWSTG-ATHZ-02 / WSTG-ATHZ-04INThis gate is the subscription revenue named in the objective. Direct object reference on a slug the account has no entitlement for.40 min
2/api/flags/submit β€” flag submissionPOSTfree Γ—2WSTG-BUSL-01 / WSTG-BUSL-02INConverts work into leaderboard standing. Tests whether a flag is accepted for a machine the account never spawned.35 min
3/api/instances/{id} β€” spawn / reset / destroyPOST/DELETEfree Γ—2WSTG-ATHZ-04 / WSTG-BUSL-02INInstance ownership boundary. If account A can reset account B's instance, one learner can wreck another's engagement.25 min
4/vaults/{id}/claim β€” Treasure Vault claimPOSTfreeWSTG-BUSL-02 / WSTG-ATHZ-02INA one-time, scarce, paid-tier action β€” the classic replay and double-claim target.20 min
5/leaderboard + scoring recalculationGETfreeWSTG-BUSL-01 / WSTG-ATHZ-04INSecond half of the objective. Checks whether standing can be inflated without solving.15 min
6/profile β€” display name, avatar, bioPOSTfreeWSTG-INPV-02 / WSTG-ATHZ-03INStored XSS renders on the leaderboard, seen by every user including staff. Also the likeliest mass-assignment surface (role, tier).20 min
7/paths, /quests β€” progression unlocksGET/POSTfreeWSTG-BUSL-02INWorkflow with an ordering assumption; skipping a step is cheap to test and feeds row 5.15 min
8/api/docs β€” published API surfaceGETfreeWSTG-CONF-05 / WSTG-INFO-02INRead-only enumeration to confirm rows 2–4 are complete. No requests fired from it beyond those rows.10 min
9?next= / ?redirect= params on nav routesGETfreeWSTG-CLNT-04INCheap, and an open redirect chains into row 1 by carrying an entitled session somewhere it should not go.10 min
10/premium β€” entitlement display vs enforcementGETfree, premiumWSTG-ATHZ-02INPaired with row 1: is the gate enforced server-side or only rendered? 10 minutes with two sessions answers it.10 min
11Set-Cookie on session issue and on tier upgradeβ€”free, premiumWSTG-SESS-02 / WSTG-SESS-03INTwo minutes of observation; if the session does not rotate on upgrade it undermines rows 1 and 10.10 min
IN subtotal β€” matches the 210-minute MUST + SHOULD budget210 min
1296 single challenge machines (Injectrix, Loophole, Debugtrap, …)β€”freefull INPV / ATHZ / BUSL setDEFERREDAuthorized and in-theme, but 96 machines at even 20 min each is 32 hours. Cannot be sampled honestly in 300 minutes.β€”
13CMWAP Range β€” turnstile, nightglass, crossfire, ledgerloop, cacheleakβ€”freeWSTG-ATHZ-02, INPV-02, / SESS-05, BUSL-01, CONF-04DEFERREDThe single most relevant range to the objective's classes, but 5 machines needs ~2 h and would take the whole MUST block.β€”
14Pentest Range β€” IronClad, MedBridge, FinTrustβ€”freeWSTG-ATHZ-01, BUSL-01DEFERREDEach is itself a 24-hour engagement. Including one would consume the window and answer a different question.β€”
15AD / network ranges β€” CorpNet, VaultNet, MegaCorp, OperationSwitchboardβ€”freeoutside WSTG scopeDEFERREDNetwork and AD classes, not web. Authorized, but outside the objective and outside the CMWAP class set.β€”
16/hub, /tips, /reviews β€” community contentGET/POSTfreeWSTG-INPV-02, CLNT-01DEFERREDReal stored-XSS surface, but row 6 already covers the same sink class on a higher-value page.β€”
17β€œThe Burrow” β€” undocumented areaGETfreeWSTG-CONF-05DEFERREDInteresting and exactly the kind of thing that eats an afternoon. Named here so that if I test it, it is a logged decision and not drift.β€”
18/login, /signup, session handlingPOSTβ€”WSTG-ATHN-03, IDNT-04OUTPortal authentication. Excluded by /rules; not in the engagement letter. Would need separate written authorization.β€”
19/api/* portal endpoints as infrastructureβ€”β€”β€”OUTExcluded by /rules. Rows 2–4 exercise them only as a normal user would, never as scan targets.β€”
20Kubernetes, container orchestration, cloud accountsβ€”β€”WSTG-CONF-11OUTExplicitly excluded by /rules and outside the engagement letter's asset list.β€”
21Other users' accounts, sessions, vault claimsβ€”β€”WSTG-ATHZ-04OUTThird-party data. No lawful basis. Row 3 uses two accounts I own for the same question.β€”
22Checkout and payment processorPOSTβ€”WSTG-BUSL-01OUTThird-party system. Testing it would test someone else's asset.β€”
23Automated scanning / DoS against any portal endpointβ€”β€”β€”OUTExplicitly forbidden by /rules, and destructive to other learners mid-engagement.β€”

The line I will not cross. If an IN row reveals a route out of a challenge container, into orchestration, or into real user data, I stop, do not develop it further, and escalate to security@ratctf.com within the hour. Confirming reachability is the finding; proving impact would put me outside my own table.

4 Β· Deferred register (included above)

Deferred itemWSTG ID(s)Why it did not fitWhat would pull it forward
CMWAP Range (5 machines)ATHZ-02, INPV-02, SESS-05, BUSL-01~2 h; would consume the entire MUST blockIf rows 1–5 close before 12:15, take turnstile only (~25 min) as it overlaps row 1's question
Community content β€” hub, tips, reviewsINPV-02, CLNT-01Duplicate sink class to row 6, lower valueIf row 6 finds stored XSS, spend 15 min confirming the same sink here to widen impact
β€œThe Burrow”CONF-05Unknown size β€” cannot be budgeted honestlyOnly in the verify block, only if everything else is closed, capped at 15 min and logged
96 single machines + Pentest Range + AD rangesfull set32 h+ of work against a 5 h budgetNothing in this window. Recommended as a separate engagement in the report.

5 Β· Rules of engagement (0:35 – 0:40)

EnvironmentProduction β€” the only one that exists. No destructive tests, no persistence.
AccountsTwo free accounts I create (named in the report) + one premium account supplied by the client
Rate limitMax 10 concurrent requests to any challenge host, 100 ms delay. No automated tooling pointed at portal endpoints at any rate.
Will NOT doNo DoS, no destructive writes, no persistence on shared machines, no interaction with other users' accounts or vault claims, no publishing of flags
Out-of-band listenerinteractsh, stood up in the recon block; host recorded in the notes vault
EvidenceRequest, payload, response and a one-frame proof shot per finding, stored locally; nothing uploaded to third parties
EscalationBoundary crossing, real user data, or availability impact β†’ stop, notify security@ratctf.com within the hour, log it
Abort criteriaSigns of a third-party intrusion; evidence my testing degraded the platform for others; any finding I cannot explore without leaving this table
Tools declaredBurp Community, ffuf (10 threads), jwt_tool, interactsh, Obsidian β€” all free. AI assistant (free tier) for payload variants and a first report draft; 20 min budgeted inside the report block to verify everything it produces by hand.

6 Β· Thesis, risks and change log (0:40 – 0:45)

Thesis

The serious finding is in row 1. A platform that gates premium and retired content by slug almost always checks entitlement in the page that lists machines rather than in the handler that serves one. If that holds, a free account reads paid content by direct reference β€” which is the revenue question the objective asks, and it chains into row 10. I test row 1 first, at 10:45.

Assumptions and risks

Assumption or riskWhat I do if it turns out false
The supplied premium account reflects a real paid entitlementRow 10 becomes untestable as designed; note the substitution in the change log and say so in the debrief
Challenge instances are per-user, not sharedRow 3 is dropped β€” it cannot be tested without touching another user. Recorded as untested, not as clean.
Recon confirms the endpoint names in this tableRows are renamed in the change log; dispositions and budgets carry over unchanged
210 minutes of IN work is achievable at the stated rate limitRows 9 and 11 are the first to go β€” 20 min recovered, both are supporting evidence rather than the objective

Change log

Empty at submission. These three were added during the window β€” this is the section the examiner reads to check adherence.

T+What changedCostPaid for by
T+2:10Row 1 overran its 40-minute box β€” the entitlement bypass looked reachable and was worth finishing+25 minRow 9 (open redirect) dropped; recorded as untested
T+4:05Row 3 abandoned β€” could not spawn a second concurrent instance reliably, and testing it any other way needs another user's accountβˆ’25 minReturned to the SHOULD block; row 7 got the time
T+4:50Pulled turnstile forward from the deferred register per its stated trigger, capped at 25 min+25 minThe recovered row 3 time. Trigger condition was met and is quoted in the report.

Why this plan scores

Planning β€” 210 IN minutes against a 210-minute budget; the arithmetic closes. Adherence β€” every finding in the report traces to an IN row, and all three deviations are logged with what paid for them. Findings β€” impact stated in revenue and leaderboard terms, matching the objective. Time spent β€” planned versus actual is readable straight off the wall-clock table. Next iteration β€” row 3 was the wrong row to plan; it needed an assumption I could not verify before committing to it.

The XSS Rat Β· CMWAP Β· Worked example for teaching. Authorized testing only β€” RatCTF's published rules at /rules govern that platform and this plan does not override them.