macOS - AMFI - AppleMobileFileIntegrity

Reading time: 7 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

AppleMobileFileIntegrity.kext et amfid

Il se concentre sur l'application de l'intégrité du code exécuté sur le systÚme, fournissant la logique derriÚre la vérification de la signature du code de XNU. Il est également capable de vérifier les droits et de gérer d'autres tùches sensibles telles que permettre le débogage ou obtenir des ports de tùche.

De plus, pour certaines opérations, le kext préfÚre contacter l'espace utilisateur exécutant le démon /usr/libexec/amfid. Cette relation de confiance a été abusée dans plusieurs jailbreaks.

AMFI utilise des politiques MACF et enregistre ses hooks au moment de son dĂ©marrage. De plus, empĂȘcher son chargement ou son dĂ©chargement pourrait dĂ©clencher un kernel panic. Cependant, il existe certains arguments de dĂ©marrage qui permettent de dĂ©biliter AMFI :

  • amfi_unrestricted_task_for_pid: Permet Ă  task_for_pid d'ĂȘtre autorisĂ© sans droits requis
  • amfi_allow_any_signature: Autorise toute signature de code
  • cs_enforcement_disable: Argument systĂšme utilisĂ© pour dĂ©sactiver l'application de la signature de code
  • amfi_prevent_old_entitled_platform_binaries: Annule les binaires de plateforme avec des droits
  • amfi_get_out_of_my_way: DĂ©sactive complĂštement amfi

Voici quelques-unes des politiques MACF qu'il enregistre :

  • cred_check_label_update_execve: La mise Ă  jour de l'Ă©tiquette sera effectuĂ©e et renverra 1
  • cred_label_associate: Met Ă  jour le slot d'Ă©tiquette mac d'AMFI avec l'Ă©tiquette
  • cred_label_destroy: Supprime le slot d'Ă©tiquette mac d'AMFI
  • cred_label_init: DĂ©place 0 dans le slot d'Ă©tiquette mac d'AMFI
  • cred_label_update_execve: Il vĂ©rifie les droits du processus pour voir s'il doit ĂȘtre autorisĂ© Ă  modifier les Ă©tiquettes.
  • file_check_mmap: Il vĂ©rifie si mmap acquiert de la mĂ©moire et la dĂ©finit comme exĂ©cutable. Dans ce cas, il vĂ©rifie si la validation de la bibliothĂšque est nĂ©cessaire et, si c'est le cas, appelle la fonction de validation de la bibliothĂšque.
  • file_check_library_validation: Appelle la fonction de validation de la bibliothĂšque qui vĂ©rifie, entre autres, si un binaire de plateforme charge un autre binaire de plateforme ou si le processus et le nouveau fichier chargĂ© ont le mĂȘme TeamID. Certains droits permettront Ă©galement de charger n'importe quelle bibliothĂšque.
  • policy_initbsd: Configure les clĂ©s NVRAM de confiance
  • policy_syscall: Il vĂ©rifie les politiques DYLD comme si le binaire a des segments non restreints, s'il doit autoriser les variables d'environnement... cela est Ă©galement appelĂ© lorsqu'un processus est dĂ©marrĂ© via amfi_check_dyld_policy_self().
  • proc_check_inherit_ipc_ports: Il vĂ©rifie si, lorsqu'un processus exĂ©cute un nouveau binaire, d'autres processus avec des droits SEND sur le port de tĂąche du processus doivent les conserver ou non. Les binaires de plateforme sont autorisĂ©s, le droit get-task-allow le permet, les droits task_for_pid-allow sont autorisĂ©s et les binaires avec le mĂȘme TeamID.
  • proc_check_expose_task: applique les droits
  • amfi_exc_action_check_exception_send: Un message d'exception est envoyĂ© au dĂ©bogueur
  • amfi_exc_action_label_associate & amfi_exc_action_label_copy/populate & amfi_exc_action_label_destroy & amfi_exc_action_label_init & amfi_exc_action_label_update: Cycle de vie de l'Ă©tiquette lors du traitement des exceptions (dĂ©bogage)
  • proc_check_get_task: VĂ©rifie les droits comme get-task-allow qui permet Ă  d'autres processus d'obtenir le port des tĂąches et task_for_pid-allow, qui permet au processus d'obtenir les ports des tĂąches d'autres processus. Si aucun de ceux-ci, il appelle amfid permitunrestricteddebugging pour vĂ©rifier si c'est autorisĂ©.
  • proc_check_mprotect: Refuser si mprotect est appelĂ© avec le drapeau VM_PROT_TRUSTED qui indique que la rĂ©gion doit ĂȘtre traitĂ©e comme si elle avait une signature de code valide.
  • vnode_check_exec: Est appelĂ© lorsque des fichiers exĂ©cutables sont chargĂ©s en mĂ©moire et dĂ©finit cs_hard | cs_kill qui tuera le processus si l'une des pages devient invalide
  • vnode_check_getextattr: MacOS: VĂ©rifie com.apple.root.installed et isVnodeQuarantined()
  • vnode_check_setextattr: Comme get + com.apple.private.allow-bless et droit Ă©quivalent d'installateur interne
  • vnode_check_signature: Code qui appelle XNU pour vĂ©rifier la signature de code en utilisant des droits, un cache de confiance et amfid
  • proc_check_run_cs_invalid: Il intercepte les appels ptrace() (PT_ATTACH et PT_TRACE_ME). Il vĂ©rifie pour l'un des droits get-task-allow, run-invalid-allow et run-unsigned-code et si aucun, il vĂ©rifie si le dĂ©bogage est autorisĂ©.
  • proc_check_map_anon: Si mmap est appelĂ© avec le drapeau MAP_JIT, AMFI vĂ©rifiera le droit dynamic-codesigning.

