Mis aventuras hackeando el iParcelBox


En 2019, McAfee Advanced Threat Research (ATR) reveló una vulnerabilidad en un producto llamado BoxLock. Algún tiempo después de esto, el CEO de iParcelBox, una compañía del Reino Unido, nos contactó y ofreció enviar algunos de sus productos para probarlos. Si bien este no es el típico M.O. Por nuestra investigación, aplaudimos a la compañía por ser proactiva en sus esfuerzos de seguridad y, por lo tanto, como el equipo de iParcelBox tuvo la amabilidad de enviarnos todo, decidimos echar un vistazo.

IParcelBox es una gran caja de acero a la que pueden acceder mensajeros, vecinos, etc. para recuperar o entregar artículos de forma segura sin necesidad de ingresar a su hogar. El iParcelBox tiene un solo botón que, cuando se presiona, notificará al propietario que alguien quiere colocar un objeto dentro. El propietario recibirá una notificación push de solicitud "abierta" en su dispositivo móvil, que puede aceptar o rechazar.

El iParcelBox (Crédito de la foto: iparcelbox.com)

Recon

Lo primero que notamos sobre este dispositivo es su simplicidad. En la mentalidad de un atacante, siempre estamos mirando una amplia variedad de vectores de ataque. Este dispositivo solo tiene tres vectores externos: API de nube remota, WIFI y un solo botón físico.

Botón de entrega iParcelBox (Crédito de la foto: iparcelbox.com)

Durante la configuración, iParcelBox crea un punto de acceso WIFI para que la aplicación móvil se conecte y envíe información de configuración. Cada iParcelBox tiene una contraseña WiFi de 16 caracteres generada aleatoriamente que hace que el uso de la clave WPA2 quede fuera de discusión. Además, este punto de acceso solo está disponible cuando iParcelBox está en modo de configuración. El iParcelBox puede colocarse en modo de configuración manteniendo presionado el botón, pero advertirá al propietario mediante una notificación y solo permanecerá en modo de configuración durante unos minutos antes de volver al funcionamiento normal.

Contraseña de punto de acceso WiFi aleatorio iParcelBox (16 caracteres)

Dado que tenemos la contraseña de WiFi para iParcelBox en nuestro laboratorio, nos conectamos al dispositivo para ver qué podemos obtener del servidor web. El dispositivo solo escuchaba en el puerto 443, lo que significa que el tráfico entre la aplicación y iParcelBox probablemente estaba encriptado, lo que luego verificamos. Esto nos indicó la aplicación de Android para tratar de descifrar qué tipo de mensajes se enviaban a iParcelBox durante la configuración.

Escaneo de puertos iParcelBox

