Checkm8

From The French Apple Wiki
Jump to navigationJump to search

Exploit checkm8

[edit | edit source]
Vulnérabilité dans SecureROM
Logiciel : Appareils exécutant iOS, iPadOS, tvOS, watchOS, bridgeOS, audioOS, Haywire, etc.
Vulnérable dans : ? - 3401.0.0.1.16
Corrigé dans : 3865.0.0.4.7
Divulgué : 27 septembre 2019
Découvert par : axi0mX
CVE : CVE-2019-8900

L'exploit checkm8 est une vulnérabilité du BootROM, identifiée par le CVE-2019-8900, permettant d'exécuter du code non signé sur les appareils iOS, iPadOS, tvOS, watchOS, bridgeOS, audioOS et Haywire équipés de processeurs allant de l'A5 à l'A11, ainsi que des S1P, S3, S5L8747 et T2 (permettant ainsi le jailbreak). Les jailbreaks basés sur checkm8 sont des jailbreaks semi-connectés, car l'exploit exploite des vulnérabilités dans la pile USB DFU. La principale vulnérabilité de type use-after-free reste non corrigée dans les T8020, T8027 ou T8030, mais elle ne peut pas être exploitée sans une fuite de mémoire, celle utilisée dans checkm8 ayant été rendue inaccessible dans le T8020 et les versions ultérieures.

Les outils principaux capables d'exploiter checkm8 sont ipwndfu, Fugu, gaster et checkm8-a5. Les outils principaux pour effectuer un jailbreak avec l'exploit checkm8 sont checkra1n et palera1n.

Contexte

[edit | edit source]

Lors de l'initialisation de l'USB en mode DFU, une interface est enregistrée pour gérer tous les transferts et un tampon d'entrée/sortie global est alloué pour ces transferts. Lorsqu'une donnée est envoyée à DFU, le paquet de configuration est traité par le code USB principal, qui le transmet à l'interface DFU. Le code de l'interface s'assure que le paramètre wLength est plus court que le tampon alloué avant l'initialisation USB. Si cela est vérifié, il met à jour un pointeur utilisé pour le tampon de sortie vers celui du tampon d'entrée/sortie global.

Le code principal met ensuite à jour une variable globale avec la longueur des données à envoyer et se prépare pour la phase de données. Les données reçues sont écrites dans le tampon d'entrée/sortie, et une deuxième variable globale suit la quantité de données reçues. Une fois toutes les données reçues, DFU copie le contenu du tampon dans la zone où l'image sera ensuite démarrée. Le code USB réinitialise ensuite toutes les variables globales et se prépare pour le transfert suivant.

Si DFU se termine, le tampon d'entrée/sortie est libéré. En cas d'échec de l'analyse, SecureROM relance DFU.

Vulnérabilité de type Use-after-Free

[edit | edit source]

La vulnérabilité de type use-after-free réside dans l'implémentation de la phase de données d'un transfert USB. Pour l'exploiter, il faut d'abord déclencher le début de la phase de données dans la pile USB. Ensuite, un transfert USB violant les normes de la spécification USB est envoyé (SecureROM ne s'y attend pas) sans envoyer de données. Après cela, en déclenchant la réentrée de DFU (via une réinitialisation USB ou en provoquant une analyse d'image qui échoue inévitablement), SecureROM relance DFU, et le tampon d'entrée/sortie est libéré. Cependant, comme le processus a été interrompu prématurément, le code USB ne réinitialise pas les variables globales, notamment celle qui contient un pointeur vers le tampon d'entrée/sortie maintenant libéré, qui sera utilisé comme tampon principal pour les transferts USB.

Vulnérabilité de fuite de mémoire

[edit | edit source]

Lorsqu'une requête est traitée par la pile USB, un paquet de longueur nulle est envoyé pour signaler la fin d'un transfert. Cependant, sur certains SoC compatibles avec checkm8 (A9X, A10, A10X et A11), une vulnérabilité permet à ces objets de requête de fuir et de rester alloués lors de l'arrêt de DFU. En bloquant le point de terminaison et en envoyant de nombreuses requêtes, chaque requête alloue une demande de paquet de longueur nulle sur le tas, qui s'accumulent pendant le blocage. Toutefois, en déclenchant l'arrêt de DFU avant que ces requêtes n'aient été traitées, les paquets de longueur nulle ne sont jamais envoyés ni désalloués, ce qui entraîne une fuite. Cette fuite peut être déclenchée de manière conditionnelle, car seules les requêtes répondant à des conditions spécifiques (par exemple, une longueur non multiple de 64 octets) provoquent l'enregistrement d'un paquet de longueur nulle. Cette fuite de tas peut être utilisée pour manipuler l'état du tas et créer un trou de taille exacte, qui sera l'emplacement privilégié pour malloc lors de la prochaine allocation.

Cette fuite n'est pas nécessaire sur les appareils A8, A8X et A9, où un bogue d'annulation de DFU est exploité pour obtenir une exécution directe de code sans avoir besoin de ROP ou JOP. Sur l'A7, la fuite est déclenchée pour toutes les requêtes (au lieu de celles répondant aux bonnes conditions), donc la stratégie consiste à presque remplir le tas jusqu'à ce qu'il reste juste assez d'espace pour un trou préféré pour le tampon.

Exploitation

[edit | edit source]

Des techniques de heap feng-shui (également appelées heap grooming) sont utilisées pour s'assurer que le tampon d'entrée/sortie pour la prochaine itération de DFU (après avoir déclenché le use-after-free) n'est pas alloué à l'emplacement du tampon libéré. Ensuite, un transfert de phase de données incomplet est effectué pour définir les variables globales et entrer dans l'état checkm8. Une requête DFU_CLR_STATUS est ensuite envoyée, ce qui entraîne une réinitialisation de DFU et le début d'un nouveau cycle. Le tampon d'entrée/sortie est alors libéré, mais l'état global reste inchangé avec les variables intactes.

Un objet usb_device_io_request est ensuite débordé avec une réécriture, remplaçant le pointeur vers une fonction de rappel à exécuter une fois la requête terminée et un pointeur vers l'objet suivant du même type. Cela empêche l'appareil de tenter de libérer la requête (ce qui provoquerait une panique en raison de métadonnées de tas endommagées) et redirige le flux de contrôle vers la charge utile.

Ensuite, la charge utile est envoyée via USB, suivie d'une réinitialisation USB. Cette réinitialisation déclenche une boucle d'annulation des requêtes incomplètes dans la file d'attente. Le reste de la file a été remplacé par l'exploit, ce qui signifie que le contrôle du flux de rappel est obtenu, et le contrôle est transféré au shellcode une fois que l'appareil exécute la fonction de rappel de la requête débordée.

Problèmes connus d'exploitation

[edit | edit source]
  • Exploitation sur A5 : L'outil checkm8-a5 doit être exécuté sur un Arduino en raison d'une différence dans la manière dont ce SoC gère les paquets USB. L'exploitation n'est pas possible avec un ordinateur classique, car un contrôle total des requêtes USB envoyées est nécessaire, y compris celles envoyées par défaut lorsque l'appareil est connecté à un ordinateur.
  • Exploitation sur les Mac Apple Silicon : Un problème dans la pile USB de ces Mac empêche certains appareils d'être exploités par checkm8 via un port USB-C. Les outils checkra1n et gaster contournent ce problème, mais d'autres outils comme ipwndfu et Fugu ne fonctionnent pas. Plus d'informations peuvent être trouvées dans ce billet de blog de checkra1n.

Liens externes

[edit | edit source]
  • Wikipédia : Jailbreak iOS