iOS Pentesting

Reading time: 46 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

iOS Basics

iOS Basics

Testing Environment

Dans cette page, vous pouvez trouver des informations sur le simulateur iOS, les Ă©mulateurs et le jailbreaking :

iOS Testing Environment

Initial Analysis

Basic iOS Testing Operations

Lors des tests, plusieurs opĂ©rations vont ĂȘtre suggĂ©rĂ©es (se connecter Ă  l'appareil, lire/Ă©crire/tĂ©lĂ©charger/tĂ©lĂ©verser des fichiers, utiliser certains outils...). Par consĂ©quent, si vous ne savez pas comment effectuer l'une de ces actions, veuillez commencer Ă  lire la page :

iOS Basic Testing Operations

note

Pour les Ă©tapes suivantes, l'application doit ĂȘtre installĂ©e sur l'appareil et doit dĂ©jĂ  avoir obtenu le fichier IPA de l'application.
Lisez la page Basic iOS Testing Operations pour apprendre comment faire cela.

Basic Static Analysis

Quelques décompilateurs intéressants pour les fichiers iOS - IPA :

  • https://github.com/LaurieWired/Malimite
  • https://ghidra-sre.org/

Il est recommandé d'utiliser l'outil MobSF pour effectuer une analyse statique automatique du fichier IPA.

Identification des protections présentes dans le binaire :

  • PIE (Position Independent Executable) : Lorsqu'il est activĂ©, l'application se charge Ă  une adresse mĂ©moire alĂ©atoire Ă  chaque lancement, rendant plus difficile la prĂ©diction de son adresse mĂ©moire initiale.
bash
otool -hv <app-binary> | grep PIE   # Il devrait inclure le drapeau PIE
  • Stack Canaries : Pour valider l'intĂ©gritĂ© de la pile, une valeur de ‘canari’ est placĂ©e sur la pile avant d'appeler une fonction et est validĂ©e Ă  nouveau une fois la fonction terminĂ©e.
bash
otool -I -v <app-binary> | grep stack_chk   # Il devrait inclure les symboles : stack_chk_guard et stack_chk_fail
  • ARC (Automatic Reference Counting) : Pour prĂ©venir les dĂ©fauts courants de corruption de mĂ©moire
bash
otool -I -v <app-binary> | grep objc_release   # Il devrait inclure le symbole _objc_release
  • Encrypted Binary : Le binaire doit ĂȘtre chiffrĂ©
bash
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # Le cryptid devrait ĂȘtre 1

Identification des Fonctions Sensibles/Insecure

  • Algorithmes de Hachage Faibles
bash
# Sur l'appareil iOS
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"

# Sur linux
grep -iER "_CC_MD5"
grep -iER "_CC_SHA1"
  • Fonctions AlĂ©atoires Insecure
bash
# Sur l'appareil iOS
otool -Iv <app> | grep -w "_random"
otool -Iv <app> | grep -w "_srand"
otool -Iv <app> | grep -w "_rand"

# Sur linux
grep -iER "_random"
grep -iER "_srand"
grep -iER "_rand"
  • Fonction ‘Malloc’ Insecure
bash
# Sur l'appareil iOS
otool -Iv <app> | grep -w "_malloc"

# Sur linux
grep -iER "_malloc"
  • Fonctions Insecure et VulnĂ©rables
bash
# Sur l'appareil iOS
otool -Iv <app> | grep -w "_gets"
otool -Iv <app> | grep -w "_memcpy"
otool -Iv <app> | grep -w "_strncpy"
otool -Iv <app> | grep -w "_strlen"
otool -Iv <app> | grep -w "_vsnprintf"
otool -Iv <app> | grep -w "_sscanf"
otool -Iv <app> | grep -w "_strtok"
otool -Iv <app> | grep -w "_alloca"
otool -Iv <app> | grep -w "_sprintf"
otool -Iv <app> | grep -w "_printf"
otool -Iv <app> | grep -w "_vsprintf"

# Sur linux
grep -R "_gets"
grep -iER "_memcpy"
grep -iER "_strncpy"
grep -iER "_strlen"
grep -iER "_vsnprintf"
grep -iER "_sscanf"
grep -iER "_strtok"
grep -iER "_alloca"
grep -iER "_sprintf"
grep -iER "_printf"
grep -iER "_vsprintf"

Basic Dynamic Analysis

Consultez l'analyse dynamique que MobSF effectue. Vous devrez naviguer à travers les différentes vues et interagir avec elles, mais cela va accrocher plusieurs classes en faisant d'autres choses et préparera un rapport une fois que vous aurez terminé.

Listing Installed Apps

Utilisez la commande frida-ps -Uai pour déterminer le bundle identifier des applications installées :

bash
$ frida-ps -Uai
PID  Name                 Identifier
----  -------------------  -----------------------------------------
6847  Calendar             com.apple.mobilecal
6815  Mail                 com.apple.mobilemail
-  App Store            com.apple.AppStore
-  Apple Store          com.apple.store.Jolly
-  Calculator           com.apple.calculator
-  Camera               com.apple.camera
-  iGoat-Swift          OWASP.iGoat-Swift

ÉnumĂ©ration de base et Hooking

Apprenez à énumérer les composants de l'application et comment hooker facilement des méthodes et des classes avec objection :

iOS Hooking With Objection

Structure IPA

La structure d'un fichier IPA est essentiellement celle d'un package compressĂ©. En renommant son extension en .zip, il peut ĂȘtre dĂ©compressĂ© pour rĂ©vĂ©ler son contenu. Dans cette structure, un Bundle reprĂ©sente une application entiĂšrement empaquetĂ©e prĂȘte Ă  ĂȘtre installĂ©e. À l'intĂ©rieur, vous trouverez un rĂ©pertoire nommĂ© <NAME>.app, qui encapsule les ressources de l'application.

  • Info.plist : Ce fichier contient des dĂ©tails de configuration spĂ©cifiques de l'application.
  • _CodeSignature/ : Ce rĂ©pertoire inclut un fichier plist qui contient une signature, garantissant l'intĂ©gritĂ© de tous les fichiers dans le bundle.
  • Assets.car : Une archive compressĂ©e qui stocke des fichiers d'actifs comme des icĂŽnes.
  • Frameworks/ : Ce dossier abrite les bibliothĂšques natives de l'application, qui peuvent ĂȘtre sous forme de fichiers .dylib ou .framework.
  • PlugIns/ : Cela peut inclure des extensions Ă  l'application, connues sous le nom de fichiers .appex, bien qu'elles ne soient pas toujours prĂ©sentes. * Core Data : Il est utilisĂ© pour sauvegarder les donnĂ©es permanentes de votre application pour une utilisation hors ligne, pour mettre en cache des donnĂ©es temporaires et pour ajouter une fonctionnalitĂ© d'annulation Ă  votre application sur un seul appareil. Pour synchroniser des donnĂ©es sur plusieurs appareils dans un seul compte iCloud, Core Data reflĂšte automatiquement votre schĂ©ma dans un conteneur CloudKit.
  • PkgInfo : Le fichier PkgInfo est un moyen alternatif de spĂ©cifier les codes de type et de crĂ©ateur de votre application ou bundle.
  • en.lproj, fr.proj, Base.lproj : Sont les packs de langue qui contiennent des ressources pour ces langues spĂ©cifiques, et une ressource par dĂ©faut au cas oĂč une langue ne serait pas supportĂ©e.
  • SĂ©curitĂ© : Le rĂ©pertoire _CodeSignature/ joue un rĂŽle critique dans la sĂ©curitĂ© de l'application en vĂ©rifiant l'intĂ©gritĂ© de tous les fichiers empaquetĂ©s grĂące Ă  des signatures numĂ©riques.
  • Gestion des actifs : Le fichier Assets.car utilise la compression pour gĂ©rer efficacement les actifs graphiques, crucial pour optimiser les performances de l'application et rĂ©duire sa taille globale.
  • Frameworks et PlugIns : Ces rĂ©pertoires soulignent la modularitĂ© des applications iOS, permettant aux dĂ©veloppeurs d'inclure des bibliothĂšques de code rĂ©utilisables (Frameworks/) et d'Ă©tendre la fonctionnalitĂ© de l'application (PlugIns/).
  • Localisation : La structure prend en charge plusieurs langues, facilitant la portĂ©e mondiale de l'application en incluant des ressources pour des packs de langue spĂ©cifiques.

Info.plist

Le Info.plist sert de pierre angulaire pour les applications iOS, encapsulant des données de configuration clés sous forme de paires clé-valeur. Ce fichier est requis non seulement pour les applications mais aussi pour les extensions d'application et les frameworks empaquetés. Il est structuré en format XML ou binaire et contient des informations critiques allant des autorisations d'application aux configurations de sécurité. Pour une exploration détaillée des clés disponibles, on peut se référer à la Documentation des développeurs Apple.

Pour ceux qui souhaitent travailler avec ce fichier dans un format plus accessible, la conversion XML peut ĂȘtre rĂ©alisĂ©e facilement grĂące Ă  l'utilisation de plutil sur macOS (disponible nativement sur les versions 10.2 et ultĂ©rieures) ou plistutil sur Linux. Les commandes pour la conversion sont les suivantes :

  • Pour macOS :
bash
$ plutil -convert xml1 Info.plist
  • Pour Linux:
bash
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Parmi la myriade d'informations que le fichier Info.plist peut divulguer, les entrĂ©es notables incluent les chaĂźnes de permission d'application (UsageDescription), les schĂ©mas d'URL personnalisĂ©s (CFBundleURLTypes), et les configurations pour la sĂ©curitĂ© du transport d'application (NSAppTransportSecurity). Ces entrĂ©es, ainsi que d'autres comme les types de documents personnalisĂ©s exportĂ©s/importĂ©s (UTExportedTypeDeclarations / UTImportedTypeDeclarations), peuvent ĂȘtre facilement localisĂ©es en inspectant le fichier ou en utilisant une simple commande grep :

bash
$ grep -i <keyword> Info.plist

Chemins de données

Dans l'environnement iOS, les répertoires sont désignés spécifiquement pour les applications systÚme et les applications installées par l'utilisateur. Les applications systÚme résident dans le répertoire /Applications, tandis que les applications installées par l'utilisateur sont placées sous /var/mobile/containers/Data/Application/. Ces applications se voient attribuer un identifiant unique connu sous le nom de UUID 128 bits, rendant la tùche de localiser manuellement le dossier d'une application difficile en raison de l'aléatoire des noms de répertoires.

warning

Comme les applications iOS doivent ĂȘtre isolĂ©es, chaque application aura Ă©galement un dossier Ă  l'intĂ©rieur de $HOME/Library/Containers avec le CFBundleIdentifier de l'application comme nom de dossier.

Cependant, les deux dossiers (dossiers de données et de conteneurs) contiennent le fichier .com.apple.mobile_container_manager.metadata.plist qui relie les deux fichiers dans la clé MCMetadataIdentifier).

