Firewalls industriais: firmware da ADS-TEC

Conforme prometido, vamos dar uma analisada agora no firmware da ADS-TEC, que pode ser obtido em http://cgi.ads-tec.de/uploads/pdf/downloads/Ads-tec-IF1xxx-1.1.1-5398.zip. Abrindo o arquivo, encontramos:

unzip Ads-tec-IF1xxx-1.1.1-5398.zip
Archive:  Ads-tec-IF1xxx-1.1.1-5398.zip
inflating: releases/Ads-tec-IF1xxx-1.1.1-SVN-R9428.B-5398.bin
inflating: Changelog-Ads-IF.txt
inflating: gplinfo.pdf

O arquivo gplinfo.pdf lista todos os programas usados que seguem a licença GPL e tem ainda uma cópia do texto da GNU GPL. Também dão o endereço de contato para você adquirir os fontes, por meros 50 euros o CD. Se alguém comprar, por favor, eu aceito uma cópia.

Um hexdump no arquivo Ads-tec-IF1xxx-1.1.1-SVN-R9428.B-5398.bin revela uma primeira parte com código ARM (alguns anos trabalhando com ARM lhe fazem perceber um código mesmo em binário…) que deve ser um bootloader (o redboot citado no gplinfo.pdf), depois uma região que parece compactada/encriptada (o kernel, como veremos depois) e, finalmente, algo compreensível, no formato compressed ROMFS.

Trechos a seguir, para ilustração:

BOOTLOADER:

