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 0×1f e 0×8b. 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 0×2c38 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 0×000e0000, 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.
Franz [Membro] 8:37 am em Janeiro 30, 2008 Link Permanente
Legal Marcelo.
Com uma máquina destas nas mãos, tem que explorar mesmo.
[ ]’s