Files
Embedded-Hacking/0x0001b_ctf/CTF-R.md
T

217 lines
11 KiB
Markdown

# CTF Challenge: Operation Black Start
## Project Requirements & Grading Criteria
```
+----------------------------------------------------------------------------------------+
| |
| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ |
| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ |
| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ |
| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ |
| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ |
| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ |
| |
| |
| O P E R A T I O N B L A C K S T A R T |
| |
| REQUIREMENTS & GRADING CRITERIA |
| |
+----------------------------------------------------------------------------------------+
```
---
## Project Overview
Students are the reverse-engineering reserve team called in after WorldGrid
Compact's emergency firmware build shipped a miscompiled safety threshold and
a false status string to its GRID-7 relay fleet. Students reverse engineer
the supplied RP2350 image with Ghidra, locate two real defects, patch them
directly in the binary, export a corrected image, flash it to real hardware,
and verify the corrected behavior on a physical Pico 2 — the same workflow
used in the FINAL projects.
Students must use only Weeks 1-3 concepts: ARM registers and stack behavior,
UART output, GDB, Ghidra static analysis and binary patching, vector tables,
reset startup, XIP, and Thumb addressing. No LED, relay, sensor, display, or
later-week peripheral-control task is part of this CTF.
The challenge is separate from all FINAL projects and contains no FINAL-project
answer, constant, address, bug, or patch.
---
## Learning Objectives
Students will demonstrate the ability to:
1. Capture a clean UART baseline before modifying the binary.
2. Decode an RP2350 vector table and initial stack pointer.
3. Explain the Thumb bit in a reset-handler pointer.
4. Trace a flash string into the UART output call and argument register.
5. Locate a miscompiled immediate value used in **multiple** locations and
understand why every occurrence must be patched.
6. Correctly compute a patched immediate value even when the compiler has
transformed the original comparison (e.g., `<` optimized to `<=`).
7. Patch a string literal in flash without corrupting adjacent data.
8. Export a patched binary, convert it to UF2, and verify the fix on real
hardware.
9. Recover a quarantined data frame from flash as static evidence.
---
## Deliverables Checklist
| # | Deliverable | Format | Task |
|---|-------------|--------|------|
| 1 | Ghidra project screenshot (project name, processor, base address) | PNG/JPG | Task 1 |
| 2 | `main()`, status-loop, and vector-table address table | Inside `CTF-01-Answers.md` | Task 1 |
| 3 | Bug #1 analysis: both addresses, original/patched bytes, immediate-value reasoning | Inside `CTF-01-Answers.md` | Task 2 |
| 4 | Bug #2 analysis: string address, original/patched bytes, character-by-character mapping | Inside `CTF-01-Answers.md` | Task 3 |
| 5 | Recovered dispatch frame and its address | Inside `CTF-01-Answers.md` | Task 4 |
| 6 | `CTF-01_fixed.bin` — exported patched binary | BIN file | Task 5 |
| 7 | `CTF-01_fixed.uf2` — UF2-converted binary | UF2 file | Task 5 |
| 8 | Verification transcript: corrected UART output on real hardware | Inside `CTF-01-Answers.md` | Task 5 |
| 9 | Summary table of all patches (address, original bytes, patched bytes) | Inside `CTF-01-Answers.md` | Task 5 |
| 10 | Written reflection (two short answers) | Inside `CTF-01-Answers.md` | Task 6 |
---
## Required Tools and Equipment
| Tool | Purpose | Required For |
|------|---------|-------------|
| Raspberry Pi Pico 2 | Isolated target | All tasks |
| 3.3 V USB-UART adapter | UART capture | Tasks 1, 5 |
| Serial monitor | Observe output | Tasks 1, 5 |
| Ghidra | Static analysis and binary patching | Tasks 1-4 |
| Python (`uf2conv.py`) | UF2 conversion | Task 5 |
| `CTF-01.bin` and `CTF-01.uf2` | Supplied artifacts | All tasks |
UART settings: **115200 baud, 8 data bits, no parity, 1 stop bit**.
The instructor-issued artifact hashes are:
```text
CTF-01.bin 6FD296F7A85F243FB26BF6BFFCBEAB26815FD8915101A81F72069063A5635E5A
CTF-01.uf2 980F04369C23AD32A063DFE18DE5AF08DF3830138FC7E7898B1F011B4F5E1D9D
```
---
## Task 1: Setup and Initial Analysis — 15 points
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| Ghidra project setup | 3 | Screenshot shows correct project name, ARM Cortex 32-bit little endian, base `0x10000000` | One item off | Not set up |
| `main()` and status-loop addresses | 4 | Both addresses correctly documented | One correct | Neither found |
| Vector table | 4 | Correct base, initial SP, reset pointer | One missing | Not found |
| Thumb addressing | 4 | Correctly clears bit 0 to identify the real instruction address | General explanation | Incorrect |
---
## Task 2: Find and Patch Bug #1 — Miscalibrated Safety Threshold — 30 points
**What to find:** the frozen reading is compared against a miscompiled
safety constant at **two separate addresses** — once for the operator-facing
status and once for the automated dispatch decision.
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| Found location A | 5 | Correct address and original instruction/bytes documented | Address off | Not found |
| Found location B | 5 | Correct address and original instruction/bytes documented | Address off | Not found |
| Correct immediate-value reasoning | 8 | Explains the `<` vs `<=` compiler transform and derives the correct patched immediate | Correct value, no reasoning | Wrong value |
| Patched location A | 4 | Grader verifies the byte change | Wrong byte | Not patched |
| Patched location B | 4 | Grader verifies the byte change | Wrong byte | Not patched |
| Explained why both must be patched | 4 | Clear explanation of duplicated/independent comparisons | Vague | Missing |
---
## Task 3: Find and Patch Bug #2 — The False Signal Banner — 20 points
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| Found the string | 5 | Correct address, found via Ghidra Defined Strings or hex inspection | Approximate | Not found |
| Patched correctly | 8 | All required bytes changed, string length preserved, grader verifies boot output | Correct text but wrong bytes documented | Wrong length or corrupted data |
| Character-by-character documentation | 4 | Original vs. patched bytes for every changed character | Partial | Missing |
| Explained the danger of a hardcoded status word | 3 | Clear, specific reasoning | Generic | Missing |
---
## Task 4: Recover the Quarantined Dispatch Frame — 10 points
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| Found the hidden frame | 6 | Correct address and full recovered text | Partial text | Not found |
| Explained why it is not transmitted | 4 | Clear static-analysis explanation | Vague | Missing |
Students must **not** patch this value; it is evidence only.
---
## Task 5: Export and Verify — 20 points
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| Exported patched binary | 4 | Valid `CTF-01_fixed.bin` submitted | Corrupted | Not submitted |
| Converted to UF2 correctly | 4 | Valid `CTF-01_fixed.uf2`, correct base/family flags | Wrong flags | Not submitted |
| Hardware verification | 8 | Grader confirms corrected UART output: `GRID STATUS: CRITICAL`, `DISPATCH PATH: HELD`, corrected signal word | Only some lines corrected | No verification |
| Summary table of all patches | 4 | Complete table with addresses and before/after bytes | Missing entries | No table |
---
## Task 6: Written Reflection — 5 points
| Criterion | Points | Full Credit | Partial Credit | No Credit |
|-----------|--------|-------------|----------------|-----------|
| "Rushed build" is not an excuse | 2 | Specific, grounded reasoning | Generic | Missing |
| Engineering practice per bug | 3 | Names one concrete, relevant practice for **each** bug | Names one for only one bug | Missing |
---
## Recommended Answer File Structure
```text
# Operation Black Start - Incident Report
## 1. Scope and Artifact Integrity
## 2. Ghidra Setup and Boot/Vector Table
## 3. Bug #1 - Miscalibrated Safety Threshold
## 4. Bug #2 - False Signal Banner
## 5. Recovered Dispatch Frame
## 6. Export and Hardware Verification
## 7. Patch Summary Table
## 8. Written Reflection
```
---
## ⚠ Common Pitfalls
| Pitfall | Consequence | Avoidance |
|---------|-------------|-----------|
| Patching only one of the two threshold locations | Half the fleet's telemetry still lies | Search for **every** occurrence of the wrong immediate |
| Assuming the threshold immediate equals the safety limit directly | Off-by-one patch, wrong behavior | Check whether the compiler used `<` or `<=` semantics |
| Replacing a string with a different length | Corrupts adjacent flash data | Count bytes before patching |
| Treating an odd vector address as invalid | Thumb analysis fails | Explain bit 0 |
| Skipping hardware verification | Patch is unproven | Flash and capture real UART output |
| Modifying the quarantined dispatch frame | Destroys required evidence | Recover it, do not patch it |
---
## Reference Memory Map
| Region | Address | Purpose |
|--------|---------|---------|
| Bootrom | `0x00000000` | Immutable boot code |
| Flash/XIP | `0x10000000` | Vector table, code, constant strings |
| SRAM | `0x20000000` | Stack and writable state |
---
## Safety and Academic Integrity
Use only the supplied Pico 2 and firmware. Do not connect the exercise to an
operational grid, water plant, public network, military system, or third-party
device. This is a controlled, isolated educational exercise.