Blog

Extracting firmware from devices using JTAG

JTAG is a physical hardware interface that makes it possible, among other things, to extract the firmware image from electronic devices.

The firmware, a program that executes in a dedicated way and with a specific purpose in a microcontroller or microprocessor, is usually stored in a persistent memory device like a NAND/NOR flash or EEPROM.

The extraction process involves reading and copying the firmware image stored in the device’s memory to a file on your computer. This process of extracting the firmware image is also called dumping or snarfing.

But why extract the firmware from an electronic device?

Why?

Imagine an electronic device like a router, an IP camera or a hard disk.

Now imagine that you want to understand better how the device works, but you don’t have much information about it. Extracting and analyzing the firmware image can be a viable option to understand its operation.

You may want to improve or change the behavior of the device. Without access to the source code, one possibility is to extract the firmware to make the necessary changes and then update the device.

What if you forgot your credentials and lost access to the device? One possibility to regain access is to extract and change the firmware image.

If you are a security researcher, you may want to extract the firmware of the device to look for vulnerabilities in the software.

And what if the device is very old and is no longer being manufactured or sold by the vendor? You may want to clone it, and extracting the firmware image will be essential in this process.

As we can see, there are many situations that can motivate us to extract the firmware from an electronic device. Even if it’s just for fun!

Several techniques can be used to extract the firmware from an electronic device.

But before you start, make sure the firmware image is not available on the manufacturer’s website. Many device manufacturers such as routers and cameras publish updated firmware images on their websites, so that customers can download and update the device. In this case, the effort to extract the firmware is zero!

With physical access to the device, a technique for extracting the firmware is to directly read the device’s storage memory. We can identify and remove the memory chip from the board, solder it on another board and extract the firmware. It works, but can be quite painful and maybe a little risky (there is a possibility of burning the memory chip during the extraction process).

A less risky technique is to simply read the device’s storage memory through a connection to the bootloader or operating system of the device.

For example, with access to the bootloader (via a serial connection), we can try to read the device’s memory and send the data to our machine. Likewise, with access to a command line terminal in the operating system (serial, ssh, etc.) and with privileges, we can try to dump the storage memory of the device and send it to our machine.

As we can see, different techniques can be used to extract the firmware from a device, depending on the situation.

And if none of these techniques are viable, the JTAG interface may be a good option!

What is the JTAG interface?

In the past, tests on PCBs (Printed Circuit Boards) were done through a system called bed-of-nails.

In this system, the PCB was designed with several test points to be connected to a test board. And this test board performed several checks on the connections and electronic components of the board.

As the complexity of a PCB increased, it started to get difficult and complicated to design a bed-of-nails for it.

Then some debug and test interfaces integrated into the chips (processor, microcontroller, SoC, FPGA, etc.) started to appear.

Exactly for this purpose, in 1985 the JTAG (Joint Test Action Group) interface was created, a standard (IEEE 1149.1) to test printed circuit boards during manufacture.

Over time, JTAG has become one of the most popular interfaces to test electronic circuits, getting other features like debugging and burning flash devices.

Currently, this interface is available in most processors and microcontrollers of different architectures such as ARM, x86, MIPS and PowerPC.

How does the JTAG interface work?

Although there are some variations of the standard, the JTAG interface is usually implemented by the chip manufacturer via four mandatory pins (TDI, TDO, TCK, TMS) and one optional pin (TRST):

  • TDI (Test Data In): data input.
  • TDO (Test Data Out): data output.
  • TCK (Test Clock): clock whose maximum frequency depends on the chip (usually from 10MHz to 100MHz).
  • TMS (Test Mode Select): pin to control the JTAG state machine.
  • TRST (Test Reset): optional pin to reset the JTAG state machine.

The pins of the JTAG interface are internally connected to the chip through a module called TAP (Test Access Port).

The TAP interface implements the basic JTAG communication protocol, and several TAPs can be connected simultaneously in a daisy chain architecture.

The TAP interface implements a finite state machine (16 states) that allows access to a group of registers (IR, DR) to instrument the chip. The control of this state machine is done through the pins TMS and TCK. Through this state machine, it is possible to select an operation via the IR register (Instruction Register) and pass parameters or check the result via the DR register (Data Register).

