Engenharia reversa de um roteador doméstico usando binwalk. Você confia no software do seu roteador?

Engenharia reversa de um roteador doméstico usando binwalk. Você confia no software do seu roteador?

Há alguns dias, decidi realizar a engenharia reversa do firmware do meu roteador utilizando o binwalk.

Eu comprei para mim mesmo um roteador doméstico TP-Link Archer C7. Não é o melhor roteador, mas atende bem às minhas necessidades.

Sempre que compro um novo roteador, instalo OpenWRT. 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 baixei a última imagem do firmware 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?

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, stripped

Time 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 Wikis 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 baixar o código-fonte e seguir as instruções de instalação ou guia rápido, 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 especificada

Digitalização de imagens

Começamos procurando assinaturas de arquivos dentro da imagem (imagem do site TP-Link).

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:41

Agora temos muitas informações sobre essa imagem.

A imagem usa U-Boot 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/s

Como a imagem está comprimida com LZMA, precisamos descomprimí-la:

$ unlzma u-boot.bin.lzma

Agora temos a imagem U-Boot:

$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Fev  5 08:48 u-boot.bin

E 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=128M

Variá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/s

Podemos 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: 0xBB9D4F94

O 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/s

A imagem está comprimida, então vamos descompactá-la:

$ unlzma Image.lzma

Agora temos a imagem do núcleo Linux:

$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Fev  5 10:51 Image

O 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 2019

Embora 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ção

E 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.bin

O 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 detecção de erros e vulnerabilidades.

Com qemu e chroot 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, zcat

Legal! 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?

Engenharia reversa de um roteador doméstico usando binwalk. Você confia no software do seu roteador?

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.

Assinaturas personalizadas 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 documentação oficial.

Extensão do binwalk

Existe API 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 plugins em Python para personalizar e expandir o binwalk.

Também há um plugin IDA e uma versão em nuvem Binwalk Pro.

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

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster