hacktricks/mobile-pentesting/ios-pentesting/ios-app-extensions.md
2023-06-03 13:10:46 +00:00

15 KiB

Extensions d'application iOS

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Les extensions d'application permettent aux applications d'offrir des fonctionnalités et du contenu personnalisés aux utilisateurs lorsqu'ils interagissent avec d'autres applications ou le système. Voici quelques exemples notables :

  • Clavier personnalisé : remplace le clavier système iOS par un clavier personnalisé pour une utilisation dans toutes les applications.
  • Partager : publier sur un site de partage ou partager du contenu avec d'autres.
  • Aujourd'hui : également appelés widgets, ils offrent du contenu ou effectuent des tâches rapides dans la vue Aujourd'hui du Centre de notification.

Par exemple, l'utilisateur sélectionne du texte dans l'application hôte, clique sur le bouton "Partager" et sélectionne une "application" ou une action dans la liste. Cela déclenche l'extension d'application de l'application conteneur. L'extension d'application affiche sa vue dans le contexte de l'application hôte et utilise les éléments fournis par l'application hôte, le texte sélectionné dans ce cas, pour effectuer une tâche spécifique (le publier sur un réseau social, par exemple). Cette image du Guide de programmation des extensions d'application Apple résume assez bien cela :

Considérations de sécurité

Du point de vue de la sécurité, il est important de noter que :

  • Une extension d'application ne communique jamais directement avec son application conteneur (généralement, elle ne fonctionne même pas pendant que l'extension d'application contenue est en cours d'exécution).
  • Une extension d'application et l'application hôte communiquent via une communication inter-processus.
  • L'application conteneur de l'extension et l'application hôte ne communiquent pas du tout.
  • Un widget Aujourd'hui (et aucun autre type d'extension d'application) peut demander au système d'ouvrir son application conteneur en appelant la méthode openURL:completionHandler: de la classe NSExtensionContext.
  • Toute extension d'application et son application conteneur peuvent accéder à des données partagées dans un conteneur partagé défini de manière privée.
  • Les extensions d'application ne peuvent pas accéder à certaines API, par exemple, HealthKit.
  • Elles ne peuvent pas recevoir de données via AirDrop, mais peuvent envoyer des données.
  • Aucune tâche de fond de longue durée n'est autorisée, mais des téléchargements ou des téléversements peuvent être initiés.
  • Les extensions d'application ne peuvent pas accéder à la caméra ou au microphone d'un appareil iOS (sauf pour les extensions d'application iMessage).

Analyse statique

Vérification si l'application contient des extensions d'application

Si vous avez le code source original, vous pouvez rechercher toutes les occurrences de NSExtensionPointIdentifier avec Xcode (cmd+shift+f) ou jeter un coup d'œil dans "Build Phases / Embed App extensions" :

Vous pouvez y trouver les noms de toutes les extensions d'application intégrées suivies de .appex, vous pouvez maintenant accéder aux extensions d'application individuelles dans le projet.

Si vous n'avez pas le code source original :

Recherchez NSExtensionPointIdentifier parmi tous les fichiers à l'intérieur du bundle de l'application (IPA ou application installée) :

$ grep -nr NSExtensionPointIdentifier Payload/Telegram\ X.app/
Binary file Payload/Telegram X.app//PlugIns/SiriIntents.appex/Info.plist matches
Binary file Payload/Telegram X.app//PlugIns/Share.appex/Info.plist matches
Binary file Payload/Telegram X.app//PlugIns/NotificationContent.appex/Info.plist matches
Binary file Payload/Telegram X.app//PlugIns/Widget.appex/Info.plist matches
Binary file Payload/Telegram X.app//Watch/Watch.app/PlugIns/Watch Extension.appex/Info.plist matches

Vous pouvez également y accéder via SSH, trouver le bundle de l'application et lister tous les PlugIns à l'intérieur (ils y sont placés par défaut) ou le faire avec objection:

ph.telegra.Telegraph on (iPhone: 11.1.2) [usb] # cd PlugIns
    /var/containers/Bundle/Application/15E6A58F-1CA7-44A4-A9E0-6CA85B65FA35/
    Telegram X.app/PlugIns

ph.telegra.Telegraph on (iPhone: 11.1.2) [usb] # ls
NSFileType      Perms  NSFileProtection    Read    Write     Name
------------  -------  ------------------  ------  -------   -------------------------
Directory         493  None                True    False     NotificationContent.appex
Directory         493  None                True    False     Widget.appex
Directory         493  None                True    False     Share.appex
Directory         493  None                True    False     SiriIntents.appex

Nous pouvons maintenant voir les mêmes quatre extensions d'application que nous avons vues dans Xcode auparavant.

Détermination des types de données pris en charge

Ceci est important pour les données partagées avec des applications hôtes (par exemple via des extensions de partage ou d'action). Lorsque l'utilisateur sélectionne un type de données dans une application hôte et qu'il correspond aux types de données définis ici, l'application hôte proposera l'extension. Il convient de noter la différence entre cela et le partage de données via UIActivity où nous devions définir les types de documents, également en utilisant des UTI. Une application n'a pas besoin d'avoir une extension pour cela. Il est possible de partager des données en utilisant uniquement UIActivity.

Inspectez le fichier Info.plist de l'extension d'application et recherchez NSExtensionActivationRule. Cette clé spécifie les données prises en charge ainsi que, par exemple, le nombre maximal d'éléments pris en charge. Par exemple:

<key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsImageWithMaxCount</key>
            <integer>10</integer>
            <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
    </dict>

Seuls les types de données présents ici et n'ayant pas 0 comme MaxCount seront pris en charge. Cependant, un filtrage plus complexe est possible en utilisant une chaîne de prédicats appelée qui évaluera les UTI donnés. Veuillez vous référer au Guide de programmation des extensions d'application Apple pour plus d'informations détaillées à ce sujet.

Vérification du partage de données avec l'application conteneur

Rappelez-vous que les extensions d'application et leurs applications conteneurs n'ont pas un accès direct aux conteneurs de l'autre. Cependant, le partage de données peut être activé. Cela se fait via les "Groupes d'applications" et l'API NSUserDefaults. Voir cette figure du Guide de programmation des extensions d'application Apple:

Comme mentionné dans le guide, l'application doit configurer un conteneur partagé si l'extension d'application utilise la classe NSURLSession pour effectuer un téléchargement ou un téléversement en arrière-plan, afin que l'extension et son application conteneur puissent accéder aux données transférées.

Vérification si l'application restreint l'utilisation des extensions d'application

Il est possible de rejeter un type spécifique d'extension d'application en utilisant la méthode suivante:

Cependant, il est actuellement possible uniquement pour les extensions d'application "clavier personnalisé" (et doit être vérifié lors des tests d'applications manipulant des données sensibles via le clavier comme les applications bancaires, par exemple).

Analyse dynamique

Pour l'analyse dynamique, nous pouvons faire ce qui suit pour acquérir des connaissances sans avoir le code source:

  • Inspection des éléments partagés
  • Identification des extensions d'application impliquées

Inspection des éléments partagés

Pour cela, nous devons accrocher NSExtensionContext - inputItems dans l'application d'origine des données.

En suivant l'exemple précédent de Telegram, nous allons maintenant utiliser le bouton "Partager" sur un fichier texte (qui a été reçu d'un chat) pour créer une note dans l'application Notes avec celui-ci:

