write-up: Hardware/Phantom_JTAG/README.md

This commit is contained in:
Eun0us 2026-03-26 17:33:23 +00:00
parent 127a1aafc6
commit c483eefa6e

View File

@ -1,61 +1,133 @@
# Phantom JTAG — Solution
# Phantom JTAG
## Overview
| Field | Value |
|-------|-------|
| Category | Hardware |
| Difficulty | Medium-Hard |
| Points | 500 |
| Author | Eun0us |
| CTF | Espilon 2026 |
Simulated JTAG debug port with IEEE 1149.1 TAP state machine. The debug interface is locked and requires a key to unlock. Once unlocked, memory can be read to extract the flag.
---
## Steps
## Description
1. Connect:
A JTAG debug port on a WIRED-MED module is partially accessible.
The debug interface is locked, but the TAP controller still responds to state transitions.
Navigate the IEEE 1149.1 state machine, read the device IDCODE, unlock the debug interface,
and extract secrets from memory.
- JTAG Port: `tcp/<host>:3400`
Format: **ESPILON{...}**
---
## TL;DR
Interact with a simulated JTAG TAP controller. Reset the state machine, read the IDCODE via
standard IR instruction 0x1, then send the proprietary unlock instruction (IR=0x5) with key
`0xDEAD`. Once debug is unlocked, use MEM_READ (IR=0x8) to dump memory at 0x1000 and
reassemble the flag.
---
## Tools
| Tool | Purpose |
|------|---------|
| `nc` | Connect to JTAG port |
| Python 3 | Automate IR/DR sequences and decode memory |
| Knowledge of IEEE 1149.1 | Understand TAP state machine |
---
## Solution
### Step 1 — Connect
```bash
nc <host> 3400
```
2. Reset the TAP controller:
> 📸 `[screenshot: JTAG port banner showing TAP controller information]`
```
### Step 2 — Reset the TAP controller
```text
reset
```
3. Read device IDCODE:
The TAP state machine enters Test-Logic-Reset, then shifts to Run-Test/Idle.
```
### Step 3 — Read device IDCODE
Load IR instruction 0x1 (IDCODE), then shift out the 32-bit DR:
```text
ir 1
dr 00000000 32
```
Returns `0x4BA00477` (ARM Cortex-M like device).
Returns `0x4BA00477` — an ARM Cortex-M style IDCODE.
4. Unlock debug interface — load IR instruction 0x5 and send key `0xDEAD`:
> 📸 `[screenshot: IDCODE read returning 0x4BA00477]`
```
### Step 4 — Unlock the debug interface
Load the proprietary lock control instruction (IR=0x5) and send the 16-bit unlock key `0xDEAD`:
```text
ir 5
dr DEAD 16
```
Check with `state` — should show "Debug: UNLOCKED".
5. Read memory — load MEM_READ instruction (IR 0x8):
Verify:
```text
state
```
Output should now show: `Debug: UNLOCKED`
> 📸 `[screenshot: state command showing Debug: UNLOCKED]`
### Step 5 — Load the memory read instruction
```text
ir 8
```
6. Dump flag from memory at 0x1000:
### Step 6 — Dump flag from memory
```
Send address 0x1000 as the first DR, then read back the 32-bit word:
```text
dr 1000 16
dr 00000000 32
```
The first `dr` sends the address, the second reads the 32-bit word at that address. Repeat for addresses 0x1000, 0x1004, 0x1008... until the full flag is recovered.
The second `dr` reads the 32-bit little-endian word at address 0x1000.
Repeat for addresses 0x1004, 0x1008, etc. until the flag is complete.
7. Convert the 32-bit little-endian words back to ASCII to reconstruct the flag.
Convert each little-endian 32-bit word to 4 ASCII bytes and concatenate.
## Key Concepts
> 📸 `[screenshot: dr reads returning flag bytes as 32-bit little-endian words]`
- **JTAG TAP state machine**: IEEE 1149.1 defines a 16-state FSM controlled by TMS signal
- **IR/DR registers**: Instruction Register selects the operation, Data Register carries parameters/results
- **Debug port locking**: Many chips have a lock mechanism requiring a key to enable debug access
- **Memory dump via JTAG**: Once debug is unlocked, arbitrary memory reads are possible
### Key concepts
- **JTAG TAP state machine**: IEEE 1149.1 defines a 16-state FSM controlled by the TMS signal.
TDI/TDO carry shift register data; TCK clocks transitions.
- **IR/DR registers**: The Instruction Register selects the active operation; the Data Register
carries parameters and results for that operation.
- **Debug port locking**: Many chips implement a proprietary lock mechanism requiring a secret
key to enable debug memory access.
- **Memory dump via JTAG**: Once debug is unlocked, arbitrary memory reads become possible —
a common firmware extraction technique used in hardware security research.
---
## Flag
`ESPILON{jt4g_d3bug_unl0ck3d}`