- Le Rabbit R1 est un appareil basé sur une application exécutée comme en mode kiosk sur Android 13 AOSP, et un jailbreak tethered permettant d’obtenir un shell root a été réalisé sans déverrouiller le bootloader ni modifier le stockage interne
- Le jailbreak laisse la chaîne de démarrage MediaTek passer les vérifications normalement, puis remplace en mémoire, juste avant son utilisation réelle, l’image personnalisée envoyée par USB à la place de l’image
boot vérifiée
- Le R1 utilise un MediaTek MT6765, 4 Go de DRAM et 128 Go d’eMMC ; même avec
ro.boot.verifiedbootstate à green, un accès uid=0(root) était possible via un TCP bind shell
- Les journaux du stockage interne contenaient la position GPS, le nom du WiFi, les identifiants des antennes relais environnantes, l’IP externe, des tokens utilisateur pour l’API backend de Rabbit, ainsi que les MP3 vocaux Rabbit et leurs transcriptions ; RabbitOS v0.8.112 a réduit la journalisation et ajouté une option de réinitialisation d’usine
- Rabbit Inc. n’a pas publié le code source des pilotes du scroll wheel à effet Hall et du moteur de rotation de la caméra, liés statiquement au noyau Linux, ce qui constitue une violation de la GPL2 ; au 22 juillet, l’entreprise n’avait pas répondu aux questions à ce sujet
Point de départ de l’analyse du Rabbit R1
- Le Rabbit R1 a reçu des critiques négatives, et des unités neuves sous blister se vendent sur le marché de l’occasion à un prix inférieur au tarif officiel de 200 dollars
- RabbitOS n’est pas un modèle d’IA local distinct, mais une application exécutée comme en mode kiosk sur Android 13 AOSP, qui communique avec le cloud via une API JSON au-dessus de WebSocket
- Les clés d’API exposées signalées précédemment auraient fuité depuis le code source côté serveur, et n’étaient pas stockées dans l’appareil
- Les mises à jour ultérieures de l’application ont intégré un outil commercial d’obfuscation, ainsi qu’une détection d’outils d’analyse comme Magisk et Frida et une logique de vérification visant à confirmer que l’appareil est bien un R1
- L’analyse statique étant devenue plus fastidieuse, un R1 a été acheté sur eBay pour 122 £, puis une analyse à l’exécution a été menée en conservant autant que possible le firmware d’usine intact
Matériel du R1 et état de sécurité de base
- Le R1 utilise un SoC MediaTek MT6765, 4 Go de DRAM et 128 Go de stockage eMMC
- Le MT6765 est concerné par
kamakiri, un exploit de bootrom connu depuis 2019
- Les 128 Go de stockage semblent être un choix inhabituel pour un appareil qui, par nature, ne conserve pas beaucoup de données locales
- Des propriétaires de R1 ont confirmé qu’il était possible d’utiliser
mtkclient pour déverrouiller le bootloader et flasher une ROM custom ou obtenir le root
- L’objectif de l’analyse n’était pas d’installer une image système Android custom, mais d’examiner l’appareil en conservant autant que possible le firmware installé en usine
- La méthode consistant à déverrouiller le bootloader et installer Magisk pose plusieurs problèmes
- Les mises à jour OTA delta peuvent être cassées
- Le code actuel anti-analyse peut la détecter
- De futures mises à jour pourraient la détecter si elles vérifient des valeurs comme
ro.boot.verifiedbootstate
- Il fallait donc obtenir des droits root locaux en réduisant les points de modification afin de minimiser la surface détectable par la logique anti-analyse
Chaîne de démarrage basée sur MediaTek
- La chaîne de démarrage est constituée de la logique MediaTek, et son point de départ est la bootrom gravée dans le silicium du CPU
- La bootrom initialise le matériel de base, puis charge le
Preloader depuis la partition eMMC boot0 vers la SRAM
- Le Preloader est signé et la bootrom vérifie sa signature
- Toutefois, sur le R1, il est possible qu’il ne soit pas réellement vérifié ; une confirmation supplémentaire est nécessaire
- Le Preloader initialise la DRAM et charge trois images depuis les partitions GPT de l’eMMC vers la DRAM
tee : Arm Trusted Firmware, EL3
gz : GenieZone Hypervisor, EL2
lk : Little Kernel, EL1
- LK implémente Android Verified Boot 2.0 et
dm-verity
- Si le bootloader est locked, l’appareil refuse de démarrer en cas d’échec de vérification
- S’il est unlocked, il affiche un avertissement et définit des flags liés à l’orange state
- Si la vérification
dm-verity échoue, le démarrage ne se fait pas même si le bootloader est unlocked
- Une fois la vérification réussie, LK décompresse et démarre le noyau Linux, puis le noyau exécute
/init depuis l’initramfs
- Le R1 utilise un partitionnement A/B ; selon le slot actif,
boot correspond donc à boot_a ou boot_b
- L’état locked/unlocked du bootloader est stocké dans la partition GPT
seccfg
seccfg est constitué de quelques flags et d’un hash chiffré
- Le dernier octet de la partition
frp intervient dans l’autorisation de déverrouillage du bootloader, par exemple via fastboot flashing unlock
carroot : un jailbreak tethered qui ne touche pas au stockage
- La root of trust de la chaîne de confiance est le hash du certificat inscrit dans les efuses du CPU, ainsi que le code de la bootrom qui le vérifie
- Le MT6765 dispose de l’exploit de bootrom
kamakiri, mais sur le R1, même sans exploit, le mode USB bootloader de la brom et du Preloader accepte des images DA non signées et les exécute en mémoire
- Un payload DA maison a été créé afin que le Preloader le charge en DRAM
- Le déroulé est le suivant
- Une image Android
boot personnalisée est chargée en DRAM par USB
- Un hook est installé juste avant que le Preloader ne saute vers LK
- Le flux revient au Preloader et le processus de démarrage normal se poursuit
- Le Preloader charge et vérifie les images
tee, gz et lk depuis l’eMMC
- Juste avant l’entrée dans LK, le hook s’exécute et installe des hooks et patches supplémentaires dans LK
- LK charge et vérifie la partition
boot d’origine de l’eMMC
- Au moment où l’image
boot est copiée depuis le code AVB vers le code de démarrage Linux, le hook la remplace par l’image boot personnalisée envoyée par USB
- Un message personnalisé est également affiché à l’écran
- Le point clé est de laisser les données soumises à vérification être vérifiées telles quelles, puis de remplacer les données patchées après la vérification, juste avant leur utilisation
- Le stockage flash n’est jamais modifié ; tout le processus de jailbreak se déroule uniquement en mémoire
- Après un redémarrage, l’appareil revient à un état propre
- Cela facilite le retour à l’état initial pendant la rétro-ingénierie
- L’image
boot personnalisée utilise flashable-android-rootkit
- Elle remplace le binaire
/init par défaut afin d’injecter le payload sous forme de service en espace utilisateur avec les privilèges maximaux
- L’outil de patch d’image
magiskboot provient du projet Magisk
- magiskboot_build est utilisé pour compiler et exécuter
magiskboot sur Linux classique
- Le payload est un simple TCP bind shell
- Il n’est pas furtif et pourrait être détecté par l’application Rabbit
- Il pourra être amélioré par la suite si nécessaire
Outil de jailbreak basé sur WebSerial et résultats d’exécution
- Pour manipuler des appareils MediaTek, mtkclient fournit déjà les fonctionnalités nécessaires, mais un client USB Python a été écrit directement afin de mieux comprendre le fonctionnement
- Il a ensuite été porté en js/WebSerial, afin de pouvoir jailbreaker un Rabbit R1 physiquement connecté depuis une page web
- Le jailbreak a été nommé carroot, en référence au jeu de mots avec rabbit
- L’outil expérimental est disponible sur r1_jailbreak
- Après le démarrage, la connexion via TCP bind shell a donné le résultat suivant
$ 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
- Le système considérait l’état de secure boot comme
green, tout en autorisant l’accès à un shell root
- Le domaine SELinux
rootkit est défini par flashable-android-rootkit
Interfaces de l’appareil utilisées pour l’analyse et ressources de référence
- Les photos de démontage iFixit du R1 montrent des test pads marqués TX et RX, qui sont des test pads UART
- L’UART fournit des journaux de debug tout au long de la chaîne de démarrage
- Étape brom : 115200 bauds
- Étapes suivantes : 921600 bauds
- Le niveau logique est de 1,8 V ; sur l’appareil analysé, le 3,3 V a aussi fonctionné sans dommage
- Le Preloader désactive l’UART logging si la touche volume-up n’est pas maintenue
- Le R1 n’ayant pas de touche volume-up, le Preloader a été patché pour désactiver cette vérification
- Le Preloader patché peut être démarré via le mode USB download de la bootrom
- Les flags suivants ont été patchés dans la command line du noyau Linux afin de sortir les journaux du noyau sur UART
earlycon console=ttyS1,921600
- Cette combinaison de patches a permis de collecter les journaux UART de l’ensemble du processus de démarrage
- En tirant vers GND, pendant un reset, le test pad situé près du bouton de reset accessible via le logement SIM, il est possible de démarrer en mode USB brom
- Les principales ressources de référence sont les suivantes
Données personnelles découvertes dans les journaux internes
- Le R1 conservait des journaux texte par date sous
Android/data/tech.rabbit.r1launcher.r1/files/logs/ dans le stockage interne
- Au 7 juillet 2024, le répertoire de logs contenait des fichiers
.log couvrant plusieurs dates, dont certains faisaient plusieurs Mo
- Les journaux incluaient les données suivantes
- La position GPS précise
- Le nom du réseau WiFi
- Les identifiants des antennes relais environnantes, collectés même sans carte SIM
- L’adresse IP exposée à Internet
- Des tokens utilisateur utilisés pour l’authentification à l’API backend de Rabbit
- Les MP3 encodés en Base64 de tout ce que Rabbit avait dit à l’utilisateur, ainsi que les transcriptions texte
- Parmi ces données, la position GPS et les identifiants des antennes relais étaient également envoyés aux serveurs de Rabbit
- Le problème était double
- Une journalisation de données excessivement détaillées sur un appareil dépourvu de sécurité matérielle significative
- L’absence de méthode de réinitialisation d’usine accessible aux utilisateurs ordinaires, rendant les logs quasiment permanents
- Dans un contexte de revente active, les logs de l’utilisateur précédent pouvaient rester présents lors d’une vente, d’un don ou d’une mise au rebut
- RabbitOS v0.8.112 a réduit la journalisation et ajouté une option de réinitialisation d’usine dans les paramètres, via un avis de sécurité
- Cette réponse a été rapide et constitue, selon l’analyse, le premier cas où Rabbit a réagi de manière relativement proactive à des problèmes de confidentialité et de sécurité des utilisateurs
Portée réelle de la personnalisation d’AOSP
- En réponse aux articles affirmant que RabbitOS n’était qu’une simple application, Rabbit a décrit le système comme un AOSP très personnalisé avec des “lower level firmware modifications”
- Les personnalisations identifiées jusqu’à présent consistent surtout à supprimer des fonctions Android pour maintenir un mode kiosk à application unique
- Pas de barre de navigation
- Pas de barre de notifications
- Présence de mesures visant à empêcher l’activation d’ADB
- Une application appelée
Judy s’exécute en arrière-plan et désactive ADB s’il est en cours d’exécution
- Le 4 juillet, @MarcelD505 a publié une méthode de kiosk escape partant du navigateur de login de portail captif WiFi pour accéder à l’application Android system settings
- Dans les dernières mises à jour, Rabbit a bloqué cette voie en supprimant entièrement l’application Android system settings de l’appareil
- Jusqu’à présent, les modifications AOSP bespoke identifiées relèvent davantage de la suppression de fonctionnalités que de l’ajout de nouvelles capacités
- Aucune raison technique montrant que l’implémentation actuelle de RabbitOS serait impossible sous forme d’application classique de smartphone n’a encore été identifiée
Points auxquels les utilisateurs ordinaires du R1 doivent faire attention
- Si vous craignez que l’appareil ait été jailbreaké à votre insu, il suffit de l’éteindre puis de le rallumer
- S’il démarre normalement sans message d’avertissement, il peut généralement être considéré comme sûr
- Toutefois, si la brom est configurée pour démarrer une image Preloader non signée depuis l’eMMC, ce n’est pas certain et des tests supplémentaires sont nécessaires
- Il serait préférable de pouvoir reflasher une image stock firmware fiable fournie par le vendeur, mais Rabbit ne propose pas ce moyen
- Si le R1 est laissé sans surveillance, les données stockées sur l’appareil peuvent être facilement extraites par une personne disposant des connaissances nécessaires
- Avant une vente, un don ou une mise au rebut, il faut d’abord effectuer une réinitialisation d’usine avec la nouvelle option ajoutée dans les paramètres
Violation de la GPL et conclusion
- À l’exception de la molette de défilement et de la caméra rotative, le Rabbit R1 ressemble davantage à un appareil Android MediaTek ordinaire qu’à un matériel spécialisé
- Les personnalisations d’AOSP consistent pour l’essentiel à supprimer des fonctionnalités existantes afin d’imposer un mode kiosk à application unique
- La sécurité de la chaîne de démarrage n’est pas efficace, ce qui rend difficile de laisser l’appareil sans surveillance en toute sécurité
- Rabbit Inc. viole la licence GPL2 du noyau Linux
- Le pilote de détection de la molette de défilement à effet Hall reste closed source
- Le pilote de contrôle du moteur pas à pas de rotation de la caméra reste également closed source
- Les deux pilotes sont liés statiquement à l’image du noyau GPL
- Le 12 juillet, Rabbit Inc. a été contactée pour commenter le contenu de l’article et présenter ses plans de conformité GPL, mais au 22 juillet, aucune réponse n’avait été reçue
- L’outil de jailbreak tethered publié est un outil expérimental destiné à aider les chercheurs à accéder à leur propre R1 et, à l’avenir, les utilisateurs avancés à étendre les capacités de l’appareil
1 commentaires
Commentaires Hacker News
La GPL impose de publier la licence et le code source sur demande, mais Truth Social n’a même pas publié la licence tant que l’usage de code AGPL n’avait pas été révélé, puis n’a publié les sources qu’à ce moment-là
Je me demande si Rabbit s’en sortira de la même manière
En pratique, il est difficile de poursuivre des violations dont les ayants droit n’ont pas connaissance, et l’objectif est souvent davantage de remettre le contrevenant en conformité que d’obtenir des dommages et intérêts
https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Je croyais qu’il existait côté Linux une exception GPL pour les modules du noyau, indépendamment du mode de liaison, tant qu’il n’était pas nécessaire de modifier le noyau lui-même
Le contenu de ces logs est franchement très sale : position GPS exacte, noms des réseaux Wi‑Fi, identifiants des antennes-relais voisines même sans carte SIM, adresse IP exposée à l’extérieur, jetons utilisateur servant à l’authentification auprès de l’API backend de Rabbit, et même les MP3 encodés en Base64 de tout ce que Rabbit a dit à l’utilisateur, avec la transcription texte
Qu’un appareil conçu pour répondre à une question comme « Où y a-t-il un bon resto dans le coin ? » envoie le contexte de localisation avec la requête n’a rien de surprenant, mais s’il diffuse la position en continu sans raison, là c’est préoccupant
Les noms de réseaux Wi‑Fi doivent être conservés pour permettre la reconnexion, et voir l’adresse IP dans des logs locaux n’a rien de très anormal
Les jetons d’accès utilisateur doivent aussi être stockés sur l’appareil pour éviter de se reconnecter à chaque fois. En revanche, les laisser tels quels dans les logs est une mauvaise pratique, même si, si ces logs sont stockés au même endroit que la base de données ou le fichier de configuration, cela ne crée pas à lui seul un problème entièrement nouveau. En revanche, s’ils sont téléversés directement vers le serveur, là c’est évidemment problématique
Si on voulait qu’un appareil comme celui-ci fonctionne de manière fluide et presque magique, il devait forcément écouter, regarder et envoyer la position en permanence. Pour que cela marche vraiment bien, il faudrait en fait de l’inférence locale, et je ne sais pas pourquoi quelqu’un paierait aujourd’hui pour un produit dont Apple sortira une bien meilleure version dans cinq ans, mais si on en achète un, ce fonctionnement est inévitable
On ne peut pas détester les grandes entreprises tout en espérant qu’une startup produise un bon produit sans données. Rabbit a besoin de ces données s’il veut avoir la moindre chance de faire mieux à l’avenir
Si cela vous met mal à l’aise, il faut expliquer précisément pourquoi. En soi, la plupart de ces éléments n’ont rien d’alarmant
C’est drôle. J’ai travaillé chez Rabbit, j’ai lu le codebase, j’ai été gaslighté par les dirigeants, puis j’ai démissionné
Vu les jailbreaks et les vulnérabilités visibles de l’extérieur, on dirait juste la partie émergée de l’iceberg
Si Rabbit n’a pas répondu, c’est sans doute parce que ses avocats examinent comment attaquer en justice
En pratique, ça ne leur laisse quasiment aucune heure ouvrée pour répondre
Les développeurs de RabbitOS pourraient corriger le problème en configurant l’eFuse pour bloquer l’accès au bootloader via USB
Moto avait fait pareil il y a quelques années quand ses appareils MediaTek étaient vulnérables à la même surface d’attaque au niveau de la boot ROM. Si je me souviens bien, cette eFuse avait été configurée à l’étape LK et déployée via une simple mise à jour firmware sans fil
L’article est excellent
Le logiciel a l’air d’être une catastrophe, et l’entreprise n’inspire pas vraiment confiance pour l’instant
Malgré tout, si on peut facilement faire tourner des apps personnalisées, même juste en mode kiosque, ce format ouvre des usages assez intéressants
Si on peut y coller à peu près une PWA, c’est beaucoup plus rapide que de bricoler soi-même un ESP32, une batterie et un écran, et ça ressemble à un appareil tout-en-un plutôt correct
Idéalement, ce serait bien de pouvoir le faire tourner de manière plus sûre sans les services Google, dans une direction type GrapheneOS
Je n’ai pas encore regardé, mais je me demande s’il existe des cas d’usage ou des ressources à consulter pour ce type d’app personnalisée à usage unique
Si le prix descend sous les 50 dollars, par exemple une fois les serveurs coupés, alors oui, je pourrais admettre que c’est une plateforme matérielle convenable
C’est dommage, j’aurais aimé que ce produit fonctionne bien
J’espère que ça ne deviendra pas un boulet pour les futures expérimentations autour des interfaces matérielles + IA. Je reste d’accord avec cette idée à la Bret Victor selon laquelle on peut faire mieux que taper et balayer sur un rectangle de verre
Plus simplement encore, une smartwatch peut relayer la requête vers le téléphone
Même si Humane ne semble pas avoir résolu un vrai problème, je respecte au moins le fait qu’ils aient vraiment essayé quelque chose de différent. Le Rabbit R1, lui, c’est juste de la camelote bon marché
C’est assez drôle de voir que tout ou presque de l’enthousiasme initial pour Rabbit venait du design de Teenage Engineering
J’aimerais que TE choisisse mieux ses clients à l’avenir. La personne derrière Rabbit est un escroc notoire
Je pourrais chercher son nom, mais la qualité des moteurs de recherche est devenue si mauvaise ces temps-ci que je ne vais pas m’embêter. Un lien exposant plus en détail les critiques serait utile
On dirait le Juicero des assistants IA
Le vrai problème, c’est que l’entreprise pensait que des gens paieraient une somme absurde pour une machine destinée à presser des sachets de mélange de fruits prédécoupés fournis exclusivement par elle. Tout fonctionnait exactement comme prévu ; c’est le modèle économique qui était absurde
J’espérais quelque chose comme une combinaison de Mycroft(https://en.wikipedia.org/wiki/Mycroft_(software)) et Leon(https://getleon.ai), autrement dit un assistant IA open source respectueux de la vie privée