Pour faciliter la découverte du répertoire d'installation d'une application installée par l'utilisateur, l'outil objection fournit une commande utile, env. Cette commande révÚle des informations détaillées sur le répertoire de l'application en question. Voici un exemple de la façon d'utiliser cette commande :

bash
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env

Name               Path
-----------------  -------------------------------------------------------------------------------------------
BundlePath         /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
CachesDirectory    /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
DocumentDirectory  /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
LibraryDirectory   /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library

Alternativement, le nom de l'application peut ĂȘtre recherchĂ© dans le /private/var/containers en utilisant la commande find :

bash
find /private/var/containers -name "Progname*"

Des commandes telles que ps et lsof peuvent Ă©galement ĂȘtre utilisĂ©es pour identifier le processus de l'application et lister les fichiers ouverts, respectivement, fournissant des informations sur les chemins de rĂ©pertoire actifs de l'application :

bash
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1

RĂ©pertoire du bundle :

  • AppName.app
  • C'est le bundle de l'application comme vu prĂ©cĂ©demment dans l'IPA, il contient des donnĂ©es essentielles de l'application, du contenu statique ainsi que le binaire compilĂ© de l'application.
  • Ce rĂ©pertoire est visible par les utilisateurs, mais les utilisateurs ne peuvent pas y Ă©crire.
  • Le contenu de ce rĂ©pertoire n'est pas sauvegardĂ©.
  • Les contenus de ce dossier sont utilisĂ©s pour valider la signature du code.