00000000  e1 a0 00 00 e1 a0 00 00  e1 a0 00 00 e1 a0 00 00  |................|
00000010  e1 a0 00 00 e1 a0 00 00  e1 a0 00 00 e1 a0 00 00  |................|
00000020  ea 00 00 02 01 6f 28 18  1d 60 00 00 1d 6d b7 04  |.....o(..`...m..|
00000030  e1 a0 70 01 e3 a0 80 00  e1 0f 20 00 e3 12 00 03  |..p....... .....|
00000040  1a 00 00 01 e3 a0 00 17  ef 12 34 56 e1 0f 20 00  |..........4V.. .|
00000050  e3 82 20 c0 e1 21 f0 02  e3 cf 20 1f e2 82 38 01  |.. ..!.... ...8.|
00000060  e4 92 00 20 e1 32 00 03  1a ff ff fc ee 07 0f 9a  |... .2..........|
00000070  ee 07 0f 17 ee 11 0f 10  e3 c0 00 05 e3 c0 0a 01  |................|
00000080  ee 01 0f 10 e3 a0 70 63  e3 87 7c 02 ee 11 0f 10  |......pc..|.....|
REGIÃO COMPACTADA (logo após 0x2c38, antes pode-se ver as mensagens do boot loader):

00002c00  4d 65 6d 6f 72 79 20 65  72 72 6f 72 0a 00 00 00  |Memory error....|
00002c10  4d 61 6c 6c 6f 63 20 65  72 72 6f 72 0a 00 00 00  |Malloc error....|
00002c20  72 61 6e 20 6f 75 74 20  6f 66 20 69 6e 70 75 74  |ran out of input|
00002c30  20 64 61 74 61 0a 00 00  1f 8b 08 00 bf 4c 2f 47  | data........L/G|
00002c40  02 03 ec fd 0b 7c 54 d5  b9 3f 8c ef 3d 33 49 06  |.....|T..?..=3I.|
00002c50  08 30 81 a0 a9 72 d9 81  a8 51 09 d9 73 c9 cd a2  |.0...r...Q..s...|
00002c60  26 4c 02 49 4d 60 48 02  a6 02 35 43 12 48 24 24  |&L.IM`H...5C.H$$|
00002c70  31 97 0a 3d 9e 76 72 e1  a2 85 36 0a 28 c7 62 33  |1..=.vr...6.(.b3|
00002c80  6d 6d 6b 7b 6c 0f ed e1  78 68 8f e7 9c 5d c5 96  |mmk{l...xh...]..|
00002c90  5a fd 95 7a 69 a9 d5 d3  99 09 53 d0 b1 96 b6 b6  |Z..zi.....S.....|
REGIÃO DO COMPRESSED ROMFS (inicia em 0x000e0000, o resto é ff por causa da imagem de flash)

000dffd0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000dffe0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000dfff0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
000e0000  45 3d cd 28 00 a0 c3 00  03 01 00 00 00 00 00 00  |E=.(............|
000e0010  43 6f 6d 70 72 65 73 73  65 64 20 52 4f 4d 46 53  |Compressed ROMFS|
000e0020  7e 04 f4 96 00 00 00 00  9c 1e 00 00 b1 06 00 00  |~...............|
000e0030  43 6f 6d 70 72 65 73 73  65 64 00 00 00 00 00 00  |Compressed......|
000e0040  ed 41 e8 03 fc 00 00 e8  c0 04 00 00 ed 41 00 00  |.A...........A..|
000e0050  1c 00 00 00 81 14 00 00  2e 73 73 68 ed 41 00 00  |.........ssh.A..|

O meu chute inicial era que teríamos um bootloader e, logo a seguir, o kernel Linux compactado. Não é preciso ser nenhum guru para chutar isso, é o óbvio. Para tentar provar a minha hipótese, procurei por um documento que falasse sobre o gzip e sua possível assinatura. O GZIP segue o RFC 1952 e está bem documentado. Ele fala que os dois primeiros bytes são 0x1f e 0x8b. Depois tem um byte indicando o método de compressão, seguido de um campo de flags, data de modificação, flags adicionais e sistema operacional. Em 0x2c38 eu encontrei um padrão que casava

00002c30  20 64 61 74 61 0a 00 00  1f 8b 08 00 bf 4c 2f 47 | data........L/G|
00002c40  02 03 ec fd 0b 7c 54 d5  b9 3f 8c ef 3d 33 49 06  |.....|T..?..=3I.|
00002c50  08 30 81 a0 a9 72 d9 81  a8 51 09 d9 73 c9 cd a2  |.0...r...Q..s...|

- 1f 8b: assinatura GZIP
- 08: "deflate" compression method
- 00: flags desligados
- bf 4c 2f 47: time stamp (está em big endian, a conversão gera 1194282175, que significa
Mon, 05 Nov 2007 17:02:55 GMT, segundo o site Online Conversion
- 02: compressor used maximum compression
- 03: sistema operacional Unix

Seria coincidência demais não ser GZIP. Sabendo que o o sistema de arquivos deveria estar em 0x000e0000, na região da assinatura do compressed ROMFS, dividi o arquivo em três:

dd if=Ads-tec-IF1xxx-1.1.1-SVN-R9428.B-5398.bin of=bootloader.bin count=11320 bs=1
dd if=Ads-tec-IF1xxx-1.1.1-SVN-R9428.B-5398.bin of=vmlinuz.gz skip=11320 count=894864 bs=1
dd if=Ads-tec-IF1xxx-1.1.1-SVN-R9428.B-5398.bin of=romfs.img skip=917504 bs=1

Descompactei o kernel:

gunzip -v vmlinuz.gz
vmlinuz.gz:
gzip: vmlinuz.gz: decompression OK, trailing garbage ignored
58.4% -- replaced with vmlinuz

O warning se refere ao fato de a região da imagem do kernel ter sido completada com 0xff até o início do ROMFS comprimido. Ignorei isto e realmente o kernel estava lá:

ls -lh
-rw-r--r-- 1 barros barros  12K 2008-01-28 09:05 bootloader.bin
-rw-r--r-- 1 barros barros  13M 2008-01-28 09:18 romfs.img
-rw-r--r-- 1 barros barros 2,1M 2008-01-28 09:09 vmlinuz
-rw-r--r-- 1 barros barros 874K 2008-01-28 12:09 vmlinuz.gz

strings vmlinuz | grep Linux
Linux version 2.4.32-uc0 (snpr@wintermute) (gcc version 3.3.2) #SVN-R9428.B-5398 Mo 5. Nov 18:02:54 CET 2007

Montar o ROMFS comprimido foi mais fácil ainda.

mkdir romfs
sudo mount -t cramfs -o loop romfs.img romfs

No fundo, usar um initrd comprimido para partida do sistema não é a melhor opção já que gasta mais memória RAM. A abordagem com JFFS2 da Innominate é melhor. Uma espiadinha no sistema deles está a seguir:

du * -sh

4,6M    bin
6,5K    dev
5,8M    etc
1,0K    home
512     include
6,2M    lib
512     mnt
1,0K    nvram
512     proc
2,0M    sbin
114K    share
512     tmp
9,9M    usr
512     var

ls etc/init.d/

rcS              S11macs           S41firewall  S42adsdpd   S44smbmount         S80modem
S00init          S12vlan           S41lldpd     S42hosts    S50snmpd            S80thttpd
S01-i2c-modules  S13syslog-local   S41pforward  S42syslog   S51stunnel          S99lednormal
S02startup       S15-rtl8305       S41routing   S43ipsec    S61dnsmasq          S99zlcdmenu
S03-ixp-modules  S30preparechains  S41shaping   S43l2tp     S62nagios
S03time          S40network        S41sshd      S43modbusd  S70checkbootloader
S10Bonding       S40nt0_ntp        S41statusd   S43samba    S70init

ls etc/www.rom/ ( página web do equipamento ?)

db      images      index.php  lang    priv  quickstart  vendor
errors  index.html  js         logout  pub   style       wizard

Vi que eles tem sqlite, zebra, libc GNU, thttp como webserver, entre vários outras coisas. A persistência da informação foi feita em flash mesmo, com JFFS2, que é montado no diretório nvram. Bom já chega de bisbilhotar.

Nota: não se teve acesso físico a nenhum destes equipamentos, apenas foram analisado as atualizações de firmware fornecidas pelos fabricantes. Também não foi feita nenhuma engenharia reversa nos programas distribuídos, somente a constatação pura e simples do conjunto de programas que compunham o firmware.
  1. #1 by Alan [Membro] on janeiro 28, 2008 - 7:16 pm

    Marcelo,
    não tinha lido até o final, realmente você fez o dever de casa direitinho, rs.

    Foi um trabalho de Hércules, parabéns.

    Algumas dicas para melhorar a eficiência:
    ao invés de colocar skip=11320 .. bs=1 use skip=1415 .. bs=8, copiar byte a byte demora uma eternidade.

    Nota 9 :-)

    Alan

  2. #2 by Lutieri on fevereiro 20, 2008 - 9:28 pm

    Cara!
    Achei achei demais o post!!!

    Eu sei que não é um conhecimento que se adquire em pouco tempo mas quero te pedir se tuns alguma leitura pra me recomendar? quero me divertir mais em baixo nível nas horas vagas!!

    Obrigado!!

  3. #3 by Rafael on maio 27, 2009 - 11:27 am

    opa amigo t0 com um problema, eu esqueci a senha da minha internet, nao o modem, a senha que eu coloquei no explorer mesmo, aí fucei fucei e achei o codigo binario dele, mas nao sei como decifra-lo é o seguinte:
    dd 92 0f 72 03 58 92 ed de af d0 66 64 68 3e 88
    se alguem souber como decodifica-lo eu agradeço, meu email é anjodamorte30@uol.com.br

  1. Etherscope II da Fluke, mais um com Linux ! « Jedizone

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Join 417 other followers