The size of the IR register and the number of instructions supported is defined by the chip manufacturer. For example, a 5-bit IR register will support up to 32 instructions.

Each instruction has its own DR (Data Register), which has a variable size. Three instructions are defined by the JTAG standard and must be implemented by the manufacturer (BYPASS, EXTEST, SAMPLE/PRELOAD). Other instructions are optional, but are also usually implemented (eg, IDCODE).

  • BYPASS: instruction that selects a 1-bit register that rotates from TDI to TDO, very useful for testing the JTAG interface.
  • EXTEST: instruction that selects the BSR (Boundary Scan Register) to read and change the state of the pins.
  • SAMPLE/PRELOAD: instruction that selects the BSR register (Boundary Scan Register) to read the status of the pins.
  • IDCODE: instruction that selects the device ID register (32 bits) that contains the chip ID.

In addition to the instructions defined by the standard, the chip manufacturer can implement other instructions as needed. In this way, many manufacturers extend the JTAG interface with debugging and memory access functions (eg: MIPS EJTAG).

Information about supported JTAG instructions and the pins on a chip is usually documented in a file called BSDL (Boundary Scan Description Language), a subset of VHDL (VHSIC Hardware Description Language).

For example, here’s a short excerpt from the STM32F1 BSDL available on the ST website. As we can see in the line 29, the JTAG interface of this microcontroller supports up to 32 instructions (5 bits).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[...]

 entity STM32F1_High_density_LFBGA144 is

 -- This section identifies the default device package selected.

   generic (PHYSICAL_PIN_MAP: string:= "BGA144_PACKAGE");