Répertoire des données :

  • Documents/
  • Contient toutes les donnĂ©es gĂ©nĂ©rĂ©es par l'utilisateur. L'utilisateur final de l'application initie la crĂ©ation de ces donnĂ©es.
  • Visible par les utilisateurs et les utilisateurs peuvent y Ă©crire.
  • Le contenu de ce rĂ©pertoire est sauvegardĂ©.
  • L'application peut dĂ©sactiver des chemins en dĂ©finissant NSURLIsExcludedFromBackupKey.
  • Library/
  • Contient tous les fichiers qui ne sont pas spĂ©cifiques Ă  l'utilisateur, tels que caches, prĂ©fĂ©rences, cookies, et fichiers de configuration de liste de propriĂ©tĂ©s (plist).
  • Les applications iOS utilisent gĂ©nĂ©ralement les sous-rĂ©pertoires Application Support et Caches, mais l'application peut crĂ©er des sous-rĂ©pertoires personnalisĂ©s.
  • Library/Caches/
  • Contient des fichiers mis en cache semi-persistants.
  • Invisible pour les utilisateurs et les utilisateurs ne peuvent pas y Ă©crire.
  • Le contenu de ce rĂ©pertoire n'est pas sauvegardĂ©.
  • Le systĂšme d'exploitation peut supprimer automatiquement les fichiers de ce rĂ©pertoire lorsque l'application n'est pas en cours d'exĂ©cution et que l'espace de stockage est faible.
  • Library/Application Support/
  • Contient des fichiers persistants nĂ©cessaires au fonctionnement de l'application.
  • Invisible pour les utilisateurs et les utilisateurs ne peuvent pas y Ă©crire.
  • Le contenu de ce rĂ©pertoire est sauvegardĂ©.
  • L'application peut dĂ©sactiver des chemins en dĂ©finissant NSURLIsExcludedFromBackupKey.
  • Library/Preferences/
  • UtilisĂ© pour stocker des propriĂ©tĂ©s qui peuvent persister mĂȘme aprĂšs le redĂ©marrage d'une application.
  • Les informations sont sauvegardĂ©es, non chiffrĂ©es, Ă  l'intĂ©rieur du sandbox de l'application dans un fichier plist appelĂ© [BUNDLE_ID].plist.
  • Tous les paires clĂ©/valeur stockĂ©es en utilisant NSUserDefaults peuvent ĂȘtre trouvĂ©es dans ce fichier.
  • tmp/
  • Utilisez ce rĂ©pertoire pour Ă©crire des fichiers temporaires qui n'ont pas besoin de persister entre les lancements de l'application.
  • Contient des fichiers mis en cache non persistants.
  • Invisible pour les utilisateurs.
  • Le contenu de ce rĂ©pertoire n'est pas sauvegardĂ©.
  • Le systĂšme d'exploitation peut supprimer automatiquement les fichiers de ce rĂ©pertoire lorsque l'application n'est pas en cours d'exĂ©cution et que l'espace de stockage est faible.

Examinons de plus prÚs le répertoire du bundle de l'application iGoat-Swift (.app) à l'intérieur du répertoire du bundle (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app) :

bash
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
NSFileType      Perms  NSFileProtection    ...  Name
------------  -------  ------------------  ...  --------------------------------------
Regular           420  None                ...  rutger.html
Regular           420  None                ...  mansi.html
Regular           420  None                ...  splash.html
Regular           420  None                ...  about.html

Regular           420  None                ...  LICENSE.txt
Regular           420  None                ...  Sentinel.txt
Regular           420  None                ...  README.txt

Reversing Binaire

À l'intĂ©rieur du dossier <application-name>.app, vous trouverez un fichier binaire appelĂ© <application-name>. C'est le fichier qui sera exĂ©cutĂ©. Vous pouvez effectuer une inspection de base du binaire avec l'outil otool :

bash
otool -Vh DVIA-v2 #Check some compilation attributes
magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64    ARM64        ALL  0x00     EXECUTE    65       7112   NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE

otool -L DVIA-v2 #Get third party libraries
DVIA-v2:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
@rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
[...]

Vérifiez si l'application est chiffrée

VĂ©rifiez s'il y a une sortie pour :

bash
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO

DĂ©sassembler le binaire

DĂ©sassemblez la section texte :

bash
otool -tV DVIA-v2
DVIA-v2:
(__TEXT,__text) section
+[DDLog initialize]:
0000000100004ab8    sub    sp, sp, #0x60
0000000100004abc    stp    x29, x30, [sp, #0x50]   ; Latency: 6
0000000100004ac0    add    x29, sp, #0x50
0000000100004ac4    sub    x8, x29, #0x10
0000000100004ac8    mov    x9, #0x0
0000000100004acc    adrp    x10, 1098 ; 0x10044e000
0000000100004ad0    add    x10, x10, #0x268

Pour imprimer le segment Objective-C de l'application d'exemple, on peut utiliser :

bash
otool -oV DVIA-v2
DVIA-v2:
Contents of (__DATA,__objc_classlist) section
00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
isa        0x1004423a8 _OBJC_METACLASS_$_DDLog
superclass 0x0 _OBJC_CLASS_$_NSObject
cache      0x0 __objc_empty_cache
vtable     0x0
data       0x1003de748
flags          0x80
instanceStart  8

Pour obtenir un code Objective-C plus compact, vous pouvez utiliser class-dump:

bash
class-dump some-app
//
//     Generated by class-dump 3.5 (64 bit).
//
//     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//

#pragma mark Named Structures

struct CGPoint {
double _field1;
double _field2;
};

struct CGRect {
struct CGPoint _field1;
struct CGSize _field2;
};

struct CGSize {
double _field1;
double _field2;
};

Cependant, les meilleures options pour désassembler le binaire sont : Hopper et IDA.

Stockage des données

Pour en savoir plus sur la façon dont iOS stocke les données sur l'appareil, lisez cette page :

iOS Basics

warning

Les endroits suivants pour stocker des informations doivent ĂȘtre vĂ©rifiĂ©s juste aprĂšs l'installation de l'application, aprĂšs avoir vĂ©rifiĂ© toutes les fonctionnalitĂ©s de l'application et mĂȘme aprĂšs s'ĂȘtre dĂ©connectĂ© d'un utilisateur et s'ĂȘtre connectĂ© Ă  un autre.
L'objectif est de trouver des informations sensibles non protégées de l'application (mots de passe, jetons), de l'utilisateur actuel et des utilisateurs précédemment connectés.

Plist

Les fichiers plist sont des fichiers XML structurés qui contiennent des paires clé-valeur. C'est un moyen de stocker des données persistantes, donc parfois vous pouvez trouver des informations sensibles dans ces fichiers. Il est recommandé de vérifier ces fichiers aprÚs l'installation de l'application et aprÚs les avoir utilisés intensivement pour voir si de nouvelles données sont écrites.

La façon la plus courante de persister des données dans des fichiers plist est par l'utilisation de NSUserDefaults. Ce fichier plist est enregistré à l'intérieur du bac à sable de l'application dans Library/Preferences/<appBundleID>.plist

La classe NSUserDefaults fournit une interface programmatique pour interagir avec le systĂšme par dĂ©faut. Le systĂšme par dĂ©faut permet Ă  une application de personnaliser son comportement en fonction des prĂ©fĂ©rences de l'utilisateur. Les donnĂ©es enregistrĂ©es par NSUserDefaults peuvent ĂȘtre consultĂ©es dans le bundle de l'application. Cette classe stocke des donnĂ©es dans un fichier plist, mais elle est destinĂ©e Ă  ĂȘtre utilisĂ©e avec de petites quantitĂ©s de donnĂ©es.

Ces donnĂ©es ne peuvent plus ĂȘtre accessibles directement via un ordinateur de confiance, mais peuvent ĂȘtre accessibles en effectuant une sauvegarde.

Vous pouvez dumper les informations enregistrées en utilisant NSUserDefaults avec objection's ios nsuserdefaults get

Pour trouver tous les plist utilisés par l'application, vous pouvez accéder à /private/var/mobile/Containers/Data/Application/{APPID} et exécuter :

bash
find ./ -name "*.plist"

Pour convertir des fichiers au format XML ou binaire (bplist) en XML, plusieurs méthodes selon votre systÚme d'exploitation sont disponibles :

Pour les utilisateurs de macOS : Utilisez la commande plutil. C'est un outil intégré dans macOS (10.2+), conçu à cet effet :

bash
$ plutil -convert xml1 Info.plist

Pour les utilisateurs de Linux : Installez d'abord libplist-utils, puis utilisez plistutil pour convertir votre fichier :

bash
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist

Dans une session Objection : Pour analyser des applications mobiles, une commande spécifique vous permet de convertir des fichiers plist directement :

bash
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist

Core Data

Core Data est un framework pour gĂ©rer la couche modĂšle des objets dans votre application. Core Data peut utiliser SQLite comme son magasin persistant, mais le framework lui-mĂȘme n'est pas une base de donnĂ©es.
CoreData ne chiffre pas ses donnĂ©es par dĂ©faut. Cependant, une couche de chiffrement supplĂ©mentaire peut ĂȘtre ajoutĂ©e Ă  CoreData. Voir le GitHub Repo pour plus de dĂ©tails.

Vous pouvez trouver les informations SQLite Core Data d'une application dans le chemin /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support

Si vous pouvez ouvrir le SQLite et accéder à des informations sensibles, alors vous avez trouvé une mauvaise configuration.

Code from iGoat
-(void)storeDetails {
AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);

NSManagedObjectContext *context =[appDelegate managedObjectContext];

User *user = [self fetchUser];
if (user) {
return;
}
user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:context];
user.email = CoreDataEmail;
user.password = CoreDataPassword;
NSError *error;
if (![context save:&error]) {
NSLog(@"Error in saving data: %@", [error localizedDescription]);

}else{
NSLog(@"data stored in core data");
}
}

