Você está na página 1de 14

Extraindo firmware com JTAG

20/02/2020 - POR SERGIO PRADO

Categorias: Engenharia Reversa Tags: jtag, Segurança


JTAG é uma interface física provida pelo hardware que possibilita, dentre outras coisas, a
extração da imagem do firmware de dispositivos eletrônicos.

O firmware, código que executa de forma dedicada e com um propósito específico em um


microcontrolador ou microprocessador, fica normalmente gravado em um dispositivo de
armazenamento persistente como uma memória flash ou EEPROM.

O processo de extração envolve ler e copiar a imagem do firmware gravado na memória


do dispositivo para um arquivo na sua máquina. Este processo de extração de firmware
também é chamado de dumping ou snarfing.
Mas porque extrair o firmware de um dispositivo eletrônico?

Motivações
Imagine um dispositivo eletrônico qualquer como um roteador, uma câmera IP ou uma
máquina fotográfica.

Agora imagine que você queira entender melhor como o dispositivo funciona, mas não tem
muita informação sobre ele. Extrair e analisar a imagem do firmware pode ser uma opção
viável para entender seu funcionamento.

Talvez você queira melhorar ou alterar o comportamento do dispositivo. Sem acesso ao


código-fonte, uma possibilidade é extrair o firmware para realizar as alterações
necessárias e depois atualizar a imagem no dispositivo.

E se você perdeu as credenciais de acesso ao dispositivo? Uma possibilidade para


recuperar o acesso é extrair e alterar a imagem do firmware.

Caso você seja um pesquisador de segurança, talvez queira extrair o firmware do


dispositivo para procurar por vulnerabilidades no software.

E se o dispositivo for bem antigo e não estiver sendo mais fabricado ou vendido pelo
fabricante? Você pode querer fazer um clone dele, e a extração da imagem do firmware
será essencial neste processo.

Perceba então que são muitas as situações que podem te motivar a extrair o firmware de
um dispositivo eletrônico. Nem que seja apenas por diversão! :-)
Técnicas para extração do firmware
Diversas técnicas podem ser utilizadas para extrair o firmware de um dispositivo eletrônico.

Mas antes de começar, verifique se a imagem do firmware não está disponível no site do
fabricante. Muitos fabricantes de dispositivos como roteadores e câmeras disponibilizam
imagens atualizadas do firmware na Internet para que seus clientes possam baixar e
atualizar o dispositivo. Neste caso, o esforço para extração do firmware é zero!

Com acesso físico ao dispositivo, uma técnica para extrair o firmware é lendo diretamente
a memória de armazenamento do dispositivo. Podemos identificar e remover o chip de
memória (flash) da placa de circuito impresso, soldá-lo em uma outra placa e extrair o
firmware. Funciona, mas pode ser bastante trabalhoso e também um pouco arriscado
(existe a possibilidade de queimar o chip de memória durante o processo de extração).

Uma técnica menos arriscada é simplesmente ler a memória de armazenamento do


dispositivo através de uma conexão com o bootloader ou sistema operacional.

Por exemplo, com acesso ao bootloader (via uma conexão serial), podemos tentar ler a
memória do dispositivo e enviar os dados para a nossa máquina. Da mesma forma, com
acesso a um terminal de comandos no sistema operacional (serial, ssh, etc) e com
privilégios de execução, podemos tentar fazer um dump da memória de armazenamento
do dispositivo e enviar para a nossa máquina.

Perceba que diferentes técnicas podem ser utilizadas para extrair o firmware de um
dispositivo, dependendo dos recursos disponíveis.

E se nenhuma destas técnicas for viável, a interface JTAG pode ser uma boa opção!

O que é a interface JTAG?


Antigamente, testes em placas de circuito impresso eram feitos através de um sistema
chamado de cama-de-pregos (bed-of-nails).
Nesse sistema, a placa de circuito impresso era projetada com diversos pontos de teste
que se conectavam a uma placa de testes. E esta placa de testes executava rotinas de
verificação de funcionamento dos circuitos integrados, das conexões e dos componentes
eletrônicos da placa.
Conforme a complexidade das placas de circuito eletrônico aumentava, ficava cada vez
mais difícil e complicado projetar uma cama-de-pregos para ela.

Então começaram a surgir algumas interfaces de teste e debug providas pelos próprios
componentes de hardware (processador, microcontrolador, SoC, FPGA, etc).

Exatamente com este propósito, em 1985 foi criada a interface JTAG (Joint Test Action
Group), um padrão (IEEE 1149.1) para testar placas de circuito impresso depois de sua
fabricação.
Com o tempo, JTAG se tornou uma das mais populares interfaces de teste de circuitos
eletrônicos, ganhando outras funcionalidades como debugging e gravação de firmware na
memória flash.

