Début septembre, Apple a présenté l’iMac Pro, c’est une nouvelle machine de guerre destinée aux professionnels. Ce nouveau bijou de la marque à la pomme embarque en plus de macOS un autre système d’exploitation : bridgeOS.

iMac Pro

l’iMac Pro qui embarque cet OS est d’après le site d’Apple destiné aux Monteurs vidéo, animateurs 3D, musiciens, développeurs, scientifiques, etc…

imacpro

Ce nouvel ordinateur embarque un processeur Intel Xeon qui peut aller jusqu’à 18 cœurs et 22 teraflops, une possibilité de Turbo Boost jusqu’à 4,5 GHz. l’iMac Pro serait fourni avec un minimum de 32GB de RAM.

Pour ce qui est de réalité augmentée, Apple a fait fort, ils ont inauguré les nouvelles cartes graphiques d’AMD : Radeon Pro Vega 555 et 560.

Mais en plus de tout ça, cet iMac Pro contient un SoC d’iPhone 7 avec un système d’exploitation : BridgeOS

Pour info, un autre Mac est arrivé avec un OS embarqué il y a un an de ça : le MacBook Pro avec Touch Bar. La Touch Bar a son propre OS dérivé de WatchOS donc avec une architecture ARMv7, celui-ci est nommé embeddedOS.

BridgeOS

On va premièrement récupérer le dît OS, l’extraire pour ainsi l’analyser dans la seconde partie.

Téléchargement

BridgeOS est disponible depuis le catalogue logiciel d’Apple comme on peut voir avec ce noeud :

<dict>
	<key>Digest</key>
	<string>92065ba9dead00bca9a51439300ba2eb6d2cab42</string>
	<key>Size</key>
	<integer>145411417</integer>
	<key>MetadataURL</key>
	<string>https://swdist.apple.com/content/downloads/18/08/091-41916/yfl0z4f8iyfmwqre6nqpqk9h02cbsm580c/BridgeOSUpdateCustomer.pkm</string>
	<key>URL</key>
	<string>http://swcdn.apple.com/content/downloads/18/08/091-41916/yfl0z4f8iyfmwqre6nqpqk9h02cbsm580c/BridgeOSUpdateCustomer.pkg</string>
</dict>

C’est donc le lien dans la dernière balise <string> qui nous intéresse : on télécharge !

Extraction

On se retrouve donc avec un fichier ayant une extension .pkg.

$ file BridgeOSUpdateCustomer.pkg 
BridgeOSUpdateCustomer.pkg: xar archive - version 1

Pour extraire les composants de cet archive on va utiliser le logiciel Pacifist avec une license gratuite, c’est suffisant pour ce qu’on veut faire.

pacifist-def

Comme dit plus haut, l’archive est au format xar, donc on va cliquer sur le premier onglet : “Ouvrir un paquet”. Ensuite on sélectionne le fichier BridgeOSUpdateCustomer.pkg qu’on a téléchargé.

pacifist-pack

Une nouvelle fenêtre s’ouvre et on peut voir l’architecture du fichier. La partie la plus intéressante se trouve dans le fichier UpdatedBundle.zip. Pour extraire le fichier de l’archive c’est simple, vous glissez-déposez le fichier n’importe où. Pour ma part ça sera sur le bureau.

Toujours au format .zip, vous le décompressez et vous obtenez un répertoire comme ceci :

bndl

Analyse

On a récupéré puis extrait l’archive on va maintenant faire une analyse approfondie de ce (pas si) mystérieux système d’exploitation

Architecture

Voici comment est organisé le repertoire UpdateBundle , si vous avez déjà jeté un oeil à une mise à jour firmware OTA d’iPhone ou d’iPad, les architectures sont similaires.

UpdateBundle/
├──boot/
├─── 058-69774-293.dmg
├─── BuildManifest.plist
├─── 058-32359-015.dmg
├─── Firmware/
├───── AOP/
├─────── aopfw-t8012aop.im4p
├───── MacEFI/
├─────── J137.im4p
├───── all_flash/
├─────── DeviceTree.j137ap.im4p
├─────── DeviceTree.j137ap.im4p.plist
├─────── LLB.j137.RELEASE.im4p
├─────── LLB.j137.RELEASE.im4p.plist
├─────── iBoot.j137.RELEASE.im4p
├─────── iBoot.j137.RELEASE.im4p.plist
├─────── sep-firmware.j137.RELEASE.im4p
├─────── sep-firmware.j137.RELEASE.im4p.plist
├───── dfu/
├─────── iBEC.j137.RELEASE.im4p
├─────── iBEC.j137.RELEASE.im4p.plist
├─────── iBSS.j137.RELEASE.im4p
├─────── iBSS.j137.RELEASE.im4p.plist
├───── usr/
├─────── local/
├────── standalone/
├─── kernelcache.release.j137
├── Info.plist
├── META-INF
├── payload
├── payload.bom
├── payload.bom.signature
├── payloadv2
├── post.bom
└── pre.bom