YapDatabase

YapDatabase est un magasin clé/valeur construit sur SQLite.
Comme les bases de données Yap sont des bases de données sqlite, vous pouvez les trouver en utilisant la commande proposée dans la section précédente.

Autres bases de données SQLite

Il est courant que les applications crĂ©ent leur propre base de donnĂ©es sqlite. Elles peuvent stocker des donnĂ©es sensibles et les laisser non chiffrĂ©es. Par consĂ©quent, il est toujours intĂ©ressant de vĂ©rifier chaque base de donnĂ©es dans le rĂ©pertoire des applications. Allez donc dans le rĂ©pertoire de l'application oĂč les donnĂ©es sont enregistrĂ©es (/private/var/mobile/Containers/Data/Application/{APPID})

bash
find ./ -name "*.sqlite" -or -name "*.db"

Firebase Real-Time Databases

Les développeurs peuvent stocker et synchroniser des données dans une base de données NoSQL hébergée dans le cloud grùce à Firebase Real-Time Databases. Stockées au format JSON, les données sont synchronisées avec tous les clients connectés en temps réel.

Vous pouvez trouver comment vérifier les bases de données Firebase mal configurées ici :

Firebase Database

Bases de données Realm

Realm Objective-C et Realm Swift offrent une alternative puissante pour le stockage de données, non fournie par Apple. Par défaut, elles stockent les données sans chiffrement, avec un chiffrement disponible via une configuration spécifique.

Les bases de données se trouvent à : /private/var/mobile/Containers/Data/Application/{APPID}. Pour explorer ces fichiers, on peut utiliser des commandes comme :

bash
iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
default.realm  default.realm.lock  default.realm.management/  default.realm.note|

$ find ./ -name "*.realm*"

Pour visualiser ces fichiers de base de données, l'outil Realm Studio est recommandé.

Pour implĂ©menter le chiffrement dans une base de donnĂ©es Realm, le code suivant peut ĂȘtre utilisĂ© :

swift
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
let config = Realm.Configuration(encryptionKey: getKey())
do {
let realm = try Realm(configuration: config)
// Use the Realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}

Bases de données Couchbase Lite

Couchbase Lite est dĂ©crit comme un moteur de base de donnĂ©es lĂ©ger et intĂ©grĂ© qui suit l'approche orientĂ©e document (NoSQL). Conçu pour ĂȘtre natif Ă  iOS et macOS, il offre la capacitĂ© de synchroniser les donnĂ©es de maniĂšre transparente.

Pour identifier les bases de donnĂ©es Couchbase potentielles sur un appareil, le rĂ©pertoire suivant doit ĂȘtre inspectĂ© :

bash
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/

Cookies

iOS stocke les cookies des applications dans le Library/Cookies/cookies.binarycookies Ă  l'intĂ©rieur de chaque dossier d'application. Cependant, les dĂ©veloppeurs dĂ©cident parfois de les enregistrer dans le keychain car le fichier de cookie mentionnĂ© peut ĂȘtre accessible dans les sauvegardes.

Pour inspecter le fichier de cookies, vous pouvez utiliser ce script python ou utiliser ios cookies get d'objection.
Vous pouvez également utiliser objection pour convertir ces fichiers en format JSON et inspecter les données.

bash
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
[
{
"domain": "highaltitudehacks.com",
"expiresDate": "2051-09-15 07:46:43 +0000",
"isHTTPOnly": "false",
"isSecure": "false",
"name": "username",
"path": "/",
"value": "admin123",
"version": "0"
}
]

Cache

Par dĂ©faut, NSURLSession stocke des donnĂ©es, telles que les requĂȘtes et rĂ©ponses HTTP dans la base de donnĂ©es Cache.db. Cette base de donnĂ©es peut contenir des donnĂ©es sensibles, si des tokens, des noms d'utilisateur ou toute autre information sensible ont Ă©tĂ© mises en cache. Pour trouver les informations mises en cache, ouvrez le rĂ©pertoire de donnĂ©es de l'application (/var/mobile/Containers/Data/Application/<UUID>) et allez Ă  /Library/Caches/<Bundle Identifier>. Le cache WebKit est Ă©galement stockĂ© dans le fichier Cache.db. Objection peut ouvrir et interagir avec la base de donnĂ©es avec la commande sqlite connect Cache.db, car c'est une base de donnĂ©es SQLite normale.

Il est recommandĂ© de dĂ©sactiver la mise en cache de ces donnĂ©es, car elles peuvent contenir des informations sensibles dans la requĂȘte ou la rĂ©ponse. La liste suivante montre diffĂ©rentes façons d'y parvenir :

  1. Il est recommandĂ© de supprimer les rĂ©ponses mises en cache aprĂšs la dĂ©connexion. Cela peut ĂȘtre fait avec la mĂ©thode fournie par Apple appelĂ©e removeAllCachedResponses. Vous pouvez appeler cette mĂ©thode comme suit :

URLCache.shared.removeAllCachedResponses()

Cette mĂ©thode supprimera toutes les requĂȘtes et rĂ©ponses mises en cache du fichier Cache.db.

  1. Si vous n'avez pas besoin de profiter des cookies, il serait recommandé d'utiliser simplement la propriété de configuration .ephemeral de URLSession, qui désactivera la sauvegarde des cookies et des caches.

Documentation Apple :

Un objet de configuration de session éphémÚre est similaire à une configuration de session par défaut (voir défaut), sauf que l'objet de session correspondant ne stocke pas de caches, de magasins d'identifiants ou de données liées à la session sur le disque. Au lieu de cela, les données liées à la session sont stockées dans la RAM. La seule fois qu'une session éphémÚre écrit des données sur le disque, c'est lorsque vous lui dites d'écrire le contenu d'une URL dans un fichier.

  1. Le cache peut Ă©galement ĂȘtre dĂ©sactivĂ© en dĂ©finissant la politique de cache sur .notAllowed. Cela dĂ©sactivera le stockage du cache de toute maniĂšre, que ce soit en mĂ©moire ou sur disque.

Snapshots

Chaque fois que vous appuyez sur le bouton d'accueil, iOS prend un instantané de l'écran actuel pour pouvoir effectuer la transition vers l'application de maniÚre beaucoup plus fluide. Cependant, si des données sensibles sont présentes à l'écran actuel, elles seront sauvegardées dans l'image (qui persiste à travers les redémarrages). Ce sont les instantanés auxquels vous pouvez également accéder en double-tapant sur l'écran d'accueil pour passer d'une application à l'autre.

À moins que l'iPhone ne soit jailbreakĂ©, l'attaquant doit avoir accĂšs Ă  l'appareil dĂ©bloquĂ© pour voir ces captures d'Ă©cran. Par dĂ©faut, le dernier instantanĂ© est stockĂ© dans le bac Ă  sable de l'application dans le dossier Library/Caches/Snapshots/ ou Library/SplashBoard/Snapshots (les ordinateurs de confiance ne peuvent pas accĂ©der au systĂšme de fichiers depuis iOS 7.0).

Une façon de prévenir ce mauvais comportement est de mettre un écran vide ou de supprimer les données sensibles avant de prendre l'instantané en utilisant la fonction ApplicationDidEnterBackground().

La suite est un exemple de méthode de remédiation qui définira une capture d'écran par défaut.

Swift:

swift
private var backgroundImage: UIImageView?

func applicationDidEnterBackground(_ application: UIApplication) {
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
myBanner.frame = UIScreen.main.bounds
backgroundImage = myBanner
window?.addSubview(myBanner)
}

func applicationWillEnterForeground(_ application: UIApplication) {
backgroundImage?.removeFromSuperview()
}

Objective-C :

@property (UIImageView *)backgroundImage;

- (void)applicationDidEnterBackground:(UIApplication *)application {
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
self.backgroundImage = myBanner;
self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
[self.window addSubview:myBanner];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
[self.backgroundImage removeFromSuperview];
}

Cela dĂ©finit l'image de fond sur overlayImage.png chaque fois que l'application est mise en arriĂšre-plan. Cela empĂȘche les fuites de donnĂ©es sensibles car overlayImage.png remplacera toujours la vue actuelle.

Keychain

Pour accéder et gérer le trousseau iOS, des outils comme Keychain-Dumper sont disponibles, adaptés aux appareils jailbreakés. De plus, Objection fournit la commande ios keychain dump à des fins similaires.

Stockage des Identifiants

La classe NSURLCredential est idéale pour enregistrer des informations sensibles directement dans le trousseau, contournant ainsi le besoin de NSUserDefaults ou d'autres wrappers. Pour stocker des identifiants aprÚs la connexion, le code Swift suivant est utilisé :

swift
NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];

