Home DIY : Cable de debugging pour iPhone
Post
Cancel

DIY : Cable de debugging pour iPhone

swaggy_logo

Dans un précédent article de blog, j’ai expliqué comment déboguer le bootloader des appareil Apple. Le problème de cet article c’est qu’il nécessitait un câble qui n’est plus disponible à la vente depuis plus de deux ans.

Cette fois-ci je vais présenter une solution équivalente permettant d’accéder à la sortie série d’un iPhone mais aussi de faire du debugging avancé via SWD.

Cette solution a été développée par Thomas Roth (stacksmashing) et présentée à la DEFCON.

Solution de debugging interne d’Apple

Avant de parler de la solution de Thomas Roth. Il est important de comprendre pourquoi elle a été développée.

A la sortie de l’usine les appareils de Apple sont verrouillés de façon matérielle pour des raisons de sécurité. Il n’est pas possible d’y attacher un débogueur.

D’après Vice, certains chercheurs en sécurité iOS auraient mis la main sur des appareils non-verrouillés utilisé lors des premières phases de développement des appareils. Mais sans le matériel adéquat, ces appareils n’ont aucune utilité.

C’est là qu’interviennent les câbles internes d’Apple avec des noms de primate tels que Kong, Kanzi ou Koba.

jtag_cables Câbles Gorilla (30 pins) Kong et Kanzi - photo de 1nsane_dev sur Twitter.

Utilisés avec un logiciel nommé astris, il est possible de faire du debugging de bas niveau (SWD) et d’exploiter pleinement le potentiel des appareils de préproduction.

astris Le logiciel astris - photo de 1nsane_dev sur Twitter.

Cet outil permet de stopper l’exécution des cœurs du CPU ainsi que de lire et d’écrire dans leur mémoire et bien d’autres possibilités à condition d’avoir un appareil de développement ainsi qu’un de ces câbles peu ordinaires.

Avec ces trois composants on peut avoir un contrôle de total du processeur principal d’un appareil Apple. Malheureusement ce n’est pas très pratique ni étique comme solution.

Tamarin

A la DEFCON 30, Thomas Roth a présenté “The hitchhacker’s guide to iPhone Lightning & JTAG hacking”. Dans ses slides il explique les particularités du connecteur lightning et des protocoles associés.

De plus il présente aussi une carte permettant d’obtenir une sortie UART et la possibilité de faire du Serial Wire Debugging.

tamarin_cable Tamarin cable.

Cette carte n’étant pas encore disponible, Thomas Roth propose d’utiliser une carte Raspberry Pi Pico et un câble lightning pour faire notre propre sonde UART et SWD.

Assemblage du câble

Pour fabriquer votre propre câble il faudra un Raspberry Pi Pico, un câble lightning et des câbles GPIO.

Ensuite, il suffit de suivre la documentation sur Github pour l’assemblage.

Dans un premier temps je n’ai pas pu faire fonctionner la connexion car il semble que certains câbles comme celui que j’ai acheté ont un brochage différent que celui décrit. Merci à tihmstar pour le tip.

J’ai fini par souder les fils du câble lightning à des câbles GPIO que j’ai branché sur les pins de la carte de cette façon :

  • GPIO1 L1n (vert)
  • GPIO2 L1p (blanc)
  • GND GND (noir)
  • GPIO3 ID1 (orange)
  • GPIO4 ID0 (rouge)
  • 5V 5V (yellow)

Après une sessions de soudage, voici le résultat, pas si catastrophique.

soldering Résultat catastrophique mais fonctionnel de mes soudures.

Compilation du firmware

Pour compiler le firmware j’ai utilisé une machine sous Ubuntu 22.04.

Avant tout, téléchargez les paquets nécessaires à la compilation du firmware: sudo apt install cmake gcc-arm-none-eabi g++ git.

On peut ensuite procéder au téléchargement du SDK et du firmware pour le Pico, puis à sa compilation.

1
2
3
4
5
6
7
8
9
mkdir -p tamarin; cd $_
git clone https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk; git submodule update --init
export PICO_SDK_PATH=$(pwd) 
cd /
git clone https://github.com/stacksmashing/tamarin-firmware.git; cd $(basename $_ .git)
mkdir build; cd $_
cmake ..
make -j

