- Rabbit R1 es un dispositivo basado en una app que se ejecuta como en modo kiosk sobre Android 13 AOSP, y se implementó un jailbreak tethered que obtiene una shell root sin desbloquear el bootloader ni modificar el almacenamiento interno
- El jailbreak deja pasar tal cual la verificación de la cadena de arranque de MediaTek y, justo antes de que la imagen
boot verificada se use realmente, la reemplaza en memoria por una imagen personalizada cargada por USB
- El R1 usa MediaTek MT6765, 4 GB de DRAM y 128 GB de eMMC, y fue posible acceder como
uid=0(root) mediante una TCP bind shell incluso con ro.boot.verifiedbootstate en estado green
- En los logs del almacenamiento interno quedaron ubicación GPS, nombres de WiFi, IDs de torres celulares cercanas, IP externa, tokens de usuario para la API del backend de Rabbit, además de MP3 de voz de Rabbit y sus transcripciones; en RabbitOS v0.8.112 se redujo el logging y se agregó una opción de restablecimiento de fábrica
- Rabbit Inc. no publicó el código fuente de los drivers del scroll wheel de efecto Hall ni del motor de la cámara giratoria, enlazados estáticamente al kernel de Linux, por lo que está en situación de violación de GPL2; al 22 de julio no había respondido las consultas relacionadas
Punto de partida del análisis de Rabbit R1
- Rabbit R1 recibió evaluaciones negativas de los críticos, y en el mercado de segunda mano se venden unidades sin abrir por debajo de su precio de lista de 200 dólares
- RabbitOS no es un modelo local de IA separado, sino una app que se ejecuta como en modo kiosk sobre Android 13 AOSP, y se comunica con la nube mediante una API JSON sobre WebSocket
- Se informó que las claves de API expuestas anteriormente se filtraron desde el código fuente del lado del servidor y no estaban almacenadas dentro del dispositivo
- En actualizaciones posteriores de la app se aplicó una herramienta comercial de ofuscación, además de lógica para detectar herramientas de análisis como Magisk y Frida, y para verificar si el dispositivo era un R1
- Como el análisis estático se volvió engorroso, se compró un R1 en eBay por £122 y se realizó análisis en tiempo de ejecución manteniendo el firmware de fábrica lo más intacto posible
Hardware del R1 y estado básico de seguridad
- El R1 usa un SoC MediaTek MT6765, 4 GB de DRAM y 128 GB de almacenamiento eMMC
- Para el MT6765 existe
kamakiri, un exploit de bootrom conocido desde 2019
- Los 128 GB de almacenamiento parecen una elección inusual dada la naturaleza de un dispositivo que no guarda muchos datos localmente
- Dueños del R1 confirmaron que con
mtkclient podían desbloquear el bootloader y flashear una ROM personalizada o rootear el dispositivo
- El objetivo del análisis no era cargar una imagen personalizada del sistema Android, sino examinar el firmware instalado de fábrica manteniéndolo lo más intacto posible
- El método de desbloquear el bootloader e instalar Magisk tiene varios problemas
- Puede romper las actualizaciones OTA delta
- Puede ser detectado por el código actual que dificulta el análisis
- Si una actualización futura comprueba valores como
ro.boot.verifiedbootstate, podría ser detectado
- Por eso hacía falta obtener privilegios root locales reduciendo los puntos de modificación y minimizando la superficie que la lógica anti-análisis pudiera detectar
Cadena de arranque basada en MediaTek
- La cadena de arranque está compuesta por la lógica de MediaTek, y su punto inicial es la bootrom fija en el silicio de la CPU
- La bootrom, tras inicializar el hardware básico, carga el
Preloader desde la partición eMMC boot0 hacia la SRAM
- El Preloader está firmado y la bootrom verifica la firma
- Sin embargo, en el R1 es posible que en la práctica no lo verifique, por lo que hace falta confirmación adicional
- El Preloader inicializa la DRAM y carga tres imágenes desde la partición GPT de la eMMC hacia la DRAM
tee: Arm Trusted Firmware, EL3
gz: GenieZone Hypervisor, EL2
lk: Little Kernel, EL1
- LK implementa Android Verified Boot 2.0 y
dm-verity
- Si el bootloader está bloqueado, rechaza el arranque cuando falla la verificación
- Si está desbloqueado, muestra una advertencia y establece flags relacionadas con el estado orange
- Si falla la verificación de
dm-verity, no arranca aunque el bootloader esté desbloqueado
- Si la verificación pasa, LK descomprime y arranca el kernel de Linux, y el kernel ejecuta
/init desde initramfs
- El R1 usa particionado A/B, por lo que
boot es boot_a o boot_b según el slot activo
- El estado locked/unlocked del bootloader se almacena en la partición GPT
seccfg
seccfg consiste en algunos flags y un hash cifrado
- El último byte de la partición
frp participa en si se permite o no desbloquear el bootloader con comandos como fastboot flashing unlock
carroot: un jailbreak tethered que no toca el almacenamiento
- La root of trust de la cadena de confianza es el hash del certificado incluido en los efuse de la CPU y el código de la bootrom que lo verifica
- El MT6765 tiene el exploit de bootrom
kamakiri, pero en el R1, incluso sin exploit, el brom y el USB bootloader mode del Preloader aceptan imágenes DA sin firma y las ejecutan en memoria
- Se creó un payload DA propio para que el Preloader lo cargara en DRAM
- El flujo de operación es el siguiente
- Se carga por USB una imagen Android
boot personalizada en la DRAM
- Se instala un hook justo antes de que el Preloader salte a LK
- Se regresa al Preloader y continúa el proceso normal de arranque
- El Preloader carga y verifica desde la eMMC las imágenes
tee, gz y lk
- Justo antes de entrar a LK se ejecuta el hook, que instala hooks y parches adicionales dentro de LK
- LK carga y verifica la partición
boot original de la eMMC
- En el momento en que la imagen
boot se copia desde el código AVB hacia el código de arranque de Linux, el hook la reemplaza por la imagen boot personalizada cargada por USB
- También se muestra un mensaje personalizado en pantalla
- La clave es dejar que los datos sujetos a verificación se verifiquen tal cual, y reemplazar los datos parcheados después de la verificación, justo antes de usarlos
- El almacenamiento flash no se modifica en absoluto, y todo el proceso de jailbreak ocurre únicamente en memoria
- Al reiniciar, el dispositivo vuelve a un estado limpio
- Es fácil volver al estado original durante el proceso de ingeniería inversa
- La imagen
boot personalizada usa flashable-android-rootkit
- Reemplaza el binario
/init predeterminado para inyectar el payload como un servicio de espacio de usuario con máximos privilegios
- La herramienta de parcheo de imágenes
magiskboot se tomó del proyecto Magisk
- Para compilar y ejecutar
magiskboot en Linux común se usó magiskboot_build
- El payload es una TCP bind shell simple
- No es un método sigiloso, y la app de Rabbit podría detectarlo
- Puede mejorarse más adelante si hace falta
Herramienta de jailbreak basada en WebSerial y resultados de ejecución
- Para manipular dispositivos MediaTek, mtkclient ya ofrece las funciones necesarias, pero se escribió un cliente USB en Python para entender el funcionamiento
- Luego se portó a js/WebSerial para permitir hacer jailbreak a un Rabbit R1 conectado físicamente desde una página web
- El jailbreak recibió el nombre carroot, en referencia al juego de palabras con rabbit
- La herramienta experimental está publicada en r1_jailbreak
- Tras el arranque, el resultado de conectarse a la TCP bind shell fue el siguiente
$ rlwrap nc 192.168.0.69 1337
# id
uid=0(root) gid=0(root) groups=0(root) context=u:r:rootkit:s0
# getprop ro.boot.verifiedbootstate
green
- El sistema reconocía el estado de secure boot como
green y aun así permitía acceder a una root shell
- El SELinux domain
rootkit lo configura flashable-android-rootkit
Interfaces del dispositivo usadas en el análisis y material de referencia
- En las fotos del desmontaje de iFixit del R1 se ven test pads marcados como TX y RX, que corresponden a test pads UART
- UART proporciona logs de depuración durante toda la cadena de arranque
- La etapa brom usa 115200 baudios
- Las etapas posteriores usan 921600 baudios
- El nivel lógico es de 1.8 V, y en el dispositivo analizado también funcionó con 3.3 V sin daños
- El Preloader desactiva el UART logging si no se mantiene presionada la tecla volume-up
- El R1 no tiene tecla volume-up, por lo que se parcheó el Preloader para desactivar esta comprobación
- El Preloader parcheado puede arrancarse mediante el USB download mode de la bootrom
- En la command line del kernel de Linux se parchearon las siguientes flags para imprimir logs del kernel por UART
earlycon console=ttyS1,921600
- Con esta combinación de parches se recopiló el log UART de todo el proceso de arranque
- Si el test pad junto al botón de reset, accesible a través de la ranura SIM, se lleva a GND durante el reset, se puede arrancar en brom USB mode
- Los principales materiales de referencia son los siguientes
Datos personales encontrados en los logs internos
- El R1 dejaba logs de texto por fecha en
Android/data/tech.rabbit.r1launcher.r1/files/logs/ dentro del almacenamiento interno
- Al 7 de julio de 2024, el directorio de logs contenía archivos
.log de varias fechas, y algunos medían varios MB
- Los logs incluían los siguientes datos
- Ubicación GPS precisa
- Nombre de redes WiFi
- IDs de torres celulares cercanas recopilados incluso sin tarjeta SIM
- Dirección IP expuesta a Internet
- Tokens de usuario usados para autenticarse contra la API del backend de Rabbit
- MP3 codificados en Base64 de todo lo que Rabbit le dijo al usuario y sus transcripciones de texto
- De estos datos, la ubicación GPS y los IDs de torres cercanas también se enviaban a los servidores de Rabbit
- Había dos problemas
- Se registraban datos excesivamente detallados en un dispositivo sin seguridad de hardware significativa
- Como el usuario común no tenía forma de hacer un restablecimiento de fábrica, los logs quedaban en la práctica de forma permanente
- En un contexto de compraventa activa de segunda mano, al vender, donar o desechar un dispositivo podían quedar logs del usuario anterior
- RabbitOS v0.8.112 redujo el logging y agregó una opción de restablecimiento de fábrica en la configuración mediante un aviso de seguridad
- La respuesta fue rápida y se considera el primer caso en que Rabbit abordó de manera relativamente proactiva problemas de privacidad y seguridad de los usuarios
Alcance real de la personalización de AOSP
- Ante reportes que describían RabbitOS como una simple app, Rabbit explicó que se trataba de un AOSP muy personalizado con “lower level firmware modifications”
- Las personalizaciones confirmadas hasta ahora consisten principalmente en eliminar funciones de Android para mantener el modo kiosk de una sola app
- Sin barra de navegación
- Sin barra de notificaciones
- Medidas para intentar impedir la activación de ADB
- Una app llamada
Judy se ejecuta en segundo plano y desactiva ADB si está en ejecución
- El 4 de julio, @MarcelD505 publicó un método de kiosk escape que partía del navegador de login de captive portal de WiFi y llegaba a la app de system settings de Android
- En la actualización más reciente, Rabbit bloqueó esa ruta eliminando por completo del dispositivo la app de system settings de Android
- Hasta ahora, los cambios bespoke confirmados en AOSP parecen orientados a eliminar funciones más que a agregar capacidades existentes
- Todavía no se ha confirmado una razón técnica por la que la implementación actual de RabbitOS no pudiera existir como una app normal de smartphone
Lo que debería preocuparle a un usuario común del R1
- Si preocupa la posibilidad de que el dispositivo haya sido jailbreakeado sin querer, basta con apagarlo y encenderlo
- Si arranca normalmente sin mensaje de advertencia, en general podría ser seguro
- Sin embargo, si brom está configurado para arrancar desde la eMMC una imagen de Preloader sin firma, no es seguro y hacen falta pruebas adicionales
- Sería mejor poder reflashearlo con una imagen de stock firmware confiable proporcionada por el proveedor, pero Rabbit no ofrece ese medio
- Si se deja un R1 unattended, una persona con los conocimientos adecuados puede extraer fácilmente los datos almacenados en el dispositivo
- Antes de venderlo, donarlo o desecharlo, se debe hacer primero un restablecimiento de fábrica con la nueva opción agregada en la configuración
Violación de GPL y conclusión
- Salvo por el scroll wheel y la cámara giratoria, el Rabbit R1 se parece a un dispositivo Android MediaTek común, no a hardware especializado
- La personalización de AOSP en su mayoría elimina funciones existentes para imponer el modo kiosk de una sola app
- La seguridad de la cadena de arranque no es efectiva, por lo que es difícil dejar el dispositivo sin supervisión de forma segura
- Rabbit Inc. está violando la licencia GPL2 del kernel de Linux
- El driver de detección del scroll wheel de efecto Hall sigue siendo closed-source
- El driver de control del stepper motor de rotación de la cámara también sigue siendo closed-source
- Ambos drivers están enlazados estáticamente a la imagen del kernel GPL
- El 12 de julio se pidió a Rabbit Inc. un comentario sobre el texto y sus planes para cumplir la GPL, pero al 22 de julio no había respuesta
- La herramienta de jailbreak tethered publicada es una herramienta experimental pensada para ayudar a investigadores a acceder a sus propios R1 y, en el futuro, a usuarios avanzados a ampliar las funciones del dispositivo
1 comentarios
Opiniones de Hacker News
La GPL exige publicar la licencia y el código fuente cuando se soliciten, pero Truth Social ni siquiera publicó la licencia hasta que se reveló que usaba código AGPL; recién entonces liberó el código fuente.
Me pregunto si Rabbit se saldrá con la suya de la misma manera.
En la práctica no se pueden rastrear infracciones que el titular de derechos no conoce y, por lo general, interesa más hacer que el infractor cumpla que cobrar daños.
https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Yo pensaba que los módulos del kernel tenían una excepción GPL del lado de Linux, independientemente del tipo de enlace, siempre que no requirieran modificar el kernel en sí.
El contenido de estos logs es bastante sucio: incluyen ubicación GPS exacta, nombres de redes WiFi, IDs de antenas celulares cercanas aunque no haya tarjeta SIM, dirección IP expuesta al exterior, token de usuario para autenticar contra la API de backend de Rabbit, e incluso MP3 codificados en Base64 de todo lo que Rabbit le dijo al usuario, junto con transcripciones en texto.
No sorprende que un dispositivo diseñado para responder preguntas como “¿qué buen restaurante hay cerca?” envíe contexto de ubicación junto con la solicitud, pero si transmite la ubicación continuamente sin motivo, eso sí sería preocupante.
Los nombres de WiFi deben guardarse para reconectarse, y tampoco es especialmente raro ver direcciones IP en logs locales.
El token de acceso del usuario también tiene que almacenarse en el dispositivo si se quiere reconectar sin iniciar sesión cada vez. Dicho eso, dejar el token tal cual en los logs es una mala práctica, y si los logs están en el mismo almacenamiento que esa base de datos o archivo de configuración, eso por sí solo no es un problema completamente nuevo. Si los logs se suben directamente al servidor, entonces obviamente sí es un problema.
Si querías que un dispositivo así funcionara de forma fluida y casi mágica, tiene que estar escuchando, viendo y enviando ubicación todo el tiempo. En realidad, para que esto funcione bien se necesita inferencia local, y no sé por qué alguien pagaría por algo que Apple probablemente hará mucho mejor dentro de 5 años, pero si vas a comprarlo, esta es la forma en que tendría que funcionar.
No puedes odiar a las megacorporaciones y al mismo tiempo esperar que una startup haga un buen producto sin datos. Si Rabbit quiere siquiera tener la posibilidad de construir algo mejor en el futuro, necesita estos datos.
Si vas a decir que eso te incomoda, hay que explicar específicamente por qué. La mayor parte no es, por sí misma, algo de lo que preocuparse demasiado.
Qué risa. Trabajé en Rabbit, leí la base de código, me hicieron gaslighting los ejecutivos y luego renuncié.
Solo viendo desde fuera el jailbreak y las vulnerabilidades, parece que eso debe ser apenas la punta del iceberg.
Supongo que Rabbit no respondió porque sus abogados están evaluando cómo demandar.
Prácticamente no les dieron horas hábiles reales para responder.
Los desarrolladores de RabbitOS pueden parchear este problema configurando el eFuse para bloquear el acceso al bootloader vía USB.
Moto hizo lo mismo hace unos años cuando sus dispositivos MediaTek eran vulnerables a la misma superficie de ataque en la boot ROM. Si no recuerdo mal, ese eFuse se configuraba en la etapa LK y se aplicaba mediante una actualización de firmware OTA normal.
El artículo está genial.
El software parece basura, y hasta ahora la empresa tampoco se ve muy bien.
Aun así, si fuera fácil correr apps personalizadas aunque sea en modo kiosco, este form factor podría tener usos bastante interesantes.
Si se le pudiera montar una PWA de forma más o menos rápida, sería mucho más veloz que armar algo uno mismo con un ESP32, batería y pantalla, y parece un dispositivo todo en uno bastante decente.
Idealmente sería bueno poder ejecutarlo de forma más segura sin servicios de Google, y algo en la línea de GrapheneOS estaría bien.
Todavía no lo he buscado, pero me pregunto si hay casos de uso o materiales de referencia para usarlo de esta forma con apps personalizadas de propósito único.
Si el precio baja a menos de 50 dólares, por ejemplo después de que apaguen los servidores, entonces sí podría estar de acuerdo en que es una buena plataforma de hardware.
Es una lástima; me habría gustado que este producto saliera bien.
Espero que no quede como un dolor de cabeza para futuros experimentos de interfaces de usuario de hardware + IA. Sigo simpatizando con la idea al estilo Bret Victor de que podemos hacerlo mejor que tocar y deslizar sobre un rectángulo de vidrio.
Incluso, de forma más cómoda, un smartwatch podría reenviar las consultas al teléfono.
Aunque Humane no parece haber resuelto un problema real, al menos le doy cierto crédito por haber intentado algo genuinamente distinto. El Rabbit R1 es simplemente chatarra barata.
Es un poco gracioso que toda, o la mayor parte, de la buena impresión inicial hacia Rabbit se debiera al diseño de Teenage Engineering.
Ojalá TE elija mejor a sus clientes en el futuro. La persona detrás de Rabbit es un estafador conocido.
Podría buscar el nombre, pero la calidad de las búsquedas hoy está tan mala que no pienso hacerlo. Sería útil tener un enlace que muestre la crítica con más detalle.
Esto es como el Juicero de los asistentes de IA.
El problema era que pensaron que la gente pagaría una cantidad absurda por una máquina que exprimía bolsas de mezclas de fruta precortada propietarias de la empresa. Todo funcionaba exactamente como estaba previsto; el modelo de negocio real era lo absurdo.
Esperaba un asistente de IA de código abierto que preservara la privacidad, algo como una combinación de Mycroft(https://en.wikipedia.org/wiki/Mycroft_(software)) y Leon(https://getleon.ai).