Pour extraire ces identifiants stockés, la commande ios nsurlcredentialstorage dump d'Objection est utilisée.

Claviers personnalisés et cache de clavier

Avec iOS 8.0 et versions ultérieures, les utilisateurs peuvent installer des extensions de clavier personnalisées, qui sont gérables sous Réglages > Général > Clavier > Claviers. Bien que ces claviers offrent des fonctionnalités étendues, ils présentent un risque d'enregistrement des frappes et de transmission de données vers des serveurs externes, bien que les utilisateurs soient informés des claviers nécessitant un accÚs réseau. Les applications peuvent, et doivent, restreindre l'utilisation de claviers personnalisés pour la saisie d'informations sensibles.

Recommandations de sécurité :

  • Il est conseillĂ© de dĂ©sactiver les claviers tiers pour une sĂ©curitĂ© accrue.
  • Soyez conscient des fonctionnalitĂ©s de correction automatique et de suggestions automatiques du clavier iOS par dĂ©faut, qui pourraient stocker des informations sensibles dans des fichiers cache situĂ©s dans Library/Keyboard/{locale}-dynamic-text.dat ou /private/var/mobile/Library/Keyboard/dynamic-text.dat. Ces fichiers cache doivent ĂȘtre rĂ©guliĂšrement vĂ©rifiĂ©s pour des donnĂ©es sensibles. Il est recommandĂ© de rĂ©initialiser le dictionnaire de clavier via RĂ©glages > GĂ©nĂ©ral > RĂ©initialiser > RĂ©initialiser le dictionnaire de clavier pour effacer les donnĂ©es mises en cache.
  • L'interception du trafic rĂ©seau peut rĂ©vĂ©ler si un clavier personnalisĂ© transmet des frappes Ă  distance.

Prévention du cache des champs de texte

Le protocole UITextInputTraits offre des propriĂ©tĂ©s pour gĂ©rer la correction automatique et la saisie de texte sĂ©curisĂ©e, essentielles pour prĂ©venir le cache d'informations sensibles. Par exemple, dĂ©sactiver la correction automatique et activer la saisie de texte sĂ©curisĂ©e peut ĂȘtre rĂ©alisĂ© avec :

objectivec
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;

De plus, les développeurs doivent s'assurer que les champs de texte, en particulier ceux pour entrer des informations sensibles comme des mots de passe et des codes PIN, désactivent la mise en cache en définissant autocorrectionType sur UITextAutocorrectionTypeNo et secureTextEntry sur YES.

objectivec
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;

Logs

Le débogage du code implique souvent l'utilisation de logging. Il y a un risque car les logs peuvent contenir des informations sensibles. Auparavant, dans iOS 6 et les versions antérieures, les logs étaient accessibles à toutes les applications, posant un risque de fuite de données sensibles. Maintenant, les applications sont limitées à l'accÚs uniquement à leurs logs.

MalgrĂ© ces restrictions, un attaquant ayant un accĂšs physique Ă  un appareil dĂ©verrouillĂ© peut toujours en tirer parti en connectant l'appareil Ă  un ordinateur et en lisant les logs. Il est important de noter que les logs restent sur le disque mĂȘme aprĂšs la dĂ©sinstallation de l'application.

Pour atténuer les risques, il est conseillé de interagir en profondeur avec l'application, en explorant toutes ses fonctionnalités et entrées pour s'assurer qu'aucune information sensible n'est enregistrée par inadvertance.

Lors de l'examen du code source de l'application à la recherche de fuites potentielles, recherchez à la fois des déclarations de logging prédéfinies et personnalisées en utilisant des mots-clés tels que NSLog, NSAssert, NSCAssert, fprintf pour les fonctions intégrées, et toute mention de Logging ou Logfile pour les implémentations personnalisées.