Boot

Le répertoire boot contient tous les fichiers de démarrage de BridgeOS : c’est à dire le noyau, les chargeurs d’amorçage, etc…

Kernel

Tout d’abord on va jeter un oeil au noyau : kernelcache.release.j137. Comme les tous les appareils 64 bits (hors Mac) le noyau est un fichier IMG4 de type IM4P. De plus celui-ci est compressé au format lzfse.

Pour le décompresser on utilise l’outil img4tool de xerub :

$ img4 -i kernelcache.release.j137 kernelcache.release.j137.dec
krnl
$ file kernelcache.release.j137.dec
kernelcache.release.j137.dec: Mach-O 64-bit executable arm64

L’utilisation de l’utilitaire file nous confirme bien que le noyau est un fichier pour arm64, donc le SoC a bien un processeur 64 bits.

On va ensuite obtenir la version ainsi que le type de SoC. Pour éviter de lancer IDA Pro on utilise strings comme ceci :

$ strings kernelcache.release.j137.dec | grep "Darwin Kernel Version"
Darwin Kernel Version 17.2.0: Thu Sep 21 17:29:18 PDT 2017; root:xnu-4570.20.58~3/RELEASE_ARM64_T8010

Les caractères RELEASE_ARM64_T8010 signifient que BridgeOS embarque un processeur A10 d’iPhone 7.

Avec jtool on affiche les 4 dernières sections du noyau :

$ jtool -l kernelcache.release.j137.dec| tail -n 4
LC 17: LC_BUILD_VERSION         Build Version:           Platform: BridgeOS 2.0.0
LC 18: LC_SOURCE_VERSION        Source Version:          4570.20.58.0.0
LC 19: LC_UNIXTHREAD            Entry Point:             0xfffffff0070d00c0
LC 20: LC_FUNCTION_STARTS       Offset: 6355032, Size: 18368 (0x60f858-0x614018)

La version de BridgeOS est la 2.0.0, donc soit la version 1.0 est celle de eOS (embedded OS) soit une version testée en interne. Le noyau a été compilé avec les sources de la version 4570.20.58.0.0 de XNU. Le code source pour cette version n’est pas encore Open Source, la dernière version dont le code est disponible est la xnu-4570.1.46.

iBoot - LLB - iBEC/iBSS

Tous ces composants de la chaine de demarrage d’iOS sont toujours chiffrés. Bien qu’Apple publie ses kernelcaches et autres composants comme le devicetree de façon non-chiffrée, les bootloaders des appareils 64 bits sont toujours chiffrés.

SEP

Au niveau hardware il n’y a aucun moyen de savoir si celui-ci est présent puisque l’iMac Pro n’est pas encore sorti. Bien heureusement le firmware est présent dans le même répertoire que les chargeurs d’amorçage : sep-firmware.j137.RELEASE.im4p.

De plus certaines extensions sont présentes dans le kernelcache notamment le SEP Manager qui permet de faire communiquer certains drivers avec le SEP.

$ joker -k kernelcache.release.j137.dec | grep SEP
0xfffffff0064df980: AppleSEPManager (com.apple.driver.AppleSEPManager)
0xfffffff0064f5300: AppleSEPKeyStore (com.apple.driver.AppleSEPKeyStore)
0xfffffff00655ab00: AppleSEPCredentialManager (com.apple.driver.AppleSEPCredentialManager)

Pour plus d’informations sur le Secure Enclave Processor je vous invite à lire mon post sur son analyse complète.

MacEFI

Le répertoire MacEFI contient un fichier. Celui-ci étant compressé, on lance img4tool :

$ img4 -i J137.im4p J137.im4p.dec
mefi
$ file J137.im4p.dec
J137.im4p.dec: Intel serial flash for PCH ROM

j137

On dirait que le but de l’implémentation d’une image EFI permettrait au processeur A10 de gérer le démarrage de l’iMac Pro puis d’ainsi autoriser le processeur Intel à démarrer.

Il semble que MacEFI ai un rôle à jouer avec la kext MacEFIManager (com.apple.driver.MacEFIManager). On va utiliser la fonction d’extraction de kexts de joker

