JTAG: What It Is, How It Works, and How to Use It in Hardware Pentesting

What is JTAG and how does it work? Learn about pins, JTAGulator, OpenOCD, firmware dumps, and the risks of an exposed JTAG interface in hardware pentesting.
- Posted on 2026-09-23
- Reading time: 8 min
JTAG: A Complete Guide to the Hardware Debugging Interface and Its Security Implications #
If you've never heard of JTAG before, it's the interface hidden inside almost every modern chip so developers can test and "talk" to it directly, bypassing the device's operating system. For engineers, it's used to upload firmware and find bugs. For hardware pentesters, that same port—when it's accessible and unprotected on the finished product—can become the most direct way to read a device's memory, extract firmware, and in some cases even interfere with the security controls designed to prevent this.
This guide starts from scratch: what it is, how it physically sits on a board, how to connect it, and what you can do once you're connected—with real commands, not just theory.
What is JTAG (and Why the Name Doesn't Help) #
JTAG stands for Joint Test Action Group, the committee that led to the publication of the IEEE 1149.1 standard in 1990. The standard's official name—Test Access Port and Boundary-Scan Architecture—better explains its original purpose: to verify that every single solder joint on a printed circuit board was electrically sound, without having to manually probe every single pin. This original feature is called boundary scan.
Over time, the same physical infrastructure has been repurposed to do much more: loading firmware onto a chip, pausing CPU execution for debugging, reading and writing internal registers. These are different uses, built on top of the same Test Access Port (TAP), but not all chips implement them all—and this is the most important point of this entire article: JTAG is not a single function with fixed capabilities . What you can do via JTAG on a specific device depends on how the manufacturer has configured debug access on that SoC.
The Pinout: The Signals That Make Up JTAG #
A complete JTAG interface exposes these signals:
| Pin | Direction | Function |
|---|---|---|
| TCK (Test Clock) | Entrance | Synchronize every operation on the interface |
| TMS (Test Mode Select) | Entrance | Check the status of the internal machine (TAP controller) |
| TDI (Test Data In) | Entrance | Data entering the device |
| TDO (Test Data Out) | Dismissal | Data leaving the device |
| TRST (Test Reset) | Entrance, optional | Dedicated reset of the test logic |
| GND | Common ground between adapter and target | |
| VREF / VTref | Target logic voltage reference |
The last two—GND and VREF—are often forgotten in introductory guides, but they're essential: without a common ground and a voltage reference, the adapter doesn't even know at which logic level (1.8V, 3.3V, 5V) to interpret the signals it receives. Connecting an adapter set to the wrong voltage is one of the most common—and most destructive—mistakes for beginners in hardware hacking.
JTAG Connector: What It Looks Like Physically #
There's no single standard JTAG connector—it varies greatly from manufacturer to manufacturer. The most common formats you'll find:
- Header 2×5 or 2×10 — double rows of pins on 2.54mm or 1.27mm pitch, the most common format on development boards
- 20-pin ARM JTAG — standard historically used on ARM chips
- Cortex Debug Connector — more compact version (10 pins), common on modern ARM microcontrollers, often shared with SWD (see below)
- Test pad without connector — simple copper pads on the PCB, without any soldered headers, intended for factory use only
A practical warning: don't assume a header with 10 or 20 pins is necessarily JTAG just because it "looks like it." Many headers with the same number of pins are used for other purposes (power, other buses). Always check.
How to Find JTAG Pins on a PCB #
1. Look for suspicious connectors or pad groups #
Look for unpopulated headers, closely spaced groups of 4-6 pads, or dedicated connectors near the main chip (the SoC). These are often found on the back of the board or in a secluded corner.
2. Check the screen printing #
Sometimes manufacturers leave readable labels near the pins: TCK, TMS, TDI, TDO, TRST, GND, VREF, or simply JTAG o DEBUGIf you find them, the job is almost done.
3. Consult the datasheet and documentation of the card #
Before connecting anything, check if there is a public datasheet for the SoC or a documented board revision: sometimes the JTAG pinout is already known and published online.
4. Use a multimeter as a first clue (not as proof) #
In continuity mode, some JTAG pins display a recognizable electrical pattern—for example, a pull-up to power. This is a clue to follow, not a reliable identification method by itself : the electrical characteristics vary from implementation to implementation, and relying on this alone often leads to incorrect conclusions.
5. Use the JTAGulator for automatic identification #
When pins aren't labeled, the JTAGulator (an open-source hardware device dedicated to this very purpose) automates the search. It's connected via a serial terminal:
screen /dev/ttyUSB0 115200Before any scan, the target voltage is set — a mandatory step, failing to do so can damage the device:
JTAGulator> V
Enter target I/O voltage [1.2 - 3.3, or 'S' to skip]: 3.3Then a JTAG Scan is launched (command J), which combines an IDCODE lookup and a BYPASS test in a single pass, indicating which channels to connect the target's unidentified candidate pins to:
JTAGulator> J
Enter starting channel [0]: 0
Enter ending channel [max]: 12
Number of samples [50]:
Warning: This process can be destructive to some circuits. Continue [Y/N]?: YIf a valid IDCODE is found, the JTAGulator returns the channel combination that corresponds to TCK, TMS, TDI, and TDO — the pinout is identified without having to guess by hand.
JTAG vs. SWD: They're Not the Same Thing #
On modern ARM microcontrollers (particularly Cortex-M), it is increasingly common to find SWD (Serial Wire Debug) instead of JTAG, or next to it on the same Cortex Debug connector.
| JTAG | Swd | |
|---|---|---|
| Main signals | TCK, TMS, TDI, TDO | SWCLK, SWDIO (2 lines only) |
| Origin | IEEE 1149.1 | ARM Debug Interface |
| Boundary scan | Yes | No |
| Typical use | PCB testing + debugging + programming | Debug only |
| Promotion | Large, historic | Very common on recent ARM microcontrollers |
If you're looking for a debug interface on an ARM microcontroller-based board and don't find anything resembling JTAG, check to see if there's an SWD header instead before concluding that the device has no exposed debug interface.
The Tools to Connect #
Once you've found the pins, you need an adapter that speaks JTAG and connects it to your computer:
- FTDI-based adapters (e.g. FT2232H) — cheap, well supported by OpenOCD, a good starting point
- Segger J-Link — one of the most popular adapters in the embedded industry, very broad driver support for ARM architectures
- Bus Pirate — cheap and multi-protocol (in addition to JTAG it supports SPI, I2C, UART), useful if you don't yet know exactly what you're dealing with
The physical connection diagram, in a simplified version:
ADAPTER JTAG SCHEDA TARGET
TCK ────────────────── TCK
TMS ────────────────── TMS
TDI ────────────────── TDI
TDO ────────────────── TDO
GND ────────────────── GND
VREF ────────────────── VREF (riferimento tensione)Connecting with OpenOCD #
OpenOCD (Open On-Chip Debugger) is the software that bridges the gap between the physical adapter and analysis tools like GDB. You need a configuration file that tells OpenOCD what type of adapter you're using and how to communicate with the target. A basic example for an FTDI adapter:
interface ftdi
ftdi_vid_pid 0x0403 0x6014
transport select jtag
adapter_khz 1000
telnet_port 4444
gdb_port 3333
jtag newtap mytarget tap -irlen 4 -expected-id 0x12345678
init
scan_chainIt starts with:
openocd -f mio_config.cfgA typical output, line by line:
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : JTAG tap: mytarget.tap tap/device found: 0x12345678
Info : Listening on port 3333 for gdb connectionsThe line JTAG tap: ... tap/device found This is confirmation that OpenOCD actually talked to the chip and received a valid response — if this line does not appear, the previously identified pins are likely incorrect, or debugging is disabled or protected.
At this point you connect via telnet to interact manually:
telnet localhost 4444> scan_chain
TapName Enabled IdCode Expected IrLen
------- ------- ---------- ---------- -----
mytarget.tap Y 0x12345678 0x12345678 4
> halt
target halted due to debug-request
> reg
(mostra i registri della CPU nel loro stato attuale)
> mdw 0x20000000 16
(legge 16 word di memoria a partire dall'indirizzo indicato)halt stop CPU execution, reg show the logs in their current state, mdw (memory display word) reads memory. All of these commands work only if debug access on the target allows it—on a debug-locked or authenticated chip, scan_chain it might also work (showing that a TAP exists) while halt e reg they fail.
Boundary Scan: It's Not the Same as Debugging Your CPU #
It's a common misconception that "doing JTAG" automatically means accessing the CPU. Boundary scan—the original function of JTAG—is something entirely different: it doesn't touch the processor core, but a chain of test cells connected along the chip's logic perimeter, used to verify the PCB's electrical connections.
JTAG
│
▼
TAP Controller
│
▼
Instruction Register → seleziona quale registro dati collegare
│
▼
Boundary Scan Register → celle di test sul perimetro del chip
│
▼
Pin fisici del PCBCPU debugging is a different instruction, supported by some chips and not by others, independent of boundary scan. This is why you can't generally say "you can access the CPU with JTAG": it depends on which instructions that specific TAP controller exposes.
What You Can Actually Do (Depends on the Target) #
| Capacity | Always available? |
|---|---|
| Read the chip IDCODE | Almost always, if JTAG responds |
| Boundary scan | Only if implemented by the manufacturer |
| Accessing CPU registers | Only if debug access is enabled |
| Memory Reading (SRAM/Flash) | Only if mapped and accessible from debug |
| Stop/resume CPU (halt) | Only if debugging is allowed |
| Firmware extraction | It depends on memory access |
| Secure Boot Bypass | Not automatic — depends on the architecture |
Extract the Firmware #
If memory access is available, the OpenOCD command to extract it is:
> dump_image firmware.bin 0x08000000 0x100000The address 0x08000000 This is just an example—it should always be checked against the target's specific memory map, not copied from another project. The general syntax is:
dump_image <file_output> <indirizzo_iniziale> <dimensione>Once the file is obtained, the analysis begins with standard tools:
file firmware.bin
strings firmware.bin
binwalk firmware.binbinwalk It's particularly useful because it automatically recognizes filesystems, known headers, and compressed data embedded in the dump. A targeted search for credentials or keys:
strings firmware.bin | grep -Ei 'pass|password|token|secret|key'For a more in-depth analysis of the extracted code, the reference tool is Ghidra: import the binary, indicate the CPU architecture (often deducible from the SoC datasheet), and let the automatic analysis start before manually exploring the functions.
Why “JTAG Bypasses Secure Boot” Is a Dangerous Simplification #
Secure boot verifies the firmware signature at startup. If an attacker can stop the CPU from executing via JTAG before that verification is complete, or modify memory after the check has already passed, the secure boot guarantees can effectively be circumvented—but this only happens if the chip's debug architecture allows it , not as an automatic consequence of JTAG's existence.
Manufacturers who take this risk seriously implement concrete countermeasures:
- Disable via fuse — a bit burned at the end of production, a physical and irreversible guarantee
- Authenticated debugging — for example, AMD, on its Versal SoCs, requires a cryptographically signed message (RSA or ECDSA) before re-enabling JTAG when secure boot is active; the mechanism can, however, be permanently disabled via eFUSE
Simply removing the physical connector from the final PCB, without disabling the silicon-level interface, is not enough: if the pins remain electrically active on the circuit board, anyone with time and a soldering iron can still reach them.
A Real Case: CVE-2024-7726 on Kioxia CM6/PM6/PM7 #
Accesso fisico temporaneo
│
▼
JTAG esposto (apertura nell'enclosure)
│
▼
Accesso ai 2 core CPU del SoC
│
▼
Lettura/scrittura firmware e memoria
│
▼
Esecuzione di codice arbitrario
│
▼
Bypass della verifica firma al boot| Element | Detail |
|---|---|
| Target | Kioxia CM6, PM6, PM7 (enterprise SSD) |
| CVE | CVE-2024-7726 |
| C.W.E. | CWE-306 (Missing Authentication for Critical Function) |
| Discoverer | Google Security Research |
| Login required | Physical, temporary |
| Authentication on JTAG | Absent |
On these drives, a large opening in the enclosure makes the JTAG port accessible without even removing the drive. Note that the official classification is CWE-306—missing authentication for a critical function—not generically “dangerous JTAG”: it's a specific access control that hasn't been implemented here, exactly the kind of distinction explained above.
Complete Methodology: From the Card to the Report #
- Identify the target — SoC, datasheet, board review
- Localize the interface — silkscreen, documentation, or physical pin search
- Map the pins — multimeter as a clue, JTAGulator for confirmation
- Check the voltage level before connecting anything
- Connect the adapter and start OpenOCD
- Enumerate the scan chain — confirm that a TAP is responding and with which IDCODE
- Check what's really accessible — halt, reg, memory read: do they work or is debugging blocked/authenticated?
- Extract firmware or memory, if access permits and the activity is authorized
- Analyze what you extracted — binwalk, strings, Ghidra
- Document in the report the specific cause (e.g. CWE-306, CWE-1191), not just “exposed JTAG”
From Firmware to Privilege Escalation #
Once you gain access to the firmware—which on many embedded devices is a bare-bones Linux system— Linux privilege escalation techniques become as relevant as on any other target: misconfigured SUIDs, writable cron jobs, excessive capabilities. GTFOBins is also worth checking out , as many embedded systems include BusyBox and a small but often sufficient set of exploitable escalation utilities.
JTAG itself isn't the vulnerability—it's an interface that does exactly what it was designed to do. The problem, as CWE-1191 describes , is when that interface remains accessible without proper access control until the finished product.