Si nous exécutons une trace, nous verrons la sortie suivante:

(0x1c06bb420) NSExtensionContext - inputItems
0x18284355c Foundation!-[NSExtension _itemProviderForPayload:extensionContext:]
0x1828447a4 Foundation!-[NSExtension _loadItemForPayload:contextIdentifier:completionHandler:]
0x182973224 Foundation!__NSXPCCONNECTION_IS_CALLING_OUT_TO_EXPORTED_OBJECT_S3__
0x182971968 Foundation!-[NSXPCConnection _decodeAndInvokeMessageWithEvent:flags:]
0x182748830 Foundation!message_handler
0x181ac27d0 libxpc.dylib!_xpc_connection_call_event_handler
0x181ac0168 libxpc.dylib!_xpc_connection_mach_event
...
RET: (
"<NSExtensionItem: 0x1c420a540> - userInfo:
{
    NSExtensionItemAttachmentsKey =     (
    "<NSItemProvider: 0x1c46b30e0> {types = (\n \"public.plain-text\",\n \"public.file-url\"\n)}"
    );
}"
)

Ici, nous pouvons observer que :

  • Cela s'est produit sous le capot via XPC, concrètement, il est implémenté via une NSXPCConnection qui utilise le framework libxpc.dylib.
  • Les UTI inclus dans le NSItemProvider sont public.plain-text et public.file-url, ce dernier étant inclus dans NSExtensionActivationRule du Info.plist de l'extension "Share" de Telegram.

Identification des extensions d'application impliquées

Vous pouvez également découvrir quelle extension d'application s'occupe de vos demandes et réponses en accrochant NSExtension - _plugIn :

Nous exécutons à nouveau le même exemple :

(0x1c0370200) NSExtension - _plugIn
RET: <PKPlugin: 0x1163637f0 ph.telegra.Telegraph.Share(5.3) 5B6DE177-F09B-47DA-90CD-34D73121C785
1(2) /private/var/containers/Bundle/Application/15E6A58F-1CA7-44A4-A9E0-6CA85B65FA35
/Telegram X.app/PlugIns/Share.appex>

(0x1c0372300)  -[NSExtension _plugIn]
RET: <PKPlugin: 0x10bff7910 com.apple.mobilenotes.SharingExtension(1.5) 73E4F137-5184-4459-A70A-83
F90A1414DC 1(2) /private/var/containers/Bundle/Application/5E267B56-F104-41D0-835B-F1DAB9AE076D
/MobileNotes.app/PlugIns/com.apple.mobilenotes.SharingExtension.appex>

Comme vous pouvez le voir, il y a deux extensions d'application impliquées :

  • Share.appex envoie le fichier texte (public.plain-text et public.file-url).
  • com.apple.mobilenotes.SharingExtension.appex qui reçoit et traitera le fichier texte.

Si vous voulez en savoir plus sur ce qui se passe sous le capot en termes de XPC, nous vous recommandons de jeter un coup d'œil aux appels internes de "libxpc.dylib". Par exemple, vous pouvez utiliser frida-trace et approfondir les méthodes qui vous semblent les plus intéressantes en étendant les stubs générés automatiquement.

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