Auditer la sécurité d’une application iOS avec Needle – partie 1/2

Needle [needle] (aiguille en anglais) est un cadriciel (framework) open source qui accélère considérablement les analyses orientées sécurité des applications iOS. Conçu par Marco Lancini de la société MWR et présenté lors de l’édition 2016 de Black Hat Vegas, il prend une place laissée vacante jusqu’à maintenant. Sans lui les testeurs étaient obligés de s’armer de tout un tas d’outils disposant chacun de sa syntaxe, de son mode opératoire et de ses limitations. Avec Needle de très nombreuses actions peuvent maintenant être lancées depuis une interface unique, avec une syntaxe et un esprit modulaire « à la metasploit » qui plus est !

1. Pas de bonne trousse à outils sans aiguille

L’installation très bien documentée [installation] se fait rapidement et sans douleur sur Kali et OS X et ne mérite donc pas de s’étendre dessus. Elle consiste à installer les quelques dépendances comme python, sqlite, frida ou sshtunnel puis à faire un git clone. Un docker devrait même être bientôt disponible, ce qui laisse peu d’excuses pour ne pas l’essayer.

Fig. 1 : Lancement de Needle !


Les habitués de Metasploit ne seront pas dépaysés, la structure modulaire reprend le même principe : on sélectionne un module (
use xxx), on spécifie une cible (ici une application plutôt qu’un hôte dans Metasploit), on fournit éventuellement une ou plusieurs options (set OPTION1 xxx), on supprime une option (unset OPTION2) et on lance le tout (run). Il est également possible de lister les tâches qui tournent en arrière-plan (job) puis de les arrêter (kill).

Certaines commandes basiques, mais essentielles empruntent la même syntaxe : pull/push pour rapatrier ou déposer des fichiers, shell pour obtenir un shell sur le terminal, search pour chercher une chaîne de caractères dans les modules (pratique pour retrouver rapidement un module) et les commandes sont historisées depuis la version 0.2.0 : la flèche du haut rappellera les dernières commandes.

2. Les étapes de l’analyse d’une application

Avant de commencer à aiguillonner, rappelons les grandes étapes d’une analyse d’application iOS : analyse de code (encore faut-il en disposer), analyse des données (les préférences utilisateur, cookies, caches, etc.), contournement des fonctions de sécurité s’il y en a (détection de jailbreak, code pin, etc.) puis finalement interception des communications réseau.

Chaque étape demandera l’utilisation de techniques et d’outils particuliers. La plupart de ces opérations ne seront donc réalisables que sur un terminal jailbreaké de manière à pouvoir bénéficier d’allègement des fonctions de sécurité ainsi que des logiciels nécessaires qui ne sont pas disponibles sur le store officiel.

Sur la figure 2, les étapes principales sont listées et pour chacune est indiqué le besoin de disposer d’un terminal jailbreaké ou non.

Fig. 2 : Techniques et leur besoin de jailbreak.


On voit que c’est surtout ce qui concerne l’analyse des communications qui est réalisable sans jailbreak et encore cela est impossible si l’application utilise le
certificate pinning, ce qui est de plus en plus fréquent.

En effet, cette analyse va généralement commencer par la mise en place d’un proxy intercepteur (comme Burp Suite [burpsuite]) qui introduira fatalement une rupture SSL/TLS que l’application auditée ne tolèrera pas, car elle s’attendra à recevoir un certificat bien particulier et sans lui elle stoppera la communication.

3. Environnement de test

On vient de voir qu’il était préférable d’avoir sous la main un terminal jailbreaké pour réaliser un audit de sécurité. Pour Needle, c’est indispensable et c’est un prérequis parfois difficile à remplir : tous les terminaux (tablettes ou smartphones) et toutes les versions d’iOS ne sont pas débridables.

Il suffit de consulter la figure 3 (provenant du site [iphonewiki]), qui liste les jailbreaks disponibles pour iOS 9, pour s’en rendre compte.

Fig. 3 : Jailbreaks pour iOS9.


Pour corser le tout, certaines dépendances de l’outil ne sont pas compatibles avec iOS 9 ou supérieur et d’autres encore ne fonctionnent pas avec les plateformes 64bits. La version
0.2.0 de Needle, sortie en février 2017, introduit un premier support d’iOS 10 et la version 1.0.0 sortie en mars 2017 l’améliore encore en intégrant NeedleAgent, une application iOS à installer sur le terminal qui permet de s’affranchir des différents problèmes de compatibilité et de dépendances en intégrant directement certaines fonctionnalités comme celles de class_dump. C’est toutefois la version 0.2.0, plus stable, qui a été utilisée pour cet article.