Monitoring System Logs

Les applications enregistrent diverses informations qui peuvent ĂȘtre sensibles. Pour surveiller ces logs, des outils et des commandes comme :

bash
idevice_id --list   # To find the device ID
idevicesyslog -u <id> (| grep <app>)   # To capture the device logs

sont utiles. De plus, Xcode offre un moyen de collecter des journaux de console :

  1. Ouvrez Xcode.
  2. Connectez l'appareil iOS.
  3. AccĂ©dez Ă  FenĂȘtre -> Appareils et simulateurs.
  4. SĂ©lectionnez votre appareil.
  5. DĂ©clenchez le problĂšme que vous enquĂȘtez.
  6. Utilisez le bouton Ouvrir la console pour voir les journaux dans une nouvelle fenĂȘtre.

Pour un journalisation plus avancée, se connecter au shell de l'appareil et utiliser socat peut fournir une surveillance des journaux en temps réel :

bash
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock

Suivi des commandes pour observer les activitĂ©s de journal, ce qui peut ĂȘtre inestimable pour diagnostiquer des problĂšmes ou identifier des fuites potentielles de donnĂ©es dans les journaux.

Sauvegardes

Les fonctionnalités de sauvegarde automatique sont intégrées dans iOS, facilitant la création de copies de données de l'appareil via iTunes (jusqu'à macOS Catalina), Finder (à partir de macOS Catalina) ou iCloud. Ces sauvegardes englobent presque toutes les données de l'appareil, à l'exception des éléments hautement sensibles comme les détails d'Apple Pay et les configurations de Touch ID.

Risques de sécurité

L'inclusion des applications installées et de leurs données dans les sauvegardes soulÚve la question de la fuite de données potentielle et du risque que les modifications de sauvegarde puissent altérer la fonctionnalité de l'application. Il est conseillé de ne pas stocker d'informations sensibles en texte clair dans le répertoire d'une application ou ses sous-répertoires pour atténuer ces risques.

Exclusion de fichiers des sauvegardes

Les fichiers dans Documents/ et Library/Application Support/ sont sauvegardĂ©s par dĂ©faut. Les dĂ©veloppeurs peuvent exclure des fichiers ou des rĂ©pertoires spĂ©cifiques des sauvegardes en utilisant NSURL setResourceValue:forKey:error: avec le NSURLIsExcludedFromBackupKey. Cette pratique est cruciale pour protĂ©ger les donnĂ©es sensibles d'ĂȘtre incluses dans les sauvegardes.

Test des vulnérabilités

Pour Ă©valuer la sĂ©curitĂ© de la sauvegarde d'une application, commencez par crĂ©er une sauvegarde en utilisant Finder, puis localisez-la en suivant les conseils de la documentation officielle d'Apple. Analysez la sauvegarde Ă  la recherche de donnĂ©es sensibles ou de configurations qui pourraient ĂȘtre modifiĂ©es pour affecter le comportement de l'application.

Des informations sensibles peuvent ĂȘtre recherchĂ©es Ă  l'aide d'outils en ligne de commande ou d'applications comme iMazing. Pour les sauvegardes chiffrĂ©es, la prĂ©sence de chiffrement peut ĂȘtre confirmĂ©e en vĂ©rifiant la clĂ© "IsEncrypted" dans le fichier "Manifest.plist" Ă  la racine de la sauvegarde.

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
...
<key>Date</key>
<date>2021-03-12T17:43:33Z</date>
<key>IsEncrypted</key>
<true/>
...
</plist>

Pour traiter les sauvegardes chiffrĂ©es, des scripts Python disponibles dans le rĂ©pertoire GitHub de DinoSec, comme backup_tool.py et backup_passwd.py, peuvent ĂȘtre utiles, bien qu'ils nĂ©cessitent potentiellement des ajustements pour ĂȘtre compatibles avec les derniĂšres versions d'iTunes/Finder. L'outil iOSbackup est une autre option pour accĂ©der aux fichiers dans des sauvegardes protĂ©gĂ©es par mot de passe.

Modification du Comportement de l'Application

Un exemple de modification du comportement d'une application par le biais de modifications de sauvegarde est dĂ©montrĂ© dans l'application de portefeuille bitcoin Bither, oĂč le code PIN de verrouillage de l'interface utilisateur est stockĂ© dans net.bither.plist sous la clĂ© pin_code. La suppression de cette clĂ© du plist et la restauration de la sauvegarde supprime l'exigence du code PIN, offrant un accĂšs illimitĂ©.

Résumé sur les Tests de Mémoire pour les Données Sensibles

Lorsqu'il s'agit d'informations sensibles stockĂ©es dans la mĂ©moire d'une application, il est crucial de limiter le temps d'exposition de ces donnĂ©es. Il existe deux approches principales pour enquĂȘter sur le contenu de la mĂ©moire : crĂ©er un dump de mĂ©moire et analyser la mĂ©moire en temps rĂ©el. Les deux mĂ©thodes prĂ©sentent des dĂ©fis, y compris le risque de manquer des donnĂ©es critiques lors du processus de dump ou d'analyse.

Récupération et Analyse d'un Dump de Mémoire

Pour les appareils jailbreakés et non jailbreakés, des outils comme objection et Fridump permettent de dumper la mémoire du processus d'une application. Une fois le dump effectué, l'analyse de ces données nécessite divers outils, en fonction de la nature des informations que vous recherchez.

Pour extraire des chaĂźnes d'un dump de mĂ©moire, des commandes telles que strings ou rabin2 -zz peuvent ĂȘtre utilisĂ©es :

bash
# Extracting strings using strings command
$ strings memory > strings.txt

# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt

Pour une analyse plus détaillée, y compris la recherche de types de données ou de motifs spécifiques, radare2 offre des capacités de recherche étendues :

bash
$ r2 <name_of_your_dump_file>
[0x00000000]> /?
...

Analyse de la mémoire à l'exécution

r2frida offre une alternative puissante pour inspecter la mémoire d'une application en temps réel, sans avoir besoin d'un dump mémoire. Cet outil permet l'exécution de commandes de recherche directement sur la mémoire de l'application en cours d'exécution :

bash
$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>

Cryptographie Brisée

Mauvaises Pratiques de Gestion des Clés

Certains dĂ©veloppeurs enregistrent des donnĂ©es sensibles dans le stockage local et les cryptent avec une clĂ© codĂ©e en dur/prĂ©visible dans le code. Cela ne devrait pas ĂȘtre fait car un certain reverse engineering pourrait permettre aux attaquants d'extraire les informations confidentielles.

Utilisation d'Algorithmes Insecure et/ou ObsolĂštes

Les dĂ©veloppeurs ne devraient pas utiliser des algorithmes obsolĂštes pour effectuer des vĂ©rifications d'autorisation, stocker ou envoyer des donnĂ©es. Certains de ces algorithmes sont : RC4, MD4, MD5, SHA1... Si des hashes sont utilisĂ©s pour stocker des mots de passe par exemple, des hashes rĂ©sistants Ă  la force brute devraient ĂȘtre utilisĂ©s avec du sel.