Atualmente, esta interface é utilizada e está disponível na maioria dos processadores e


microcontroladores de diversas arquiteturas como ARM, x86, MIPS e PPC.

Como a interface JTAG funciona?


Apesar de haver algumas variações do padrão, a interface JTAG é implementada
normalmente pelo fabricante do chip através de 4 pinos obrigatórios
(TDI, TDO, TCK, TMS) e 1 pino opcional (TRST):
 TDI (Test Data In): entrada de dados.
 TDO (Test Data Out): saída de dados.
 TCK (Test Clock): clock cuja frequência máxima depende do chip (normalmente de
10MHz a 100MHz).
 TMS (Test Mode Select): pino de controle da máquina de estados.
 TRST (Test Reset): é um pino opcional para resetar a máquina de estados da
controladora JTAG.
Os pinos da interface JTAG se conectam internamente ao chip através de um módulo
chamado TAP (Test Access Port).

O TAP implementa o protocolo básico de comunicação com o chip via JTAG, e diversos
TAPs podem ser conectados simultâneamente em uma arquitetura de anel (daisy chain).

O TAP implementa uma máquina de estados finita (16 estados) que permite acessar um
grupo de registradores (IR, DR) para instrumentar o chip. O controle desta máquina de
estados é feita através dos pinos TMS E TCK. Através desta máquina de estados, é
possível selecionar uma operação através do registrador IR (Instruction Register) e
parametrizar a operação ou verificar o resultado no registrador DR (Data register).
O tamanho do registrador IR e a quantidade de instruções suportadas é definida pelo
fabricante do chip. Por exemplo, um registrador IR de 5 bits irá suportar até 32 instruções.
Cada instrução tem o seu registrador de dados (DR), que possui tamanho variável. Três
instruções são definidas pelo padrão JTAG (IEEE 1149.1) e devem ser obrigatoriamente
implementadas pelo fabricante (BYPASS, EXTEST, SAMPLE/PRELOAD). Outras
instruções são opcionais, mas também são normalmente implementadas (ex: IDCODE).
 BYPASS: instrução que seleciona um registrador de 1 bit que faz um
rotacionamento do TDI para o TDO, bastante útil para testar a interface JTAG.
 EXTEST: instrução que seleciona o registrador BSR (Boundary Scan Register)
para ler e alterar o estado dos pinos do chip.
 SAMPLE/PRELOAD: instrução que seleciona o registrador BSR (Boundary Scan
Register) para ler o estado dos pinos do chip.
 IDCODE: instrução que seleciona o registrador device ID (32 bits) que contém o ID
do chip.
Além das instruções definidas pelo padrão, o fabricante do chip pode implementar outras
instruções conforme a necessidade. Desta forma, muitos fabricantes estendem a interface
JTAG com funções de debugging e gravação de firmware em flash (ex: MIPS EJTAG).
Informações sobre as instruções JTAG suportadas e os pinos de um chip são
normalmente documentadas em um arquivo chamado BSDL (Boundary Scan Description
Language), um subset da VHDL (VHSIC Hardware Description Language).
Por exemplo, segue um pequeno trecho do BSDL do STM32F1 disponibilizado pela ST.
Podemos perceber, por exemplo, que a interface JTAG deste microcontrolador suporta até
32 instruções (5 bits).
[...]

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)";

Agora que conhecemos um pouco sobre a interface JTAG, o que podemos fazer com ela
na prática?

A interface JTAG na prática


Com JTAG podemos controlar a execução do firmware (parar a execução, inspecionar a
memória, colocar breakpoints, executar passo-a-passo, etc). Desta forma, podemos
inspecionar o estado do processador e de seus registradores, ler/escrever na memória e
acionar dispositivos de I/O.

Através de um recurso chamado Boundary Scan, a interface JTAG permite o acesso a


todos os pinos do chip! Desta forma, podemos ler e escrever individualmente em cada
pino, e consequentemente manipular os periféricos conectados ao
processador/microcontrolador (GPIO, memória, flash, etc).
Na prática, com a interface JTAG podemos:

 Identificar informações sobre o hardware (processador, memória, etc).


 Fazer um dump da memória RAM e obter acesso a dados sensíveis como senhas
e chaves criptográficas.
 Alterar o comportamento de programas em tempo de execução para obter acesso
privilegiado ao sistema.
 Capturar dados sensíveis de dispositivos de hardware, como informações
armazenadas em uma EEPROM.
 Acionar periféricos e mudar seu comportamento, como ligar ou desligar um pino de
