ESPILON-CTF-2026-Writeups/Hardware/Phantom_JTAG
Eun0us 6a0877384d [+] Writeups v2 — sync solves, real points, scoreboard stats, cleanup
- Remove undeployed challenges: Phantom_Byte, Cr4cK_w1f1, Lain_Br34kC0r3 V1,
  Lain_VS_Knights, Lets_All_Love_UART, AETHER_NET, Last_Train_451, Web3/
- Sync 24 solve/ files from main CTF-Espilon repo
- Update all READMEs with real CTFd final scores at freeze
- Add git-header.png banner
- Rewrite README: scoreboard top 10, edition stats (1410 users, 264 boards,
  1344 solves), correct freeze date March 26 2026
2026-03-27 21:27:45 +01:00
..
solve [+] Writeups v2 — sync solves, real points, scoreboard stats, cleanup 2026-03-27 21:27:45 +01:00
README.md [+] Writeups v2 — sync solves, real points, scoreboard stats, cleanup 2026-03-27 21:27:45 +01:00

Phantom JTAG

Field Value
Category Hardware
Difficulty Medium-Hard
Points 464
Author Eun0us
CTF Espilon 2026

Description

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

nc <host> 3400

JTAG port banner showing TAP controller information

Step 2 — Reset the TAP controller

reset

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:

ir 1
dr 00000000 32

Returns 0x4BA00477 — an ARM Cortex-M style IDCODE.

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:

ir 5
dr DEAD 16

Verify:

state

Output should now show: Debug: UNLOCKED

state command showing Debug: UNLOCKED

Step 5 — Load the memory read instruction

ir 8

Step 6 — Dump flag from memory

Send address 0x1000 as the first DR, then read back the 32-bit word:

dr 1000 16
dr 00000000 32

The second dr reads the 32-bit little-endian word at address 0x1000. Repeat for addresses 0x1004, 0x1008, etc. until the flag is complete.

Convert each little-endian 32-bit word to 4 ASCII bytes and concatenate.

dr reads returning flag bytes as 32-bit little-endian words

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}