AMFI.kext expose également une API pour d'autres extensions de noyau, et il est possible de trouver ses dépendances avec :

bash
kextstat | grep " 19 " | cut -c2-5,50- | cut -d '(' -f1
Executing: /usr/bin/kmutil showloaded
No variant specified, falling back to release
8   com.apple.kec.corecrypto
19   com.apple.driver.AppleMobileFileIntegrity
22   com.apple.security.sandbox
24   com.apple.AppleSystemPolicy
67   com.apple.iokit.IOUSBHostFamily
70   com.apple.driver.AppleUSBTDM
71   com.apple.driver.AppleSEPKeyStore
74   com.apple.iokit.EndpointSecurity
81   com.apple.iokit.IOUserEthernet
101   com.apple.iokit.IO80211Family
102   com.apple.driver.AppleBCMWLANCore
118   com.apple.driver.AppleEmbeddedUSBHost
134   com.apple.iokit.IOGPUFamily
135   com.apple.AGXG13X
137   com.apple.iokit.IOMobileGraphicsFamily
138   com.apple.iokit.IOMobileGraphicsFamily-DCP
162   com.apple.iokit.IONVMeFamily

amfid

C'est le démon en mode utilisateur que AMFI.kext utilisera pour vérifier les signatures de code en mode utilisateur.
Pour que AMFI.kext communique avec le démon, il utilise des messages mach via le port HOST_AMFID_PORT, qui est le port spécial 18.

Notez qu'il n'est plus possible dans macOS pour les processus root de détourner des ports spéciaux car ils sont protégés par SIP et seul launchd peut y accéder. Dans iOS, il est vérifié que le processus renvoyant la réponse a le CDHash codé en dur de amfid.

Il est possible de voir quand amfid est demandĂ© pour vĂ©rifier un binaire et la rĂ©ponse de celui-ci en le dĂ©boguant et en plaçant un point d'arrĂȘt dans mach_msg.

Une fois qu'un message est reçu via le port spécial, MIG est utilisé pour envoyer chaque fonction à la fonction qu'il appelle. Les principales fonctions ont été inversées et expliquées dans le livre.

Provisioning Profiles

Un profil de provisionnement peut ĂȘtre utilisĂ© pour signer du code. Il existe des profils Developer qui peuvent ĂȘtre utilisĂ©s pour signer du code et le tester, et des profils Enterprise qui peuvent ĂȘtre utilisĂ©s sur tous les appareils.

AprÚs qu'une application soit soumise à l'Apple Store, si elle est approuvée, elle est signée par Apple et le profil de provisionnement n'est plus nécessaire.

Un profil utilise gĂ©nĂ©ralement l'extension .mobileprovision ou .provisionprofile et peut ĂȘtre extrait avec :

bash
openssl asn1parse -inform der -in /path/to/profile

# Or

security cms -D -i /path/to/profile

Bien que parfois appelés certifiés, ces profils de provisioning ont plus qu'un certificat :

  • AppIDName : L'identifiant de l'application
  • AppleInternalProfile : DĂ©signe ceci comme un profil interne Ă  Apple
  • ApplicationIdentifierPrefix : PrĂ©fixĂ© Ă  AppIDName (identique Ă  TeamIdentifier)
  • CreationDate : Date au format YYYY-MM-DDTHH:mm:ssZ
  • DeveloperCertificates : Un tableau de certificat(s) (gĂ©nĂ©ralement un), encodĂ© en donnĂ©es Base64
  • Entitlements : Les droits autorisĂ©s avec les droits pour ce profil
  • ExpirationDate : Date d'expiration au format YYYY-MM-DDTHH:mm:ssZ
  • Name : Le nom de l'application, identique Ă  AppIDName
  • ProvisionedDevices : Un tableau (pour les certificats de dĂ©veloppeur) de UDIDs pour lesquels ce profil est valide
  • ProvisionsAllDevices : Un boolĂ©en (vrai pour les certificats d'entreprise)
  • TeamIdentifier : Un tableau de chaĂźne(s) alphanumĂ©rique(s) (gĂ©nĂ©ralement une) utilisĂ©e(s) pour identifier le dĂ©veloppeur Ă  des fins d'interaction entre applications
  • TeamName : Un nom lisible par l'homme utilisĂ© pour identifier le dĂ©veloppeur
  • TimeToLive : ValiditĂ© (en jours) du certificat
  • UUID : Un identifiant unique universel pour ce profil
  • Version : Actuellement dĂ©fini sur 1

Notez que l'entrée des droits contiendra un ensemble restreint de droits et que le profil de provisioning ne pourra donner que ces droits spécifiques pour éviter de donner des droits privés à Apple.

Notez que les profils se trouvent généralement dans /var/MobileDeviceProvisioningProfiles et qu'il est possible de les vérifier avec security cms -D -i /path/to/profile

libmis.dyld

C'est la bibliothÚque externe que amfid appelle pour demander s'il doit autoriser quelque chose ou non. Cela a été historiquement abusé dans le jailbreak en exécutant une version backdoorée qui permettrait tout.

Dans macOS, cela se trouve dans MobileDevice.framework.

AMFI Trust Caches

iOS AMFI maintient une liste de hachages connus qui sont signés ad-hoc, appelée Trust Cache et trouvée dans la section __TEXT.__const du kext. Notez que dans des opérations trÚs spécifiques et sensibles, il est possible d'étendre ce Trust Cache avec un fichier externe.

References

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks