- gala est un projet visant à implémenter soi-même un jailbreak d’iOS 4 pour iPhone 4 ; cette première partie se concentre sur l’obtention d’une exécution de code initiale en exploitant une vulnérabilité de SecureROM sur un ancien appareil
- Le démarrage d’iOS commence par la vérification, par SecureROM, de LLB ou d’iBSS, puis se poursuit par une chaîne de confiance où chaque étape vérifie la suivante ; SecureROM ne peut pas être remplacée par une mise à jour après la fabrication
- limera1n cible la SecureROM du SoC A4 et attaque un appareil en mode DFU qui attend le transfert d’iBSS ; un crash découvert par fuzzing des messages de contrôle USB semble mener à un débordement de tas et à l’exécution de shellcode
- En s’appuyant sur le dumper SecureROM de pod2g, le projet réimplémente le flux qui utilise la zone de communication
0x84000000et la requête de lecture USB0xA1:2pour récupérer le dump de SecureROM et des valeurs de debug côté hôte - Un pipeline a été créé pour extraire, depuis
__TEXT,__textd’un Mach-O, un payload écrit en Rust sous forme de shellcode à exécuter ; mais les chaînes statiques étant placées dans__const, il a fallu recourir à un adressage relatif au pointeur d’instruction et à un placement en assembleur
Point de départ du projet de jailbreak de l’iPhone 4
- gala est un projet visant à créer un jailbreak d’iOS 4 pour iPhone 4, et ce document correspond à sa première partie, « Gaining Entry »
- L’expérience précédente de développement de tweaks iOS avait mené à la distribution via Cydia, à la modification de fonctionnalités de SpringBoard, à l’utilisation directe du runtime Objective-C et au reverse engineering de binaires propriétaires
- L’objectif d’écrire soi-même un jailbreak est de comprendre comment le processus de jailbreak fonctionne réellement
- Ce travail s’appuie largement sur les connaissances partagées en open source par p0sixninja et axi0mX
Choisir un ancien iPhone et une vulnérabilité de Boot ROM
- La première étape a consisté à acheter un iPhone 4 et un iPhone 3GS sur eBay
- Comme les versions récentes de Xcode n’autorisent pas le ciblage d’anciennes versions d’iOS, la voie consistant à compiler et installer une app à la manière des années 2010 s’est vite retrouvée bloquée
- L’installation d’un ancien Mac OS X et d’un ancien Xcode dans une VM a aussi été envisagée, puis abandonnée
- Il n’était pas clair non plus si Apple signerait encore des binaires ciblant d’anciennes versions d’iOS
- L’alternative consiste à viser directement une vulnérabilité de Boot ROM
- Cela peut être tenté sans ancienne toolchain ni VM, avec seulement du code interagissant avec l’appareil en USB depuis la machine hôte
- Le code de l’exploit limera1n a été trouvé dans la section
Vulnerabilities and Exploitsde l’iPhone Wiki
SecureROM et chaîne de confiance du démarrage iOS
- Dans la terminologie Apple, SecureROM est la première étape du processus de démarrage d’iOS, et lance l’étape de démarrage suivante
- SecureROM peut charger deux composants
- Lors d’un démarrage normal, elle démarre le
Low Level Bootloader, ou LLB, depuis une partition disque de la NOR - En mode DFU, lorsqu’elle est connectée à un ordinateur via USB, elle peut recevoir le bootloader
iBoot Single Stage, ou iBSS, pendant le processusRestore iPhone
- Lors d’un démarrage normal, elle démarre le
- SecureROM vérifie que LLB ou iBSS est une image fiable signée par Apple
- Ensuite, LLB et iBSS vérifient eux aussi l’étape suivante qu’ils chargent, formant ainsi une chaîne de confiance
- Comme SecureROM est la première étape, elle n’est pas vérifiée par une étape précédente et est gravée en mémoire en lecture seule lors de la fabrication
- Les autres étapes peuvent être remplacées par une mise à jour d’iOS
- Une vulnérabilité dans une version donnée de SecureROM reste définitivement présente sur les appareils fabriqués avec cette version
Obtenir l’exécution de code sur un appareil DFU avec limera1n
- limera1n est un exploit SecureROM publié par geohot en 2010 et empaqueté dans l’outil de jailbreak du même nom
- limera1n peut être utilisé lorsqu’un appareil en mode DFU attend de recevoir iBSS depuis l’hôte via USB
- La SecureROM incluse dans le SoC A4 étant vulnérable, l’iPhone 4 est une cible adaptée
- Le fonctionnement exact de limera1n n’est pas entièrement documenté publiquement
- geohot a dit ne pas savoir pourquoi cela fonctionnait
- p0sixninja en a proposé une théorie
- Le crash a été découvert par fuzzing de messages de contrôle USB ; il ressemble à une race condition menant à un débordement de tas, et semble permettre l’injection et l’exécution de shellcode
Lire la mémoire d’un appareil en mode DFU
- Le dumper SecureROM de pod2g sert d’implémentation de référence montrant à la fois une implémentation de limera1n, un exemple de payload et une méthode de lecture mémoire via USB
- Le dumper SecureROM copie la mémoire
0x0, où SecureROM est mappée, dans la zone de réception USB, puis l’hôte lit les données via un message de contrôle USB - Le flux compris est le suivant
- La MMU de l’A4 mappe le début de la SRAM à
0x84000000 - L’hôte peut envoyer l’image iBSS par morceaux avec des paquets de contrôle USB de
request type 0x21etrequest ID 1 - Ces données sont copiées en SRAM à partir de
0x84000000, et SecureROM maintient un compteur interne qui suit la position de copie du paquet suivant - L’appareil répond aussi aux paquets de contrôle de
request type 0xA1etrequest ID 2, en envoyant à l’hôte le contenu mémoire de0x84000000
- La MMU de l’A4 mappe le début de la SRAM à
- Cette fonction de lecture est particulièrement utile lorsque l’on peut exécuter du code sur l’appareil
- Le payload copie les données souhaitées vers
0x84000000 - L’hôte peut récupérer ces données avec la requête de lecture
A1:2
- Le payload copie les données souhaitées vers
- Les slides de la présentation Hack In the Box Malaysia 2013 de p0sixninja indiquent que le dumper SecureROM de pod2g est basé sur SHAtter, mais l’utilitaire réel utilise une implémentation de limera1n
- Une implémentation maison de limera1n a permis de dumper SecureROM avec succès
Débogage de payload avec 0x84000000
- Après avoir obtenu l’exécution de code, il fallait vérifier où le shellcode s’exécutait, où se trouvait la pile et quelle mémoire le shellcode écrasait
- Le flux de lecture du dumper SecureROM a été réutilisé comme sortie de debug
- Le payload copie les valeurs du pointeur d’instruction (instruction pointer) et du pointeur de pile (stack pointer) vers
0x84000000 - Le code côté hôte relit les valeurs de la même manière
- Cette approche joue le rôle d’un
print()rudimentaire via dump mémoire
- Le payload copie les valeurs du pointeur d’instruction (instruction pointer) et du pointeur de pile (stack pointer) vers
- Le script automatique dumpe les premiers mots à
0x84000000après l’exécution de l’exploit et les affiche dans la fenêtre de sortie - Les valeurs obtenues indiquent l’emplacement d’exécution du shellcode et celui de la pile
- Le pointeur d’instruction était proche de
0x8402b048 - Le pointeur de pile était
0x8403bfa0 - Le pointeur de pile se trouvait dans la zone de pile normale configurée par SecureROM, tandis que le pointeur d’instruction se trouvait dans la zone de l’image reçue
- Le pointeur d’instruction était proche de
Payload Rust et extraction de shellcode Mach-O
- Plutôt que d’écrire le payload uniquement en assembleur, un système de build a été configuré pour compiler un payload Rust puis le convertir en shellcode
- Rust a abandonné la prise en charge de la cible
armv7-apple-iosdébut 2020, maisrustuppermet de basculer vers une ancienne toolchain qui la prend encore en charge - Compiler dans un langage de haut niveau produit non seulement du code machine brut, mais aussi un binaire contenant des métadonnées, des informations de configuration de l’espace d’adressage virtuel, une table de symboles et des informations de linker
- Pour l’exploit, seuls les octets à injecter en mémoire puis vers lesquels sauter sont nécessaires ; il ne faut donc pas tout le Mach-O, mais seulement la section
__textdu segment__TEXT - strongarm est une bibliothèque d’analyse Mach-O, utilisée dans le système de build pour parser le Mach-O et extraire dans un fichier la section
__TEXT,__text - Les octets du fichier extrait deviennent le shellcode exécuté sur l’appareil via limera1n
Linker et problème des données statiques
- Un binaire classique utilise l’infrastructure de l’OS et des conventions de symboles de point d’entrée comme
startou_main, mais un tel symbole n’est pas nécessaire pour cet usage de shellcode - Par défaut, le linker émet une erreur en l’absence de
_mainou destart - La combinaison des options
-U _main,-U startet-statica permis de créer un fichier Mach-O n’utilisant pas dyld - Au départ, strongarm levait une exception parce qu’il ne savait pas traiter les binaires sans commande de chargement
LC_DYLD_INFO- Ce binaire n’utilise pas dyld et n’a donc pas de
LC_DYLD_INFO - Un patch a été ajouté à strongarm pour gérer ce cas
- Ce binaire n’utilise pas dyld et n’a donc pas de
- L’ajout d’une chaîne statique dans le code Rust a cassé le payload
- La chaîne statique compilée est placée dans
__const - Le processus d’extraction du shellcode ne conserve que
__TEXT,__text, donc les données de__constne sont pas chargées en mémoire - Résultat : le code tente de lire la chaîne à une adresse non mappée et plante
- La chaîne statique compilée est placée dans
- La solution consiste à inclure les données statiques dans
__TEXT,__textet à utiliser un adressage relatif au pointeur d’instruction afin de ne pas supposer d’adresse de chargement stable - L’approche actuelle définit la chaîne en assembleur et passe son adresse au point d’entrée du payload Rust
Pipeline d’exécution achevé dans la partie 1
- Le pipeline final fonctionne dans l’ordre suivant
- Modifier le payload Rust
- Appuyer sur un bouton pour compiler le payload
- Extraire le shellcode du binaire
- Le runner exécute le payload avec limera1n sur l’iPhone en DFU connecté
- Le runner lit automatiquement les données à
0x84000000, utilisées comme espace de communication, et les affiche sous forme de hexdump
- À ce stade, il est possible d’exécuter du code arbitraire sur l’appareil
- L’exécution de code arbitraire permet théoriquement de nombreuses choses, mais faire réellement accomplir quelque chose d’intéressant à l’appareil reste une étape distincte
- La suite se poursuit avec Part 2: Bypassing the Bootchain
1 commentaires
Commentaires sur Hacker News
Après des années à lire sans participer, j’ai enfin créé un compte Hacker News juste pour laisser ce message. Merci d’avoir ainsi expliqué quelque chose qui, pendant longtemps, a été une boîte noire mystérieuse pour beaucoup de gens.
Je me souviens très nettement du stress que j’ai ressenti quand je jailbreakais mon iPod 4G sous iOS 4, en regardant les messages défiler dans le terminal. Ensuite, à la pause déjeuner au lycée, je le faisais aussi pour les appareils de mes amis, en craignant de me tromper et de transformer leur téléphone à plusieurs centaines de dollars en brique.
Avec le recul, des années plus tard, cette « magie » consistant à percer les murs d’Apple pour exécuter du code utilisateur est ce qui m’a fait tomber dans la programmation, et j’en suis profondément reconnaissant à toutes les personnes impliquées.
Merci beaucoup pour l’article. Il faut une compréhension profonde pour expliquer aussi simplement des concepts aussi complexes. En le lisant, de bons souvenirs me sont revenus, ceux de nuits passées à bidouiller des projets de jailbreak.
J’ai pris énormément de plaisir à lire tout ça, d’autant plus que je suis encore maladroit en rétro-ingénierie de code natif.
Ici, comme le mécanisme de restauration du système est utilisé pour casser la chaîne de confiance et démarrer un iOS modifié, cela ressemble à un jailbreak tethered. Je me demande donc comment fonctionne un jailbreak untethered. Est-ce bien une approche qui consiste à laisser la chaîne de démarrage sécurisé intacte, sans la contourner directement, puis à exploiter un processus privilégié ou non privilégié du système en cours d’exécution avant de procéder à une élévation de privilèges séparée ? Je me demande aussi comment la persistance est assurée, et comment on patche la vérification de signature du noyau sans toucher aux vérifications de signature du bootloader ni du noyau lui-même.
Vraiment un excellent article. Ça fait plaisir de voir que tu es toujours actif dans la communauté.
Merci d’avoir créé ça. J’ai un iPhone 4s qui contient beaucoup de photos importantes, mais j’ai oublié le code PIN par accident et il est bloqué depuis des années.
S’il n’y avait pas ces photos, je l’aurais simplement réinitialisé, mais je me demande si cela permettrait de réinitialiser le PIN et de copier les photos.
Modification : je me trompe peut-être. [0] indique aussi que, pendant un temps, seul le stockage de Mail était chiffré, et que le comportement par défaut a changé avec iOS 7. Donc si l’iPhone est sous iOS <= 6, cette méthode pourrait peut-être permettre d’accéder à l’appareil et de copier les photos. L’outil en [1] pourrait aider.
[1] https://code.google.com/archive/p/iphone-dataprotection/
[0] https://darthnull.org/ios-encryption/
C’était vraiment un bon article. En revanche, voir l’ancienne interface iOS montrer toute la gloire du design skeuomorphique m’a retourné l’estomac. Ça m’a rappelé à quel point je déteste John Ive.
Jony aurait peut-être dû continuer à concevoir des repose-poignets en aluminium tranchants comme des lames de rasoir plutôt que de s’occuper de logiciel.
J’ai lu les premières parties avec beaucoup de plaisir. C’est génial de suivre les choses sous cet angle. Moi aussi, je lis énormément de code source pour comprendre comment d’autres implémentent des choses comme des exploits, et ça fait plaisir de voir que d’autres font pareil.
Je ne l’ai pas encore lu, mais j’ai hâte. J’ai utilisé tous les tweaks listés au début, et je voulais simplement dire merci de les avoir créés. Les débuts du jailbreak iOS étaient vraiment amusants.
C’était excellent. J’ai essayé de le lancer, mais malheureusement mon vieil appareil ne démarrait même plus.
À l’époque, moi aussi je créais des tweaks, et le jailbreak me semblait relever de la magie noire. Même après avoir lu cet article, j’ai encore un peu cette impression.
Merci beaucoup d’avoir mis tout cela au clair. Je suis très intéressé par l’apprentissage de ce genre de choses. J’aimerais surtout apprendre, par exemple, à « libérer » des caméras de sécurité Wi‑Fi bon marché comme avec dafang-hacks en y installant mon propre firmware personnalisé, ou à créer un nouvel exploit pour rooter des tablettes Kindle Fire.
Pourtant, les articles qui expliquent ce processus en détail sont étonnamment difficiles à trouver.