Si tout s’est bien passé vous devriez avoir les fichiers suivants dans le répertoire build:

1
2
3
4
5
6
7
λ ~/tamarin/tamarin-firmware/build(main*) » ls
CMakeCache.txt       lightning_tx.pio.h    tamarin_firmware.dis
CMakeFiles           Makefile              tamarin_firmware.elf
cmake_install.cmake  pico-sdk              tamarin_firmware.elf.map
elf2uf2              pioasm                tamarin_firmware.hex
generated            probe.pio.h           tamarin_firmware.uf2
lightning_rx.pio.h   tamarin_firmware.bin

Le fichier qui nous intéresse est tamarin_firmware.uf2 que l’on va copier sur la carte Raspberry Pi Pico.

Installation du firmware

Branchez la carte sur un des ports USB de votre ordinateur et même temps appuyez sur le bouton BOOTSEL (vous ne pouvez pas le rater c’est le seul bouton présent sur le Pico). Un nouveau block device devrait être détecté.

1
2
3
4
5
 λ ~/tamarin/tamarin-firmware/build(main*) » lsblk
 NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
 [..]
 sdb                     8:16   1   128M  0 disk  
 └─sdb1                  8:17   1   128M  0 part

Montez-le dans un répertoire, copiez tamarin_firmware.uf2 dans ce même répertoire et démontez-le

1
2
3
4
λ ~/tamarin/tamarin-firmware/build(main*) » sudo mkdir -p /mnt/pico
λ ~/tamarin/tamarin-firmware/build(main*) » sudo mount /dev/sdb1 $_
λ ~/tamarin/tamarin-firmware/build(main*) » sudo cp tamarin_firmware.uf2 $_
λ ~/tamarin/tamarin-firmware/build(main*) » sudo umount $_

Vérifiez avec dmesg que le nouveau périphérique USB est détécté

1
2
3
4
5
6
7
usb 1-4: New USB device found, idVendor=2b3e, idProduct=0004, bcdDevice= 1.00
usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-4: Product: Tamarin Cable
usb 1-4: Manufacturer: stacksmashing
usb 1-4: SerialNumber: 31337
cdc_acm 1-4:1.0: ttyACM0: USB ACM device
cdc_acm 1-4:1.3: ttyACM1: USB ACM device

Le premier device ttyACM0 correspond à l’interface du firmware permettant d’interagir avec lui. Le second est utilisé pour le mode DCSD, qui permet d’avoir une sortie série vers ce périphérique.

Connexion

Maintenant que le firmware est installé on peut se connecter au Raspberry Pi Pico avec minicom : sudo minicom -D /dev/ttyACM0 -b 115200. Appuyez sur entrée et le menu du firmware s’affiche.

hello Menu du firmware tamarin.

On se retrouve avec 5 options :

  • JTAG mode : active le mode JTAG via la puce dans le connecteur lightning femelle (Tristar/Hydra).
  • DCSD mode : active le mode DCSD qui permet d’avoir une sortie série sur le second périphérique (ttyACM1).
  • Reset device : Redémarrage l’appareil.
  • Reset and DFU : Redémarre en mode DFU.
  • Reset Tamarin Cable : Réinitialise la connexion USB du firmware.

Le mode USB n’est pas supporté, donc il n’est pas possible de faire du transfert de données ou de charger un appareil avec ce cable.

Serial Wire Debug (SWD)

Le SWD est à peu près similaire à JTAG, mais n’existe que sur les architectures ARM et utilise moins de pins que JTAG.

Pour la suite de cet article on va compiler OpenOCD, demote un iPhone 7 à l’aide de checkm8, puis activer le mode JTAG sur le Raspberry Pi Pico afin de s’y connecter à l’aide d’OpenOCD.

OpenOCD

Téléchargeons et compilons le fork d’OpenOCD pour le Pico et le firmware du Tamarin.

1
2
3
4
5
6
7
apt update; apt install -y libtool pkg-config libusb-1.0-0-dev
git clone https://github.com/stacksmashing/openocd.git
cd openocd
git submodule update --init
./bootstrap
./configure --enable-tamarin
make -j