VĂ©rification

Les principales vérifications à effectuer consistent à trouver si vous pouvez trouver des mots de passe/secrets codés en dur dans le code, ou si ceux-ci sont prévisibles, et si le code utilise des algorithmes de cryptographie faibles.

Il est intéressant de savoir que vous pouvez surveiller certaines bibliothÚques crypto automatiquement en utilisant objection avec :

swift
ios monitor crypt

Pour plus d'informations sur les API et bibliothÚques cryptographiques iOS, accédez à https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

Authentification Locale

L'authentification locale joue un rĂŽle crucial, surtout lorsqu'il s'agit de protĂ©ger l'accĂšs Ă  un point de terminaison distant par des mĂ©thodes cryptographiques. L'essence ici est que sans une mise en Ɠuvre appropriĂ©e, les mĂ©canismes d'authentification locale peuvent ĂȘtre contournĂ©s.

Le framework d'authentification locale d'Apple et le keychain fournissent des API robustes pour permettre aux développeurs de faciliter les dialogues d'authentification des utilisateurs et de gérer en toute sécurité les données secrÚtes, respectivement. Le Secure Enclave sécurise l'ID d'empreinte digitale pour Touch ID, tandis que Face ID repose sur la reconnaissance faciale sans compromettre les données biométriques.

Pour intégrer Touch ID/Face ID, les développeurs ont deux choix d'API :

  • LocalAuthentication.framework pour une authentification utilisateur de haut niveau sans accĂšs aux donnĂ©es biomĂ©triques.
  • Security.framework pour un accĂšs aux services de keychain de bas niveau, sĂ©curisant les donnĂ©es secrĂštes avec une authentification biomĂ©trique. Divers wrappers open-source simplifient l'accĂšs au keychain.

caution

Cependant, Ă  la fois LocalAuthentication.framework et Security.framework prĂ©sentent des vulnĂ©rabilitĂ©s, car ils retournent principalement des valeurs boolĂ©ennes sans transmettre de donnĂ©es pour les processus d'authentification, les rendant susceptibles d'ĂȘtre contournĂ©s (voir Don't touch me that way, par David Lindner et al).

Mise en Ɠuvre de l'authentification locale

Pour demander aux utilisateurs une authentification, les développeurs doivent utiliser la méthode evaluatePolicy dans la classe LAContext, en choisissant entre :

  • deviceOwnerAuthentication : Demande Touch ID ou code d'accĂšs de l'appareil, Ă©chouant si aucun des deux n'est activĂ©.
  • deviceOwnerAuthenticationWithBiometrics : Demande exclusivement Touch ID.

Une authentification réussie est indiquée par une valeur de retour booléenne de evaluatePolicy, soulignant une potentielle faille de sécurité.

Authentification locale utilisant le Keychain

La mise en Ɠuvre de l'authentification locale dans les applications iOS implique l'utilisation des API de keychain pour stocker en toute sĂ©curitĂ© des donnĂ©es secrĂštes telles que des jetons d'authentification. Ce processus garantit que les donnĂ©es ne peuvent ĂȘtre accessibles que par l'utilisateur, en utilisant son code d'accĂšs de l'appareil ou une authentification biomĂ©trique comme Touch ID.

Le keychain offre la capacité de définir des éléments avec l'attribut SecAccessControl, qui restreint l'accÚs à l'élément jusqu'à ce que l'utilisateur s'authentifie avec succÚs via Touch ID ou code d'accÚs de l'appareil. Cette fonctionnalité est cruciale pour améliorer la sécurité.

Voici des exemples de code en Swift et Objective-C démontrant comment enregistrer et récupérer une chaßne dans/le keychain, en tirant parti de ces fonctionnalités de sécurité. Les exemples montrent spécifiquement comment configurer le contrÎle d'accÚs pour exiger une authentification Touch ID et garantir que les données ne sont accessibles que sur l'appareil sur lequel elles ont été configurées, sous la condition qu'un code d'accÚs de l'appareil soit configuré.

swift
// From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md

// 1. create AccessControl object that will represent authentication settings

var error: Unmanaged<CFError>?

guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
SecAccessControlCreateFlags.biometryCurrentSet,
&error) else {
// failed to create AccessControl object

return
}

// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute

var query: [String: Any] = [:]

query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecAttrAccount as String] = "OWASP Account" as CFString
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
query[kSecAttrAccessControl as String] = accessControl

// 3. save item

let status = SecItemAdd(query as CFDictionary, nil)

if status == noErr {
// successfully saved
} else {
// error while saving
}

Maintenant, nous pouvons demander l'élément enregistré dans le trousseau. Les services de trousseau présenteront la boßte de dialogue d'authentification à l'utilisateur et renverront des données ou nil en fonction de la fourniture ou non d'une empreinte digitale appropriée.

swift
// 1. define query
var query = [String: Any]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecAttrAccount as String] = "My Name" as CFString
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString

// 2. get item
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}

if status == noErr {
let password = String(data: queryResult as! Data, encoding: .utf8)!
// successfully received password
} else {
// authorization not passed
}

DĂ©tection

L'utilisation de frameworks dans une application peut Ă©galement ĂȘtre dĂ©tectĂ©e en analysant la liste des bibliothĂšques dynamiques partagĂ©es du binaire de l'application. Cela peut ĂȘtre fait en utilisant otool:

bash
$ otool -L <AppName>.app/<AppName>

Si LocalAuthentication.framework est utilisé dans une application, la sortie contiendra les deux lignes suivantes (rappelez-vous que LocalAuthentication.framework utilise Security.framework en arriÚre-plan) :

bash
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security

Si Security.framework est utilisé, seul le second sera affiché.

Contournement du Cadre d'Authentification Locale

Objection

GrĂące au Objection Biometrics Bypass, situĂ© sur cette page GitHub, une technique est disponible pour surmonter le mĂ©canisme LocalAuthentication. Le cƓur de cette approche consiste Ă  exploiter Frida pour manipuler la fonction evaluatePolicy, garantissant qu'elle renvoie systĂ©matiquement un rĂ©sultat True, indĂ©pendamment du succĂšs rĂ©el de l'authentification. Cela est particuliĂšrement utile pour contourner les processus d'authentification biomĂ©trique dĂ©fectueux.

Pour activer ce contournement, la commande suivante est utilisée :

bash
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
(agent) [3mhtws9x47q] OS authentication response: false
(agent) [3mhtws9x47q] Marking OS response as True instead
(agent) [3mhtws9x47q] Biometrics bypass hook complete

Cette commande dĂ©clenche une sĂ©quence oĂč Objection enregistre une tĂąche qui modifie effectivement le rĂ©sultat de la vĂ©rification evaluatePolicy en True.

Frida

Un exemple d'utilisation de evaluatePolicy de l'application DVIA-v2 :

