Dans ce post, on va voir comment déchiffrer les bootloaders d’Apple à l’aide de différents outils.
iBoot
L’iBoot est le nom donné au deuxième bootloader de la séquence de démarrage d’iOS pour les appareils pré-A10. Ci-dessous un schéma de la bootchain.
1
2
3
4
5
6
7
NAND/Normal +------+ +-------+
------------> | LLB | --> | iBoot | --> OS
+-----------+ / +------+ +-------+
| SecureROM |<
+-----------+ \ +------+ +-------+
------------> | iBSS | --> | iBEC | --> Restore
USB/DFU +------+ +-------+
Pour les SoCs A10+, il n’y a plus qu’un bootloader : l’iBoot. Celui-ci est chargé par la SecureROM et il est utilisé pour toutes les tâches d’initialisation avant le démarrage du kernel. Il permet aussi d’entrer en mode de récupération. Les images LLB
, iBEC
et iBSS
sont toujours présentes, mais elles sont identiques à l’iBoot.
Dans la suite de cet article, lorsque je parle de l’iBoot, cela s’applique aussi aux autres bootloaders.
Firmware
Vous pouvez télécharger un firmware depuis ipsw.me ou theiphonewiki et en extraire le bootloader. Pour aller plus vite il est possible de télécharger uniquement l’iBoot à l’aide de partialZipBrowser. Pour ce post, je vais télécharger l’iBoot d’iOS 14.5 pour iPhone X.
1
2
3
4
5
6
7
8
λ ~ » pzb -g Firmware/all_flash/iBoot.d22.RELEASE.im4p http://updates-http.cdn-apple.com/2021SpringFCS/fullrestores/071-17697/00D910BB-FB55-49BD-80F5-33A3D73EF831/iPhone10,3,iPhone10,6_14.5_18E199_Restore.ipsw
Version: 3fc8c093f4660f6c6e07c0c9214618733da01ffc - 36
libfragmentzip version: 0.62-6c8f5156558d83485c984b23a88e04845440fea2
init pzb: http://updates-http.cdn-apple.com/2021SpringFCS/fullrestores/071-17697/00D910BB-FB55-49BD-80F5-33A3D73EF831/iPhone10,3,iPhone10,6_14.5_18E199_Restore.ipsw
init done
getting: Firmware/all_flash/iBoot.d22.RELEASE.im4p
100% [===================================================================================================>]
download succeeded
On peut inspecter le fichier avec xxd
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
λ ~ » xxd iBoot.d22.RELEASE.im4p | head -n 15
00000000: 3083 10a9 7316 0449 4d34 5016 0469 626f 0...s..IM4P..ibo
00000010: 7416 1069 426f 6f74 2d36 3732 332e 3130 t..iBoot-6723.10
00000020: 322e 3404 8310 a8d0 8fc3 868f 0a45 1665 2.4..........E.e
00000030: 70f5 af72 28b6 0cdf 1cda 5d94 d91d 8180 p..r(.....].....
00000040: 0230 7637 f930 6db8 6f8c cfbf ce62 720d .0v7.0m.o....br.
00000050: 5685 8393 1fce 2cff 1cdb d340 1765 34f2 V.....,....@.e4.
00000060: d780 7c49 fe33 390e 696e f9a4 5f05 2e93 ..|I.39.in.._...
00000070: 867f 047c 5d5f c855 50d1 2c5c 7bea 82d2 ...|]_.UP.,\{...
00000080: 3a94 ac2d d44b 705a 59ef ff33 96fc ce54 :..-.KpZY..3...T
00000090: 5cfe b815 a46c e35d c541 1192 66f2 e924 \....l.].A..f..$
000000a0: 81fb 6a71 39f6 89b5 b92c 4f54 aa20 f275 ..jq9....,OT. .u
000000b0: 68e8 62b2 7fa7 28d4 1735 4df1 6e9c 68d0 h.b...(..5M.n.h.
000000c0: 555e 680a c787 12e5 4b6e b28e c7b1 3687 U^h.....Kn....6.
000000d0: 1aeb 65e3 eebb f4b1 136b 6958 6895 b5f8 ..e......kiXh...
000000e0: d2cd 232f 49f3 7369 cce8 6592 2cd1 79b6 ..#/I.si..e.,.y.
On remarque trois chaines de caractères :
IM4P
: le format des images Appleibot
: le type d’imageiBoot-6723.10.2.4
: la version de l’iBoot
Le reste est le payload qui contient les données brutes chiffrées.
Déchiffrer l’iBoot
L’accès au moteur AES pour récupérer les clés de chiffrement peut se faire uniquement depuis la SecureROM ou l’iBoot. Lors du démarrage, l’iBoot va désactiver l’accès au moteur AES avant de démarrer le kernel. Il n’est plus possible d’y accéder ou de le réactiver d’une quelconque façon sans redémarrer.
Mais grâce à checkm8, on peut exécuter du code dans la BootROM sur les appareils A7-A11 pour récupérer les clés permettant de déchiffrer les bootloaders.
img4lib
L’outil img4
présent dans img4lib va nous permettre de récupérer la kbag, mais aussi de déchiffrer l’iBoot. Pour cela, il faut cloner dépôt Github :
1
2
3
4
5
6
7
8
9
10
11
12
λ ~/dev » git clone https://github.com/xerub/img4lib && cd img4lib
Cloning into 'img4lib'...
remote: Enumerating objects: 217, done.
remote: Counting objects: 100% (30/30), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 217 (delta 18), reused 24 (delta 13), pack-reused 187
Receiving objects: 100% (217/217), 116.58 KiB | 4.66 MiB/s, done.
Resolving deltas: 100% (137/137), done.
λ ~/dev/img4lib(master) » git submodule update --init --recursive
Submodule 'lzfse' (https://github.com/lzfse/lzfse) registered for path 'lzfse'
Cloning into '/home/mathieu/dev/img4lib/lzfse'...
Submodule path 'lzfse': checked out '88e2d2788b4021d0b2eb9fe2d97352ae9190f128'
Puis on compile le projet. Veillez à avoir installé le paquet libssl-dev
.
1
2
3
4
λ ~/dev/img4lib(master) » make -C lzfse && make
make: Entering directory '/home/mathieu/dev/img4lib/lzfse'
[..]
gcc -o img4 -g -Llzfse/build/bin img4.o lzss.o libDER/DER_Encode.o libDER/DER_Decode.o libDER/oids.o libvfs/vfs_file.o libvfs/vfs_mem.o libvfs/vfs_sub.o libvfs/vfs_enc.o libvfs/vfs_lzss.o libvfs/vfs_lzfse.o libvfs/vfs_img4.o libimg4.a -llzfse -lcrypto
On se retrouve avec exécutable img4
. Dans un premier temps, on peut récupérer la kbag que l’on va utiliser pour récupérer la clé avec l’option -b
.
1
2
3
λ ~ » img4 -i iBoot.d22.RELEASE.im4p -b
7D0C73B2F6CF7B953F9BD9941EDCFA2E8321944DFD2B3A35EE834B27919167B6114F1932263A1A90038A4868A4DB82AA
B0D4280844D4E1E88970E881B75C186BA037E4140C8CF4C2888AE98812BA52082CEA176B9D0B0D3B3054EC9732D19834
L’outil affiche 2 chaînes de caractères. La première est la kbag utilisée pour déchiffrer les bootloaders pour les appareils de production. La seconde est dédiée aux appareils développement interne à Apple qui sont hors du scope de cet article.
ipwndfu
ipwndfu est l’outil initial qui implémente checkm8. Il permet d’effectuer certaines actions de bas niveau, comme dumper la SecureROM, activer le SWD, et déchiffrer les kbags. Mais il ne permet pas de jailbreak un iPhone.
La première étape est de passer l’iPhone en pwned DFU.
1
2
3
4
5
λ ~/dev/ipwndfu(master) » ./ipwndfu -p
*** checkm8 exploit by axi0mX ***
Found: CPID:8015 CPRV:11 CPFM:03 SCEP:01 BDID:0A ECID:0004784A0844A83A IBFL:3C SRTG:[iBoot-3332.0.0.1.23]
Device is now in pwned DFU Mode.
(1.56 seconds)
On peut ensuite déchiffrer la kbag avec l’option --decrypt-gid
:
1
2
3
λ ~/dev/ipwndfu(master) » ./ipwndfu --decrypt-gid 7D0C73B2F6CF7B953F9BD9941EDCFA2E8321944DFD2B3A35EE834B27919167B6114F1932263A1A90038A4868A4DB82AA
Decrypting with t8015si GID key.
af7f2f4752095c355a2784071e7e9354c30040fd396b854415f6b5682b1383e6a3df8e1b038d5ae535b8d8ee72de3735
La commande nous retourne la clé : af7f2f4752095c355a2784071e7e9354c30040fd396b854415f6b5682b1383e6a3df8e1b038d5ae535b8d8ee72de3735
. Il ne reste plus qu’à passer la clé avec img4
:
1
λ ~ » img4 -i iBoot.d22.RELEASE.im4p iBoot.d22.RELEASE.bin af7f2f4752095c355a2784071e7e9354c30040fd396b854415f6b5682b1383e6a3df8e1b038d5ae535b8d8ee72de3735
Pour vérifier si cela a fonctionné, vous pouvez inspecter le fichier avec xxd
. Si vous voyez la chaine de caractères iBoot for d22 cela indique que l’iBoot a été déchiffré avec succès !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
λ ~ » xxd -s 0x1d0 -l 0x100 iBoot.d22.RELEASE.bin
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000200: 6942 6f6f 7420 666f 7220 6432 322c 2043 iBoot for d22, C
00000210: 6f70 7972 6967 6874 2032 3030 372d 3230 opyright 2007-20
00000220: 3231 2c20 4170 706c 6520 496e 632e 0000 21, Apple Inc...
00000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000240: 5245 4c45 4153 4500 1f20 03d5 1f20 03d5 RELEASE.. ... ..
00000250: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000260: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000270: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000280: 6942 6f6f 742d 3637 3233 2e31 3032 2e34 iBoot-6723.102.4
00000290: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000002a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000002b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000002c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
PongoOS
PongoOS est un système d’exploitation bare metal utilisé dans l’outil de jailbreak checkra1n. C’est grâce à PongoOS qu’il est possible d’installer Android et Linux sur l’iPhone 7.
Il contient aussi un driver permettant d’interagir avec le moteur AES. Il est ainsi possible de déchiffrer les kbags avec la commande suivante : aes dec gid0 KBAG
.
Tout comme ipwndfu
, cette commande nous retourne la clé de déchiffrement.
Un inconvénient de PongoOS, c’est que pour interagir avec il faut un Mac pour l’instant. L’outil pongoterm utilisé pour communiquer avec Pongo n’est pas compatible avec Linux. La communication via la sortie série de l’iPhone est possible, mais necessite du materiel supplémentaire, comme un cable DCSD.
Autodecrypt
Si vous n’avez pas l’appareil cible pour lequel vous voulez analyser l’iBoot, il est toujours possible de récupérer les clés. Celles-ci sont disponibles sur theiphonewiki.
Pour automatiser le téléchargement de l’image, la récupération de la clé, puis le déchiffrement, j’ai écrit un outil : autodecrypt. Il va simplement aller scrapper le wiki, déchiffrer le bootloader sans aucune interaction.
Vous pouvez installer à l’aide de pip
ou directement depuis Github.
1
2
3
4
5
6
λ ~ » python3 -m pip install autodecrypt
Collecting autodecrypt
Downloading autodecrypt-2.2.2-py3-none-any.whl (10 kB)
[..]
Installing collected packages: identify, cfgv, nodeenv, pre-commit, remotezip, cssselect, lxml, pyquery, pyusb, soupsieve, beautifulsoup4, autodecrypt
Successfully installed autodecrypt-2.2.2 beautifulsoup4-4.9.3 cfgv-3.2.0 cssselect-1.1.0 identify-2.2.4 lxml-4.6.3 nodeenv-1.6.0 pre-commit-2.12.1 pyquery-1.4.3 pyusb-1.1.1 remotezip-0.9.3 soupsieve-2.2.1
Il suffit ensuite de spécifier le type de fichier, le modèle de l’iPhone et la version d’iOS.
1
2
3
4
5
6
7
8
9
λ ~ » autodecrypt -f iBoot -d iPhone10,6 -i 14.5
[w] could not get OTA url, trying with IPSW url
[i] downloading iBoot.d22.RELEASE.im4p
[i] image : iboot
[i] grabbing keys for iPhone10,6/18E199
[x] iv : af7f2f4752095c355a2784071e7e9354
[x] key : c30040fd396b854415f6b5682b1383e6a3df8e1b038d5ae535b8d8ee72de3735
[i] decrypting iBoot.d22.RELEASE.im4p to iBoot.d22.RELEASE.bin...
[x] done
Dans votre répertoire actuel vous aurez donc deux nouveaux fichiers : iBoot.d22.RELEASE.im4p
et iBoot.d22.RELEASE.bin
. Le fichier qui nous intéresse étant le second.
Ces 3 outils permettent à l’aide d’img4lib de déchiffrer les bootloaders Apple iOS, iPadOS, TVOS et même MacOS.
La GID key embarquée est la même pour chaque génération de SOC. Vous pouvez ainsi utiliser un appareil différent possédant la même generation de puce pour obtenir les clés. Par exemple, avec la puce A10 (t8010) et l’iPhone 7, vous pouvez récuperer les clés des bootloaders pour les iPad 6ème et 7ème génération.
Je n’ai pas parlé du SEP qui est toujours chiffré, mais avec l’exploit blackbird embarqué dans PongoOS, il est possible de déchiffrer le firmware pour les puces A10.
Le prochain post parlera des différentes méthodes que j’utilise récuperer les noms des fonctions et leur localisation dans les bootloader à l’aide de Binary Ninja.
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 :