Usando dex2jar pudimos desmontar el archivo APK y mirar el código dentro de la aplicación. Notamos rápidamente que iParcelBox estaba usando MQTT (MQ Telemetry Transport) para pasar mensajes de ida y vuelta entre iParcelBox y la nube. MQTT es un protocolo de mensaje de publicación / suscripción donde los dispositivos pueden suscribirse a "temas" y recibir mensajes. Una descripción simple se puede encontrar aquí: (https://youtu.be/EIxdz-2rhLs)

Comando Dex2Jar

El siguiente paso típico es recuperar el firmware del dispositivo, por lo que comenzamos a buscar en el código APK desmontado las URL interesantes. Si bien no encontramos ningún enlace directo de firmware, pudimos encontrar información útil.

Código desmontado extraído de APK

El código recortado arriba muestra algunos puntos interesantes, incluida la cadena "config.iparcelbox.com", así como la línea con "aplicación" y "TBpwkjoU68M". Pensamos que esto podría ser credenciales para un usuario de la aplicación pasado a iParcelBox durante la configuración; sin embargo, volveremos a esto más tarde. La URL no se resolvió en Internet, pero al conectarnos al punto de acceso iParcelBox y al hacer una consulta Dig pudimos ver que se resuelve en iParcelBox.

Búsqueda de DNS de config.iparcelbox.com

Nada de la aplicación de Android o del servidor web en el dispositivo se nos apareció, así que decidimos buscar más a fondo. Una de las formas más comunes en que se puede recopilar información sobre los objetivos es mirando a través de foros de usuarios y viendo si hay otros que intentan modificar y modificar el dispositivo. A menudo con los dispositivos IOT, los foros de automatización del hogar tienen numerosos ejemplos de uso de API, así como scripts de usuario para interactuar con dichos dispositivos. Queríamos ver si había algo así para el iParcelBox. Nuestra búsqueda inicial de iParcelBox quedó vacía, aparte de algunos contenidos de marketing, pero cuando la búsqueda se cambió a la API de iParcelBox, notamos algunas publicaciones interesantes.

Búsqueda de Google para "iparcelbox api"

Podríamos ver que incluso en la primera página hay algunos informes de errores y un par de foros de usuarios para "Mongoose-OS". Después de ir a los foros de Mongoose-OS, pudimos ver claramente que un usuario era parte del equipo de desarrollo de iParcelBox. Esto nos dio una idea de que el dispositivo estaba ejecutando Mongoose-OS en un Junta de desarrollo ESP32, lo cual es importante ya que un dispositivo ESP32 puede actualizarse con muchos otros tipos de código. Comenzamos a rastrear las publicaciones del usuario y pudimos descubrir información extensa sobre el dispositivo y las decisiones de desarrollo durante todo el proceso de construcción. Lo más importante es que esto sirvió como acceso directo a muchas de las técnicas de análisis restantes.

Como se mencionó anteriormente, una alta prioridad es tratar de obtener acceso al firmware del dispositivo extrayéndolo directamente del dispositivo o descargándolo del sitio del proveedor. Tirar del firmware es un poco más tedioso ya que a menudo debes soldar cables al chip flash o quitar el chip por completo para interactuar con el flash. Antes de comenzar a intentar extraer el firmware del ESP32, notamos otra publicación en los foros que mencionaba que la memoria flash del dispositivo estaba encriptada.

Publicación que describe el cifrado flash

Con este conocimiento, omitimos los cables de soldadura al ESP32 y ni siquiera intentamos extraer el firmware manualmente, ya que habría resultado difícil quitarle nada. Esto también nos dio una idea del proceso de aprovisionamiento y cómo se configura cada dispositivo. Con este conocimiento, comenzamos a buscar cómo se descargan las actualizaciones de OTA.

Al buscar un poco más, pudimos encontrar la carga de un archivo de registro grande que contenía lo que parecía el procedimiento de arranque de iParcelBox. Al buscar en el registro encontramos algunos datos altamente confidenciales.

Credenciales de administrador y gh-token del registro de arranque

En el fragmento anterior, puede ver que se pasan las credenciales de administrador y el token de GitHub. No es necesario decir que esta no es una buena práctica, veremos si podemos usar eso más adelante. Pero en este registro, también encontramos una URL de firmware.

URL de firmware del registro de arranque

Sin embargo, la URL requería un nombre de usuario y contraseña.

Firmware.iparcelbox.com .htaccess

Encontramos esta publicación del foro donde se configura ".htaccess" para evitar el acceso no deseado a la descarga del firmware.

.htaccess post

La contraseña de administrador que se encontró anteriormente no se autenticó, por lo que queríamos quitar los registros del dispositivo para ver si se trataba de credenciales antiguas y si podíamos imprimir las nuevas credenciales en UART.

Los componentes internos de iParcelBox (TX y RX resaltados en rojo)

Los pines ESP32 RX y TX se asignan a la conexión USB-C, pero si observa el circuito no hay FTDI (Future Technology Devices International) chip para hacer el procesamiento, por lo que esto es solo serie en bruto. Decidimos simplemente soldar a la vias (Acceso de interconexión vertical) resaltado en rojo arriba, pero aún no se transfirieron datos.

Luego, comenzamos a buscar nuevamente las publicaciones demasiado útiles en el foro, y rápidamente encontramos la razón.

Deshabilitar UART

Esto al menos verificó que no era algo que configuramos incorrectamente, sino que el registro simplemente se deshabilitó a través de UART.

Método # 1 – RPC

Desde nuestro trabajo de reconocimiento, nos basamos en el hecho de que no íbamos a entrar fácilmente en iParcelBox desde un punto de vista físico y decidimos cambiar un enfoque de red. Sabíamos que durante la configuración, iParcelBox crea un AP inalámbrico y que podemos conectarnos a él. Armados con nuestro conocimiento de los foros, decidimos volver a visitar el servidor web en iParcelBox. Comenzamos enviando algunos comandos de control "MOS" (Mongoose-OS) para ver qué se atascaba.

Las instrucciones de configuración para Mongoose-OS se pueden encontrar aquí. En lugar de instalar directamente en el sistema operativo, lo hicimos en Docker para la portabilidad.

Archivo Docker utilizado para crear mos

Hacer referencia a los foros proporcionó varios ejemplos de cómo usar el comando mos.

Docker mos comandos

El primer comando devolvió un mensaje prometedor de que solo necesitamos proporcionar credenciales. ¿Recuerdas cuando encontramos el registro de arranque antes? Sí, las credenciales de administrador se publicaron en línea, ¡y realmente funcionan!

En este punto, teníamos acceso root efectivo completo a iParcelBox, incluido el acceso a todos los archivos, código JavaScript y, lo que es más importante, el certificado AWS y la clave privada.

Con los archivos extraídos del dispositivo, notamos que los desarrolladores de iParcelBox implementaron una Lista de control de acceso (ACL). Para un dispositivo IOT esto es poco común pero es una buena práctica.

ACL que muestra los permisos de los usuarios

Las credenciales que encontramos anteriormente en el APK de Android desmontado con el nombre de usuario "aplicación" eran credenciales RPC pero con permisos limitados para ejecutar solo Sys.GetInfo, Wifi.Scan, Wifi.PortalSave y Sys.Reboot. No se puede hacer nada demasiado interesante con esas credenciales, por lo que para el resto de este método nos quedaremos con las credenciales "admin".

Ahora que tenemos las credenciales, los certificados y las claves privadas, queríamos intentar pasar a otros dispositivos. Durante la configuración, notamos que la dirección MAC estaba etiquetada como "ID de tema".

Proceso de configuración que vincula la dirección MAC al ID de tema

Como determinamos anteriormente, iParcelBox usa MQTT para negociar la comunicación entre el dispositivo, la nube y la aplicación móvil. Estábamos interesados ​​en averiguar si existían barreras de autenticación o si todo lo que necesita es la dirección MAC del dispositivo para iniciar comandos de forma remota.

Dado que esencialmente teníamos acceso raíz, habilitar el registro era el siguiente paso lógico para que pudiéramos ver lo que sucedía en el dispositivo. En una de las publicaciones de los foros de Mongoose-OS vimos que puede habilitar el registro UDP en un dispositivo local cambiando la configuración en iParcelBox.

Cómo habilitar la publicación de registro UDP

Aprovisionamos el iParcelBox, luego mantuvimos presionado el botón hasta que ingresamos al modo de configuración (donde estaba disponible el AP), lo que permitió volver a activar las llamadas RPC. Luego configuramos el "udp_log_addr" en nuestra máquina local.

Volver a habilitar el inicio de sesión en iParcelBox

Ahora tenemos registros y mucha más información. Queríamos probar si podíamos acceder al agente MQTT y modificar otros iParcelBoxes. En los registros pudimos validar que el agente MQTT estaba configurado en AWS IOT y estaba usando el certificado y las claves que obtuvimos anteriormente. Encontramos algunos ejemplos de Python para conectarse al agente de AWS MQTT (https://github.com/aws/aws-iot-device-sdk-python) pero asumió que conoce la ruta completa del tema (por ejemplo, topic_id / command / unlock).

Archivo de registro UDP

Analizando los registros extraídos de UDP, pudimos encontrar el formato para el tema MQTT "sombra / actualización". Sin embargo, al intentar suscribirse con el script de Python, parecía conectarse al agente MQTT, pero nunca pudimos recibir ningún mensaje para enviar o recibir. Nuestra mejor suposición es que se limitó a una suscripción por tema o que nuestro código estaba roto.

Fuimos a buscar otra forma de controlar los dispositivos. Esto nos trajo de vuelta al foro de Mongoose-OS (¿está viendo un patrón aquí?). Encontramos esta publicación explicando que los dispositivos pueden ejecutar comandos RPC sobre MQTT.

RPC sobre MQTT

Esto sería mejor para un atacante que solo el acceso MQTT, ya que proporciona acceso completo al dispositivo, incluidos certificados, claves, archivos de configuración de usuario, contraseñas WIFI y más. También podríamos usar RPC para escribir código personalizado o firmware personalizado en este punto. Encontramos el soporte oficial de Mongoose-OS para esto aquí (https://github.com/mongoose-os-libs/rpc-mqtt), a lo que incluso incluyeron un ejemplo con AWS IOT.

Después de conectarlo al comando "mos", pudimos ejecutar todos los comandos administrativos de RPC en el dispositivo del que extrajimos las teclas, pero también cualquier otro dispositivo del que supiéramos la dirección MAC.

Ejecución de comandos RPC en múltiples dispositivos de laboratorio ATR

Al observar los dos iParcelBox que nos enviaron, las direcciones MAC son solo ligeramente diferentes y sugieren que probablemente se generen de forma incremental.

  • 30AEA4C59D30
  • 30AEA4C59D6C

Teóricamente, con las direcciones MAC incrementales, podríamos haber escrito un script simple para recorrer cada una de las direcciones MAC de iParcelBoxes, encontrar cualquier iParcelBox conectado a Internet y controlarlas o modificarlas de la manera que quisiéramos. Sin embargo, el ataque más común probablemente sería uno más específico, donde el atacante buscaba robar un paquete o incluso las credenciales de WiFi de la casa de la víctima. Un atacante podría hacer un escaneo de red simple para encontrar la dirección MAC del iParcelbox objetivo utilizando una herramienta como "airodump-ng". Luego, después de que el atacante conozca la dirección MAC de destino, podría usar las credenciales de administrador para iniciar un comando "mos" sobre MQTT y ejecutar un comando "GPIO.Toggle" dirigido al pin GPIO (Entrada de Salida de Propósito General) que controla el bloqueo mecanismo en el iParcelBox. Una palanca invertirá el estado, por lo que si iParcelBox está bloqueado, una palanca GPIO desbloqueará la caja. Si el atacante tenía otros motivos, también podría iniciar un volcado de configuración para obtener acceso a las credenciales de WiFi a las que está conectado el iParcelBox.

Escaneo de iParcelBoxes y control de ellos con RPC

Método # 2 – Configuración incorrecta de AWS

Mientras escribíamos este blog, queríamos verificar que el anclaje SSL se haya realizado correctamente. Después de ver esta publicación durante nuestro reconocimiento, asumimos que estaba fijando un certificado. Configuramos un Android con un desanclador de certificado usando Frida. Con el desanclador instalado y funcionando, pudimos descifrar el tráfico entre la aplicación y los servidores de AWS, pero no pudo descifrar los datos de la aplicación al iParcelBox. Siga esta técnica si desea aprender cómo desanclar certificados en dispositivos Android.

A continuación, volvemos a ejecutar la aplicación iParcelBox sin Frida SSL Unpinner, que devolvió las mismas transacciones del servidor AWS, lo que significa que la fijación no estaba habilitada. Examinamos algunas de las capturas y encontramos algunas solicitudes interesantes.

Cognito Credential SSL Network Capture

Las "credenciales" en la captura despertaron de inmediato nuestro interés. Son devueltos por un servicio llamado "Cognito", que es un servicio de AWS que permite que las aplicaciones y los usuarios accedan a los recursos dentro del ecosistema de AWS por períodos cortos de tiempo y con acceso limitado a recursos privados.

Ejemplo de AWS Cognito (Crédito de la foto: Amazon.com)

Cuando una aplicación quiere acceder a un servicio de AWS, puede solicitar credenciales temporales para la tarea específica. Si los permisos están configurados correctamente, las credenciales emitidas por el servicio Cognito permitirán que la aplicación o el usuario completen esa tarea y denieguen todos los demás usos de las credenciales a otros servicios.

Para usar estas credenciales, necesitábamos la interfaz AWS-CLI. Afortunadamente, Amazon incluso tiene una imagen Docker para AWS-CLI que nos facilitó mucho las cosas. Acabamos de guardar las credenciales devueltas del servicio Cognito dentro de una carpeta "~ / .aws". Luego verificamos qué papel se les dio a estas credenciales.

Comando acoplable AWS-CLI

Las credenciales capturadas de la aplicación de Android recibieron la "AppAuth_Role". Para averiguar a qué tenía acceso el "AppAuth_Role", ejecutamos una enumeración de servicios en la nube utilizando las credenciales; los scripts se pueden encontrar aquí (https://github.com/NotSoSecure/cloud-service-enum) y son proporcionados por el equipo de NotSoSecure. El script de AWS no encontró ningún agujero de seguridad significativo y mostró que las credenciales estaban protegidas correctamente. Sin embargo, al observar las siguientes capturas de red, notamos que estas credenciales se estaban utilizando para acceder a la base de datos DynamoDB.

Comprobando si el usuario está suscrito al servicio Premium

Obtener los dispositivos del propietario

Después de leer parte de la documentación de DynamoDB, pudimos crear consultas en la base de datos.

DynamoDB Query

Debido a que la "clave principal" para la base de datos es el "DeviceID", que sabemos que es solo la dirección MAC de iParcelBox, podemos modificar esta consulta y obtener las entradas de la base de datos de cualquier otro dispositivo. Si bien no lo probamos por razones éticas, sospechamos que podríamos haber utilizado esta información para obtener acceso a los servicios MQTT. Tampoco intentamos escribir en la base de datos, ya que esta era una base de datos de producción en vivo y no queríamos corromper ningún dato.

Investigamos la aplicación de Android que intentaba desencadenar algunas interacciones más en la base de datos para ver qué otras consultas se enviaban, pero se limitaron a lo siguiente:

  • Cuentas: muestra información de suscripción premium
  • Propietarios: muestra los dispositivos e invitados de cada iParcelBox
  • Usuarios: se usa para salvar a los propietarios de cada iParcelBox (solo durante la configuración)

Con nuestras restricciones de escritura de base de datos autoimpuestas, ninguna de estas tablas realmente nos ayudó de todos modos. Fue entonces cuando comenzamos a mirar el código desmontado de la aplicación de Android para obtener más pistas. Como ahora conocíamos los nombres de las tablas, buscamos "ClientID", que mostró el archivo Java "DBConstants.class".

Archivo de constantes de APK

Este archivo de constantes nos dio información de que hay más tablas y campos de bases de datos, a pesar de que nunca los vimos en el tráfico de la red. La "TABLE_DEVICES_PASSWORD" nos llamó la atención de la tabla "iParcelBox_devices".

También probamos las credenciales "AppAuth_Role" en esta tabla, lo cual fue aceptado.

Solicitar información de la tabla iParcelBox_devices

Pudimos obtener la contraseña del dispositivo y el número de serie de la dirección MAC. Recuerde la imagen de "Información de configuración de iParcelBox" al comienzo del blog y cómo menciona que debe mantener esta información segura. La razón por la que esta información debe mantenerse segura es que puede convertirse en el propietario de iParcelBox si conoce la dirección MAC, el número de serie y la contraseña, incluso sin el código QR, gracias al botón "Agregar manualmente".

Opción "Agregar manualmente" durante la configuración

Con esta información, un atacante podría registrarse para una nueva cuenta iParcelBox, iniciar sesión en la aplicación, capturar las credenciales de Cognito, comenzar el proceso de "configuración", hacer clic en "Agregar manualmente" y luego ingresar toda la información requerida devuelta desde la base de datos para obtener el control total sobre cualquier iParcelBox. Todo esto podría tener lugar simplemente conociendo la dirección MAC, ya que "AppAuth_Role" puede leer cualquier entrada de la base de datos.

Información requerida para configurar iParcelBox

Lecciones aprendidas

Este proyecto pasó de un proyecto clásico de investigación de hardware / dispositivo IOT a un tema de investigación de OSINT desde el principio. Realmente demuestra que incluso los errores simples con la higiene de datos en línea podrían exponer detalles clave a los atacantes, lo que les permite reducir los vectores de ataque o exponer información confidencial como credenciales.

Como se trataba de un proyecto patrocinado por iParcelBox, informamos esto a la compañía de inmediato. Rápidamente cambiaron la contraseña de administrador para cada iParcelBox y pidieron a los desarrolladores de Mongoose-OS que implementen un cambio donde el certificado AWS y la clave privada de un dispositivo no puedan controlar ningún otro dispositivo. Esto se parchó dentro de las 12 horas posteriores a la divulgación de nuestro proveedor, lo que coloca a iParcelBox en el mejor tiempo de respuesta para un parche que hemos visto. Hemos probado el parche y ya no podemos controlar otros dispositivos o usar la contraseña de administrador anterior para acceder a los dispositivos desde el modo de configuración.

iParcelBox también corrigió la aplicación de Android que no fijaba los certificados correctamente y eliminó todas las llamadas directas a DynamoDB. Todavía pudimos descifrar parte del tráfico con el desanclador SSL de Frida, pero la aplicación se bloqueó, lo que creemos se debe a que el agente MQTT no acepta un certificado personalizado. Las consultas de DynamoDB ahora están envueltas en llamadas API que también se comparan con la ID del cliente. Esto evita que alguien use sus credenciales Cognito extraídas para obtener información de cualquier dispositivo que no sea el suyo. Ajustar las consultas de la base de datos dentro de las llamadas API también es una solución de seguridad efectiva, ya que los datos se pueden analizar, verificar y desinfectar antes de comprometerse con la base de datos.

Queríamos dar un apoyo al equipo de iParcelBox por su enfoque en la seguridad durante el desarrollo de este producto. Es fácil ver desde el dispositivo y las publicaciones del foro que los desarrolladores han estado tratando de asegurar este dispositivo desde el principio y lo han hecho bien. Todas las funciones no esenciales como UART y Bluetooth están desactivadas de forma predeterminada y el enfoque en la protección de datos está claramente presente, como lo demuestra el uso de SSL y el cifrado de la memoria flash. No hay muchas superficies de ataque que un atacante pueda aprovechar del dispositivo y es un gran refresco ver que los dispositivos IOT se dirigen en esta dirección.





Enlace a la noticia original