Escolar Documentos
Profissional Documentos
Cultura Documentos
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.
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).
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!
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.
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
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;
[...]
Agora que conhecemos um pouco sobre a interface JTAG, o que podemos fazer com ela
na prática?
Mas se a interface JTAG é tão insegura, porque muitos fabricantes de hardware não
removem ou desabilitam o acesso a esta interface?
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!
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!
Portanto, o processo de identificação da interface JTAG pode ser bastante trabalhoso e vai
exigir muita paciência!
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.
$ jtag
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> 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.
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).
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).
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
Um abraço,
Sergio Prado