write-up: Hardware/Phantom_JTAG/README.md
This commit is contained in:
parent
127a1aafc6
commit
c483eefa6e
@ -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}`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user