Mais le casse-tête ne s’arrête pas là, il faut également prendre en compte la version d’iOS minimale requise pour faire fonctionner l’application à auditer, souvent iOS 8 aujourd’hui. Il faut donc se tourner vers un terminal et une version d’iOS suffisamment récents pour qu’ils puissent lancer l’application à auditer, mais pas trop non plus pour pouvoir disposer d’un jailbreak correct et des dépendances qui vont bien. Si vous trouvez un terminal dans une version débridable d’iOS 8 vous serez donc dans la meilleure configuration possible, jusqu’à ce que les applications requièrent iOS 9 minimum, soit probablement d’ici quelques mois.

Une fois Needle installé et le terminal jailbreaké relié à l’ordinateur (par USB ou alors connecté au même réseau Wifi), Needle va pouvoir commencer à picoter.

4. Analyses

4.1 L’analyse statique

Si le code source de l’application est fourni, la recherche de chaînes de caractères spécifiques peut s’avérer très utile, car elle peut dévoiler de nombreuses informations permettant d’aider l’auditeur à découvrir certaines vulnérabilités. On peut citer par exemple :

  • la mise en cache accidentelle de ressources ou de frappes clavier ;
  • le stockage d’identifiants en clair ou dans des fichiers non protégés ;
  • la présence de serveurs « back-end » non détectés lors d’une analyse dynamique de l’application ;
  • la mauvaise gestion du presse-papier (est-il vidé lorsque l’application est fermée ? est-il de type privé pour ne pas être accessible par les autres applications ?) ;
  • l’utilisation d’une base SQL, pouvant mener à des injections SQL ;
  • l’utilisation de la classe UIWebView (permettant d’inclure du contenu web) pouvant mener à des injections de code de type XSS ;
  • la journalisation trop verbeuse ;
  • l’appel à des fonctions C comme strcat, strcpy, sprintf, fopen, etc.
  • Le module static/code_checks facilite la tâche de l’auditeur et automatise toutes ces recherches.

Bien sûr il est assez rare de disposer du code source de l’application, heureusement dans ce cas quelques modules peuvent, à partir de l’application installée sur le terminal, aider l’auditeur dans la compréhension du fonctionnement et de la configuration de l’application.

Le module binary/info/metadata est sans doute le premier à exécuter lorsque l’on se lance dans l’analyse d’une application. Il va récupérer plusieurs informations essentielles comme la version, l’ UUID, le chemin du binaire, les répertoires d’installation du bundle et des données, les « url handlers », etc.

Au premier lancement d’un module, si aucune application cible n’a été préalablement sélectionnée (avec set APP xxx), un « wizard » va se charger de rapatrier la liste des applications installées par l’utilisateur (grâce au fichier /private/var/installd/Library/MobileInstallation/LastLaunchServicesMap.plist pour iOS 9) et l’afficher à l’écran pour sélection. Une fois la sélection faite, les informations sont rapatriées puis affichées à l’écran.

Il est utilisé ici sur l’application Skype for Business.

Fig. 4 : Extrait de la sortie du module binary/info/metadata.


Ensuite l’ensemble des autres actions sera réalisé par défaut sur la même application. Pour changer de cible, il suffit de remonter d’un niveau (
back) puis de choisir l’identifiant de l’application (Bundle ID) avec set APP xxx et de repartir sur le module de son choix comme par exemple binary/info/compilation_checks qui va vérifier si quelques options de sécurité (chiffrement du binaire, stack canaries, ARC, PIE) sont positionnées pour l’application [iicontact].

Le module binary/reversing/shared_libraries va lister les bibliothèques utilisées.

Le module binary/reversing/strings va chercher dans les ressources de l’application ainsi que le binaire, préalablement déchiffré, les chaînes de caractères ainsi que les URI.

Une différence notable par rapport à un strings Unix/Linux: ici, par défaut, seules les chaînes de dix caractères ou plus seront affichées (contrairement à quatre), mais le nombre de caractères minimum est configurable avec l’option LENGTH.

L’option FILTER permet, comme son nom l’indique, de filtrer la sortie. Ici nous cherchons à titre d’exemple la chaîne « jailb » pour déterminer si l’application procède à une vérification de l’intégrité du terminal.

Le module binary/reversing/class_dump va simplement lancer l’outil class_dump sur le binaire pour retrouver les interfaces (voir encart). Ce qui peut aider dès lors que l’on s’intéresse de près au fonctionnement d’une application et/ou que l’on souhaite contourner certaines de ses fonctions de sécurité comme la détection de jailbreak ou la saisie d’un code PIN.

RandoriSec – Davy DOUHINE (@ddouhine)

La seconde partie de cet article sera publiée prochainement sur le blog, restez connectés 😉

Retrouvez cet article (et bien d’autres) dans MISC n°91, disponible sur la boutique et sur la plateforme de lecture en ligne Connect !