iOS Pentesting
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)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Notions de base iOS
Environnement de test
Sur cette page, vous trouverez des informations sur le iOS simulator, les emulators et le jailbreaking :
Analyse initiale
Opérations de test iOS de base
Pendant les tests, plusieurs opérations seront proposées (connexion à l’appareil, lecture/écriture/téléversement/téléchargement de fichiers, utilisation d’outils…). Donc, si vous ne savez pas comment effectuer l’une de ces actions, commencez par lire la page :
Tip
Pour les étapes suivantes l’app doit être installée sur l’appareil et le fichier IPA de l’application doit déjà être obtenu.
Lisez la page Basic iOS Testing Operations pour apprendre comment procéder.
Analyse statique de base
Quelques décompilateurs intéressants pour fichiers iOS - IPA :
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 est chargée à une adresse mémoire aléatoire à chaque lancement, rendant plus difficile la prédiction de son adresse mémoire initiale.
otool -hv <app-binary> | grep PIE # It should include the PIE flag
- Stack Canaries : Pour valider l’intégrité de la stack, une valeur ‘canary’ est placée sur la stack avant d’appeler une fonction et est validée à nouveau lorsque la fonction se termine.
otool -I -v <app-binary> | grep stack_chk # It should include the symbols: stack_chk_guard and stack_chk_fail
- ARC (Automatic Reference Counting) : Pour prévenir les défauts courants de corruption mémoire
otool -I -v <app-binary> | grep objc_release # It should include the _objc_release symbol
- Encrypted Binary : Le binaire devrait être chiffré
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # The cryptid should be 1
Identification des fonctions sensibles/insécurisées
- Weak Hashing Algorithms
# On the iOS device
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"
# On linux
grep -iER "_CC_MD5"
grep -iER "_CC_SHA1"
- Insecure Random Functions
# On the iOS device
otool -Iv <app> | grep -w "_random"
otool -Iv <app> | grep -w "_srand"
otool -Iv <app> | grep -w "_rand"
# On linux
grep -iER "_random"
grep -iER "_srand"
grep -iER "_rand"
- Insecure ‘Malloc’ Function
# On the iOS device
otool -Iv <app> | grep -w "_malloc"
# On linux
grep -iER "_malloc"
- Insecure and Vulnerable Functions
# On the iOS device
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"
# On 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"
Méthodes courantes de détection du jailbreak
- File System Checks : Rechercher la présence de fichiers et répertoires jailbreak courants, tels que
/Applications/Cydia.appou/Library/MobileSubstrate/MobileSubstrate.dylib. - Sandbox Violations : Tenter d’accéder à des zones restreintes du système de fichiers, qui devraient être bloquées sur les appareils non-jailbreakés.
- API Checks : Vérifier s’il est possible d’utiliser des appels interdits comme
fork()pour créer un processus enfant ousystem()pour voir si /bin/sh existe. - Process Checks : Surveiller la présence de processus connus liés au jailbreak, tels que
Cydia,Substrate, oussh. - Kernel Exploits : Vérifier la présence d’exploits du kernel couramment utilisés dans les jailbreaks.
- Environment Variables : Inspecter les variables d’environnement à la recherche de signes de jailbreak, comme
DYLD_INSERT_LIBRARIES. - Libraries Check : Vérifier les libs qui sont chargées dans le processus de l’app.
- Check schemes : Comme
canOpenURL(URL(string: "cydia://")).
Méthodes courantes de détection anti-debugging
- Check for Debugger Presence : Utiliser
sysctlou d’autres méthodes pour vérifier si un debugger est attaché. - Anti-Debugging APIs : Rechercher des appels à des APIs anti-debugging comme
ptraceouSIGSTOPcommeptrace(PT_DENY_ATTACH, 0, 0, 0). - Timing Checks : Mesurer le temps pris pour certaines opérations et rechercher des écarts pouvant indiquer un debugging.
- Memory Checks : Inspecter la mémoire pour des artefacts ou modifications connus des debuggers.
- Environment Variables : Vérifier les variables d’environnement qui peuvent indiquer une session de debugging.
- Mach Ports : Détecter si des mach exception ports sont utilisés par des debuggers.
Analyse dynamique de base
Consultez l’analyse dynamique que MobSF réalise. Vous devrez naviguer dans les différentes vues et interagir avec elles, mais il effectuera du hooking de plusieurs classes et préparera un rapport une fois terminé.
Lister les apps installées
Utilisez la commande frida-ps -Uai pour déterminer le bundle identifier des apps installées :
$ 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 & Hooking
Apprenez à énumérer les composants de l’application et comment facilement hook methods and classes avec objection:
Structure de l’IPA
La structure d’un fichier IPA correspond essentiellement à celle d’un package zippé. En renommant son extension en .zip, il peut être décompressé pour en révéler le contenu. Dans cette structure, un Bundle représente une application entièrement empaquetée prête à l’installation. À 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 contient un fichier plist qui inclut une signature, garantissant l’intégrité de tous les fichiers du bundle.Assets.car: Une archive compressée qui contient des ressources graphiques comme les icônes.Frameworks/: Ce dossier contient les bibliothèques natives de l’application, qui peuvent prendre la forme de fichiers.dylibou.framework.PlugIns/: Cela peut inclure des extensions de l’application, connues sous la forme 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 la fonctionnalité d’annulation à votre app sur un seul appareil. Pour synchroniser les données entre plusieurs appareils d’un même compte iCloud, Core Data reflète automatiquement votre schéma dans un conteneur CloudKit.PkgInfo: Le fichierPkgInfoest une façon alternative de spécifier les codes type et creator de votre application ou bundle.- en.lproj, fr.proj, Base.lproj: Ce sont les packs de langues qui contiennent les ressources pour ces langues spécifiques, et une ressource par défaut au cas où une langue n’est pas prise en charge.
- Security: 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 inclus via des signatures numériques. - Asset Management: Le fichier
Assets.carutilise la compression pour gérer efficacement les ressources graphiques, crucial pour optimiser les performances de l’application et réduire sa taille globale. - Frameworks and 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/). - Localization: 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 fichier Info.plist sert de pierre angulaire pour les applications iOS, regroupant les 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 inclus. Il est structuré en format XML ou binaire et contient des informations critiques allant des permissions de l’application aux configurations de sécurité. Pour une exploration détaillée des clés disponibles, on peut se référer à la Apple Developer Documentation.
Pour ceux qui souhaitent travailler avec ce fichier dans un format plus accessible, la conversion en XML peut être effectuée facilement en utilisant plutil sur macOS (disponible nativement sur les versions 10.2 et ultérieures) ou plistutil sur Linux. Les commandes de conversion sont les suivantes:
- Pour macOS:
$ plutil -convert xml1 Info.plist
- Pour Linux:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Parmi la multitude d’informations que le fichier Info.plist peut divulguer, des entrées notables incluent les chaînes de permission de l’application (UsageDescription), les schémas d’URL personnalisés (CFBundleURLTypes) et les configurations pour App Transport Security (NSAppTransportSecurity). Ces entrées, ainsi que d’autres comme les types de documents personnalisés exportés/importés (UTExportedTypeDeclarations / UTImportedTypeDeclarations), peuvent être aisément localisées en inspectant le fichier ou en utilisant une simple commande grep :
$ 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 128-bit UUID, ce qui rend la tâche de localiser manuellement le dossier d’une application difficile en raison du caractère aléatoire des noms de répertoires.
Warning
Comme les applications iOS doivent être sandboxées, chaque application aura aussi un dossier à l’intérieur de
$HOME/Library/Containersportant comme nom leCFBundleIdentifierde l’application.Cependant, les deux dossiers (dossiers de données & dossiers de conteneur) contiennent le fichier
.com.apple.mobile_container_manager.metadata.plistqui 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, le objection tool fournit une commande utile, env. Cette commande révèle des informations détaillées sur les répertoires de l’application concernée. Ci-dessous un exemple d’utilisation de cette commande :
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 /private/var/containers en utilisant la commande find :
find /private/var/containers -name "Progname*"
Des commandes telles que ps et lsof peuvent également être utilisées pour identifier le processus de l’app et lister les fichiers ouverts, respectivement, fournissant des informations sur les chemins de répertoires actifs de l’app :
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1
Répertoire Bundle :
- AppName.app
- C’est le bundle d’application tel que vu précédemment dans l’IPA ; il contient les données essentielles de l’application, le 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é.
- Le contenu de ce dossier est utilisé pour valider la signature du code.
Répertoire Data :
- 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’app peut exclure des chemins de la sauvegarde en définissant
NSURLIsExcludedFromBackupKey. - Library/
- Contient tous les fichiers non spécifiques à l’utilisateur, tels que les caches, les préférences, les cookies, et les fichiers de configuration property list (plist).
- Les apps iOS utilisent généralement les sous-répertoires
Application SupportetCaches, mais l’app 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é.
- L’OS peut supprimer automatiquement les fichiers de ce répertoire lorsque l’app n’est pas en cours d’exécution et que l’espace de stockage est faible.
- Library/Application Support/
- Contient les fichiers persistants nécessaires au fonctionnement de l’app.
- Invisible pour les utilisateurs et les utilisateurs ne peuvent pas y écrire.
- Le contenu de ce répertoire est sauvegardé.
- L’app peut exclure des chemins de la sauvegarde en définissant
NSURLIsExcludedFromBackupKey. - Library/Preferences/
- Utilisé pour stocker des propriétés qui peuvent persister même après le redémarrage de l’application.
- Les informations sont enregistrées, non chiffrées, à l’intérieur du sandbox de l’application dans un fichier plist appelé [BUNDLE_ID].plist.
- Toutes les paires clé/valeur stockées via
NSUserDefaultsse trouvent 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’app.
- Contient des fichiers mis en cache non persistants.
- Invisible pour les utilisateurs.
- Le contenu de ce répertoire n’est pas sauvegardé.
- L’OS peut supprimer automatiquement les fichiers de ce répertoire lorsque l’app n’est pas en cours d’exécution et que l’espace de stockage est faible.
Regardons de plus près le bundle d’application (.app) d’iGoat-Swift dans le répertoire Bundle (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app) :
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
Binary Reversing
À 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 basique du binaire avec l’outil otool:
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érifier si l’application est chiffrée
Vérifiez s’il y a une sortie pour :
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
Désassemblage du binaire
Désassembler la section .text :
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 afficher le Objective-C segment de l’application d’exemple, on peut utiliser :
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:
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 apprendre comment iOS stocke les données sur l’appareil, consultez cette page :
Warning
Les emplacements suivants pour stocker des informations doivent être vérifiés immédiatement après l’installation de l’application, après avoir testé toutes les fonctionnalités de l’application et même après s’être déconnecté d’un utilisateur et s’être connecté avec un autre.
L’objectif est de trouver informations sensibles non protégées de l’application (mots de passe, tokens), de l’utilisateur actuel et des utilisateurs précédemment connectés.
Plist
plist files are structured XML files that contains key-value pairs. It’s a way to store persistent data, so sometimes you may find sensitive information in these files. It’s recommended to check these files after installing the app and after using intensively it to see if new data is written.
La façon la plus courante de persister des données dans des fichiers plist est l’utilisation de NSUserDefaults. Ce fichier plist est enregistré dans le sandbox 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 utilisateur. Les données sauvegardé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 pour de petites quantités de données.
Ces données ne peuvent plus être accessibles directement via un ordinateur de confiance, mais peuvent être consultées en effectuant une sauvegarde.
Vous pouvez dump les informations enregistrées avec NSUserDefaults en utilisant objection : 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 :
find ./ -name "*.plist"
Pour convertir des fichiers au format XML or binary (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 :
$ plutil -convert xml1 Info.plist
Pour les utilisateurs Linux : Installez libplist-utils d’abord, puis utilisez plistutil pour convertir votre fichier :
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Within an Objection Session: Pour analyser des applications mobiles, une commande spécifique permet de convertir des fichiers plist directement :
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 de votre application. Core Data can use SQLite as its persistent store, mais le framework en 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 fichier SQLite et accéder à des informations sensibles, alors vous avez trouvé une mauvaise configuration.
-(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 au-dessus de SQLite.
Comme les bases Yap sont des bases 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. Il est donc toujours intéressant de vérifier chaque base de données dans le répertoire de l’application. Allez donc dans le répertoire de l’application où les données sont enregistrées (/private/var/mobile/Containers/Data/Application/{APPID})
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 via Firebase Real-Time Databases. Stockées au format JSON, les données sont synchronisées en temps réel vers tous les clients connectés.
Vous pouvez trouver comment vérifier des bases de données Firebase mal configurées ici :
Bases de données Realm
Realm Objective-C and Realm Swift offrent une alternative puissante pour le stockage des données, non fournie par Apple. Par défaut, elles stockent les données non chiffrées, le chiffrement étant 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 telles que :
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 consulter 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, l’extrait de code suivant peut être utilisé :
// 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 embarqué qui suit l’approche orientée document (NoSQL). Conçu pour être natif sur iOS et macOS, il offre la capacité de synchroniser les données de manière transparente.
Pour identifier d’éventuelles bases de données Couchbase sur un appareil, le répertoire suivant doit être inspecté:
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
Cookies
iOS stocke les cookies des apps dans le Library/Cookies/cookies.binarycookies à l’intérieur du dossier de chaque app. Cependant, certains développeurs choisissent parfois de les enregistrer dans le keychain car le fichier de cookies mentionné peut être accessible dans les sauvegardes.
Pour inspecter le fichier de cookies vous pouvez utiliser this python script ou utiliser la commande d’objection ios cookies get.
Vous pouvez aussi utiliser objection pour convertir ces fichiers au format JSON et inspecter les données.
...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 HTTP requests and responses in the Cache.db database. Cette base de données peut contenir données sensibles, si des tokens, noms d’utilisateur ou toute autre information sensible a été mise en cache. Pour trouver les informations en cache, ouvrez le répertoire de données de l’app (/var/mobile/Containers/Data/Application/<UUID>) et allez dans /Library/Caches/<Bundle Identifier>. Le WebKit cache is also being stored in the Cache.db file. Objection peut ouvrir et interagir avec la base de données avec la commande sqlite connect Cache.db, car il s’agit d’une normale base de données SQLite.
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 :
- 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
removeAllCachedResponsesVous 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.
- Si vous n’avez pas besoin d’utiliser l’avantage des cookies, il serait recommandé d’utiliser simplement la propriété de configuration .ephemeral de URLSession, qui désactivera l’enregistrement des cookies et des Caches.
An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesn’t store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.
- Le Cache peut aussi être désactivé en définissant la Cache Policy sur .notAllowed. Cela désactivera le stockage du Cache de quelque manière que ce soit, en mémoire ou sur disque.
Snapshots
Chaque fois que vous appuyez sur le bouton Home, iOS prend un snapshot de l’écran courant pour pouvoir effectuer la transition vers l’application de manière plus fluide. Cependant, si des données sensibles sont présentes sur l’écran courant, elles seront enregistrées dans l’image (qui persiste après redémarrages). Ce sont les snapshots auxquels vous pouvez aussi accéder en double-tapant le bouton Home pour changer d’apps.
À moins que l’iPhone ne soit jailbreaké, l’attaquant doit avoir accès à l’appareil déverrouillé pour voir ces captures d’écran. Par défaut, le dernier snapshot est stocké dans le sandbox de l’application dans Library/Caches/Snapshots/ ou Library/SplashBoard/Snapshots (les ordinateurs de confiance ne peuvent pas accéder au système de fichiers depuis iOX 7.0).
Une façon d’empêcher ce comportement est d’afficher un écran vierge ou de supprimer les données sensibles avant la prise du snapshot en utilisant la fonction ApplicationDidEnterBackground().
Ce qui suit est une méthode de remédiation exemple qui définira une capture d’écran par défaut.
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. Il empêche les leaks de données sensibles car overlayImage.png remplacera toujours la vue courante.
Keychain
Pour accéder et gérer le keychain iOS, des outils comme Keychain-Dumper sont disponibles, adaptés aux appareils jailbroken. De plus, Objection fournit la commande ios keychain dump pour des usages similaires.
Stockage des identifiants
La classe NSURLCredential est idéale pour enregistrer des informations sensibles directement dans le keychain, évitant le besoin de NSUserDefaults ou d’autres wrappers. Pour stocker les identifiants après la connexion, le code Swift suivant est utilisé:
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 Objection ios nsurlcredentialstorage dump est utilisée.
Claviers personnalisés et cache du clavier
À partir d’iOS 8.0, les utilisateurs peuvent installer des extensions de clavier personnalisées, qui sont gérées 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, même si les utilisateurs sont avertis lorsque les claviers nécessitent un accès réseau. Les apps peuvent — et doivent — restreindre l’utilisation des claviers personnalisés pour la saisie d’informations sensibles.
Recommandations de sécurité :
- Il est conseillé de désactiver les claviers tiers pour renforcer la sécurité.
- Faites attention aux fonctions de correction automatique et de suggestions automatiques du clavier iOS par défaut, qui peuvent stocker des informations sensibles dans des fichiers cache situés dans
Library/Keyboard/{locale}-dynamic-text.datou/private/var/mobile/Library/Keyboard/dynamic-text.dat. Ces fichiers cache doivent être régulièrement vérifiés pour détecter des données sensibles. Réinitialiser le dictionnaire du clavier via Réglages > Général > Réinitialiser > Réinitialiser le dictionnaire du clavier est recommandé 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.
Empêcher la mise en cache des champs de texte
Le protocole UITextInputTraits offre des propriétés pour gérer la correction automatique et la saisie sécurisée, essentielles pour empêcher la mise en cache d’informations sensibles. Par exemple, désactiver la correction automatique et activer la saisie sécurisée peut être réalisé avec :
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;
De plus, les développeurs doivent s’assurer que les champs de texte, en particulier ceux destinés à saisir des informations sensibles telles que les mots de passe et les PIN, désactivent la mise en cache en réglant autocorrectionType sur UITextAutocorrectionTypeNo et secureTextEntry sur YES.
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
Logs
Le débogage de code implique souvent l’utilisation de logging. Il y a un risque car les logs peuvent contenir des informations sensibles. Auparavant, sous iOS 6 et les versions antérieures, les logs étaient accessibles à toutes les apps, posant un risque de leak de données sensibles. Désormais, les applications sont limitées à accéder uniquement à leurs logs.
Malgré ces restrictions, un attacker with physical access à un appareil déverrouillé peut toujours exploiter cela 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’app.
Pour atténuer les risques, il est conseillé d’interagir soigneusement avec l’app, en explorant toutes ses fonctionnalités et entrées afin de s’assurer qu’aucune information sensible n’est enregistrée involontairement dans les logs.
Lorsque vous examinez le code source de l’app pour d’éventuels leaks, recherchez à la fois des instructions prédéfinies et des custom logging statements 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 apps enregistrent diverses informations qui peuvent être sensibles. Pour surveiller ces logs, des outils et commandes comme:
idevice_id --list # To find the device ID
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
sont utiles. De plus, Xcode fournit un moyen de collecter les logs de la console :
- Ouvrez Xcode.
- Connectez votre appareil iOS.
- Naviguez vers Window -> Devices and Simulators.
- Sélectionnez votre appareil.
- Reproduisez le problème que vous étudiez.
- Utilisez le bouton Open Console pour afficher les logs dans une nouvelle fenêtre.
Pour une journalisation plus avancée, se connecter au shell de l’appareil et utiliser socat peut fournir une surveillance des logs en temps réel :
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
Suivi de commandes pour observer les activités des logs, ce qui peut être inestimable pour diagnostiquer des problèmes ou identifier une potentielle data leakage.
Sauvegardes
Fonctions d’auto-sauvegarde sont intégrées à iOS, facilitant la création de copies des 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 d’éléments très sensibles comme les informations Apple Pay et les configurations Touch ID.
Risques de sécurité
L’inclusion des apps installées et de leurs données dans les sauvegardes soulève le problème d’une potentielle data leakage et le risque que des modifications de la sauvegarde puissent altérer le fonctionnement de l’app. Il est conseillé de ne pas stocker d’informations sensibles en plaintext dans le répertoire d’une app ou ses sous-répertoires pour atténuer ces risques.
Exclure des 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 répertoires spécifiques des sauvegardes en utilisant NSURL setResourceValue:forKey:error: avec la clé NSURLIsExcludedFromBackupKey. Cette pratique est cruciale pour protéger les données sensibles afin qu’elles ne soient pas incluses dans les sauvegardes.
Tests de vulnérabilités
Pour évaluer la sécurité des sauvegardes d’une app, commencez par créer une sauvegarde en utilisant Finder, puis localisez-la en suivant les instructions de Apple’s official documentation. Analysez la sauvegarde à la recherche de données sensibles ou de configurations qui pourraient être modifiées pour affecter le comportement de l’app.
Les 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 d’un chiffrement peut être confirmée en vérifiant la clé “IsEncrypted” dans le fichier “Manifest.plist” à la racine de la sauvegarde.
<?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 gérer les encrypted backups, les scripts Python disponibles dans DinoSec’s GitHub repo, comme backup_tool.py et backup_passwd.py, peuvent être utiles, bien qu’ils puissent nécessiter des ajustements pour la compatibilité avec les dernières versions d’iTunes/Finder. L’iOSbackup tool est une autre option pour accéder aux fichiers dans des password-protected backups.
Modification du comportement de l’application
Un exemple d’altération du comportement d’une app via des backup modifications est démontré dans le Bither bitcoin wallet app, où le UI lock PIN est stocké dans net.bither.plist sous la clé pin_code. Supprimer cette clé du plist et restaurer le backup supprime l’exigence de PIN, fournissant un accès sans restriction.
Résumé sur les tests mémoire pour les données sensibles
Lorsqu’on traite des 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 examiner le contenu de la mémoire : creating a memory dump et analyzing the memory in real time. Les deux méthodes présentent des défis, notamment le risque de passer à côté de données critiques pendant le processus de dump ou l’analyse.
Retrieving and Analyzing a Memory Dump
Pour les appareils jailbroken et non-jailbroken, des outils comme objection et Fridump permettent de dumper la mémoire d’un processus d’application. Une fois dumpée, l’analyse de ces données nécessite divers outils, selon la nature des informations recherchées.
Pour extraire des chaînes depuis un memory dump, des commandes telles que strings ou rabin2 -zz peuvent être utilisées :
# Extracting strings using strings command
$ strings memory > strings.txt
# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt
Pour une analyse plus approfondie, y compris la recherche de types de données ou de motifs spécifiques, radare2 offre des capacités de recherche étendues :
$ 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 app en temps réel, sans avoir besoin d’un memory dump. Cet outil permet d’exécuter des commandes de recherche directement sur la mémoire de l’application en cours d’exécution :
$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>
Cryptographie défaillante
Mauvaises pratiques de gestion des clés
Certains développeurs enregistrent des données sensibles dans le stockage local et les chiffrent avec une clé codée en dur/prédictible dans le code. Cela ne devrait pas être fait, car une rétro-ingénierie pourrait permettre à des attaquants d’extraire les informations confidentielles.
Utilisation d’algorithmes non sécurisés et/ou obsolètes
Les développeurs ne doivent pas utiliser deprecated algorithms pour effectuer des contrôles d’autorisation, store ou send 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 au brute-force doivent être utilisés avec du salt.
Vérification
Les principales vérifications à effectuer consistent à rechercher si des mots de passe/secrets sont codés en dur dans le code, s’ils sont prévisibles, et si le code utilise des algorithmes de cryptographie faibles.
Il est intéressant de savoir que vous pouvez monitor certaines crypto libraries automatiquement en utilisant objection avec :
ios monitor crypt
Pour plus d’informations sur les API et bibliothèques cryptographiques iOS, consultez 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, notamment lorsqu’il s’agit de protéger l’accès à un endpoint distant via des méthodes cryptographiques. L’essentiel est que, sans une implémentation appropriée, les mécanismes d’authentification locale peuvent être contournés.
Le Local Authentication framework d’Apple et le keychain fournissent des API robustes permettant aux développeurs d’afficher des dialogues d’authentification utilisateur et de gérer de manière sécurisée les données secrètes, respectivement. Le Secure Enclave protège l’ID d’empreinte 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 le choix entre deux API :
LocalAuthentication.frameworkpour l’authentification utilisateur de haut niveau sans accès aux données biométriques.Security.frameworkpour l’accès bas niveau aux services du keychain, sécurisant les données secrètes avec une authentification biométrique. Divers open-source wrappers simplifient l’accès au keychain.
Caution
Cependant,
LocalAuthentication.frameworketSecurity.frameworkprésentent des vulnérabilités, car ils renvoient principalement des valeurs booléennes sans transmettre de données pour les processus d’authentification, ce qui les rend susceptibles d’être contournés (voir Don’t touch me that way, by David Lindner et al).
Implémentation de l’authentification locale
Pour inviter les utilisateurs à s’authentifier, les développeurs doivent utiliser la méthode evaluatePolicy de la classe LAContext, en choisissant entre :
deviceOwnerAuthentication: invite à utiliser Touch ID ou le code d’accès de l’appareil, et échoue si aucun n’est activé.deviceOwnerAuthenticationWithBiometrics: invite exclusivement à utiliser Touch ID.
Une authentification réussie est indiquée par une valeur booléenne retournée par evaluatePolicy, ce qui met en évidence une faille de sécurité potentielle.
Authentification locale utilisant le keychain
La mise en œuvre de l’authentification locale dans les apps iOS implique l’utilisation des keychain APIs pour stocker de manière sécurisée des données secrètes telles que des tokens d’authentification. Ce processus garantit que les données ne peuvent être accessibles que par l’utilisateur, en utilisant le code d’accès de l’appareil ou une authentification biométrique comme Touch ID.
Le keychain permet de définir des items avec l’attribut SecAccessControl, qui restreint l’accès à l’élément tant que l’utilisateur ne s’est pas authentifié avec succès via Touch ID ou le code d’accès de l’appareil. Cette fonctionnalité est cruciale pour renforcer la sécurité.
Ci-dessous se trouvent des exemples de code en Swift et Objective-C montrant comment sauvegarder et récupérer une chaîne vers/depuis le keychain, en tirant parti de ces fonctionnalités de sécurité. Les exemples montrent en particulier comment configurer le contrôle d’accès pour exiger l’authentification Touch ID et garantir que les données sont accessibles uniquement sur l’appareil où elles ont été configurées, à condition qu’un code d’accès soit configuré sur l’appareil.
// 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
}
Nous pouvons maintenant demander l’élément enregistré au Keychain. Les services Keychain afficheront la boîte de dialogue d’authentification à l’utilisateur et retourneront data ou nil selon qu’une empreinte digitale appropriée ait été fournie ou non.
// 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 app peut aussi être détectée en analysant la liste des bibliothèques dynamiques partagées du binaire de l’app. Cela peut être fait en utilisant otool:
$ otool -L <AppName>.app/<AppName>
Si LocalAuthentication.framework est utilisé dans une app, la sortie contiendra les deux lignes suivantes (rappelez-vous que LocalAuthentication.framework utilise Security.framework en interne):
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security
Si Security.framework is used, only the second one will be shown.
Contournement du LocalAuthentication Framework
Objection
Grâce à l’Objection Biometrics Bypass, disponible sur this GitHub page, une technique permet de contourner le mécanisme LocalAuthentication. L’idée principale consiste à utiliser Frida pour manipuler la fonction evaluatePolicy, en la forçant à renvoyer systématiquement la valeur True, quel que soit le résultat réel de l’authentification. C’est particulièrement utile pour contourner des mécanismes biométriques mal implémentés.
Pour activer ce bypass, la commande suivante est utilisée :
...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 depuis DVIA-v2 application:
+(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 Local Authentication, un script Frida est écrit. Ce script cible la vérification evaluatePolicy, interceptant son callback pour garantir qu’il retourne success=1. En modifiant le comportement du callback, le contrôle d’authentification est effectivement bypassé.
Le script ci‑dessous est injecté pour modifier le résultat de la méthode evaluatePolicy. Il change le résultat du callback pour indiquer systématiquement le succès.
// 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 :
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
Sensitive Functionality Exposure Through IPC
Custom URI Handlers / Deeplinks / Custom Schemes
iOS Custom URI Handlers / Deeplinks / Custom Schemes
Universal Links
UIActivity Sharing
UIPasteboard
App Extensions
WebViews
Serialisation and Encoding
iOS Serialisation and Encoding
Network Communication
Il est important de vérifier qu’aucune communication n’a lieu sans chiffrement et aussi que l’application valide correctement le certificat TLS du serveur.
Pour vérifier ce type de problèmes, vous pouvez utiliser un proxy comme Burp :
Hostname check
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 de ne pas vérifier si le hostname du certificat correspond au hostname accédé.
Pour vérifier ce problème avec Burp, après avoir fait confiance à la Burp CA sur l’iPhone, vous pouvez créer un nouveau certificat avec Burp pour un hostname différent et l’utiliser. Si l’application fonctionne toujours, alors elle est vulnérable.
Certificate Pinning
Si une application utilise correctement SSL Pinning, alors l’application ne fonctionnera que si le certificat est celui attendu. Lors des tests, cela peut poser problème car Burp présentera son propre certificat.
Pour contourner cette protection sur un appareil jailbroken, vous pouvez installer l’application SSL Kill Switch ou installer Burp Mobile Assistant
Vous pouvez aussi utiliser objection ios sslpinning disable
Misc
- Dans
/System/Libraryvous 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 sont situées dans
/User/Applications - Et
/User/Librarycontient les données sauvegardées par les applications au niveau utilisateur - Vous pouvez accéder à
/User/Library/Notes/notes.sqlitepour lire les notes enregistrées dans l’application. - À l’intérieur du 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’appiTunesMetadata.plist: informations de l’app utilisées dans l’App Store/Library/*: contient les préférences et le cache. Dans/Library/Cache/Snapshots/*vous pouvez trouver le snapshot réalisé de l’application avant de l’envoyer en arrière-plan.
Hot Patching/Enforced Updateing
Les développeurs peuvent patcher à distance toutes les installations de leur app instantanément sans avoir à soumettre à nouveau l’application sur l’App store et attendre son approbation.
Pour cela, on utilise généralement JSPatch. Mais il existe d’autres options comme 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 (si elle existe) et de la tester. Vous pouvez essayer de télécharger une version antérieure de l’app à cet effet.
Third Parties
Un défi important avec les 3rd party SDKs est le manque de contrôle granulaire sur leurs fonctionnalités. Les développeurs font face à un choix : intégrer le SDK et accepter toutes ses fonctionnalités, y compris les potentielles vulnérabilités de sécurité et problèmes de confidentialité, ou renoncer entièrement à ses avantages. Souvent, les développeurs ne peuvent pas corriger eux-mêmes les vulnérabilités contenues dans ces SDK. De plus, à mesure que des SDK gagnent en confiance au sein de la communauté, certains peuvent commencer à contenir du malware.
Les services fournis par les SDK tiers peuvent inclure le suivi du comportement utilisateur, l’affichage de publicités, ou des améliorations de l’expérience utilisateur. Cependant, cela introduit un risque car les développeurs ne sont pas toujours pleinement conscients du code exécuté par ces bibliothèques, ce qui peut entraîner des risques 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 des services tiers se présente généralement sous deux formes : une library autonome ou un SDK complet. Pour protéger la vie privée des utilisateurs, toute donnée partagée avec ces services devrait être anonymized afin d’empêcher la divulgation de Personal Identifiable Information (PII).
Pour identifier les libraries qu’une application utilise, on peut employer la commande otool. Cet outil doit être exécuté contre l’application et chaque shared library qu’elle utilise pour découvrir des bibliothèques additionnelles.
otool -L <application_path>
Vulnérabilités intéressantes et études de cas
Air Keyboard Remote Input Injection
Itunesstored Bookassetd Sandbox Escape
Zero Click Messaging Image Parser Chains
Références & ressources supplémentaires
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering
- Pentesting iOS & applications mobiles - INE
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/
- https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage
- https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060
- https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064
- https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054
- https://github.com/ivRodriguezCA/RE-iOS-Apps/ cours iOS gratuit(https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)
- https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577
- https://www.slideshare.net/RyanISI/ios-appsecurityminicourse
- https://github.com/prateek147/DVIA
- https://github.com/prateek147/DVIA-v2
- https://github.com/OWASP/MSTG-Hacking-Playground%20
- OWASP iGoat https://github.com/OWASP/igoat <<< version Objective-C https://github.com/OWASP/iGoat-Swift <<< version Swift
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/nabla-c0d3/ssl-kill-switch2
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)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


