
Há alguns dias, decidi realizar a engenharia reversa do firmware do meu roteador utilizando o binwalk.
Eu comprei para mim mesmo . Não é o melhor roteador, mas atende bem às minhas necessidades.
Sempre que compro um novo roteador, instalo . Por quê? Geralmente, os fabricantes não se preocupam muito em dar suporte aos seus roteadores e, com o tempo, o software se torna obsoleto, surgem vulnerabilidades e, enfim, vocês entenderam. Por isso, prefiro um firmware open-source, bem mantido pela comunidade, como o OpenWRT.
Após baixar o OpenWRT, eu também para o meu novo Archer C7 do site oficial e decidi analisá-la. Apenas por diversão e para falar sobre o binwalk.
O que é o binwalk?
é uma ferramenta de código aberto para análise, engenharia reversa e extração de imagens de firmware.
Criado em 2010 por Craig Heffner, o binwalk pode escanear imagens de firmware e encontrar arquivos, identificar e extrair imagens de sistemas de arquivos, código executável, arquivos comprimidos, carregadores e núcleos, formatos de arquivo como JPEG e PDF, e muito mais.
Você pode usar o binwalk para realizar engenharia reversa de um firmware para entender como ele funciona. Buscar vulnerabilidades em arquivos binários, extrair arquivos e procurar backdoors ou certificados digitais. Também é possível encontrar opcodes para uma variedade de CPUs.
Você pode descompactar imagens de sistemas de arquivos para buscar arquivos de senhas específicos (passwd, shadow etc.) e tentar quebrar hashes de senhas. Você pode realizar uma análise binária entre dois ou mais arquivos. Você pode realizar uma análise de entropia de dados para buscar dados comprimidos ou chaves de criptografia codificadas. Tudo isso sem a necessidade de acesso ao código-fonte.
No geral, tudo que você precisa está aqui 🙂
Como funciona o binwalk?
A principal característica do binwalk é a sua varredura de assinatura. O binwalk pode escanear uma imagem de firmware em busca de vários tipos de arquivos e sistemas de arquivos incorporados.
Você conhece a ferramenta de linha de comando arquivo?
file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, strippedTime arquivoOlha para o cabeçalho do arquivo e procura a assinatura (número mágico) para determinar o tipo de arquivo. Por exemplo, se o arquivo começa com a sequência de bytes 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, ela sabe que é um arquivo PNG. Na há uma lista de assinaturas de arquivo comuns.
O Binwalk funciona da mesma forma. Mas em vez de procurar assinaturas apenas no início do arquivo, o binwalk fará a varredura de todo o arquivo. Além disso, o binwalk pode extrair arquivos encontrados na imagem.
Ferramentas arquivo e binwalk usa a biblioteca libmagic para identificar assinaturas de arquivos. Mas binwalk também suporta uma lista de assinaturas mágicas personalizadas para a busca de arquivos compactados / arquivados, cabeçalhos de firmwares, núcleos Linux, bootloaders, sistemas de arquivos e muito mais.
Vamos nos divertir?
Instalação do binwalk
O Binwalk é suportado em várias plataformas, incluindo Linux, OSX, FreeBSD e Windows.
Para instalar a versão mais recente do binwalk, você pode e seguir as ou , disponível no site do projeto.
O Binwalk tem muitas opções diferentes:
$ binwalk
Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Uso: binwalk [OPÇÕES] [ARQUIVO1] [ARQUIVO2] [ARQUIVO3] ...
Opções de Varredura de Assinatura:
-B, --assinatura Escanear arquivo(s) alvo(s) em busca de assinaturas de arquivo comuns
-R, --raw= Escanear arquivo(s) alvo(s) pela sequência de bytes especificada
-A, --opcodes Escanear arquivo(s) alvo(s) em busca de assinaturas de opcode executáveis comuns
-m, --magic= Especificar um arquivo mágico personalizado para usar
-b, --dumb Desativar palavras-chave de assinatura inteligentes
-I, --invalid Mostrar resultados marcados como inválidos
-x, --exclude= Excluir resultados que correspondem a
-y, --include= Mostrar apenas resultados que correspondem a
Opções de Extração:
-e, --extract Extrair automaticamente tipos de arquivo conhecidos
-D, --dd= Extrair assinaturas , dar aos arquivos uma extensão de e executar
-M, --matryoshka Escanear recursivamente arquivos extraídos
-d, --depth= Limitar a profundidade da recursão matryoshka (padrão: 8 níveis profundos)
-C, --directory= Extrair arquivos/pastas para um diretório personalizado (padrão: diretório de trabalho atual)
-j, --size= Limitar o tamanho de cada arquivo extraído
-n, --count= Limitar o número de arquivos extraídos
-r, --rm Excluir arquivos cortados após a extração
-z, --carve Extrair dados de arquivos, mas não executar utilitários de extração
-V, --subdirs Extrair em subdiretórios nomeados pelo deslocamento
Opções de Entropia:
-E, --entropy Calcular a entropia do arquivo
-F, --fast Usar análise de entropia mais rápida, mas menos detalhada
-J, --save Salvar gráfico como PNG
-Q, --nlegend Omitir a legenda do gráfico da entropia
-N, --nplot Não gerar um gráfico de entropia
-H, --high= Definir o limiar de acionamento da entropia de borda ascendente (padrão: 0.95)
-L, --low= Definir o limiar de acionamento da entropia de borda descendente (padrão: 0.85)
Opções de Diferença Binária:
-W, --hexdump Realizar um hexdump / diferença de um arquivo ou arquivos
-G, --green Mostrar apenas linhas contendo bytes que são os mesmos entre todos os arquivos
-i, --red Mostrar apenas linhas contendo bytes que são diferentes entre todos os arquivos
-U, --blue Mostrar apenas linhas contendo bytes que são diferentes entre alguns arquivos
-u, --similar Exibir apenas linhas que são iguais entre todos os arquivos
-w, --terse Diferença entre todos os arquivos, mas exibir apenas um hexdump do primeiro arquivo
Opções de Compressão Bruta:
-X, --deflate Escanear em busca de fluxos de compressão deflate brutos
-Z, --lzma Escanear em busca de fluxos de compressão LZMA brutos
-P, --partial Realizar uma varredura superficial, mas mais rápida
-S, --stop Parar após o primeiro resultado
Opções Gerais:
-l, --length= Número de bytes a escanear
-o, --offset= Iniciar escaneamento a partir deste deslocamento de arquivo
-O, --base= Adicionar um endereço base a todos os deslocamentos impressos
-K, --block= Definir o tamanho do bloco do arquivo
-g, --swap= Reverter a cada n bytes antes de escanear
-f, --log= Registrar resultados em um arquivo
-c, --csv Registrar resultados em um arquivo no formato CSV
-t, --term Formatar saída para caber na janela do terminal
-q, --quiet Suprimir saída no stdout
-v, --verbose Habilitar saída detalhada
-h, --help Mostrar saída de ajuda
-a, --finclude= Escanear apenas arquivos cujos nomes correspondem a esta regex
-p, --fexclude= Não escanear arquivos cujos nomes correspondem a esta regex
-s, --status= Habilitar o servidor de status na porta especificadaDigitalização de imagens
Começamos procurando assinaturas de arquivos dentro da imagem (imagem do site ).
Executando binwalk com o parâmetro —signature:
$ binwalk --signature --term archer-c7.bin
DECIMAL HEXADECIMAL DESCRIPTION
------------------------------------------------------------------------------------------
21876 0x5574 String da versão do U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (20 de maio
de 2019 - 18:45:16)"
21940 0x55B4 Tabela polinomial CRC32, big endian
23232 0x5AC0 Cabeçalho uImage, tamanho do cabeçalho: 64 bytes, CRC do cabeçalho:
0x386C2BD5, criado: 2019-05-20 10:45:17, tamanho da imagem:
41162 bytes, Endereço de Dados: 0x80010000, Ponto de Entrada:
0x80010000, CRC de dados: 0xC9CD1E38, SO: Linux, CPU: MIPS,
tipo de imagem: Imagem de Firmware, tipo de compressão: lzma, nome da
imagem: "imagem do u-boot"
23296 0x5B00 Dados comprimidos LZMA, propriedades: 0x5D, tamanho do dicionário:
8388608 bytes, tamanho descomprimido: 97476 bytes
64968 0xFDC8 Documento XML, versão: "1.0"
78448 0x13270 Cabeçalho uImage, tamanho do cabeçalho: 64 bytes, CRC do cabeçalho:
0x78A267FF, criado: 2019-07-26 07:46:14, tamanho da imagem:
1088500 bytes, Endereço de Dados: 0x80060000, Ponto de Entrada:
0x80060000, CRC de dados: 0xBB9D4F94, SO: Linux, CPU: MIPS,
tipo de imagem: Imagem Multi-Arquivo, tipo de compressão: lzma,
nome da imagem: "MIPS OpenWrt Linux-3.3.8"
78520 0x132B8 Dados comprimidos LZMA, propriedades: 0x6D, tamanho do dicionário:
8388608 bytes, tamanho descomprimido: 3164228 bytes
1167013 0x11CEA5 Sistema de arquivos Squashfs, little endian, versão 4.0,
compressão:xz, tamanho: 14388306 bytes, 2541 inodes,
tamanho do bloco: 65536 bytes, criado: 2019-07-26 07:51:38
15555328 0xED5B00 Dados comprimidos gzip, do Unix, última modificação: 2019-07-26
07:51:41Agora temos muitas informações sobre essa imagem.
A imagem usa como carregador de inicialização (cabeçalho da imagem no endereço 0x5AC0 e a imagem comprimida do carregador no endereço 0x5B00). Com base no cabeçalho uImage no endereço 0x13270, sabemos que a arquitetura do processador é MIPS, e o núcleo Linux é a versão 3.3.8. E com base na imagem encontrada no endereço 0x11CEA5, podemos ver que rootfs é o sistema de arquivos squashfs.
Agora vamos extrair o carregador (U-Boot) usando o comando dd:
$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 registros lidos
41162+0 registros gravados
41162 bytes (41 kB, 40 KiB) copiados, 0,0939608 s, 438 kB/sComo a imagem está comprimida com LZMA, precisamos descomprimí-la:
$ unlzma u-boot.bin.lzmaAgora temos a imagem U-Boot:
$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Fev 5 08:48 u-boot.binE quanto à busca pelo valor padrão de bootargs?
$ strings u-boot.bin | grep bootargs
bootargs
bootargs=console=ttyS0,115200 board=AP152 rootfstype=squashfs init=/etc/preinit mtdparts=spi0.0:128k(factory-uboot),192k(u-boot),64k(ART),1536k(uImage),14464k@0x1e0000(rootfs) mem=128MVariável de ambiente do U-Boot bootargs é usado para passar parâmetros para o núcleo Linux. E a partir do que foi mencionado acima, compreendemos melhor a memória flash do dispositivo.
O que você acha de extrair a imagem do núcleo Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 registros de entrada
1088572+0 registros de saída
1088572 bytes (1,1 MB, 1,0 MiB) copiados, 1,68628 s, 646 kB/sPodemos verificar se a imagem foi extraída com sucesso usando o comando arquivo:
$ file uImage
uImage: u-boot legacy uImage, MIPS OpenWrt Linux-3.3.8, Linux/MIPS, Multi-File Image (lzma), 1088500 bytes, Sex, 26 Jul 07:46:14 2019, Endereço de Carregamento: 0x80060000, Ponto de Entrada: 0x80060000, CRC do Cabeçalho: 0x78A267FF, CRC dos Dados: 0xBB9D4F94O formato do arquivo uImage é basicamente a imagem do núcleo Linux com um cabeçalho adicional. Vamos remover esse cabeçalho para obter a imagem final do núcleo Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 registros de entrada
1088500+0 registros de saída
1088500 bytes (1,1 MB, 1,0 MiB) copiados, 1,65603 s, 657 kB/sA imagem está comprimida, então vamos descompactá-la:
$ unlzma Image.lzmaAgora temos a imagem do núcleo Linux:
$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Fev 5 10:51 ImageO que podemos fazer com a imagem do núcleo? Poderíamos, por exemplo, procurar strings na imagem e descobrir a versão do núcleo Linux e aprender sobre o ambiente usado para compilar o núcleo:
$ strings Image | grep "Linux version"
Linux version 3.3.8 (leo@leo-MS-7529) (gcc version 4.6.3 20120201 (pré-lançamento) (Linaro GCC 4.6-2012.02)) #1 Seg 20 Mai 18:53:02 CST 2019Embora o firmware tenha sido lançado no ano passado (2019), quando escrevo este artigo, ele usa uma versão antiga do núcleo Linux (3.3.8), lançada em 2012, compilada com uma versão muito antiga do GCC (4.6), também de 2012!
(nota do tradutor: você ainda confia nos seus roteadores em casa e no escritório?)
Com a opção --opcodes também podemos usar o binwalk para pesquisar instruções de máquina e determinar a arquitetura do processador da imagem:
$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIÇÃO
--------------------------------------------------------------------------------
2400 0x960 Instruções MIPS, epílogo da função
2572 0xA0C Instruções MIPS, epílogo da função
2828 0xB0C Instruções MIPS, epílogo da funçãoE quanto ao sistema de arquivos raiz? Em vez de extrair a imagem manualmente, vamos usar a opção binwalk --extract:
$ binwalk --extract --quiet archer-c7.binO sistema de arquivos raiz completo será extraído para um subdiretório:
$ cd _archer-c7.bin.extracted/squashfs-root/
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cat etc/banner
MM NM MMMMMMM M M
$MMMMM MMMMM MMMMMMMMMMM MMM MMM
MMMMMMMM MM MMMMM. MMMMM:MMMMMM: MMMM MMMMM
MMMM= MMMMMM MMM MMMM MMMMM MMMM MMMMMM MMMM MMMMM'
MMMM= MMMMM MMMM MM MMMMM MMMM MMMM MMMMNMMMMM
MMMM= MMMM MMMMM MMMMM MMMM MMMM MMMMMMMM
MMMM= MMMM MMMMMM MMMMM MMMM MMMM MMMMMMMMM
MMMM= MMMM MMMMM, NMMMMMMMM MMMM MMMM MMMMMMMMMMM
MMMM= MMMM MMMMMM MMMMMMMM MMMM MMMM MMMM MMMMMM
MMMM= MMMM MM MMMM MMMM MMMM MMMM MMMM MMMM
MMMM$ ,MMMMM MMMMM MMMM MMM MMMM MMMMM MMMM MMMM
MMMMMMM: MMMMMMM M MMMMMMMMMMMM MMMMMMM MMMMMMM
MMMMMM MMMMN M MMMMMMMMM MMMM MMMM
MMMM M MMMMMMM M M
M
---------------------------------------------------------------
For those about to rock... (%C, %R)
---------------------------------------------------------------Agora podemos fazer muitas coisas diferentes.
Podemos procurar arquivos de configuração, hashes de senhas, chaves criptográficas e certificados digitais. Podemos analisar arquivos binários para e vulnerabilidades.
Com e podemos até executar (emular) um arquivo executável a partir da imagem:
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cp /usr/bin/qemu-mips-static .
$ sudo chroot . ./qemu-mips-static bin/busybox
BusyBox v1.19.4 (2019-05-20 18:13:49 CST) binary multi-chamada.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
e outros. Licenciado sob GPLv2.
Veja a distribuição de origem para o aviso completo.
Uso: busybox [função] [argumentos]...
ou: busybox --list[-full]
ou: função [argumentos]...
BusyBox é um binário multi-chamada que combina muitos utilitários Unix comuns
em um único executável. A maioria das pessoas criará um
link para o busybox para cada função que deseja usar e o BusyBox
agirá como o que foi invocado.
Funções atualmente definidas:
[, [[, addgroup, adduser, arping, ash, awk, basename, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, cut, date, dd, delgroup, deluser, dirname, dmesg, echo, egrep, env, expr, false,
fgrep, find, free, fsync, grep, gunzip, gzip, halt, head, hexdump, hostid, id, ifconfig, init, insmod, kill, killall, klogd, ln, lock, logger, ls, lsmod, mac_addr, md5sum, mkdir, mkfifo, mknod, mktemp,
mount, mv, nice, passwd, pgrep, pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, readlink, reboot, reset, rm, rmdir, rmmod, route, sed, seq, sh, sleep, sort, start-stop-daemon, strings,
switch_root, sync, sysctl, tail, tar, tee, telnet, test, tftp, time, top, touch, tr, traceroute, true, udhcpc, umount, uname, uniq, uptime, vconfig, vi, watchdog, wc, wget, which, xargs, yes, zcatLegal! Mas note que a versão do BusyBox é 1.19.4. Essa é uma versão muito antiga do BusyBox, lançada em abril de 2012.
Portanto, a TP-Link lança a imagem do firmware em 2019 usando software (toolchain GCC, kernel, BusyBox, etc.) de 2012!
Agora você entende por que eu sempre instalo o OpenWRT em meus roteadores?
Isso não é tudo
Binwalk também pode realizar análise de entropia, imprimir dados brutos de entropia e gerar gráficos de entropia. Geralmente, uma alta entropia é observada quando os bytes na imagem são aleatórios. Isso pode significar que a imagem contém um arquivo criptografado, compactado ou ofuscado. Uma chave de criptografia rígida? Por que não?

Também podemos usar o parâmetro --raw para buscar uma sequência personalizada de bytes brutos na imagem ou o parâmetro --hexdump para executar um dump hexadecimal, comparando dois ou mais arquivos de entrada.
podem ser adicionadas ao binwalk, seja através de um arquivo de assinaturas personalizadas, especificado na linha de comando usando o parâmetro --magic, ou adicionando-as ao diretório $ HOME / .config / binwalk / magic.
Você pode encontrar mais informações sobre o binwalk em .
Extensão do binwalk
Existe binwalk, implementado como um módulo Python, que pode ser utilizado por qualquer script Python para executar o scan do binwalk, e a ferramenta de linha de comando binwalk pode ser quase totalmente replicada apenas com duas linhas de código Python!
import binwalk
binwalk.scan()Com a API Python, você também pode criar para personalizar e expandir o binwalk.
Também há um e uma versão em nuvem .
Então, por que não baixar uma imagem de firmware da Internet e experimentar o binwalk? Prometo que você vai se divertir muito 🙂
Fonte: habr.com