swift
+(void)authenticateWithTouchID {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = @"Please authenticate yourself";

if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
});
}
}

Pour réaliser le bypass de l'authentification locale, un script Frida est écrit. Ce script cible la vérification evaluatePolicy, interceptant son rappel pour s'assurer qu'il renvoie success=1. En modifiant le comportement du rappel, la vérification d'authentification est effectivement contournée.

Le script ci-dessous est injecté pour modifier le résultat de la méthode evaluatePolicy. Il change le résultat du rappel pour indiquer toujours un succÚs.

swift
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
if(ObjC.available) {
console.log("Injecting...");
var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var block = new ObjC.Block(args[4]);
const callback = block.implementation;
block.implementation = function (error, value)  {

console.log("Changing the result value to true")
const result = callback(1, null);
return result;
};
},
});
} else {
console.log("Objective-C Runtime is not available!");
}

Pour injecter le script Frida et contourner l'authentification biométrique, la commande suivante est utilisée :

bash
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js

Exposition de Fonctionnalités Sensibles par IPC

iOS Custom URI Handlers / Deeplinks / Custom Schemes

Liens Universels

iOS Universal Links

Partage UIActivity

iOS UIActivity Sharing

UIPasteboard

iOS UIPasteboard

Extensions d'Application

iOS App Extensions

WebViews

iOS WebViews

SĂ©rialisation et Encodage

iOS Serialisation and Encoding

Communication RĂ©seau

Il est important de vérifier qu'aucune communication ne se produit sans cryptage et également que l'application valide correctement le certificat TLS du serveur.
Pour vérifier ce genre de problÚmes, vous pouvez utiliser un proxy comme Burp :

iOS Burp Suite Configuration

VĂ©rification du Nom d'HĂŽte

Un problÚme courant lors de la validation du certificat TLS est de vérifier que le certificat a été signé par une CA de confiance, mais ne pas vérifier si le nom d'hÎte du certificat est le nom d'hÎte accédé.
Pour vérifier ce problÚme en utilisant Burp, aprÚs avoir fait confiance à la CA de Burp sur l'iPhone, vous pouvez créer un nouveau certificat avec Burp pour un nom d'hÎte différent et l'utiliser. Si l'application fonctionne toujours, alors, quelque chose est vulnérable.

Pinning de Certificat

Si une application utilise correctement le SSL Pinning, alors l'application ne fonctionnera que si le certificat est celui attendu. Lors du test d'une application, cela peut poser un problĂšme car Burp servira son propre certificat.
Pour contourner cette protection sur un appareil jailbreaké, vous pouvez installer l'application SSL Kill Switch ou installer Burp Mobile Assistant

Vous pouvez Ă©galement utiliser objection's ios sslpinning disable

Divers

  • Dans /System/Library, vous pouvez trouver les frameworks installĂ©s sur le tĂ©lĂ©phone utilisĂ©s par les applications systĂšme
  • Les applications installĂ©es par l'utilisateur depuis l'App Store se trouvent dans /User/Applications
  • Et le /User/Library contient les donnĂ©es sauvegardĂ©es par les applications au niveau utilisateur
  • Vous pouvez accĂ©der Ă  /User/Library/Notes/notes.sqlite pour lire les notes sauvegardĂ©es dans l'application.
  • Dans le dossier d'une application installĂ©e (/User/Applications/<APP ID>/), vous pouvez trouver des fichiers intĂ©ressants :
  • iTunesArtwork : L'icĂŽne utilisĂ©e par l'application
  • iTunesMetadata.plist : Infos de l'application utilisĂ©es dans l'App Store
  • /Library/* : Contient les prĂ©fĂ©rences et le cache. Dans /Library/Cache/Snapshots/*, vous pouvez trouver le snapshot effectuĂ© sur l'application avant de l'envoyer en arriĂšre-plan.

Hot Patching/Mise à Jour Forcée

Les développeurs peuvent patcher toutes les installations de leur application instantanément sans avoir à soumettre à nouveau l'application à l'App Store et attendre son approbation.
À cette fin, on utilise gĂ©nĂ©ralement JSPatch. Mais il existe d'autres options telles que Siren et react-native-appstore-version-checker.
C'est un mĂ©canisme dangereux qui pourrait ĂȘtre abusĂ© par des SDK tiers malveillants, il est donc recommandĂ© de vĂ©rifier quelle mĂ©thode est utilisĂ©e pour la mise Ă  jour automatique (le cas Ă©chĂ©ant) et de la tester. Vous pourriez essayer de tĂ©lĂ©charger une version prĂ©cĂ©dente de l'application Ă  cette fin.

Tiers

Un dĂ©fi significatif avec les SDK tiers est le manque de contrĂŽle granulaire sur leurs fonctionnalitĂ©s. Les dĂ©veloppeurs sont confrontĂ©s Ă  un choix : soit intĂ©grer le SDK et accepter toutes ses fonctionnalitĂ©s, y compris les vulnĂ©rabilitĂ©s de sĂ©curitĂ© potentielles et les prĂ©occupations en matiĂšre de confidentialitĂ©, soit renoncer entiĂšrement Ă  ses avantages. Souvent, les dĂ©veloppeurs ne peuvent pas corriger les vulnĂ©rabilitĂ©s au sein de ces SDK eux-mĂȘmes. De plus, Ă  mesure que les SDK gagnent la confiance au sein de la communautĂ©, certains peuvent commencer Ă  contenir des logiciels malveillants.

Les services fournis par les SDK tiers peuvent inclure le suivi du comportement des utilisateurs, l'affichage de publicitĂ©s ou l'amĂ©lioration de l'expĂ©rience utilisateur. Cependant, cela introduit un risque car les dĂ©veloppeurs peuvent ne pas ĂȘtre pleinement conscients du code exĂ©cutĂ© par ces bibliothĂšques, ce qui entraĂźne des risques potentiels pour la confidentialitĂ© et la sĂ©curitĂ©. Il est crucial de limiter les informations partagĂ©es avec les services tiers Ă  ce qui est nĂ©cessaire et de s'assurer qu'aucune donnĂ©e sensible n'est exposĂ©e.

L'implĂ©mentation de services tiers se prĂ©sente gĂ©nĂ©ralement sous deux formes : une bibliothĂšque autonome ou un SDK complet. Pour protĂ©ger la vie privĂ©e des utilisateurs, toute donnĂ©e partagĂ©e avec ces services doit ĂȘtre anonymisĂ©e pour Ă©viter la divulgation d'Informations Personnelles Identifiables (PII).

Pour identifier les bibliothĂšques utilisĂ©es par une application, la commande otool peut ĂȘtre employĂ©e. Cet outil doit ĂȘtre exĂ©cutĂ© contre l'application et chaque bibliothĂšque partagĂ©e qu'elle utilise pour dĂ©couvrir des bibliothĂšques supplĂ©mentaires.

bash
otool -L <application_path>

Références & Autres Ressources

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