Le binaire compilé est ensuite disponible dans ./src/openocd.

Demotion

Comme dit plus haut, les appareils de production sont verrouillés et la fonctionnalité de SWD n’est pas activé. C’est là qu’entre en jeu checkm8 une faille de sécurité dans la stack USB de certains appareils qui permet justement de demote un appareil.

Le terme demotion désigne la modification de l’état du fusible effectif d’un appareil pour permettre le débogage de l’Application Processor dans notre cas.

Checkm8 est limité à certains appareils (A6 - A11). Pour la suite de l’article, j’utilise un iPhone 7 avec une puce A10 Fusion.

A l’aide de checkra1n on peut exploiter checkm8 pour demote l’appareil.

checkra1n Demotion d’un iPhone 7 avec checkra1n.

JTAG mode

Sur le Pico, activez le mode JTAG, puis branchez votre appareil au connecteur lightning (si vous faites l’inverse ça ne fonctionnera pas).

Dès que l’iPhone est branché, le firmware envoie la requête au Tristar qui active le mode JTAG.

jtag_mode Activation du mode JTAG.

Connexion avec OpenOCD

Le mode JTAG est activé et l’iPhone est demoted. Il nous reste qu’à récupérer le fichier configuration disponible ici.

Lancez OpenOCD : sudo ./src/openocd -f tcl/interface/tamarin.cfg -f t8010.cfg.

Si vous souhaitez acceder à OpenOCD depuis une machine différente vous pouvez ajouter l’option -c bindo 0.0.0.0 pour que le logiciel écoute sur toutes les interfaces.

Si vous avez une erreur du type Erro: Can't find a tamarin device! Please check device connections and permissions et que la carte est branchée, le VID n’est pas le bon.

Vous devrez changer la valeur de la macro VID dans le fichier src/jtag/drivers/tamarin.c:80 à la valeur 0x2B3E .

Si tout se passe bien OpenOCD se lance et écoute sur différents ports en local.

jtag_mode Exécution d’OpenOCD pour le tamarin

Le port qui nous intéresse est le 4444 avec lequel on peut se connecter via telnet pour accéder à l’interface de contrôle.

jtag_mode Liste des coeurs du CPU

Depuis cette interface on peut sélectionner un des cœurs du SOC et stopper son exécution. Cela permet par la suite d’attacher un débogueur comme GDB ou même IDA.

IDA

IDA embarque un debugger qui permet de se connecter au serveur GDB de OpenOCD. Il suffit de spécifier les informations de connexion de la machine sur laquelle tourne OpenOCD comme ci-dessous.

Cette option se trouve dans Debugger -> Process options.

ida1 Option de connexion au serveur de debug.

Par la suite, il suffit d’appuyer sur “play” (le bouton vert).

On arrive dans la fonction arch_halt (sub_1000004FC). Tout comme GDB il y a la possibilité de placer des breakpoints, step in d’instruction en instructions et visualiser la stack ainsi que les registres.

ida1 IDA Pro en mode debug.

A noter que pour cette démo, j’ai utilisé IDA 7.0, car il semble que les nouvelles versions d’IDA (7.5-8.0) n’ont plus la possibilité de se connecter au serveur GDB d’OpenOCD.


Dans cet article on a vu comment faire son propre câble JTAG pour les appareils Apple avec port lightning et comment déboguer la SecureROM de l’iPhone dans IDA.

Ce câble a quelques inconvénients : il faudra quand même utiliser un câble normal pour jailbreak avec checkra1n. Si le JTAG est activé sur le câble il faudra le débrancher puis le brancher à nouveau qu’il soit réinitialisé.

Ce blog post est assez similaire à celui sur le debugging de l’iBoot. Mais cette fois-ci j’avais envie de mettre en avant ce cable DIY et ses possibilités toute en utilisant du matériel accessible et open source.

J’espère que ce post vous a plu, n’hésitez pas à me contacter sur Twitter ou même par mail si vous avez des questions.


Liens et sources :

This post is licensed under CC BY 4.0 by the author.