Binwalk e extração de firmwares

binwalk
binwalk

Binwalk é apenas uma das ferramentas

Binwalk é uma ferramenta fundamental para análise e interação, mas não é a única coisa que você utilizará na manipulação de imagens. Em um dos posts de embedded exemplifiquei a extração de dados de um arquivo CPIO. Mas existem outros formatos com outros tipos de extração para embarcados. Então, esse será um post que talvez receba algumas atualizações conforme eu for passando por essas extrações. Para não deixá-lo de fora, iniciaremos por:

CPIO
Em diversos livecds o sistema raiz é basicamente o initrd. O initrd contém toda a estrutura de um sistema raiz necessária para fazer a pré-carga do sistema levantando módulos e serviços que porventura sejam necessários. Maiores detalhes sobre o initrd podem ser vistos nos posts sobre embedded.

Então, para extrair uma raiz de um arquivo CPIO, primeiramente copie o initrd do livecd (ou o próprio de sua distro, para fazer experimentos) para um diretório, por exemplo, /tmp/initrd. Depois, faça primeiramente a descompressão; se a extensão for gz, use gzip; lz, use lzma. Porém como foi mostrado neste post sobre embedded, algumas vezes a extensão pode ‘mentir’ sobre o real formato do arquivo. Enfim, faça a extração.

Após a extração do arquivo, um cpio com o provável nome de ‘initrd’ será gerado nesse diretório. Então para extraí-lo use:

A raiz do sistema será extraída do CPIO para o diretório em que esse comando estiver sendo executado, portanto certifique-se de que não esteja executando-o em um nível de diretório em que possa se misturar com outros dados.

bin
Arquivos bin podem ser imagens de firmware. Para extrair o sistema nesse caso são duas etapas, porque os arquivos bin possuem um conjunto que compõe o sistema como um todo. Para exemplo da extração e da estrutura de um arquivo .bin, vamos utilizar um aplicativo recomendado pelo Alan (que palestrou sobre o Linux BIOS no FISL8) para o grande mestre Marcelo Barros, que por sua vez me passou a dica através desse post. O aplicativo se chama BinWalk e o Marcelo fez um pacote (disponibilizado no link dele) e também o disponibilizo aqui.

Utilizando o binwalk
Após instalá-lo, você poderá executá-lo sobre o arquivo binário do sistema. No exemplo estou utilizando o bin do Carambola, uma board MIPS:

Como se pode ver, o sistema foi composto por 3 partes:
– uBoot (bootloader)
– kernel (utilizando a compressão LZMA)
– sistema (utilizando squashfs)

Agora vem a parte divertida, que é extrair a parte do binário referente ao sistema raiz. Para isso, utilizamos o bom e velho dd. Repare que o endereço do sistema no binário está após 1179648. Daí basta iniciar o strip do binário a partir desse endereço:

Utilizo linux Mint, então instalei através do apt o squashfs-tools, levantei o módulo e descomprimi assim:

Foi criado um diretório squashfs-root contendo toda a estrutura do sistema raiz.
Se quisesse copiar o kernel, teria que limitar o dd com count para que ele não fosse até o final do arquivo. Como o sistema raiz vai até o final do binário, não foi necessário limitar o dd.

Vamos a uma breve introdução do SquashFS:

O que é SquashFS?
Quando se está criando um sistema linux pequeno para embedded, na maioria das arquiteturas preza-se pelo espaço de armazenamento. Nesse caso, quanto maior for a compressão do sistema, melhor.

O SquashFS é um arquivo de sistemas read-only que permite a você comprimir todo o sitema ou simplesmente diretórios, escrevendo os resultados para outras partições, dispositivos ou arquivos ordinários, então monta-o diretamente (se um dispositivo) ou utilizando um dispositivo de loopback (se for um arquivo). Para utilizar um dispositivo de loopback você pode simplesmente passar a opção ‘-o loop’ na montagem do arquivo. O restante do comando é similar à montagem de um device.
Outra vantagem sobre um arquivo tar por exemplo, é a performance e velocidade de acesso, por isso seu uso é tão apreciado.

Um documento um pouco desatualizado pode ser encontrado nesse link.

