Sagemcom Router F@st 1704 – Userspace

Feb 17, 2012   #f1704  #firmware  #hacking  #mod  #router  #sagemcom 

Algumas novidades sobre as pesquisas no Sagemcom Router F@ST 1704 (“F1704″): novas informações, como enviar e executar aplicativos no router e notas gerais.

192.168.1.105, quero dizer, Sagemcom Router F@ST 1704

Depois que a Sagemcom (“SC”) liberou os fontes e o toolchain, animei a olhar o F1704 novamente. É bem mais fácil trabalhar com o material correto. :)Tirei um tempo para ver do que se tratava e conseguimos resultados razoáveis! Se pretende fazer _tweaks_ neste router, ele tem potencial (ou terá, espero!). Bem, vamos ver o que conseguimos com o tempo. Neste momento, meu F1704 está com um kernel custom e alguns utilitários rodando! Note que ele não é meu modem/router principal, por isso não posso dizer se ele é “bom” ou não. É só _hacking_ for the heck of it!

O pacote liberado pela SC contém o fonte do kernel, de algumas bibliotecas e aplicativos sob GPL, e fontes públicos da Broadcom (“BCM”). Como ferramentas, veio o toolchain GCC para MIPS – usando a uClibc -, e alguns utilitários de compressão e CRC de imagens. Obviamente não é o pacote completo, existe uma quantidade considerável de código proprietário de ambas SC e BCM que não são disponibilizadas, por isso somos obrigados a conviver com binários e, muito provavelmente, com esta versão de kernel, para evitar dor de cabeça com os módulos que não temos os fontes.

Apesar do pacote dar potencial à modificações no F1704, ele não permite gerar uma imagem final para flash via interface web ou executar um kernel construído por você. _Wait, what!?_ Vou explicar mais à frente. :)Vamos ver o que pode ser feito no router por agora.

Antes de partir para modificações e novos aplicativos, notei que existem algumas ferramentas interessantes já disponíveis no router. Se já andou vasculhando os arquivos no sistema interno, isso não é novidade e pode pular para o próximo tópico. Caso não, veja, em especial, os comandos que terminam com “ctl”: são aplicativos que permitem controlar diversos parâmetros do router:

1
2
3
4
5
# ls /bin/*ctl
/bin/adslctl /bin/ethctl /bin/xdslctl
/bin/brctl /bin/wlctl /bin/xtmctl
# ls /sbin/*ctl
/sbin/ethctl /sbin/smuxctl

Por exemplo o wlctl, que têm muitos parâmetros bacanas para controlar a interface wifi, que permitem desde alterar a potência de TX, a adicionar IEs customs nos beacons de sua rede com alguma mensagem oculta. 😀

Enviando e executando aplicativos no router

Enviando arquivos ao router

Primeiramente, você precisa ter acesso ao shell do router. Acesse via telnet e faça login com as credenciais. Se não alterou a padrão, é user “admin”, pass “gvt12345″. Assim que logar, receberá um shell simplificado com comandos dedicados à operação do router. Queremos o BusyBox. Digite “sh” para se libertar! Onde ver “192.168.1.105”, substitua pelo IP de seu router.

1
2
3
4
5
6
7
8
tripleoxygen@stratosphere:~$ telnet 192.168.1.105
Trying 192.168.1.105...
Connected to 192.168.1.105.
Escape character is '^]'.
BCM96338 xDSL Router
Login: admin
Password:
> sh

BusyBox v1.00 (2011.04.01-10:08+0000) Built-in shell (msh)

Enter ‘help’ for a list of built-in commands.

#

Geralmente, routers são bem “trancados” e oferecem poucos comandos no shell, restringindo o usuários apenas aos recursos de configuração. Veja como o BusyBox foi compilado com poucos applets:

1
2
3
4
5
6
7
8
9
# help
Built-in commands:
-------------------
. : break cd continue eval exec exit export help login newgrp
read readonly set shift times trap umask wait [ busybox cat chmod
cp date df dmesg echo expr false ftpget ifconfig init insmod
kill killall klogd linuxrc ln logger logread ls mkdir mount msh
ping ping6 ps pwd reboot rm rmmod route sendarp sh sleep smuxctl
sysinfo syslogd test top true tty umount vconfig

Note que não temos nem mesmo “mv”! Desta maneira, se quiséssemos rodar algum aplicativo no router, como faríamos para colocar algo lá dentro, já que estamos em um ambiente restrito como esse? Não existe nenhum meio óbvio (não que eu tenha imaginado! haha). E não, o _ftpget_ visto ali não funciona, foi comentado no fonte do BusyBox pela SC. 😉 Teríamos que bolar uma maneira de enviar estes dados usando este canal que temos, o shell via telnet. Mas estamos restritos a comandos de texto, correto? E para binários?

Lembre-se que podemos usar o comando echo com a opção -e e sequências escapadas para representar qualquer byte. Exemplo:

1
2
# echo -e '\x54\x65\x73\x74\x65'
Teste

Melhor ainda: redirecionamos a saída para um arquivo, e ao invés de texto, bytes representando algum dado binário:

1
2
# echo -e '\x00\xF0\xFF\x7E\x00' >> /var/my_app
# chmod +x /var/my_app

Temos então, uma maneira de enviar quaisquer dados ao router. Obviamente, algo deve automatizar este processo, lendo o arquivo que queira enviar, convertendo em sequências de texto como mostrado acima e enviando ao router. Use o sendbin.py para isso. Execute-o sem parâmetros na sua máquina para saber como usá-lo. Creio ter visto algo parecido em algum lugar, caso alguém saiba, diga onde.

A ideia agora, é enviar algum aplicativo que facilite o envio de outros e de maneira mais rápida. Assim, compilei o netcat para este propósito. Já temos como executar nossos aplicativos no router! Resumindo o processo:

  • Envie o netcat com o sendbin (não esteja logado via telnet no router, ou o sendbin falhará):

1
./sendbin.py 192.168.1.105 admin gvt12345 netcat

Note que leva cerca de 5 min para enviá-lo! Sim, é lento! Por enquanto, é nossa maneira. Agora, quando quiser enviar qualquer aplicativo ao router…

  • Faça login no router via telnet e execute a partir do shell do BusyBox:

1
/var/netcat -l -p 9999 > /var/my_app

E de sua máquina, com o aplicativo a ser enviado:

1
cat my_app | nc -q 30 192.168.1.105 9999

Uma vez recebido no router, volte ao Busybox, torne-o executável e invoque o app:

1
2
chmod +x /var/my_app
/var/my_app

Instalando o pacote fornecido e compilando aplicativos

Agora que temos certeza que podemos “fazer alguma coisa” no router, vamos ao ambiente de desenvolvimento.

Já que a SC forneceu o toolchain, optei por utilizá-lo e assim “facilitar a vida”. Se ainda não o baixou, veja o link no final da página, ele acompanha o pacote. Aproveite para instalar todo o ambiente fornecido. Descompacte o pacote _F@ST1704GVT_4.42_consumerrelease.tar.gz, você terá 3 arquivos:

  • o toolchain: uclibc-crosstools-gcc-4.2.3-3.tar.bz2
  • os fontes: F@ST1704GVT_4.42_consumer.tar.gz
  • script de instalação: _consumerinstall

Renomeie o pacote de fontes de F@ST1704GVT_4.42_consumer.tar.gz para _bcm96338consumer.tar.gz, ou o script não encontrará. Instale com:

1
$ ./consumer_install

Os fontes serão instalados em _/opt/bcm963xx_router e o toolchain em /opt/toolchains/uclibc-crosstools-gcc-4.2.3-3_. Daqui, você já pode construir todo (*cough*cough*) o sistema do F1704. Tanto o kernel como o userspace estão nesta árvore e são compilados automaticamente caso você dê um make na raíz. Para construir tudo (kernel + user):

1
make PROFILE=F@ST1704GVT

Mantenha o perfil em todas as operações que fizer. Para compilar os realms separadamente, use as regras “kernel” ou “userspace” para o make. A saída da compilação ficará em targets/F@ST1704GVT. Note que o kernel não é copiado, e deve ser pego de kernel/linux/vmlinux. Obviamente ele ainda não está no formato adequado para o router. Informações sobre kernelspace no F1704 ficam para um próximo post.

E agora, como usar tudo isso para compilar meus apps? Podemos apenas usar o toolchain e compilar manualmente (ou configurá-lo no Buildroot, por exemplo, que é como estou fazendo), ou adicioná-lo na árvore oficial, para ele seja compilado com todo o resto do sistema.

Vou abordar brevemente como adicioná-lo na árvore oficial. A vantagem é que temos acesso às bibliotecas oferecidas pela SC e BCM, que oferecem funções específicas para o F1704 (cms_boardctl, cms_util, …).

Copie a pasta com o fonte de seu app ou outro app qualquer que pretende compilar (o app deve ter port para MIPS) para:

1
/opt/bcm963xx_router/userspace/public/apps

Note que já existe alguns apps. Após copiado, você terá que adicionar seu novo aplicativo ao Makefile do sistema, para que ele possa construí-lo no próximo make. Abra o Makefile raíz da pasta apps e adicione o seu. Basta observar como os existentes foram adicionados e incluir o novo.

Para o Makefile específico (i.e. usado para construir o app), caso necessário, copie de algum aplicativo já na árvore e adapte-o. Depois de adicionado, volte à raiz do do sistema e:

1
2
$ cd /opt/bcm963xx_router
$ make PROFILE=F@ST1704GVT userspace

Dependendo das configurações de seu Makefile, o binário poderá ser copiado para o staging do rootfs em targets/F@ST1704GVT/fs.install. Se não for este o caso, ele estará na pasta do fonte, de acordo com as regras originais do Makefile. Agora, envie o binário ao router e execute!

Observação: a biblioteca do uClibc presente no router não é exatamente a mesma contida no toolchain. A versão do router está extremamente stripped para reduzir o tamanho do binário, por isso, algumas funções não utilizadas foram removidas. Neste caso, pode acontecer de sua aplicação não encontrar algum símbolo ou outro quando executado no router. Implemente esta função você mesmo, faça link estático ou copie a biblioteca compartilhada (libuClibc-0.9.29.so) do toolchain junto de seu app para o router (certifique-se de criar o link simbólico libc.so.0 que aponta para ela). Como exemplo de símbolos que não existem: strlcpy e ptrace.

Pesquisas futuras

Como foi dito, atualmente não é possível gerar imagens de firmware que podem ser usadas para atualizar o router e tornar permanentes suas modificações.

Já sei o porquê e estou trabalhando nisto. Adiantando: a Sagemcom não usa simples CRC32 para validar o cabeçalho das imagens (“tags”). Ela usa sim, para validar o rootfs e o kernel, mas o cabeçalho não. O interessante é o fato que nos fontes fornecidos, está claro que este checksum é CRC32 também, mas não é caso na “vida real”. Na verdade, o CRC32 que a Broadcom usa é um CRC32 com todos os bits invertidos, mas  pelo menos isso é documentado. Enfim, a Sagemcom fornece os fontes mas não quer que os usuários mexam no router. Sujo? Sim!

Algumas notas adicionais que deixo aqui:

  • As imagens de firmware existentes não incluem o CFE (bootloader). Isso torna o processo de update mais seguro, já que não há chances de acidentalmente corrompê-lo ao atualizar. Mesmo que o kernel ou o rootfs falhe, você terá o CFE via porta serial para resgatar o router. Parece que o CFE também tem uma interface web para isso, o que seria melhor ainda.
  • Fiz um dump completo da flash (4 MB) incluindo todas as partições e documentei o layout da flash. Com o kernel atual, não se pode ler regiões além das permitidas pelo código responsável no kernel (e.g. NVRAM, Scratchpad). Para resolver isso, modifiquei o kernel adicionando um novo parâmetro no IOCTL que controla alguns recursos a nível de “placa” (/dev/brcmboard) que permite ler qualquer endereço da flash.

Assim que tiver tempo, escrevo um novo post com novas informações. Vejam o file vault, lá tem algumas coisas úteis para quem quiser mexer no F1704. Como exemplo, deixei o binário do tcpdump pronto para uso.

Frita-frita (praticamente idle)

sendbin.py (renomeie para sendbin.py)

netcat (MIPS32)

tcpdump (MIPS32, libpcap statically linked)

mini_snmpd (MIPS32)

Sagemcom Router F@ST 1704 opensource release

F1704 Hack file vault