joker -K com.apple.driver.MacEFIManager kernelcache.release.j137.dec
mmapped: 0x1256bb000
This is a 64-bit kernel from iOS 11.x (b1+), or later (4570.20.58.0.0)
ARM64 Exception Vector is at file offset @0xc7000 (Addr: 0xfffffff0070cb000)
Found com.apple.driver.MacEFIManager at load address: fffffff00655eb00, offset: 836b00
Writing kext out to /tmp/com.apple.driver.MacEFIManager.kext
Workaround for Apple offset bug in the kernelcache!
[...]
Symbolicated stubs to /tmp/com.apple.driver.MacEFIManager.kext.ARM64.4DE3DF0C-6B6D-3663-ACC3-B3276414A4A3
Dumping symbol cache to file
$ file /tmp/com.apple.driver.MacEFIManager.kext
/tmp/com.apple.driver.MacEFIManager.kext: Mach-O 64-bit kext bundle arm64

Il semble que c’est cette kext qui initialise et gère la NVRAM lors du démarrage.

coolkext

Mise à part IDA Pro je n’ai aucun moyen de plonger plus profondément dans cette image, néanmoins je vais continuer à chercher ce que je peux trouver d’intéressant.

Root File System

Les rootFS de BridgeOS sont emballé dans un fichier nommé payload dans le dossier payloadv2. Car pour rappel l’archive contenant le système d’exploitation est censé être une fichier de mise à jour OTA.

D’après les articles de J Levin sur les mises à jour OTA, ce payload est au format pbzx comme ceci :

pb

Pour obtenir les rootfs on va donc utiliser pbzx convertir le payload au format compressé zx puis on va l’extraire avec l’outil ota aussi écrit par Jonathan Levin.

$ cat ../payload | pbzx > p
Flags: 0x1000000
Chunk #1 (flags: 1000000, length: 4816048 bytes)
OK!  (16777216 bytes)
Chunk #2 (flags: 1000000, length: 7874752 bytes)
OK!  (16777216 bytes)
[...]
Chunk #19 (flags: 3e338e, length: 636632 bytes)
OK!  (4075520 bytes)
$ ota  -e '*' ./p
$ ls
Library System  bin     etc     p       private sbin    tmp     usr

Et voilà ! On obtient donc les fichiers systèmes de BridgeOS. Encore une fois si on compare par rapport à un fichier de mise à jour OTA de l’iPhone, on n’a pas tous ces dossiers d’applications etc…

Encore une fois avec l’utilitaire file , on voit bien que c’est un processeur 64 bits :

$ file bin/ps
bin/ps: Mach-O 64-bit executable arm64

MacEFIUtil

L’exécutable MacEFIUtil qu’on retrouve dans /usr/bin/ sert aussi a gérer la NVRAM et est aussi en contact avec le Mangement Engine d’Intel. L’outil permet de :

  • Initialiser l’interface SPI embarquée.
  • “commit” un snapshot de l’interface SPI embarquée (eSPI)
  • Faire une sauvegarde de la NVRAM vers le disque
  • Restaurer un snapshot de la NVRAM depuis le disque
  • Sauvegarder les régions mémoire du Management Engine vers le disque
  • Restaurer ces mêmes régions depuis le disque
  • Exécuter des commandes NVRAM

Au final, BridgeOS servirait de chaine de demarrage sécurisée pour vérifier que le seul code signé ou de confiance soit chargé.

BridgeOS demarrerait même avant macOS juste pour verifier si il n’y a pas de bootkit ou autre malware qui persiste à chaque demarrage (et même après mise à jour).

Pour conclure, Apple abandonne petit à petit les solutions de Intel pour appliquer ses propres outils au niveau de la bootchain sur Mac. Le Secure Boot a fait ses preuves depuis ses 10 dernières années sur les appareils iOS d’Apple.

En implémentant un système comme le Secure Boot d’iOS, mais aussi le SEP, cela permet d’ajouter des fonctions comme “Hey Siri” sur macOS, mais pourquoi pas FaceID sur les prochains Mac avec un processeur A11 Bionic ?

Si vous avez besoin d’infos contactez-moi sur twitter: @matteyeux

Github : https://github.com/matteyeux


Sources : http://newosxbook.com/articles/OTA.html

http://newosxbook.com/articles/OTA2.html

http://newosxbook.com/articles/OTA3.html

http://newosxbook.com/articles/OTA4.html

http://newosxbook.com/articles/OTA5.html

http://newosxbook.com/articles/BridgeOS.html

http://opensecuritytraining.info/IntroBIOS_files/Day2_01_Advanced%20x86%20-%20BIOS%20and%20SMM%20Internals%20-%20SPI%20Flash.pdf