# iOS Pentesting {{#include ../../banners/hacktricks-training.md}} ## iOS Grundlagen {{#ref}} ios-basics.md {{#endref}} ## Testumgebung Auf dieser Seite finden Sie Informationen über den **iOS-Simulator**, **Emulatoren** und **Jailbreaking:** {{#ref}} ios-testing-environment.md {{#endref}} ## Erste Analyse ### Grundlegende iOS-Testoperationen Während des Tests **werden mehrere Operationen vorgeschlagen** (Verbinden mit dem Gerät, Dateien lesen/schreiben/hochladen/herunterladen, einige Tools verwenden...). Wenn Sie also nicht wissen, wie Sie eine dieser Aktionen ausführen, **beginnen Sie bitte mit dem Lesen der Seite**: {{#ref}} basic-ios-testing-operations.md {{#endref}} > [!NOTE] > Für die folgenden Schritte **sollte die App installiert sein** und die **IPA-Datei** der Anwendung sollte bereits vorliegen.\ > Lesen Sie die [Basic iOS Testing Operations](basic-ios-testing-operations.md) Seite, um zu erfahren, wie Sie dies tun. ### Grundlegende Statische Analyse Einige interessante iOS - IPA-Datei-Dekompilierer: - https://github.com/LaurieWired/Malimite - https://ghidra-sre.org/ Es wird empfohlen, das Tool [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) zu verwenden, um eine automatische Statische Analyse der IPA-Datei durchzuführen. Identifizierung von **Schutzmaßnahmen, die im Binärformat vorhanden sind**: - **PIE (Position Independent Executable)**: Wenn aktiviert, wird die Anwendung jedes Mal an einer zufälligen Speicheradresse geladen, was es schwieriger macht, ihre ursprüngliche Speicheradresse vorherzusagen. ```bash otool -hv | grep PIE # Es sollte das PIE-Flag enthalten ``` - **Stack Canaries**: Um die Integrität des Stacks zu validieren, wird ein 'Canary'-Wert auf den Stack gelegt, bevor eine Funktion aufgerufen wird, und erneut validiert, sobald die Funktion endet. ```bash otool -I -v | grep stack_chk # Es sollte die Symbole: stack_chk_guard und stack_chk_fail enthalten ``` - **ARC (Automatic Reference Counting)**: Um häufige Speicherbeschädigungsfehler zu verhindern ```bash otool -I -v | grep objc_release # Es sollte das _objc_release-Symbol enthalten ``` - **Verschlüsselte Binärdatei**: Die Binärdatei sollte verschlüsselt sein ```bash otool -arch all -Vl | grep -A5 LC_ENCRYPT # Der cryptid sollte 1 sein ``` **Identifizierung von Sensiblen/Unsicheren Funktionen** - **Schwache Hash-Algorithmen** ```bash # Auf dem iOS-Gerät otool -Iv | grep -w "_CC_MD5" otool -Iv | grep -w "_CC_SHA1" # Auf Linux grep -iER "_CC_MD5" grep -iER "_CC_SHA1" ``` - **Unsichere Zufallsfunktionen** ```bash # Auf dem iOS-Gerät otool -Iv | grep -w "_random" otool -Iv | grep -w "_srand" otool -Iv | grep -w "_rand" # Auf Linux grep -iER "_random" grep -iER "_srand" grep -iER "_rand" ``` - **Unsichere ‘Malloc’-Funktion** ```bash # Auf dem iOS-Gerät otool -Iv | grep -w "_malloc" # Auf Linux grep -iER "_malloc" ``` - **Unsichere und Verwundbare Funktionen** ```bash # Auf dem iOS-Gerät otool -Iv | grep -w "_gets" otool -Iv | grep -w "_memcpy" otool -Iv | grep -w "_strncpy" otool -Iv | grep -w "_strlen" otool -Iv | grep -w "_vsnprintf" otool -Iv | grep -w "_sscanf" otool -Iv | grep -w "_strtok" otool -Iv | grep -w "_alloca" otool -Iv | grep -w "_sprintf" otool -Iv | grep -w "_printf" otool -Iv | grep -w "_vsprintf" # Auf 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" ``` ### Grundlegende Dynamische Analyse Überprüfen Sie die dynamische Analyse, die [**MobSF**](https://github.com/MobSF/Mobile-Security-Framework-MobSF) durchführt. Sie müssen durch die verschiedenen Ansichten navigieren und mit ihnen interagieren, aber es wird mehrere Klassen hooken, während Sie andere Dinge tun, und einen Bericht erstellen, sobald Sie fertig sind. ### Auflistung installierter Apps Verwenden Sie den Befehl `frida-ps -Uai`, um die **Bundle-ID** der installierten Apps zu bestimmen: ```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 ``` ### Grundlegende Enumeration & Hooking Erfahren Sie, wie Sie die **Komponenten der Anwendung auflisten** und wie Sie mit Objection **Methoden und Klassen einfach hooken** können: {{#ref}} ios-hooking-with-objection.md {{#endref}} ### IPA-Struktur Die Struktur einer **IPA-Datei** ist im Wesentlichen die eines **zipped Pakets**. Durch Umbenennen der Erweiterung in `.zip` kann sie **dekomprimiert** werden, um ihren Inhalt zu enthüllen. Innerhalb dieser Struktur stellt ein **Bundle** eine vollständig verpackte Anwendung dar, die bereit für die Installation ist. Darin finden Sie ein Verzeichnis namens `.app`, das die Ressourcen der Anwendung kapselt. - **`Info.plist`**: Diese Datei enthält spezifische Konfigurationsdetails der Anwendung. - **`_CodeSignature/`**: Dieses Verzeichnis enthält eine plist-Datei, die eine Signatur enthält und die Integrität aller Dateien im Bundle sicherstellt. - **`Assets.car`**: Ein komprimiertes Archiv, das Asset-Dateien wie Icons speichert. - **`Frameworks/`**: Dieser Ordner beherbergt die nativen Bibliotheken der Anwendung, die in Form von `.dylib` oder `.framework`-Dateien vorliegen können. - **`PlugIns/`**: Dies kann Erweiterungen der Anwendung enthalten, die als `.appex`-Dateien bekannt sind, obwohl sie nicht immer vorhanden sind. \* [**`Core Data`**](https://developer.apple.com/documentation/coredata): Es wird verwendet, um die permanenten Daten Ihrer Anwendung für die Offline-Nutzung zu speichern, temporäre Daten zwischenzuspeichern und eine Rückgängig-Funktionalität für Ihre App auf einem einzelnen Gerät hinzuzufügen. Um Daten über mehrere Geräte in einem einzigen iCloud-Konto zu synchronisieren, spiegelt Core Data automatisch Ihr Schema in einen CloudKit-Container. - [**`PkgInfo`**](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): Die `PkgInfo`-Datei ist eine alternative Möglichkeit, die Typ- und Ersteller-Codes Ihrer Anwendung oder Ihres Bundles anzugeben. - **en.lproj, fr.proj, Base.lproj**: Sind die Sprachpakete, die Ressourcen für diese spezifischen Sprachen enthalten, sowie eine Standardressource für den Fall, dass eine Sprache nicht unterstützt wird. - **Sicherheit**: Das Verzeichnis `_CodeSignature/` spielt eine entscheidende Rolle für die Sicherheit der App, indem es die Integrität aller gebündelten Dateien durch digitale Signaturen überprüft. - **Asset-Management**: Die Datei `Assets.car` verwendet Kompression, um grafische Assets effizient zu verwalten, was entscheidend für die Optimierung der Anwendungsleistung und die Reduzierung ihrer Gesamtgröße ist. - **Frameworks und PlugIns**: Diese Verzeichnisse unterstreichen die Modularität von iOS-Anwendungen, die es Entwicklern ermöglichen, wiederverwendbare Codebibliotheken (`Frameworks/`) einzuschließen und die Funktionalität der App zu erweitern (`PlugIns/`). - **Lokalisierung**: Die Struktur unterstützt mehrere Sprachen und erleichtert die globale Reichweite der Anwendung, indem Ressourcen für spezifische Sprachpakete enthalten sind. **Info.plist** Die **Info.plist** dient als Grundpfeiler für iOS-Anwendungen und kapselt wichtige Konfigurationsdaten in Form von **Schlüssel-Wert**-Paaren. Diese Datei ist eine Voraussetzung nicht nur für Anwendungen, sondern auch für App-Erweiterungen und Frameworks, die im Bundle enthalten sind. Sie ist entweder im XML- oder im Binärformat strukturiert und enthält kritische Informationen, die von App-Berechtigungen bis zu Sicherheitskonfigurationen reichen. Für eine detaillierte Erkundung der verfügbaren Schlüssel kann auf die [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc) verwiesen werden. Für diejenigen, die mit dieser Datei in einem zugänglicheren Format arbeiten möchten, kann die XML-Konvertierung mühelos durch die Verwendung von `plutil` auf macOS (nativ verfügbar in Versionen 10.2 und später) oder `plistutil` auf Linux erreicht werden. Die Befehle zur Konvertierung sind wie folgt: - **Für macOS**: ```bash $ plutil -convert xml1 Info.plist ``` - **Für Linux**: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` Unter den zahlreichen Informationen, die die **Info.plist**-Datei preisgeben kann, sind bemerkenswerte Einträge wie App-Berechtigungsstrings (`UsageDescription`), benutzerdefinierte URL-Schemata (`CFBundleURLTypes`) und Konfigurationen für App Transport Security (`NSAppTransportSecurity`). Diese Einträge, zusammen mit anderen wie exportierten/importierten benutzerdefinierten Dokumenttypen (`UTExportedTypeDeclarations` / `UTImportedTypeDeclarations`), können mühelos durch Inspektion der Datei oder durch Verwendung eines einfachen `grep`-Befehls gefunden werden: ```bash $ grep -i Info.plist ``` **Datenpfade** Im iOS-Umfeld sind Verzeichnisse speziell für **Systemanwendungen** und **vom Benutzer installierte Anwendungen** vorgesehen. Systemanwendungen befinden sich im Verzeichnis `/Applications`, während vom Benutzer installierte Apps unter `/var/mobile/containers/Data/Application/` abgelegt werden. Diese Anwendungen erhalten eine eindeutige Kennung, die als **128-Bit-UUID** bekannt ist, was die manuelle Lokalisierung des App-Ordners aufgrund der Zufälligkeit der Verzeichnisnamen erschwert. > [!WARNING] > Da Anwendungen in iOS sandboxed sein müssen, hat jede App auch einen Ordner innerhalb von **`$HOME/Library/Containers`** mit der **`CFBundleIdentifier`** der App als Ordnernamen. > > Beide Ordner (Daten- und Containerordner) haben jedoch die Datei **`.com.apple.mobile_container_manager.metadata.plist`**, die beide Dateien im Schlüssel `MCMetadataIdentifier` verknüpft. Um die Entdeckung des Installationsverzeichnisses einer vom Benutzer installierten App zu erleichtern, bietet das **objection tool** einen nützlichen Befehl, `env`. Dieser Befehl zeigt detaillierte Verzeichnisinformationen für die betreffende App an. Im Folgenden ein Beispiel, wie man diesen Befehl verwendet: ```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 ``` Alternativ kann der App-Name im `/private/var/containers` mit dem `find`-Befehl gesucht werden: ```bash find /private/var/containers -name "Progname*" ``` Befehle wie `ps` und `lsof` können ebenfalls verwendet werden, um den Prozess der App zu identifizieren und offene Dateien aufzulisten, was Einblicke in die aktiven Verzeichnispfade der Anwendung bietet: ```bash ps -ef | grep -i lsof -p | grep -i "/containers" | head -n 1 ``` **Bundle-Verzeichnis:** - **AppName.app** - Dies ist das Anwendungsbundle, wie zuvor im IPA gesehen, es enthält essentielle Anwendungsdaten, statische Inhalte sowie die kompilierte Binärdatei der Anwendung. - Dieses Verzeichnis ist für Benutzer sichtbar, aber **Benutzer können nicht darauf schreiben**. - Inhalte in diesem Verzeichnis werden **nicht gesichert**. - Der Inhalt dieses Ordners wird verwendet, um **die Codesignatur zu validieren**. **Datenverzeichnis:** - **Documents/** - Enthält alle vom Benutzer generierten Daten. Der Endbenutzer der Anwendung initiiert die Erstellung dieser Daten. - Sichtbar für Benutzer und **Benutzer können darauf schreiben**. - Inhalte in diesem Verzeichnis werden **gesichert**. - Die App kann Pfade deaktivieren, indem sie `NSURLIsExcludedFromBackupKey` setzt. - **Library/** - Enthält alle **Dateien, die nicht benutzerspezifisch sind**, wie **Caches**, **Einstellungen**, **Cookies** und Konfigurationsdateien im Property List (plist)-Format. - iOS-Apps verwenden normalerweise die Unterverzeichnisse `Application Support` und `Caches`, aber die App kann benutzerdefinierte Unterverzeichnisse erstellen. - **Library/Caches/** - Enthält **semi-permanente zwischengespeicherte Dateien.** - Unsichtbar für Benutzer und **Benutzer können nicht darauf schreiben**. - Inhalte in diesem Verzeichnis werden **nicht gesichert**. - Das Betriebssystem kann die Dateien dieses Verzeichnisses automatisch löschen, wenn die App nicht läuft und der Speicherplatz knapp wird. - **Library/Application Support/** - Enthält **persistente** **Dateien**, die zum Ausführen der App erforderlich sind. - **Unsichtbar** **für** **Benutzer** und Benutzer können nicht darauf schreiben. - Inhalte in diesem Verzeichnis werden **gesichert**. - Die App kann Pfade deaktivieren, indem sie `NSURLIsExcludedFromBackupKey` setzt. - **Library/Preferences/** - Wird verwendet, um Eigenschaften zu speichern, die **auch nach einem Neustart der Anwendung bestehen bleiben können**. - Informationen werden unverschlüsselt im Anwendungs-Sandbox in einer plist-Datei namens \[BUNDLE_ID].plist gespeichert. - Alle Schlüssel/Wert-Paare, die mit `NSUserDefaults` gespeichert werden, sind in dieser Datei zu finden. - **tmp/** - Verwenden Sie dieses Verzeichnis, um **temporäre Dateien** zu schreiben, die zwischen den App-Starts nicht bestehen bleiben müssen. - Enthält nicht-persistente zwischengespeicherte Dateien. - **Unsichtbar** für Benutzer. - Inhalte in diesem Verzeichnis werden nicht gesichert. - Das Betriebssystem kann die Dateien dieses Verzeichnisses automatisch löschen, wenn die App nicht läuft und der Speicherplatz knapp wird. Lassen Sie uns einen genaueren Blick auf das Anwendungsbundle (.app) Verzeichnis von iGoat-Swift im Bundle-Verzeichnis (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`) werfen: ```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 ``` ### Binary Reversing Im `.app` Ordner finden Sie eine Binärdatei namens ``. Dies ist die Datei, die **ausgeführt** wird. Sie können eine grundlegende Inspektion der Binärdatei mit dem Tool **`otool`** durchführen: ```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) [...] ``` **Überprüfen Sie, ob die App verschlüsselt ist** Sehen Sie nach, ob es eine Ausgabe für gibt: ```bash otool -l | grep -A 4 LC_ENCRYPTION_INFO ``` **Disassemblierung der Binärdatei** Disassemblieren Sie den Textabschnitt: ```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 ``` Um das **Objective-C-Segment** der Beispielanwendung auszudrucken, kann man Folgendes verwenden: ```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 ``` Um einen kompakteren Objective-C-Code zu erhalten, können Sie [**class-dump**](http://stevenygard.com/projects/class-dump/) verwenden: ```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; }; ``` Die besten Optionen, um die Binärdatei zu disassemblieren, sind: [**Hopper**](https://www.hopperapp.com/download.html?) und [**IDA**](https://www.hex-rays.com/products/ida/support/download_freeware/). ## Datenspeicherung Um zu erfahren, wie iOS Daten auf dem Gerät speichert, lesen Sie diese Seite: {{#ref}} ios-basics.md {{#endref}} > [!WARNING] > Die folgenden Orte zur Speicherung von Informationen sollten **unmittelbar nach der Installation der Anwendung**, **nach der Überprüfung aller Funktionen** der Anwendung und sogar nach **dem Abmelden von einem Benutzer und dem Anmelden bei einem anderen** überprüft werden.\ > Das Ziel ist es, **unprotected sensitive information** der Anwendung (Passwörter, Tokens), des aktuellen Benutzers und von zuvor angemeldeten Benutzern zu finden. ### Plist **plist**-Dateien sind strukturierte XML-Dateien, die **Schlüssel-Wert-Paare** enthalten. Es ist eine Möglichkeit, persistente Daten zu speichern, daher können Sie manchmal **sensible Informationen in diesen Dateien** finden. Es wird empfohlen, diese Dateien nach der Installation der App und nach intensiver Nutzung zu überprüfen, um zu sehen, ob neue Daten geschrieben werden. Die häufigste Methode, um Daten in plist-Dateien zu persistieren, ist die Verwendung von **NSUserDefaults**. Diese plist-Datei wird im App-Sandbox unter **`Library/Preferences/.plist`** gespeichert. Die [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) Klasse bietet eine programmgesteuerte Schnittstelle zur Interaktion mit dem Standardsystem. Das Standardsystem ermöglicht es einer Anwendung, ihr Verhalten gemäß den **Benutzereinstellungen** anzupassen. Daten, die von `NSUserDefaults` gespeichert werden, können im Anwendungsbundle angezeigt werden. Diese Klasse speichert **Daten** in einer **plist**-**Datei**, ist jedoch für die Verwendung mit kleinen Datenmengen gedacht. Diese Daten können nicht mehr direkt über einen vertrauenswürdigen Computer zugegriffen werden, können jedoch durch das Durchführen eines **Backups** abgerufen werden. Sie können die Informationen, die mit **`NSUserDefaults`** gespeichert wurden, mit objections `ios nsuserdefaults get` **dumpen**. Um alle von der Anwendung verwendeten plist-Dateien zu finden, können Sie auf `/private/var/mobile/Containers/Data/Application/{APPID}` zugreifen und Folgendes ausführen: ```bash find ./ -name "*.plist" ``` Um Dateien von **XML oder binär (bplist)** Format in XML zu konvertieren, stehen je nach Betriebssystem verschiedene Methoden zur Verfügung: **Für macOS-Benutzer:** Verwenden Sie den Befehl `plutil`. Es ist ein integriertes Tool in macOS (10.2+), das für diesen Zweck entwickelt wurde: ```bash $ plutil -convert xml1 Info.plist ``` **Für Linux-Benutzer:** Installieren Sie zuerst `libplist-utils`, und verwenden Sie dann `plistutil`, um Ihre Datei zu konvertieren: ```bash $ apt install libplist-utils $ plistutil -i Info.plist -o Info_xml.plist ``` **Innerhalb einer Objection-Sitzung:** Zum Analysieren von mobilen Anwendungen ermöglicht ein spezifischer Befehl, plist-Dateien direkt zu konvertieren: ```bash ios plist cat /private/var/mobile/Containers/Data/Application//Library/Preferences/com.some.package.app.plist ``` ### Core Data [`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) ist ein Framework zur Verwaltung der Modellschicht von Objekten in Ihrer Anwendung. [Core Data kann SQLite als persistenten Speicher verwenden](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), aber das Framework selbst ist keine Datenbank.\ CoreData verschlüsselt seine Daten standardmäßig nicht. Es kann jedoch eine zusätzliche Verschlüsselungsschicht zu CoreData hinzugefügt werden. Weitere Details finden Sie im [GitHub Repo](https://github.com/project-imas/encrypted-core-data). Sie finden die SQLite Core Data-Informationen einer Anwendung im Pfad `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support` **Wenn Sie die SQLite öffnen und auf sensible Informationen zugreifen können, haben Sie eine Fehlkonfiguration gefunden.** ```objectivec: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](https://github.com/yapstudios/YapDatabase) ist ein Schlüssel/Wert-Speicher, der auf SQLite basiert.\ Da die Yap-Datenbanken SQLite-Datenbanken sind, können Sie sie mit dem im vorherigen Abschnitt vorgeschlagenen Befehl finden. ### Andere SQLite-Datenbanken Es ist üblich, dass Anwendungen ihre eigenen SQLite-Datenbanken erstellen. Sie könnten **sensible** **Daten** darauf **speichern** und sie unverschlüsselt lassen. Daher ist es immer interessant, jede Datenbank im Anwendungsverzeichnis zu überprüfen. Gehen Sie daher zum Anwendungsverzeichnis, in dem die Daten gespeichert sind (`/private/var/mobile/Containers/Data/Application/{APPID}`) ```bash find ./ -name "*.sqlite" -or -name "*.db" ``` ### Firebase Real-Time-Datenbanken Entwickler können **Daten speichern und synchronisieren** innerhalb einer **NoSQL, cloud-basierten Datenbank** über Firebase Real-Time-Datenbanken. Die Daten werden im JSON-Format gespeichert und in Echtzeit mit allen verbundenen Clients synchronisiert. Hier finden Sie, wie Sie nach falsch konfigurierten Firebase-Datenbanken suchen können: {{#ref}} ../../network-services-pentesting/pentesting-web/buckets/firebase-database.md {{#endref}} ### Realm-Datenbanken [Realm Objective-C](https://realm.io/docs/objc/latest/) und [Realm Swift](https://realm.io/docs/swift/latest/) bieten eine leistungsstarke Alternative zur Datenspeicherung, die von Apple nicht bereitgestellt wird. Standardmäßig **speichern sie Daten unverschlüsselt**, wobei Verschlüsselung durch spezifische Konfiguration verfügbar ist. Die Datenbanken befinden sich unter: `/private/var/mobile/Containers/Data/Application/{APPID}`. Um diese Dateien zu erkunden, kann man Befehle wie verwenden: ```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*" ``` Um diese Datenbankdateien anzuzeigen, wird das [**Realm Studio**](https://github.com/realm/realm-studio) Tool empfohlen. Um die Verschlüsselung innerhalb einer Realm-Datenbank zu implementieren, kann der folgende Codeausschnitt verwendet werden: ```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)") } ``` ### Couchbase Lite Datenbanken [Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) wird als eine **leichte** und **eingebettete** Datenbank-Engine beschrieben, die den **dokumentenorientierten** (NoSQL) Ansatz verfolgt. Entwickelt für **iOS** und **macOS**, bietet es die Möglichkeit, Daten nahtlos zu synchronisieren. Um potenzielle Couchbase-Datenbanken auf einem Gerät zu identifizieren, sollte das folgende Verzeichnis inspiziert werden: ```bash ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/ ``` ### Cookies iOS speichert die Cookies der Apps in der **`Library/Cookies/cookies.binarycookies`** innerhalb des Ordners jeder App. Entwickler entscheiden sich jedoch manchmal, sie im **Keychain** zu speichern, da die erwähnte **Cookie-Datei in Backups zugänglich ist**. Um die Cookie-Datei zu inspizieren, können Sie [**dieses Python-Skript**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) verwenden oder objections **`ios cookies get`.**\ **Sie können auch objection verwenden, um** diese Dateien in ein JSON-Format zu konvertieren und die Daten zu inspizieren. ```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 Standardmäßig speichert NSURLSession Daten, wie **HTTP-Anfragen und -Antworten in der Cache.db**-Datenbank. Diese Datenbank kann **sensible Daten** enthalten, wenn Tokens, Benutzernamen oder andere sensible Informationen zwischengespeichert wurden. Um die zwischengespeicherten Informationen zu finden, öffnen Sie das Datenverzeichnis der App (`/var/mobile/Containers/Data/Application/`) und gehen Sie zu `/Library/Caches/`. Der **WebKit-Cache wird ebenfalls in der Cache.db**-Datei gespeichert. **Objection** kann die Datenbank mit dem Befehl `sqlite connect Cache.db` öffnen und damit interagieren, da es sich um eine n**ormale SQLite-Datenbank** handelt. Es wird **empfohlen, das Caching dieser Daten zu deaktivieren**, da es sensible Informationen in der Anfrage oder Antwort enthalten kann. Die folgende Liste zeigt verschiedene Möglichkeiten, dies zu erreichen: 1. Es wird empfohlen, zwischengespeicherte Antworten nach dem Logout zu entfernen. Dies kann mit der von Apple bereitgestellten Methode [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses) erfolgen. Sie können diese Methode wie folgt aufrufen: `URLCache.shared.removeAllCachedResponses()` Diese Methode entfernt alle zwischengespeicherten Anfragen und Antworten aus der Cache.db-Datei. 2. Wenn Sie den Vorteil von Cookies nicht nutzen müssen, wird empfohlen, einfach die [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) Konfigurationseigenschaft von URLSession zu verwenden, die das Speichern von Cookies und Caches deaktiviert. [Apple-Dokumentation](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral): `Ein temporäres Sitzungs-Konfigurationsobjekt ähnelt einem Standard-Sitzungs-Konfigurationsobjekt (siehe Standard), mit dem Unterschied, dass das entsprechende Sitzungsobjekt keine Caches, Anmeldeinformationen oder andere sitzungsbezogene Daten auf der Festplatte speichert. Stattdessen werden sitzungsbezogene Daten im RAM gespeichert. Das einzige Mal, dass eine temporäre Sitzung Daten auf die Festplatte schreibt, ist, wenn Sie ihr sagen, den Inhalt einer URL in eine Datei zu schreiben.` 3. Der Cache kann auch deaktiviert werden, indem die Cache-Richtlinie auf [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed) gesetzt wird. Dadurch wird das Speichern des Caches in irgendeiner Form, entweder im Speicher oder auf der Festplatte, deaktiviert. ### Snapshots Immer wenn Sie die Home-Taste drücken, **nimmt iOS einen Snapshot des aktuellen Bildschirms** auf, um den Übergang zur Anwendung viel reibungsloser zu gestalten. Wenn jedoch **sensible** **Daten** auf dem aktuellen Bildschirm vorhanden sind, werden sie im **Bild** **gespeichert** (was **über** **Neustarts** **hinaus** **besteht**). Dies sind die Snapshots, auf die Sie auch zugreifen können, indem Sie doppelt auf den Home-Bildschirm tippen, um zwischen Apps zu wechseln. Es sei denn, das iPhone ist jailbroken, muss der **Angreifer** **Zugriff** auf das **Gerät** **entblockt** haben, um diese Screenshots zu sehen. Standardmäßig wird der letzte Snapshot im Sandbox der Anwendung im `Library/Caches/Snapshots/` oder `Library/SplashBoard/Snapshots`-Ordner gespeichert (vertrauenswürdige Computer können ab iOS 7.0 nicht auf das Dateisystem zugreifen). Eine Möglichkeit, dieses unerwünschte Verhalten zu verhindern, besteht darin, einen leeren Bildschirm anzuzeigen oder die sensiblen Daten zu entfernen, bevor der Snapshot mit der Funktion `ApplicationDidEnterBackground()` aufgenommen wird. Die folgende ist eine Beispiel-Maßnahme, die einen Standard-Screenshot festlegt. 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]; } ``` Dies setzt das Hintergrundbild auf `overlayImage.png`, wann immer die Anwendung in den Hintergrund versetzt wird. Es verhindert das Lecken sensibler Daten, da `overlayImage.png` immer die aktuelle Ansicht überschreibt. ### Keychain Für den Zugriff auf und die Verwaltung des iOS-Keychains sind Tools wie [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper) verfügbar, die für jailbroken Geräte geeignet sind. Darüber hinaus bietet [**Objection**](https://github.com/sensepost/objection) den Befehl `ios keychain dump` für ähnliche Zwecke. #### **Speichern von Anmeldeinformationen** Die **NSURLCredential**-Klasse ist ideal, um sensible Informationen direkt im Keychain zu speichern, wodurch die Notwendigkeit für NSUserDefaults oder andere Wrapper umgangen wird. Um Anmeldeinformationen nach dem Login zu speichern, wird der folgende Swift-Code verwendet: ```swift NSURLCredential *credential; credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent]; [[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace]; ``` Um diese gespeicherten Anmeldeinformationen zu extrahieren, wird der Befehl `ios nsurlcredentialstorage dump` von Objection verwendet. ## **Benutzerdefinierte Tastaturen und Tastatur-Cache** Mit iOS 8.0 und höher können Benutzer benutzerdefinierte Tastaturerweiterungen installieren, die unter **Einstellungen > Allgemein > Tastatur > Tastaturen** verwaltet werden können. Während diese Tastaturen erweiterte Funktionen bieten, besteht das Risiko von Tastenanschlagprotokollierung und der Übertragung von Daten an externe Server, obwohl die Benutzer über Tastaturen informiert werden, die Netzwerkzugriff benötigen. Apps können und sollten die Verwendung von benutzerdefinierten Tastaturen für die Eingabe sensibler Informationen einschränken. **Sicherheitsempfehlungen:** - Es wird empfohlen, Drittanbieter-Tastaturen zur Verbesserung der Sicherheit zu deaktivieren. - Seien Sie sich der Autokorrektur- und Auto-Vervollständigungsfunktionen der Standard-iOS-Tastatur bewusst, die sensible Informationen in Cache-Dateien speichern könnten, die sich in `Library/Keyboard/{locale}-dynamic-text.dat` oder `/private/var/mobile/Library/Keyboard/dynamic-text.dat` befinden. Diese Cache-Dateien sollten regelmäßig auf sensible Daten überprüft werden. Es wird empfohlen, das Tastaturwörterbuch über **Einstellungen > Allgemein > Zurücksetzen > Tastaturwörterbuch zurücksetzen** zurückzusetzen, um zwischengespeicherte Daten zu löschen. - Das Abfangen von Netzwerkverkehr kann aufdecken, ob eine benutzerdefinierte Tastatur Tastenanschläge remote überträgt. ### **Verhindern der Textfeld-Caching** Das [UITextInputTraits-Protokoll](https://developer.apple.com/reference/uikit/uitextinputtraits) bietet Eigenschaften zur Verwaltung der Autokorrektur und der sicheren Texteingabe, die entscheidend sind, um das Caching sensibler Informationen zu verhindern. Zum Beispiel kann das Deaktivieren der Autokorrektur und das Aktivieren der sicheren Texteingabe erreicht werden mit: ```objectivec textObject.autocorrectionType = UITextAutocorrectionTypeNo; textObject.secureTextEntry = YES; ``` Zusätzlich sollten Entwickler sicherstellen, dass Textfelder, insbesondere solche zur Eingabe sensibler Informationen wie Passwörter und PINs, das Caching deaktivieren, indem sie `autocorrectionType` auf `UITextAutocorrectionTypeNo` und `secureTextEntry` auf `YES` setzen. ```objectivec UITextField *textField = [[UITextField alloc] initWithFrame:frame]; textField.autocorrectionType = UITextAutocorrectionTypeNo; ``` ## **Protokolle** Das Debuggen von Code beinhaltet oft die Verwendung von **Protokollierung**. Es besteht ein Risiko, da **Protokolle sensible Informationen enthalten können**. Früher, in iOS 6 und früheren Versionen, waren Protokolle für alle Apps zugänglich, was ein Risiko für die Offenlegung sensibler Daten darstellte. **Jetzt sind Anwendungen darauf beschränkt, nur auf ihre eigenen Protokolle zuzugreifen**. Trotz dieser Einschränkungen kann ein **Angreifer mit physischem Zugriff** auf ein entsperrtes Gerät dies ausnutzen, indem er das Gerät mit einem Computer verbindet und **die Protokolle liest**. Es ist wichtig zu beachten, dass Protokolle auch nach der Deinstallation der App auf der Festplatte verbleiben. Um Risiken zu mindern, wird empfohlen, **gründlich mit der App zu interagieren**, alle Funktionen und Eingaben zu erkunden, um sicherzustellen, dass keine sensiblen Informationen versehentlich protokolliert werden. Bei der Überprüfung des Quellcodes der App auf potenzielle Lecks sollten sowohl **vordefinierte** als auch **benutzerdefinierte Protokollierungsanweisungen** gesucht werden, indem nach Schlüsselwörtern wie `NSLog`, `NSAssert`, `NSCAssert`, `fprintf` für integrierte Funktionen und nach Erwähnungen von `Logging` oder `Logfile` für benutzerdefinierte Implementierungen gesucht wird. ### **Überwachung von Systemprotokollen** Apps protokollieren verschiedene Informationen, die sensibel sein können. Um diese Protokolle zu überwachen, können Tools und Befehle wie: ```bash idevice_id --list # To find the device ID idevicesyslog -u (| grep ) # To capture the device logs ``` sind nützlich. Darüber hinaus bietet **Xcode** eine Möglichkeit, Konsolenprotokolle zu sammeln: 1. Öffnen Sie Xcode. 2. Schließen Sie das iOS-Gerät an. 3. Navigieren Sie zu **Fenster** -> **Geräte und Simulatoren**. 4. Wählen Sie Ihr Gerät aus. 5. Lösen Sie das Problem aus, das Sie untersuchen. 6. Verwenden Sie die Schaltfläche **Konsole öffnen**, um Protokolle in einem neuen Fenster anzuzeigen. Für fortgeschrittenes Logging kann das Verbinden mit der Geräteshell und die Verwendung von **socat** eine Echtzeit-Protokollüberwachung bieten: ```bash iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock ``` Befolgt von Befehlen zur Beobachtung von Protokollaktivitäten, die für die Diagnose von Problemen oder die Identifizierung potenzieller Datenlecks in Protokollen von unschätzbarem Wert sein können. ## Backups **Auto-Backup-Funktionen** sind in iOS integriert und erleichtern die Erstellung von Gerätesicherungen über iTunes (bis macOS Catalina), Finder (ab macOS Catalina) oder iCloud. Diese Backups umfassen fast alle Gerätedaten, mit Ausnahme von hochsensiblen Elementen wie Apple Pay-Daten und Touch ID-Konfigurationen. ### Sicherheitsrisiken Die Einbeziehung von **installierten Apps und deren Daten** in Backups wirft das Problem potenzieller **Datenlecks** und das Risiko auf, dass **Backup-Modifikationen die App-Funktionalität ändern könnten**. Es wird empfohlen, **keine sensiblen Informationen im Klartext** im Verzeichnis einer App oder deren Unterverzeichnissen zu speichern, um diese Risiken zu mindern. ### Ausschluss von Dateien aus Backups Dateien in `Documents/` und `Library/Application Support/` werden standardmäßig gesichert. Entwickler können bestimmte Dateien oder Verzeichnisse von Backups ausschließen, indem sie `NSURL setResourceValue:forKey:error:` mit dem `NSURLIsExcludedFromBackupKey` verwenden. Diese Praxis ist entscheidend, um sensible Daten vor der Aufnahme in Backups zu schützen. ### Testen auf Schwachstellen Um die Backup-Sicherheit einer App zu bewerten, beginnen Sie mit der **Erstellung eines Backups** über den Finder und suchen Sie es dann mithilfe der Anleitung aus [Apples offizieller Dokumentation](https://support.apple.com/en-us/HT204215). Analysieren Sie das Backup auf sensible Daten oder Konfigurationen, die geändert werden könnten, um das Verhalten der App zu beeinflussen. Sensible Informationen können mit Befehlszeilenwerkzeugen oder Anwendungen wie [iMazing](https://imazing.com) gesucht werden. Bei verschlüsselten Backups kann die Anwesenheit von Verschlüsselung bestätigt werden, indem der "IsEncrypted"-Schlüssel in der "Manifest.plist"-Datei im Stammverzeichnis des Backups überprüft wird. ```xml ... Date 2021-03-12T17:43:33Z IsEncrypted ... ``` Um mit verschlüsselten Backups umzugehen, können Python-Skripte, die im [DinoSec's GitHub-Repo](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts) verfügbar sind, wie **backup_tool.py** und **backup_passwd.py**, nützlich sein, obwohl möglicherweise Anpassungen für die Kompatibilität mit den neuesten iTunes/Finder-Versionen erforderlich sind. Das [**iOSbackup**-Tool](https://pypi.org/project/iOSbackup/) ist eine weitere Option, um auf Dateien innerhalb von passwortgeschützten Backups zuzugreifen. ### Modifizieren des App-Verhaltens Ein Beispiel für die Änderung des App-Verhaltens durch Backup-Modifikationen wird in der [Bither Bitcoin-Wallet-App](https://github.com/bither/bither-ios) demonstriert, wo die UI-Sperr-PIN in `net.bither.plist` unter dem **pin_code**-Schlüssel gespeichert ist. Das Entfernen dieses Schlüssels aus der plist und das Wiederherstellen des Backups entfernt die PIN-Anforderung und ermöglicht uneingeschränkten Zugriff. ## Zusammenfassung zum Speichertest für sensible Daten Beim Umgang mit sensiblen Informationen, die im Speicher einer Anwendung gespeichert sind, ist es entscheidend, die Expositionszeit dieser Daten zu begrenzen. Es gibt zwei Hauptansätze, um den Speicherinhalt zu untersuchen: **Erstellen eines Speicherdumps** und **Echtzeitanalyse des Speichers**. Beide Methoden haben ihre Herausforderungen, einschließlich der Möglichkeit, kritische Daten während des Dump-Prozesses oder der Analyse zu übersehen. ## **Abrufen und Analysieren eines Speicherdumps** Für sowohl jailbroken als auch nicht-jailbroken Geräte ermöglichen Tools wie [objection](https://github.com/sensepost/objection) und [Fridump](https://github.com/Nightbringer21/fridump) das Dumpen des Prozessspeichers einer App. Nach dem Dumpen erfordert die Analyse dieser Daten verschiedene Tools, abhängig von der Art der Informationen, nach denen Sie suchen. Um Strings aus einem Speicherdump zu extrahieren, können Befehle wie `strings` oder `rabin2 -zz` verwendet werden: ```bash # Extracting strings using strings command $ strings memory > strings.txt # Extracting strings using rabin2 $ rabin2 -ZZ memory > strings.txt ``` Für eine detailliertere Analyse, einschließlich der Suche nach spezifischen Datentypen oder Mustern, bietet **radare2** umfangreiche Suchmöglichkeiten: ```bash $ r2 [0x00000000]> /? ... ``` ## **Laufzeit-Speicheranalyse** **r2frida** bietet eine leistungsstarke Alternative zur Inspektion des Speichers einer App in Echtzeit, ohne dass ein Speicherauszug erforderlich ist. Dieses Tool ermöglicht die Ausführung von Suchbefehlen direkt im Speicher der laufenden Anwendung: ```bash $ r2 frida://usb// [0x00000000]> /\ ``` ## Gebrochene Kryptographie ### Schlechte Schlüsselverwaltungsprozesse Einige Entwickler speichern sensible Daten im lokalen Speicher und verschlüsseln sie mit einem im Code hartcodierten/vorhersehbaren Schlüssel. Dies sollte nicht getan werden, da einige Reverse-Engineering-Aktivitäten Angreifern ermöglichen könnten, die vertraulichen Informationen zu extrahieren. ### Verwendung unsicherer und/oder veralteter Algorithmen Entwickler sollten keine **veralteten Algorithmen** verwenden, um **Überprüfungen** durchzuführen, **Daten** zu **speichern** oder **zu senden**. Einige dieser Algorithmen sind: RC4, MD4, MD5, SHA1... Wenn **Hashes** verwendet werden, um Passwörter zu speichern, sollten brute-force **resistente** Hashes mit Salt verwendet werden. ### Überprüfung Die wichtigsten Überprüfungen, die durchgeführt werden sollten, sind, ob Sie **hartcodierte** Passwörter/Geheimnisse im Code finden können, oder ob diese **vorhersehbar** sind, und ob der Code eine Art von **schwachen** **Kryptographie**-Algorithmen verwendet. Es ist interessant zu wissen, dass Sie einige **Krypto**-**Bibliotheken** automatisch mit **objection** überwachen können mit: ```swift ios monitor crypt ``` Für **weitere Informationen** zu iOS-Kryptografie-APIs und -Bibliotheken besuchen Sie [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography) ## Lokale Authentifizierung **Lokale Authentifizierung** spielt eine entscheidende Rolle, insbesondere wenn es darum geht, den Zugriff an einem entfernten Endpunkt durch kryptografische Methoden zu sichern. Der Kernpunkt ist, dass lokale Authentifizierungsmechanismen ohne ordnungsgemäße Implementierung umgangen werden können. Apples [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) und der [**keychain**](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) bieten robuste APIs für Entwickler, um Benutzerauthentifizierungsdialoge zu erleichtern und geheime Daten sicher zu verwalten. Der Secure Enclave sichert die Fingerabdruck-ID für Touch ID, während Face ID auf Gesichtserkennung basiert, ohne biometrische Daten zu gefährden. Um Touch ID/Face ID zu integrieren, haben Entwickler zwei API-Optionen: - **`LocalAuthentication.framework`** für die hochgradige Benutzerauthentifizierung ohne Zugriff auf biometrische Daten. - **`Security.framework`** für den Zugriff auf niedrigere Schlüsselbunddienste, die geheime Daten mit biometrischer Authentifizierung sichern. Verschiedene [Open-Source-Wrappers](https://www.raywenderlich.com/147308/secure-ios-user-data-keychain-touch-id) erleichtern den Zugriff auf den Schlüsselbund. > [!CAUTION] > Beide `LocalAuthentication.framework` und `Security.framework` weisen jedoch Schwachstellen auf, da sie hauptsächlich boolesche Werte zurückgeben, ohne Daten für Authentifizierungsprozesse zu übertragen, was sie anfällig für Umgehungen macht (siehe [Don't touch me that way, von David Lindner et al](https://www.youtube.com/watch?v=XhXIHVGCFFM)). ### Implementierung der lokalen Authentifizierung Um Benutzer zur Authentifizierung aufzufordern, sollten Entwickler die **`evaluatePolicy`**-Methode innerhalb der **`LAContext`**-Klasse verwenden und zwischen folgenden Optionen wählen: - **`deviceOwnerAuthentication`**: Fordert Touch ID oder Gerätepasscode an und schlägt fehl, wenn keines aktiviert ist. - **`deviceOwnerAuthenticationWithBiometrics`**: Fordert ausschließlich Touch ID an. Eine erfolgreiche Authentifizierung wird durch einen booleschen Rückgabewert von **`evaluatePolicy`** angezeigt, was auf eine potenzielle Sicherheitsanfälligkeit hinweist. ### Lokale Authentifizierung mit Keychain Die Implementierung der **lokalen Authentifizierung** in iOS-Apps umfasst die Verwendung von **Keychain-APIs**, um geheime Daten wie Authentifizierungstoken sicher zu speichern. Dieser Prozess stellt sicher, dass die Daten nur vom Benutzer mit seinem Gerätepasscode oder biometrischer Authentifizierung wie Touch ID abgerufen werden können. Der Schlüsselbund bietet die Möglichkeit, Elemente mit dem Attribut `SecAccessControl` festzulegen, das den Zugriff auf das Element einschränkt, bis der Benutzer erfolgreich über Touch ID oder Gerätepasscode authentifiziert. Diese Funktion ist entscheidend für die Verbesserung der Sicherheit. Im Folgenden finden Sie Codebeispiele in Swift und Objective-C, die zeigen, wie man einen String im Schlüsselbund speichert und abruft, wobei diese Sicherheitsfunktionen genutzt werden. Die Beispiele zeigen speziell, wie man den Zugriffskontrollmechanismus einrichtet, um eine Touch ID-Authentifizierung zu verlangen und sicherzustellen, dass die Daten nur auf dem Gerät zugänglich sind, auf dem sie eingerichtet wurden, unter der Bedingung, dass ein Gerätepasscode konfiguriert ist. {{#tabs}} {{#tab name="Swift"}} ```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? 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 } ``` {{#endtab}} {{#tab name="Objective-C"}} ```objectivec // 1. create AccessControl object that will represent authentication settings CFErrorRef *err = nil; SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlUserPresence, err); // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute NSDictionary* query = @{ (_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrLabel: @"com.me.myapp.password", (__bridge id)kSecAttrAccount: @"OWASP Account", (__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding], (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef }; // 3. save item OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil); if (status == noErr) { // successfully saved } else { // error while saving } ``` {{#endtab}} {{#endtabs}} Jetzt können wir das gespeicherte Element aus dem Schlüsselbund anfordern. Die Schlüsselbunddienste zeigen dem Benutzer den Authentifizierungsdialog an und geben Daten oder nil zurück, abhängig davon, ob ein passender Fingerabdruck bereitgestellt wurde oder nicht. {{#tabs}} {{#tab name="Swift"}} ```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 } ``` {{#endtab}} {{#tab name="Objective-C"}} ```objectivec // 1. define query NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecReturnData: @YES, (__bridge id)kSecAttrAccount: @"My Name1", (__bridge id)kSecAttrLabel: @"com.me.myapp.password", (__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" }; // 2. get item CFTypeRef queryResult = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult); if (status == noErr){ NSData* resultData = ( __bridge_transfer NSData* )queryResult; NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; NSLog(@"%@", password); } else { NSLog(@"Something went wrong"); } ``` {{#endtab}} {{#endtabs}} ### Erkennung Die Verwendung von Frameworks in einer App kann auch durch die Analyse der Liste der gemeinsam genutzten dynamischen Bibliotheken der App-Binärdatei erkannt werden. Dies kann mit `otool` durchgeführt werden: ```bash $ otool -L .app/ ``` Wenn `LocalAuthentication.framework` in einer App verwendet wird, enthält die Ausgabe beide der folgenden Zeilen (denken Sie daran, dass `LocalAuthentication.framework` `Security.framework` im Hintergrund verwendet): ```bash /System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication /System/Library/Frameworks/Security.framework/Security ``` Wenn `Security.framework` verwendet wird, wird nur die zweite angezeigt. ### Umgehung des lokalen Authentifizierungsrahmens #### **Objection** Durch die **Objection Biometrics Bypass**, die auf [dieser GitHub-Seite](https://github.com/sensepost/objection/wiki/Understanding-the-iOS-Biometrics-Bypass) zu finden ist, steht eine Technik zur Verfügung, um den **LocalAuthentication**-Mechanismus zu überwinden. Der Kern dieses Ansatzes besteht darin, **Frida** zu nutzen, um die Funktion `evaluatePolicy` zu manipulieren, sodass sie konsequent ein `True`-Ergebnis liefert, unabhängig vom tatsächlichen Erfolg der Authentifizierung. Dies ist besonders nützlich, um fehlerhafte biometrische Authentifizierungsprozesse zu umgehen. Um diese Umgehung zu aktivieren, wird der folgende Befehl verwendet: ```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 ``` Dieser Befehl löst eine Sequenz aus, bei der Objection eine Aufgabe registriert, die das Ergebnis der `evaluatePolicy`-Überprüfung effektiv auf `True` ändert. #### Frida Ein Beispiel für die Verwendung von **`evaluatePolicy`** aus der [DVIA-v2-Anwendung](https://github.com/prateek147/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"]; }); } } ``` Um den **Umgehung** der lokalen Authentifizierung zu erreichen, wird ein Frida-Skript geschrieben. Dieses Skript zielt auf die **evaluatePolicy**-Überprüfung ab und fängt deren Callback ab, um sicherzustellen, dass es **success=1** zurückgibt. Durch die Änderung des Verhaltens des Callbacks wird die Authentifizierungsüberprüfung effektiv umgangen. Das folgende Skript wird injiziert, um das Ergebnis der **evaluatePolicy**-Methode zu ändern. Es ändert das Ergebnis des Callbacks, um immer Erfolg anzuzeigen. ```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!"); } ``` Um das Frida-Skript zu injizieren und die biometrische Authentifizierung zu umgehen, wird der folgende Befehl verwendet: ```bash frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js ``` ## Sensible Funktionalitätsexposition durch IPC ### Benutzerdefinierte URI-Handler / Deeplinks / Benutzerdefinierte Schemes {{#ref}} ios-custom-uri-handlers-deeplinks-custom-schemes.md {{#endref}} ### Universelle Links {{#ref}} ios-universal-links.md {{#endref}} ### UIActivity Sharing {{#ref}} ios-uiactivity-sharing.md {{#endref}} ### UIPasteboard {{#ref}} ios-uipasteboard.md {{#endref}} ### App-Erweiterungen {{#ref}} ios-app-extensions.md {{#endref}} ### WebViews {{#ref}} ios-webviews.md {{#endref}} ### Serialisierung und Kodierung {{#ref}} ios-serialisation-and-encoding.md {{#endref}} ## Netzwerkkommunikation Es ist wichtig zu überprüfen, dass keine Kommunikation **ohne Verschlüsselung** erfolgt und dass die Anwendung das **TLS-Zertifikat** des Servers korrekt **validiert**.\ Um solche Probleme zu überprüfen, können Sie einen Proxy wie **Burp** verwenden: {{#ref}} burp-configuration-for-ios.md {{#endref}} ### Hostname-Überprüfung Ein häufiges Problem bei der Validierung des TLS-Zertifikats besteht darin, zu überprüfen, ob das Zertifikat von einer **vertrauenswürdigen** **CA** signiert wurde, aber **nicht zu überprüfen**, ob **der Hostname** des Zertifikats der aufgerufene Hostname ist.\ Um dieses Problem mit Burp zu überprüfen, können Sie, nachdem Sie die Burp CA auf dem iPhone vertraut haben, **ein neues Zertifikat mit Burp für einen anderen Hostnamen erstellen** und es verwenden. Wenn die Anwendung weiterhin funktioniert, ist sie anfällig. ### Zertifikat-Pinning Wenn eine Anwendung SSL-Pinning korrekt verwendet, funktioniert die Anwendung nur, wenn das Zertifikat das erwartete ist. Bei der Prüfung einer Anwendung **kann dies ein Problem darstellen, da Burp sein eigenes Zertifikat bereitstellt.**\ Um diesen Schutz auf einem jailbroken Gerät zu umgehen, können Sie die Anwendung [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) installieren oder [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/mobile/config-ios-device) installieren. Sie können auch **objection's** `ios sslpinning disable` verwenden. ## Sonstiges - In **`/System/Library`** finden Sie die Frameworks, die auf dem Telefon von Systemanwendungen verwendet werden. - Die vom Benutzer aus dem App Store installierten Anwendungen befinden sich in **`/User/Applications`**. - Und **`/User/Library`** enthält Daten, die von benutzerebene Anwendungen gespeichert wurden. - Sie können auf **`/User/Library/Notes/notes.sqlite`** zugreifen, um die in der Anwendung gespeicherten Notizen zu lesen. - Im Ordner einer installierten Anwendung (**`/User/Applications//`**) finden Sie einige interessante Dateien: - **`iTunesArtwork`**: Das von der App verwendete Symbol. - **`iTunesMetadata.plist`**: Informationen zur App, die im App Store verwendet werden. - **`/Library/*`**: Enthält die Einstellungen und den Cache. In **`/Library/Cache/Snapshots/*`** finden Sie den Snapshot, der vor dem Senden der Anwendung in den Hintergrund erstellt wurde. ### Hot Patching/Erzwungene Aktualisierung Die Entwickler können **alle Installationen ihrer App sofort patchen**, ohne die Anwendung erneut im App Store einzureichen und auf die Genehmigung zu warten.\ Zu diesem Zweck wird normalerweise [**JSPatch**](https://github.com/bang590/JSPatch)** verwendet.** Es gibt jedoch auch andere Optionen wie [Siren](https://github.com/ArtSabintsev/Siren) und [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\ **Dies ist ein gefährlicher Mechanismus, der von böswilligen Drittanbieter-SDKs missbraucht werden könnte, daher wird empfohlen, zu überprüfen, welche Methode für automatische Aktualisierungen verwendet wird (falls vorhanden) und diese zu testen.** Sie könnten versuchen, eine frühere Version der App zu diesem Zweck herunterzuladen. ### Drittanbieter Eine erhebliche Herausforderung bei **3rd Party SDKs** ist die **fehlende granulare Kontrolle** über deren Funktionen. Entwickler stehen vor der Wahl: entweder das SDK zu integrieren und alle seine Funktionen zu akzeptieren, einschließlich potenzieller Sicherheitsanfälligkeiten und Datenschutzbedenken, oder auf seine Vorteile vollständig zu verzichten. Oft sind Entwickler nicht in der Lage, Sicherheitsanfälligkeiten innerhalb dieser SDKs selbst zu patchen. Darüber hinaus können einige SDKs, die innerhalb der Community Vertrauen gewinnen, Malware enthalten. Die von Drittanbieter-SDKs bereitgestellten Dienste können das Tracking des Benutzerverhaltens, die Anzeige von Werbung oder die Verbesserung der Benutzererfahrung umfassen. Dies birgt jedoch ein Risiko, da Entwickler möglicherweise nicht vollständig über den von diesen Bibliotheken ausgeführten Code informiert sind, was zu potenziellen Datenschutz- und Sicherheitsrisiken führen kann. Es ist entscheidend, die mit Drittanbieterdiensten geteilten Informationen auf das Notwendige zu beschränken und sicherzustellen, dass keine sensiblen Daten offengelegt werden. Die Implementierung von Drittanbieterdiensten erfolgt normalerweise in zwei Formen: einer eigenständigen Bibliothek oder einem vollständigen SDK. Um die Privatsphäre der Benutzer zu schützen, sollten alle mit diesen Diensten geteilten Daten **anonymisiert** werden, um die Offenlegung von personenbezogenen Daten (PII) zu verhindern. Um die Bibliotheken zu identifizieren, die eine Anwendung verwendet, kann der Befehl **`otool`** verwendet werden. Dieses Tool sollte gegen die Anwendung und jede von ihr verwendete gemeinsame Bibliothek ausgeführt werden, um zusätzliche Bibliotheken zu entdecken. ```bash otool -L ``` ## **Referenzen & Weitere Ressourcen** - [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering) - [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/](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-0058/) - [https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/](https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/) - [https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage](https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage) - [https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way](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-0055/) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053](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/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-0058) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060](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/Android/0x05f-Testing-Local-Authentication/) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064](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://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc) - [https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054](https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054) - [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) IOS kostenloser Kurs([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](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.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577) - [https://www.slideshare.net/RyanISI/ios-appsecurityminicourse](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse) - [https://github.com/prateek147/DVIA](https://github.com/prateek147/DVIA) - [https://github.com/prateek147/DVIA-v2](https://github.com/prateek147/DVIA-v2) - [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground) - OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< Objective-C-Version [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< Swift-Version - [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS) - [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2) {{#include ../../banners/hacktricks-training.md}}