jffs2
Esse tipo de arquivo eu não tinha a menor idéia de como extraí-lo, daí esse link do post do Marcelo. Gerei uma imagem jffs2 de 128k em um dos SDKs que utilizo (OpenWrt) para fazer essa parte do post:

Reparou em block2mtd o valor após $loop? Esse número cabalistico funcionou para mim tal como para o Marcelo e também na origem da informação em um outro link. Então, deverá funcionar para você também.
Depois bastará listar dentro rootfs para ver seus arquivos.

ROMFS
ROMFS é um econômico e pequeno sistema de arquivos read-only originado e usado em alguns projetos Linux. Ele é um sistema de arquivos baseado em blocos, disponível no kernel desde a versão 2.1.21 (Janeiro de 1997).

Diferentemente do squashfs, o romfs armazena apenas o mínimo requerido para levantar um sistema, sem considerar timestamps ou permissões. Uma boa aplicação para romfs é utilizá-lo no ramdisk inicial ou então, em um dispositivo que necessite de recursos mínimos e trabalhe em modo somente-leitura.

O Sparc-boot.org foi um projeto que utilizou romfs, porém hoje já não existe. O uClinux também fez uso do romfs para processadores Motorola m68k e ARM.
Na atualidade, sinceramente, não sei se alguém utiliza ainda esse formato, mas está disponível sua criação através de seleção no menu do BuildRoot.
Um arquivo ROMFS pode ser montado da mesma forma que um arquivo iso:

Cloop
O cloop é um módulo do kernel do Linux. Ele adiciona suporte a descompressão transparente em dispositivos de bloco read-only, mas não é um arquivo de sistemas por si só. Ele foi originalmente escrito por Rusty Russell, posteriormente mantido por Klaus Knopper, o autor do Knoppix, que deu origem a centenas de live cds, entre eles, o Kurumin. A taxa de compressão do cloop é de 2.5:1, o que fazia do Knoppix um sistema de 700MB na compressão, sendo que sua extração gerava um arquivo de 1.8GB.

Para chegar ao sistema de arquivos, duas etapas são necessárias. Primeiro, instale o pacote cloop-utils, depois:

cramfs
Compressed ROM File System, ou cramfs é um sistema de arquivos read-only simplista e eficiente, utilizado principalmente em sistemas embarcados. Diferente de uma imagem convencional, um cramfs não precisa ser descomprimido para ser utilizado, por esse motivo algumas distribuições de linux utilizam (ou utilizaram) esse formato em suas imagens de instalação. O principal motivo para utilização desse formato é a economia de memória por não haver descompressão do arquivo.

Para descomprimí-lo, instale o pacote cramfsprogs e execute:

ubifs

Unsorted Block Image File System ou UBIFS. Ele é um sucessor do JFFS2 e compete ao logfs como um arquivo de sistema para usar com memória flash raw. Seu desenvolvimento começou em 2007.
Dispositivos MTD não podem ser utilizados diretamente.
Uma das maiores diferenças entre UBIFS e JFFS2 é que UBIFS suporta cache de escrita. Sua performance também é melhor do que JFFS2 para dispositivos NAND de grandes tamanhos. Ele também preserva a compressão on-the-fly do JFFS2 e é recuperável e tolerante a falhas de energia. A compressão padrão compreende zlib e LZO.

A magnífica documentação do UBIFS pode ser encontrada aqui.

Infelizmente não há ferramenta no user-space ainda para manipulação de imagens mtd e não é possível montá-la como um loop porque ela não trabalha com dispositivos de bloco.

A documentação descreve um hacking que confesso não ter funcionado no meu sistema. De qualquer modo, as ferramentas mdt-utils são necessárias, mas instalei também o mtdev-tool.

A compressão desses arquivos normalmente é feita pelo SDK utilizado para contruir o sistema, mas há casos que a compilação manual do respectivo arquivo pode ser necessária. Eu utilizo esse método algumas vezes para construir o initrd do Phantom e o fiz também para embarcar uma versão modificada do SLITaz em um dispositivo que ainda não posso citá-lo por ser um possível produto.

Então, em algum momento farei um post mostrando como reconstruir seus arquivos de sistema, é só aguardar. Curtiu esse post? Compartilhe através das redes sociais disponibilizadas abaixo! ;-)

Comments

comments

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.

Um comentário em “Binwalk e extração de firmwares

Deixe uma resposta