I/O.
 Fazer um dump da memória flash para extrair o firmware do dispositivo!
Perceba que a interface JTAG é perfeita para inspecionar a execução do firmware e
explorar vulnerabilidades em dispositivos eletrônicos.

Mas se a interface JTAG é tão insegura, porque muitos fabricantes de hardware não
removem ou desabilitam o acesso a esta interface?

Porque a interface JTAG é bastante conveniente para o desenvolvimento e a produção do


hardware! Os desenvolvedores utilizam a interface JTAG para depurar o firmware em
execução no dispositivo. Além disso, a interface JTAG é utilizada como ferramenta de
programação e testes do dispositivo em produção.

Porém, alguns fabricantes podem utilizar algumas contra-medidas ao uso de JTAG no


produto final, incluindo:

 Obfuscação (cortar trilhas, remover resistores, etc).


 Reconfiguração dos pinos em software.
 Criptografia/assinatura do firmware.
Outros fabricantes vão além e desabilitam completamente a interface JTAG através de
alguns fuses (bits internos do chip que, uma vez programados, não podem mais ser
alterados).

Mesmo assim, ainda é possível reabilitar a interface JTAG com técnicas como silicon die
attack, capazes de alterar a configuração dos fuses. Afinal, segurança é sempre uma
questão de quanto tempo, conhecimento e recursos você tem, certo?
Mas vamos ao que interessa!

Extraindo firmware com JTAG


Estas são as quatro principais etapas para extrair o firmware de um dispositivo com JTAG:

1. Identificar os pinos de conexão JTAG.


2. Testar a conexão com um adaptador JTAG.
3. Levantar informações sobre o mapeamento de memória do chip.
4. Extrair o firmware da memória flash.
Enquanto explico o processo, irei exemplificar na prática através da extração do firmware
do roteador Linksys WRT54G.
Passo 1: Identificar os pinos JTAG
Encontrar os sinais da interface JTAG e identificar sua pinagem pode ser bastante
trabalhoso! Isso porque o fabricante do dispositivo pode esconder, obfuscar ou desabilitar
a interface JTAG.

Antes de começar, faça buscas na Internet para verificar se o trabalho de identificação da


interface JTAG já não foi feito e publicado por alguém.

Caso não encontre nada na Internet, procure na placa por um grupo de pinos juntos e não
populados através de inspeção visual. Os pinos da interface JTAG podem estar
escondidos debaixo de algum outro componente (capacitor, bateria, etc). Atente-se
também aos diversos padrões diferentes de conectores JTAG (2×10, 2×8, 2×7, 2×5, etc).

Baixe o datasheet do chip para identificar os pinos JTAG e faça testes com um multímetro,
osciloscópio ou analisador lógico. Uma ferramenta de força-bruta como
o JTAGulator também pode ajudar bastante!

Às vezes a interface JTAG está bastante evidente e documentada na Internet, como a do


roteador WRT54G:
Às vezes não está tão evidente assim, com os pinos da interface JTAG deste disco rígido
da Western Digital:

Portanto, o processo de identificação da interface JTAG pode ser bastante trabalhoso e vai
exigir muita paciência!

Passo 2: Testar a conexão JTAG


Com os pinos identificados, podemos iniciar o processo de comunicação com a interface
JTAG. Para isso, precisamos basicamente de dois componentes: um adaptador JTAG e
um software de comunicação JTAG.

O adaptador JTAG é responsável pela comunicação física com o dispositivo através da


interface JTAG, normalmente se conectando ao PC através de uma interface USB. E o
software de comunicação JTAG é responsável por se comunicar com a interface JTAG
através do adaptador JTAG.

Existem diversos adaptadores JTAG disponíveis no mercado, alguns bastante caros com
foco no uso profissional e outros mais acessíveis, sendo alguns de hardware aberto:

 SEGGER J-Link
 Keil ULINK
 Flyswatter/Flyswatter2
 Bus Blaster
 Bus Pirate
 Black Magic Probe
 Shikra
Nos meus testes irei utilizar o Flyswatter da Tin Can Tools.
Para se comunicar com a interface JTAG, existem diversas opções de software, muitas
delas proprietárias. Dentre as opções de código-aberto, temos o OpenOCD e o UrJTAG.

O OpenOCD (Open On-Chip Debugging) é uma ferramenta de código-aberto para


comunicação via JTAG. O projeto tem muitos anos de existência, se conecta facilmente ao
GDB e possui um suporte bastante abrangente de controladores JTAG e dispositivos de
hardware.
O UrJTAG é um projeto mais novo, moderno e com uma interface mais amigável, porém
com suporte a hardware mais limitado.
Nos meus testes, irei utilizar o UrJTAG, que pode ser instalado em uma distribuição
baseada no Debian conforme abaixo:

$ 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>

Com o adaptador JTAG conectado ao WRT54G, podemos utilizar o UrJTAG para testar a
comunicação com a interface JTAG e extrair o ID do dispositivo através da instrução
IDCODE (este ID é um número único atribuído pela JEDEC a cada modelo de chip
fabricado no mundo).
Como podemos ver nos comandos abaixo, a comunicação com a interface JTAG está
funcionando e o device ID do chip do WRT54G é 0x0535217F.

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: <= 2.0
EJTAG Implementation flags: R4k DMA MIPS32
Clear memory protection bit in DCR
Clear Watchdog
Potential flash base address: [0x0], [0x0]
Processor successfully switched in debug mode.

jtag> instruction IDCODE::shift ir::shift dr::dr


00000101001101010010000101111111 (0x0535217F)

Passo 3: Identificar informações sobre a memória


O próximo passo é analisar o modelo e o endereçamento de memória do chip para
identificar o endereço inicial e o tamanho da memória flash do dispositivo.

Uma inspeção visual pode ajudar a identificar o chip da flash. Buscas na Internet por
informações sobre a plataforma de hardware ou produtos com hardware similar também
podem ajudar, assim como a documentação do chip (SoC, processador, etc).

Caso tenha acesso a um terminal de comandos no dispositivo, procure no bootloader ou


nos logs do sistema operacional alguma mensagem referente ao modelo e endereçamento
da memória flash.
Às vezes, é necessário utilizar algum método de tentativa e erro ou força bruta para
identificar o endereçamento da memória flash do dispositivo.

No meu caso, como estou utilizando um roteador de arquitetura MIPS, posso utilizar
as instruções EJTAG (uma extensão da interface JTAG), para identificar o mapeamento de
memória do chip.
Pelos comandos abaixo, podemos identificar a flash no endereço 0x1FC00000 (linha 19).

1jtag> initbus ejtag_dma


2ImpCode=00000000100000000000100100000100
3EJTAG version: <= 2.0
4EJTAG Implementation flags: R4k DMA MIPS32
5Clear memory protection bit in DCR
6Clear Watchdog
7Potential flash base address: [0x0], [0x0]
8Processor successfully switched in debug mode.
9Initialized bus 1, active bus 0
10
11jtag> print
12 No. Manufacturer Part Stepping Instruction
13Register
14-------------------------------------------------------------------------------
15------------------------------------
16 0 Broadcom BCM5352 V1 EJTAG_CONTROL
17EJCONTROL
18
19Active bus:
20*0: EJTAG compatible bus driver via DMA (JTAG part No. 0)
21 start: 0x00000000, length: 0x1E000000, data width: 32 bit, (USEG : User
22addresses)
23 start: 0x1E000000, length: 0x02000000, data width: 16 bit, (FLASH :
24Addresses 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)

Podemos confirmar o endereço com o comando detectflash:


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

Passo 4: Extraindo o firmware


Para extrair o firmware, basta utilizar o software de comunicação JTAG para ler o intervalo
de memória identificado no passo anterior e salvar em um arquivo.

Dependendo do tamanho da flash e da velocidade de comunicação com a interface JTAG,


o processo pode levar vários minutos!

Com a ferramenta UrJTAG, o firmware do WRT54G pode ser extraído com o


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

Depois de vários minutos, a imagem extraída da memória flash estará disponível para
análise:
$ ls -lh flash.bin
-rw-r--r-- 1 sprado sprado 4,0M fev 18 22:12 flash.bin

$ binwalk --signature flash.bin

DECIMAL HEXADECIMAL DESCRIPTION


--------------------------------------------------------------------------------
211412 0x339D4 Copyright string: "Copyright (C) 2000,2001,2002,200
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: 321
1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x904, rootfs
262172 0x4001C gzip compressed data, maximum compression, from Uni
264452 0x40904 LZMA compressed data, properties: 0x6D, dictionary
804864 0xC4800 Squashfs filesystem, little endian, version 3.0, si
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

Agora podemos analisar a imagem do firmware com a ferramenta binwalk:


E extrair o sistema de arquivos da imagem!

$ 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

A interface JTAG é uma ferramenta fantástica para fazer pesquisas de segurança em


dispositivos eletrônicos. E hoje existem diversos adaptadores JTAG abertos, populares e
baratos que podem facilitar o processo, exigindo apenas um pouco de conhecimento e
tempo livre. Diversão garantida!

Um abraço,

Sergio Prado

Você também pode gostar