
un framework Ghidra pour le reverse engineering du kernelcache iOS
Ce framework est le produit final de mon expérience en reverse engineering de Kernelcache. Je cherche généralement des vulnérabilités en auditant manuellement le noyau et ses extensions, et j'ai automatisé la plupart des choses que je voulais vraiment voir dans Ghidra pour accélérer le processus de reverse engineering, ce qui s'est avéré efficace et permet de gagner beaucoup de temps. Le framework fonctionne sur iOS 12/13/14/15 et sur macOS 11/12 (à la fois kernelcache et KEXT unique) et a été rendu public dans le but d'aider les gens à commencer à rechercher sur le noyau iOS sans avoir à préparer leur propre environnement. À mon avis, ce framework (incluant l'ensemble d'outils qu'il fournit et avec quelques connaissances de base en IOKit) est suffisant pour commencer à bidouiller le Kernelcache.
Le framework est entièrement écrit en Python et peut être étendu pour construire d'autres outils. Il fournit quelques API de base que vous pouvez utiliser dans presque tous les projets et gagner du temps en évitant de lire le manuel verbeux. Vous êtes invité à lire les fonctionnalités principales dans le répertoire utils/.
Ghidra est bon pour analyser les Kernelcaches, mais comme d'autres outils de reverse engineering, il nécessite un certain travail manuel. ghidra_kernelcache fournit un bon point d'entrée pour corriger les choses au début et même pendant le reverse engineering, offrant ainsi une sortie de décompilateur agréable.
Il existe un projet similaire créé par @_bazad dans IDAPro appelé ida_kernelcache qui fournit un bon point d'entrée pour les chercheurs souhaitant travailler avec l'image du noyau dans IDA. Mon framework ressemble un peu au travail de Brandon, et va plus loin en fournissant beaucoup plus de fonctionnalités pour rendre le processus de travail avec le kernelcache moins pénible.
::externalMethod() et ::getTargetAndMethodForIndex().Ces fonctionnalités sont réalisées sous forme d'outils séparés qui peuvent être exécutés soit par des raccourcis clavier, soit en cliquant sur leurs icônes dans la barre d'outils.
Clonez le dépôt :```sh git clone https://github.com/0x36/ghidra_kernelcache.git
**Note importante** : Le projet a été testé sur Ghidra 10.1_PUBLIC et 10.2_DEV et n'est pas rétrocompatible.
Allez dans *`Windows → Script Manager`,* cliquez sur *`script Directory`*, puis ajoutez *`ghidra_kernelcache`* à la liste des chemins de répertoires.
Allez dans *`Windows → Script Manager`,* dans la liste *scripts*, allez dans la catégorie *`iOS→kernel`* et cochez les plugins qui y apparaissent, ils apparaîtront dans la barre d'outils GHIDRA.
dans le répertoire [logos/](https://github.com/0x36/ghidra_kernelcache/tree/master/logos), vous pouvez placer vos propres logos pour chaque outil.
## iOS kernelcache symbolication
`ghidra_kernelcache` nécessite dans un premier temps [iometa](https://github.com/Siguza/iometa/) (réalisé par [@s1guza](https://twitter.com/s1guza)), un outil puissant fournissant des informations sur les classes C++ dans le binaire du noyau. Le grand avantage est qu'il fonctionne comme un binaire autonome, donc la sortie peut être importée dans votre framework RE favori en la parsant simplement. Mon framework prend la sortie d'iometa et la parse pour symboliser et corriger les tables virtuelles.
### Utilisation
Après avoir décompressé le noyau, exécutez les commandes suivantes :```sh
$ iometa -n -A /tmp/kernel A10-legacy.txt > /tmp/kernel.txt
# if you want also to symbolicate using jtool2
$ jtool2 --analyze /tmp/kernel
Chargez le kernelcache dans Ghidra, N'UTILISEZ PAS l'import BATCH, chargez-le comme une image Mach-O.
Après que le Kernelcache soit chargé et auto-analysé, cliquez sur l'icône affichée dans la barre d'outils ou appuyez simplement sur Meta-Shift-K, puis insérez le chemin complet de la sortie d'iometa, qui est /tmp/kernel.txt dans notre cas.
si vous souhaitez utiliser les symboles jtool2, vous pouvez également utiliser jsymbol.py situé dans la catégorie iOS→kernel.
Des exemples complets de l'API se trouvent dans ghidra_kernelcache/kc.py
→ Voici quelques exemples de manipulation des objets de classe :```py from utils.helpers import * from utils.class import * from utils.iometa import ParseIOMeta
ff = "/Users/mg/ghidra_ios/kernel.txt" iom = ParseIOMeta(ff) Obj = iom.getObjects() kc = kernelCache(Obj)
kc.process_all_classes()
kc.process_classes_for_bundle("com.apple.iokit.IOSurface")
kc.process_classes_for_bundle("kernel")
kc.process_class("IOGraphicsAccelerator2")
kc.clear_class_structures()
kc.update_classes_vtable()
kc.explore_pac()
Comme vous pouvez le voir, vous pouvez symboliser entièrement ou partiellement le kernelcache ; si la symbolisation partielle est choisie, `ghidra_kernelcache` construira automatiquement toutes les dépendances de classes avant de continuer. Si vous exécutez le script sur l'ensemble du kernelcache (symbolisation complète), `ghidra_kernelcache` prendra plusieurs minutes pour analyser l'image du noyau.
Une fois terminé, Ghidra fournira ce qui suit :
→ Une nouvelle catégorie a été ajoutée dans le filtre de signets appelée « iOS » :
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image1.png" alt="image1" width="200"/>
→ Les tables virtuelles de classes IOKit sont ajoutées au signet « iOS » pour une recherche plus rapide et plus efficace de tables virtuelles ; vous pouvez simplement chercher un kext ou une classe en fournissant des lettres, des mots ou le bundle du kext dans la barre de recherche.
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image2.png" alt="image2"/>
→ Correction de la table virtuelle : désassemble/compile le code inconnu, corrige les espaces de noms, re-symbolise les méthodes de classe et applique une définition de fonction à chaque méthode :
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image3.png" alt="image3"/>
→ Création d'espaces de noms de classe et placement de chaque méthode dans son propre espace de noms correspondant :
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image4.png" alt="image4"/>
→ Création de la structure de classe en respectant la hiérarchie des classes :
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image5.png" alt="image5"/>
→ Création des tables virtuelles (vtables) de classe, et chaque méthode possède sa propre définition de méthode pour une meilleure sortie de décompilation :