
Este repositório contém os resultados da minha pesquisa de agosto de 2020 sobre o firmware de IPC/NVR da Tiandy. Encontrei duas vulnerabilidades que poderiam ser usadas para recuperar remotamente a senha do administrador e obter acesso root ao dispositivo.
Este repositório contém os resultados da minha pesquisa de agosto de 2020 sobre o firmware IPC/NVR da Tiandy (esses dispositivos também são vendidos como OMNY). Esta "pesquisa" não foi exaustiva, mas encontrei vários métodos para recuperar remotamente a senha do administrador, ativar o telnet e alterar a senha do root.
É difícil dizer exatamente quais versões são afetadas, já que só podemos baixar as recentes. Todas estas versões para download são afetadas:
DVRS_V9.12.7.20200422
DVRS_V11.7.4.20200721
NVSS_V13.6.1.20200723
NVSS_V22.1.0.20200722
Não só existem diferentes ramos para diferentes dispositivos, mas alguns componentes são versionados e atualizados separadamente, como a API web, onde encontrei um bypass de autenticação que só funciona em versões lançadas desde meados de 2019, independentemente do número da versão do firmware. Se por acaso você souber mais sobre as versões afetadas, agradeço sua ajuda.
Estou fazendo divulgação completa aqui, mas é razoável. Um patch do fornecedor (improvável, já que eles não respondem) não faria o problema desaparecer, especialmente quando nenhum dispositivo online tem o firmware mais recente (nem de longe). A vulnerabilidade real é que esses dispositivos estão expostos à internet. E isso é algo que os usuários finais precisam corrigir, não a Tiandy.
Como bônus, também estou incluindo o descompactador de firmware e algumas informações sobre como acessar os fluxos via RTSP/RTMP (boa sorte tentando encontrar isso no manual).
Primeiramente apresento os scripts:
Em seguida, tento explicar brevemente o que esses scripts fazem e porquê. Não repito o código, mas tento explicar contexto suficiente para você entender o código:
Por fim, a coisa fica relativamente técnica:
Você precisará de Python 3 com PyCrypto.
Primeiro, tente recover.py. Isso requer que a porta 3001 esteja acessível:
python3 recover.py [HOST]
se tudo correr bem, as credenciais do administrador devem ser impressas.
Se essa porta não estiver acessível, a da web pode funcionar. Isso requer a url:
python3 cgi_recover.py http://123.45.67.89
python3 cgi_recover.py https://123.45.67.89
Se nenhum dos métodos acima funcionar, verifique se o telnet está habilitado. Se estiver, você pode obter root no dispositivo diretamente, basta quebrar este hash:
support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(abra um PR caso consiga quebrá-lo :D)
Em firmwares NVR V7 mais antigos, você pode executar comandos diretamente:
python3 ftpupdate.py [host] [adminpass] '[cmd]'
mas não dá nenhuma saída. Para facilitar, incluí este atalho:
python3 ftpupdate.py [host] [adminpass] adduser [username] [password]
Isso adicionará outro usuário com uid 0.
Primeiro, habilite o telnet usando:
python3 telnet.py [host] [adminpw]
ou para dispositivos recentes:
python3 cgi_recover.py [host] telnet
Então você pode sobrescrever /etc/passwd (presumo que você saiba como isso funciona). Tente filetransport.py primeiro (para NVRs):
python3 filetransport.py [host] [adminpass] put /etc/passwd <[source_file]
isso não dá nenhum retorno; você precisa testar tentando fazer login...
Para modelos IPC onde filetransport.py não funciona, tente upgrade_rw.py:
python3 upgrade_rw.py [url] [adminpass] /etc/passwd <[source_file]
(isso também não dá nenhum retorno)
Por fim, para dispositivos ainda mais novos, isso também pode ser feito pela API web:
python3 cgi_recover.py [url] write /etc/passwd <[source_file]
Se nenhum dos métodos acima funcionou (verifique se você consegue fazer login), tente novamente todos esses métodos, mas sobrescreva /config/etc/passwd em vez disso. Em algumas versões do firmware, /etc/passwd é um symlink para esse caminho. Por fim, você também pode tentar sobrescrever /tdfs/etc/passwd, mas depois disso pode ser necessário reiniciar o dispositivo; para reiniciar, use:
python3 reboot.py [host] [adminpass]
O firmware antigo V7 (IPC e NVR) não parece ser afetado, mas se você tiver a senha do administrador, para NVRs existe um RCE autenticado (ftpupdate.py), e para IPCs, o script upgrade-rw.py pode ser usado para sobrescrever /etc/passwd.
Versões posteriores do firmware NVR (V9 e V11) têm uma conta padrão que, combinada com escalonamento de privilégios "passivo", torna possível recuperar a senha do administrador. Podemos então sobrescrever /etc/passwd usando filetransport.py.
Embora a conta padrão não esteja presente no firmware IPC, outro método de recuperação aparece: o método PSW. Este é um mecanismo de recuperação de senha sem segurança alguma. Está presente em todas as versões de firmware para download desde o V9. Enquanto filetransport.py só funciona em NVRs, upgrade_rw.py alcança o mesmo propósito em IPCs usando o mecanismo de atualização, para que ainda possamos obter o acesso root.
O firmware de 2019 introduz outro vetor de ataque: um bypass de autenticação usando a API web. Ao exportar o arquivo de configuração sem autenticação, podemos recuperar a senha e preparar um pacote de atualização para sobrescrever arquivos arbitrários.
Falando em vulnerabilidades, existem 4 delas:
Observe que não investiguei os recursos "cloud", ou seja, se é possível enumerar dispositivos e, portanto, conectar-se a dispositivos não expostos à internet (como acontece com dispositivos Xiongmai).
Em versões antigas, o telnet é habilitado por padrão e é isto que podemos encontrar no arquivo /etc/passwd:
support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(a senha do root é atualizada dinamicamente; também não quebrei este hash, então pull requests são mais que bem-vindos :D)
O usuário support (na verdade presente em todas as versões do firmware) pode parecer sem privilégios, mas, é claro, esse usuário tem privilégios suficientes para ler a senha do Admin e sobrescrever scripts de inicialização graváveis por todos em /etc/init.d ou até mesmo criar novos :)
Conceitualmente, o método é realmente simples. Apenas enviamos um pacote de login e lemos a resposta. Só isso, porque a resposta de "login bem-sucedido" contém as credenciais de todos os usuários, independentemente dos nossos privilégios. Embora já fosse assim no V7, na prática esse método só se tornou útil quando a conta padrão foi introduzida no firmware NVR. A "Default" irremovível não tem privilégios remotos, então você não pode fazer nada com ela. Bem, talvez exceto ler a senha do administrador...