2 points par GN⁺ 2024-07-18 | 1 commentaires | Partager sur WhatsApp
  • 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

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

 
GN⁺ 2024-07-18
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

    • Pas exactement. La GPL 2.0 exige au minimum la publication de la licence lors de la distribution, mais le code source lui-même peut effectivement être fourni sur demande
      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
    • Il est fort probable que Rabbit ait déjà mis la clé sous la porte avant que les conséquences liées à la GPL ne le rattrapent réellement
      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
    • La GPL est de toute façon difficile à faire appliquer. Le fabricant de Boox, Onyx, avait aussi été pointé du doigt pour le même problème il y a quelques années, sans grande conséquence, et il est peu probable que Rabbit ait de vrais ennuis à cause de ça
  • 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

    • Ce qui compte, c’est de savoir si les informations de position et de cellule sont envoyées au serveur en permanence ou seulement au moment d’une requête
      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
    • Des MP3 encodés en Base64, c’est absurde. Le seul résultat, c’est 33 % de consommation de données en plus
    • Vu la finalité du produit, il est impossible que toutes ces données aient été collectées par accident
    • La plupart de ces éléments ne me semblent pas très problématiques
      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
    • Une grande partie de cela ressemble surtout à « l’appareil auquel on confie des informations pour fournir le service les consigne aussi dans des logs à des fins de diagnostic »
      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é

    • Si ça ne te dérange pas, je serais curieux de savoir quels ont été les premiers signaux d’alerte dans le codebase
      Vu les jailbreaks et les vulnérabilités visibles de l’extérieur, on dirait juste la partie émergée de l’iceberg
    • Tu dois bien avoir quelques histoires internes intéressantes à raconter sur ce soi-disant « large action model », non ?
    • Tu as évité une balle
  • Si Rabbit n’a pas répondu, c’est sans doute parce que ses avocats examinent comment attaquer en justice

    • Ce serait franchement assez drôle si c’était vraiment le cas
    • Vu le nombre d’appareils vendus, je ne sais pas s’ils peuvent se permettre les frais d’avocat
    • Demander un commentaire un vendredi après-midi puis publier le lundi matin en disant « ils n’ont pas répondu », c’est honnêtement assez nul
      En pratique, ça ne leur laisse quasiment aucune heure ouvrée pour répondre
    • Vu le risque que l’entreprise concernée devienne bientôt insolvable, je prendrais ça à peu près comme les menaces envoyées par les gens qui ont créé Juicero
  • 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

    • En l’état actuel, le matériel reste quand même assez cher
      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

    • Oui, mais le rectangle de verre qu’on a déjà en main dispose justement de toute la puissance et de toutes les fonctions matérielles nécessaires pour proposer ce genre d’interface différente
      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

    • Cet « escroc » siège au conseil d’administration de TE, donc c’est déjà hors de contrôle
    • Je serais curieux d’avoir une source pour l’affirmation « 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

    • Juicero était beau, peut-être même surconçu, et faisait ce qu’il promettait
      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
    • Là, on est plus proche d’une presse Juicero qui n’aurait aucun composant fonctionnel, seulement un tuyau relié au siège de Juicero, où l’on mélangerait les jus de plusieurs fournisseurs avant de les renvoyer à l’appareil avec cinq minutes de latence
  • 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