-- This section declares all the ports in the design.

   port (
          BOOT0         : in    bit;
          JTDI          : in    bit;
          JTMS          : in    bit;
          JTCK          : in    bit;
          JTRST         : in    bit;
          JTDO          : out   bit;
          OSC_IN        : inout bit;
          OSC_OUT       : inout bit;
          PA0           : inout bit;
          PA1           : inout bit;
          PA2           : inout bit;
          PA3           : inout bit;

[...]

-- Specifies the number of bits in the instruction register.

   attribute INSTRUCTION_LENGTH of STM32F1_High_density_LFBGA144: entity is 5;

-- Specifies the boundary-scan instructions implemented in the design and their opcodes.

   attribute INSTRUCTION_OPCODE of STM32F1_High_density_LFBGA144: entity is
     "BYPASS  (11111)," &
     "EXTEST  (00000)," &
     "SAMPLE  (00010)," &
     "PRELOAD (00010)," &
     "IDCODE  (00001)";

Now that we know a little bit about the JTAG interface, what can we do with it?

The JTAG interface in practice

With JTAG we can control the execution of the firmware (stop the execution, inspect the memory, configure breakpoints, execute the code step-by-step, etc). We can also inspect the state of the processor and its registers, read and write to memory and access any I/O device connected to the processor.

Through a feature called Boundary Scan, the JTAG interface allows access to all the pins of the chip! In this way, we can individually read and write to each pin, and consequently manipulate the peripherals connected to the processor/microcontroller (GPIO, memory, flash, etc).

In practice, with the JTAG interface we can:

  • Identify information about the hardware (processor, memory, etc).
  • Dump RAM and gain access to sensitive data such as passwords and cryptographic keys.
  • Change the behavior of programs at run time to obtain privileged access to the system.
  • Capture sensitive data from hardware devices, such as information stored in an EEPROM.
  • Activate peripherals and change their behavior, such as setting or resetting an I/O pin.
  • And of course, dump the flash memory to extract the firmware of the device!

As we can see, the JTAG interface is perfect for inspecting the execution of the firmware, find vulnerabilities and exploit the device.

But if the JTAG interface is so insecure, why don’t many hardware manufacturers remove or disable the access to it?

Because the JTAG interface is very convenient for the development and production of the hardware! Developers use the JTAG interface to debug the firmware running on the device. Also, the JTAG interface is used as a tool for programming and testing the device in production.

However, some manufacturers may adopt countermeasures to make it difficult to use the JTAG interface in the final product, including:

  • Obfuscation (cutting tracks, removing resistors, etc).
  • Reconfiguration of the JTAG pins in software.
  • Encryption and signature validation of the firmware image.

Other manufacturers go further and completely disable the JTAG interface through some fuses (internal bits of the chip that, once programmed, can no longer be changed).

Even so, it is still possible to re-enable the JTAG interface with techniques such as a silicon die attack.

After all, security is always a matter of how much time, knowledge and resources you have, right?

Now let’s get down to business!

These are the four main steps to extract the firmware from a device using JTAG:

  1. Identify the JTAG connection pins.
  2. Test the connection with a JTAG adapter.
  3. Gather information about the memory mapping of the chip.
  4. Extract the firmware from the flash memory.

While explaining the process, I will provide a real example, extracting the firmware of the Linksys WRT54G router.

Step 1: Identify the JTAG pins

Finding the JTAG interface signals and their pinout can be quite laborious! That’s because the device manufacturer can hide, obfuscate or disable the JTAG interface.

But before you start, do some research. Maybe someone else has already identified the JTAG interface of your device and published on the Internet.

If you can’t find anything on the Internet, take the board of your device and look for a group of pins together and not populated through visual inspection. The pins of the JTAG interface may be hidden under some other component like a capacitor or a battery. Pay attention to the different standards of JTAG connectors (2×10, 2×8, 2×7, 2×5, etc).

Download the datasheet of the processor to identify the JTAG pins and test with a multimeter, oscilloscope or logic analyzer. A brute-force tool like JTAGulator can also be very useful!

Sometimes the JTAG interface is quite evident and documented on the Internet, like that of the WRT54G router:

But sometimes it’s not that obvious, like the JTAG interface of this Western Digital hard drive:

Therefore, the process of identifying the JTAG interface can take some time and will require a lot of patience!

Step 2: Test the JTAG connection

With the JTAG pins identified, we can start the communication process with the JTAG interface. For that, we basically need two components: a JTAG adapter and a JTAG communication software.

The JTAG adapter is responsible for the physical communication with the device through the JTAG interface, usually connecting to the PC via a USB interface.

The JTAG communication software is responsible for communicating with the JTAG interface through the JTAG adapter.

There are several JTAG adapters available on the market, some quite expensive for professional use and others more accessible, some of which are open hardware:

  • SEGGER J-Link
  • Keil ULINK
  • Flyswatter/Flyswatter2
  • Bus Blaster
  • Bus Pirate
  • Black Magic Probe
  • Shikra

In my tests, I am using Flyswatter from Tin Can Tools. This is my setup:

To communicate with the JTAG interface, there are several software options, many of which are proprietary. Among the open source tools, we have OpenOCD and UrJTAG.

OpenOCD (Open On-Chip Debugger) is an open source tool for communicating with JTAG interfaces. The project has been around for many years, connects easily to GDB and has a very comprehensive support of JTAG adapters and hardware devices.

UrJTAG is a newer tool, simpler but with a more friendly interface.

In my tests, I will use UrJTAG, which can be easily installed in a Debian-based distribution:

$ sudo apt install -y urjtag

$ jtag

UrJTAG 0.10 #2007
Copyright (C) 2002, 2003 ETC s.r.o.
Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors

UrJTAG is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
There is absolutely no warranty for UrJTAG.

warning: UrJTAG may damage your hardware!
Type "quit" to exit, "help" for help.

jtag>

With the JTAG adapter connected to the WRT54G, we can use UrJTAG to test communication with the JTAG interface and extract the device ID using the IDCODE instruction (this ID is a unique number assigned by JEDEC to each chip model manufactured in the world).

As we can see in the output below (line 7), the device ID of the WRT54G chip is 0x0535217F.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
jtag> cable Flyswatter
Connected to libftdi driver.

jtag> detect
IR length: 8
Chain length: 1
Device Id: 00000101001101010010000101111111 (0x0535217F)
  Manufacturer: Broadcom (0x17F)
  Part(0):      BCM5352 (0x5352)
  Stepping:     V1
  Filename:     /usr/local/share/urjtag/broadcom/bcm5352/bcm5352
ImpCode=00000000100000000000100100000100
EJTAG version:  instruction IDCODE::shift ir::shift dr::dr
00000101001101010010000101111111 (0x0535217F)

The next step is to analyze the memory address space of the chip to identify the device’s flash memory initial address and size.

Visual inspection can help to identify the flash memory chip. Searching the Internet for information about the hardware platform or products with similar hardware can also help, as well as the documentation of the chip (SoC, processor, etc).

If you have access to a command line terminal on the device, look in the bootloader or the operating system logs for any message regarding the model and address space of the flash memory.

Sometimes it is necessary to apply some trial and error method or brute force to identify the address of the device’s flash memory.

In my case, as I am using a MIPS based router, I can try the EJTAG instructions (a MIPS extension of the JTAG protocol) to identify the memory mapping of the chip. From the output below, we can see that the flash address of the device is 0x1FC00000 (line 19).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
jtag> initbus ejtag_dma
ImpCode=00000000100000000000100100000100
EJTAG version:  print
 No. Manufacturer              Part                 Stepping Instruction          Register
-------------------------------------------------------------------------------------------------------------------
   0 Broadcom                  BCM5352              V1       EJTAG_CONTROL        EJCONTROL

Active bus:
*0: EJTAG compatible bus driver via DMA (JTAG part No. 0)
        start: 0x00000000, length: 0x1E000000, data width: 32 bit, (USEG : User addresses)
        start: 0x1E000000, length: 0x02000000, data width: 16 bit, (FLASH : Addresses in flash (boot=0x1FC00000))
        start: 0x20000000, length: 0x60000000, data width: 32 bit, (USEG : User addresses)
        start: 0x80000000, length: 0x20000000, data width: 32 bit, (KSEG0: Kernel Unmapped Cached)
        start: 0xA0000000, length: 0x20000000, data width: 32 bit, (KSEG1: Kernel Unmapped Uncached)
        start: 0xC0000000, length: 0x20000000, data width: 32 bit, (SSEG : Supervisor Mapped)
        start: 0xE0000000, length: 0x20000000, data width: 32 bit, (KSEG3: Kernel Mapped)

With this address, we can use the detectflash command to collect information about flash memory. From the output below (line 19), we can see that the flash memory size is 4M:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
jtag> detectflash 0x1fc00000
Query identification string:
        Primary Algorithm Command Set and Control Interface ID Code: 0x0002 (AMD/Fujitsu Standard Command Set)
        Alternate Algorithm Command Set and Control Interface ID Code: 0x0000 (null)
Query system interface information:
        Vcc Logic Supply Minimum Write/Erase or Write voltage: 2700 mV
        Vcc Logic Supply Maximum Write/Erase or Write voltage: 3600 mV
        Vpp [Programming] Supply Minimum Write/Erase voltage: 0 mV
        Vpp [Programming] Supply Maximum Write/Erase voltage: 0 mV
        Typical timeout per single byte/word program: 16 us
        Typical timeout for maximum-size multi-byte program: 0 us
        Typical timeout per individual block erase: 1024 ms
        Typical timeout for full chip erase: 0 ms
        Maximum timeout for byte/word program: 512 us
        Maximum timeout for multi-byte program: 0 us
        Maximum timeout per individual block erase: 16384 ms
        Maximum timeout for chip erase: 0 ms
Device geometry definition:
        Device Size: 4194304 B (4096 KiB, 4 MiB)
        Flash Device Interface Code description: 0x0002 (x8/x16)
        Maximum number of bytes in multi-byte program: 1
        Number of Erase Block Regions within device: 2
        Erase Block Region Information:
                Region 0:
                        Erase Block Size: 8192 B (8 KiB)
                        Number of Erase Blocks: 8
                Region 1:
                        Erase Block Size: 65536 B (64 KiB)
                        Number of Erase Blocks: 63
Primary Vendor-Specific Extended Query:
        Major version number: 1
        Minor version number: 1
        Address Sensitive Unlock: Required
        Erase Suspend: Read/write
        Sector Protect: 4 sectors per group
        Sector Temporary Unprotect: Not supported
        Sector Protect/Unprotect Scheme: 29BDS640 mode (Software Command Locking)
        Simultaneous Operation: Not supported
        Burst Mode Type: Supported
        Page Mode Type: Not supported
        ACC (Acceleration) Supply Minimum: 11500 mV
        ACC (Acceleration) Supply Maximum: 12500 mV
        Top/Bottom Sector Flag: Bottom boot device

Now we have all we need (flash memory start address and size) to extract the firmware from the device.

To extract the firmware, we just need to use the JTAG communication software to read the memory range identified in the previous step and save the data to a file.

Depending on the size of the flash memory and the communication speed of the JTAG interface, the process can take several minutes!

With the UrJTAG tool, we can dump the flash memory’s content using the readmem command:

jtag> readmem 0x1fc00000 0x400000 flash.bin
address: 0x1FC00000
length:  0x00400000
reading:
addr: 0x20000000
Done.

After several minutes, we will have the firmware image extracted from the flash memory of the device!

$ ls -lh flash.bin
-rw-r--r-- 1 sprado sprado 4,0M fev 18 22:12 flash.bin

Now we can analyze the firmware image of the router with binwalk:

$ binwalk --signature flash.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
211412        0x339D4         Copyright string: "Copyright (C) 2000,2001,2002,2003 Broadcom Corporation."
234095        0x3926F         Copyright string: "Copyright 1995-1998 Mark Adler "
239104        0x3A600         CRC32 polynomial table, little endian
262144        0x40000         TRX firmware header, little endian, image size: 3211264 bytes, CRC32: 0xA293EEE4, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x904, rootfs offset: 0x84800
262172        0x4001C         gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
264452        0x40904         LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
804864        0xC4800         Squashfs filesystem, little endian, version 3.0, size: 2604183 bytes, 692 inodes, blocksize: 65536 bytes, created: 2011-04-04 11:37:10
3473408       0x350000        JFFS2 filesystem, little endian
3604480       0x370000        JFFS2 filesystem, little endian
4001816       0x3D1018        Zlib compressed data, compressed
4002248       0x3D11C8        JFFS2 filesystem, little endian
4004760       0x3D1B98        Zlib compressed data, compressed
4005968       0x3D2050        JFFS2 filesystem, little endian
4006772       0x3D2374        Zlib compressed data, compressed
4007356       0x3D25BC        Zlib compressed data, compressed
4008168       0x3D28E8        Zlib compressed data, compressed
4009192       0x3D2CE8        Zlib compressed data, compressed
4010552       0x3D3238        Zlib compressed data, compressed
4012236       0x3D38CC        JFFS2 filesystem, little endian
4014352       0x3D4110        Zlib compressed data, compressed
4014516       0x3D41B4        JFFS2 filesystem, little endian
4015916       0x3D472C        Zlib compressed data, compressed
4016672       0x3D4A20        JFFS2 filesystem, little endian
4038596       0x3D9FC4        JFFS2 filesystem, little endian
4062896       0x3DFEB0        Zlib compressed data, compressed
4063232       0x3E0000        JFFS2 filesystem, little endian

And extract the file system from the image!

$ binwalk --extract --quiet flash.bin

$ ls _flash.bin.extracted/squashfs-root/
bin  boot  dev  etc  jffs  lib  mnt  proc  README  rom  root  sbin  sys  tmp  usr  var  www

$ cat _flash.bin.extracted/squashfs-root/etc/passwd
root:$1$OZ1ejEbc$IgmRrZz5/bpm8FSTAbTGl1:0:0:root:/root:/bin/ash
support:$1$KhtjZGTI$BhXbTLJ4IwtdqFKbpsa2J0:100:100:support:/tmp:/bin/ash
nobody:*:65534:65534:nobody:/var:/bin/false

The JTAG interface is a fantastic tool for doing security research on electronic devices, and today several open, popular and inexpensive JTAG adapters can facilitate the process, requiring just a little knowledge and a lot of free time. Fun is guaranteed!

Author

admin