iOS Pentesting

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

iOS Grundlagen

iOS Basics

Testing Environment

Auf dieser Seite findest du Informationen zum iOS simulator, emulators und jailbreaking:

iOS Testing Environment

Initial Analysis

Basic iOS Testing Operations

Während des Tests werden mehrere Operationen vorgeschlagen (Verbindung zum Gerät herstellen, Dateien lesen/schreiben/upload/download, Werkzeuge verwenden…). Wenn du nicht weißt, wie eine dieser Aktionen durchzuführen ist, beginne bitte mit dem Lesen der Seite:

iOS Basic Testing Operations

Tip

Für die folgenden Schritte sollte die App auf dem Gerät installiert sein und es sollte bereits die IPA file der Anwendung vorliegen.
Lies die Basic iOS Testing Operations Seite, um zu lernen, wie man das macht.

Basic Static Analysis

Einige interessante iOS - IPA file Decompiler:

Es wird empfohlen, das Tool MobSF zu verwenden, um eine automatische Static Analysis der IPA file durchzuführen.

Identifizierung, ob Schutzmechanismen im Binary vorhanden sind:

  • PIE (Position Independent Executable): Wenn aktiviert, lädt die Anwendung bei jedem Start an eine zufällige Speicheradresse, was es erschwert, die Anfangsadresse vorherzusagen.
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • Stack Canaries: Zur Validierung der Integrität des Stacks wird vor dem Aufruf einer Funktion ein ‘canary’-Wert auf dem Stack platziert und nach Ende der Funktion erneut validiert.
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): Dient zur Vermeidung häufiger Memory-Corruption-Schwachstellen
otool -I -v <app-binary> | grep objc_release   # It should include the _objc_release symbol
  • Encrypted Binary: Das Binary sollte verschlüsselt sein
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # The cryptid should be 1

Identifizierung sensibler/unsicherer Funktionen

  • 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"

Gängige Jailbreak-Erkennungs-Methoden

  • File System Checks: Suche nach dem Vorhandensein gängiger Jailbreak-Dateien und -Verzeichnisse wie /Applications/Cydia.app oder /Library/MobileSubstrate/MobileSubstrate.dylib.
  • Sandbox Violations: Versuche, auf eingeschränkte Bereiche des Dateisystems zuzugreifen, die auf nicht-jailbroken Geräten blockiert sein sollten.
  • API Checks: Prüfe, ob es möglich ist, verbotene Aufrufe wie fork() zur Erzeugung eines Child-Prozesses oder system() zu verwenden, um zu sehen, ob /bin/sh existiert.
  • Process Checks: Überwache das Vorhandensein bekannter jailbreak-bezogener Prozesse wie Cydia, Substrate oder ssh.
  • Kernel Exploits: Suche nach dem Vorhandensein von Kernel-Exploits, die häufig in Jailbreaks verwendet werden.
  • Environment Variables: Untersuche Environment-Variablen auf Hinweise für einen Jailbreak, wie DYLD_INSERT_LIBRARIES.
  • Libraries Check: Prüfe die Bibliotheken, die in den App-Prozess geladen wurden.
  • Check schemes: Zum Beispiel canOpenURL(URL(string: "cydia://")).

Gängige Anti-Debugging-Methoden

  • Check for Debugger Presence: Verwende sysctl oder andere Methoden, um zu prüfen, ob ein Debugger angehängt ist.
  • Anti-Debugging APIs: Suche nach Aufrufen von Anti-Debugging-APIs wie ptrace oder SIGSTOP, z. B. ptrace(PT_DENY_ATTACH, 0, 0, 0).
  • Timing Checks: Messe die Zeit für bestimmte Operationen und suche nach Abweichungen, die auf Debugging hinweisen könnten.
  • Memory Checks: Untersuche den Speicher nach bekannten Debugger-Artefakten oder Modifikationen.
  • Environment Variables: Prüfe Environment-Variablen, die auf eine Debugging-Sitzung hinweisen könnten.
  • Mach Ports: Erkenne, ob Mach-Exception-Ports von Debuggern verwendet werden.

Basic Dynamic Analysis

Schau dir die Dynamic Analysis an, die MobSF durchführt. Du musst dich durch die verschiedenen Ansichten klicken und mit ihnen interagieren, aber es hookt mehrere Klassen und bereitet einen Report vor, sobald du fertig bist.

Listing Installed Apps

Verwende den Befehl frida-ps -Uai, um den bundle identifier der installierten Apps zu ermitteln:

$ 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

Lerne, wie du die Komponenten der Anwendung enumerate und wie du mit objection methoden und klassen hookst:

iOS Hooking With Objection

IPA-Struktur

Die Struktur einer IPA file entspricht im Wesentlichen der eines zipped package. Durch Umbenennen der Erweiterung in .zip kann sie decompressed werden, um ihren Inhalt offen zu legen. Innerhalb dieser Struktur stellt ein Bundle eine vollständig verpackte Anwendung dar, die zur Installation bereit ist. Im Inneren findest du ein Verzeichnis mit dem Namen <NAME>.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 mit einer Signatur, die die Integrität aller Dateien im Bundle sicherstellt.
  • Assets.car: Ein komprimiertes Archiv, das Asset-Dateien wie Icons speichert.
  • Frameworks/: Dieses Verzeichnis beherbergt die nativen Bibliotheken der Anwendung, die als .dylib- oder .framework-Dateien vorliegen können.
  • PlugIns/: Dies kann Erweiterungen der Anwendung enthalten, bekannt als .appex-Dateien, obwohl sie nicht immer vorhanden sind. * Core Data: Es wird verwendet, um die permanenten Daten deiner Anwendung für die Offline-Nutzung zu speichern, temporäre Daten zu cachen und Undo-Funktionalität auf einem einzelnen Gerät bereitzustellen. Um Daten über mehrere Geräte in einem einzelnen iCloud-Account zu synchronisieren, spiegelt Core Data automatisch dein Schema in einen CloudKit-Container.
  • PkgInfo: Die PkgInfo-Datei ist eine alternative Möglichkeit, die Type- und Creator-Codes deiner Anwendung oder deines 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-Verwaltung: Die Datei Assets.car verwendet Kompression, um grafische Assets effizient zu verwalten, was für die Optimierung der Anwendungsleistung und die Reduzierung der Gesamtgröße wichtig ist.
  • Frameworks und PlugIns: Diese Verzeichnisse unterstreichen die Modularität von iOS-Anwendungen, da Entwickler wiederverwendbare Code-Bibliotheken (Frameworks/) einbinden und die Funktionalität der App erweitern (PlugIns/) können.
  • Lokalisierung: Die Struktur unterstützt mehrere Sprachen und erleichtert die weltweite Verbreitung von Anwendungen, indem Ressourcen für spezifische Sprachpakete enthalten sind.

Info.plist

Die Info.plist dient als Eckpfeiler für iOS-Anwendungen und kapselt wichtige Konfigurationsdaten in Form von Schlüssel-Wert-Paaren. Diese Datei ist nicht nur für Anwendungen, sondern auch für App-Erweiterungen und in Bundles enthaltene Frameworks erforderlich. Sie ist entweder im XML- oder im binären Format strukturiert und enthält wichtige Informationen von App-Berechtigungen bis hin zu Sicherheitskonfigurationen. Für eine detaillierte Übersicht der verfügbaren Keys kann man die Apple Developer Documentation zu Rate ziehen.

Wer mit dieser Datei in einem leichter zugänglichen Format arbeiten möchte, kann die XML-Konvertierung mühelos mit plutil auf macOS (nativ verfügbar seit Versionen 10.2 und später) oder mit plistutil unter Linux durchführen. Die Befehle zur Konvertierung sind wie folgt:

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

Unter der Vielzahl an Informationen, die die Info.plist-Datei preisgeben kann, gehören bemerkenswerte Einträge zu App-Berechtigungs-Strings (UsageDescription), benutzerdefinierten URL-Schemata (CFBundleURLTypes) und Konfigurationen für App Transport Security (NSAppTransportSecurity). Diese Einträge, zusammen mit anderen wie exportierten/importierten benutzerdefinierten Dokumenttypen (UTExportedTypeDeclarations / UTImportedTypeDeclarations), lassen sich mühelos finden, indem man die Datei inspiziert oder einen einfachen grep-Befehl verwendet:

$ grep -i <keyword> Info.plist

Datenpfade

Im iOS-Umfeld sind Verzeichnisse speziell für Systemanwendungen und vom Benutzer installierte Anwendungen vorgesehen. Systemanwendungen liegen im /Applications-Verzeichnis, während user-installed apps unter /var/mobile/containers/Data/Application/ abgelegt werden. Diese Anwendungen erhalten eine eindeutige Kennung, bekannt als 128-bit UUID, was das manuelle Auffinden des App-Ordners aufgrund der Zufälligkeit der Verzeichnisnamen erschwert.

Warning

Da Anwendungen unter iOS in einer Sandbox laufen müssen, hat jede App außerdem einen Ordner innerhalb von $HOME/Library/Containers, wobei der Ordnername der CFBundleIdentifier der App ist.

Beide Ordner (data & container folders) enthalten außerdem die Datei .com.apple.mobile_container_manager.metadata.plist, die beide Einträge über den Schlüssel MCMetadataIdentifier verbindet).

Um das Auffinden des Installationsverzeichnisses einer vom Benutzer installierten App zu erleichtern, stellt das objection tool den nützlichen Befehl env bereit. Dieser Befehl zeigt detaillierte Verzeichnisinformationen für die betreffende App an. Nachfolgend ein Beispiel zur Verwendung dieses Befehls:

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 innerhalb von /private/var/containers mit dem Befehl find durchsucht werden:

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

Befehle wie ps und lsof können ebenfalls verwendet werden, um den Prozess der App zu identifizieren bzw. geöffnete Dateien aufzulisten und so Einblicke in die aktiven Verzeichnispfade der App zu geben:

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

Bundle-Verzeichnis:

  • AppName.app
  • Dies ist das Application Bundle, wie zuvor in der IPA zu sehen, es enthält essentielle Anwendungsdaten, statische Inhalte sowie das kompilierte Binary 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 Code-Signatur zu validieren.

Datenverzeichnis:

  • Documents/
  • Enthält alle vom Benutzer erzeugten Daten. Der Endbenutzer der Anwendung initiiert die Erstellung dieser Daten.
  • Für Benutzer sichtbar 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, preferences, cookies, und property list (plist) Konfigurationsdateien.
  • iOS-Apps verwenden üblicherweise die Application Support und Caches Unterverzeichnisse, aber die App kann eigene Unterverzeichnisse erstellen.
  • Library/Caches/
  • Enthält semi-persistente Cache-Dateien.
  • Für Benutzer unsichtbar und Benutzer können nicht darauf schreiben.
  • Inhalte in diesem Verzeichnis werden nicht gesichert.
  • Das OS kann die Dateien in diesem Verzeichnis 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 notwendig sind.
  • Unsichtbar für Benutzer und Benutzer können nicht darauf schreiben.
  • Inhalte in diesem Verzeichnis werden gesichert aufbewahrt.
  • 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 in der Anwendungs-Sandbox in einer plist-Datei namens [BUNDLE_ID].plist gespeichert.
  • Alle Schlüssel/Wert-Paare, die über NSUserDefaults gespeichert wurden, sind in dieser Datei zu finden.
  • tmp/
  • Verwenden Sie dieses Verzeichnis zum Schreiben von temporären Dateien, die nicht zwischen App-Starts erhalten bleiben müssen.
  • Enthält nicht-persistente Cache-Dateien.
  • Unsichtbar für Benutzer.
  • Inhalte in diesem Verzeichnis werden nicht gesichert.
  • Das OS kann die Dateien in diesem Verzeichnis automatisch löschen, wenn die App nicht läuft und der Speicherplatz knapp wird.

Lassen Sie uns einen genaueren Blick auf das Application Bundle (.app) von iGoat-Swift im Bundle-Verzeichnis (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app) werfen:

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 Ordner <application-name>.app finden Sie eine Binärdatei namens <application-name>. Dies ist die Datei, die ausgeführt wird. Sie können eine grundlegende Inspektion der Binärdatei mit dem Tool otool durchführen:

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üfe, ob die App verschlüsselt ist

Prüfe, ob es eine Ausgabe für:

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

Disassembling the binary

Disassemble the text section:

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 auszugeben, kann man Folgendes verwenden:

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 kompakteren Objective-C-Code zu erhalten, können Sie class-dump verwenden:

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 das Binary zu disassemblieren, sind jedoch: Hopper und IDA.

Datenspeicherung

Um zu lernen, wie iOS Daten auf dem Gerät speichert, lies diese Seite:

iOS Basics

Warning

Die folgenden Orte zur Speicherung von Informationen sollten sofort nach der Installation der Anwendung, nach Überprüfung aller Funktionen der Anwendung und sogar nach dem Ausloggen eines Benutzers und dem Einloggen eines anderen überprüft werden.
Das Ziel ist, ungeschützte sensible Informationen der Anwendung (Passwörter, Tokens), des aktuellen Nutzers und zuvor angemeldeter Nutzer zu finden.

Plist

plist-Dateien sind strukturierte XML-Dateien, die Schlüssel-Wert-Paare enthalten. Sie sind eine Möglichkeit, persistente Daten zu speichern, daher findet man manchmal sensible Informationen in diesen Dateien. Es wird empfohlen, diese Dateien nach der Installation der App und nach intensiver Nutzung zu überprüfen, um zu sehen, ob neue Daten geschrieben wurden.

Die gebräuchlichste Methode, Daten in plist-Dateien zu persistieren, ist die Verwendung von NSUserDefaults. Diese plist-Datei wird innerhalb des App-Sandbox in Library/Preferences/<appBundleID>.plist gespeichert.

Die Klasse NSUserDefaults bietet eine programmgesteuerte Schnittstelle zur Interaktion mit dem Standardsystem. Das Standardsystem ermöglicht einer Anwendung, ihr Verhalten an Benutzereinstellungen anzupassen. Daten, die mit NSUserDefaults gespeichert wurden, können im Application Bundle eingesehen werden. Diese Klasse speichert Daten in einer plist-Datei, ist jedoch dafür gedacht, mit kleinen Datenmengen verwendet zu werden.

Diese Daten können nicht mehr direkt über einen vertrauenswürdigen Computer abgerufen werden, können aber durch Erstellen eines Backups zugänglich gemacht werden.

Mit objection’s ios nsuserdefaults get kannst du die mit NSUserDefaults gespeicherten Informationen dumpen.

Um alle von der Anwendung verwendeten plist-Dateien zu finden, kannst du auf /private/var/mobile/Containers/Data/Application/{APPID} zugreifen und ausführen:

find ./ -name "*.plist"

Um Dateien aus dem XML- oder binären (bplist) Format in XML zu konvertieren, stehen je nach Betriebssystem verschiedene Methoden zur Verfügung:

Für macOS-Benutzer: Nutze den plutil-Befehl. Er ist ein integriertes Tool in macOS (10.2+), das für diesen Zweck gedacht ist:

$ plutil -convert xml1 Info.plist

Für Linux-Benutzer: Installieren Sie zuerst libplist-utils und verwenden Sie dann plistutil, um Ihre Datei zu konvertieren:

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

Within an Objection Session: Zur Analyse mobiler Anwendungen ermöglicht ein spezieller Befehl, plist-Dateien direkt zu konvertieren:

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

Core Data

Core Data ist ein Framework zur Verwaltung der Modellschicht von Objekten in deiner Anwendung. Core Data can use SQLite as its persistent store, 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. Siehe das GitHub Repo für weitere Details.

Du findest die SQLite Core Data-Informationen einer Anwendung im Pfad /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support

Wenn du die SQLite öffnen und auf sensible Informationen zugreifen kannst, hast du eine Fehlkonfiguration gefunden.

-(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 ist ein Key/Value-Store, der auf SQLite aufbaut.
Da die Yap-Datenbanken sqlite-Datenbanken sind, können Sie sie mit dem im vorherigen Abschnitt vorgeschlagenen Befehl finden.

Other SQLite Databases

Es ist üblich, dass Anwendungen ihre eigene sqlite-Datenbank erstellen. Sie könnten sensible Daten darin speichern und unverschlüsselt lassen. Deshalb ist es immer interessant, jede Datenbank im Anwendungsverzeichnis zu überprüfen. Gehen Sie daher in das Anwendungsverzeichnis, in dem die Daten gespeichert sind (/private/var/mobile/Containers/Data/Application/{APPID})

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

Firebase Real-Time Databases

Entwicklern wird ermöglicht, Daten zu speichern und zu synchronisieren in einer NoSQL cloud-gehosteten Datenbank über Firebase Real-Time Databases. Im JSON-Format gespeichert, werden die Daten in Echtzeit mit allen verbundenen Clients synchronisiert.

You can find how to check for misconfigured Firebase databases here:

Firebase Database

Realm databases

Realm Objective-C and Realm Swift bieten eine leistungsfähige Alternative zur Datenspeicherung, die nicht von Apple bereitgestellt wird. Standardmäßig speichern sie Daten unverschlüsselt, Verschlüsselung ist über eine spezifische Konfiguration verfügbar.

The databases are located at: /private/var/mobile/Containers/Data/Application/{APPID}. To explore these files, one can utilize commands like:

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*"

Zum Anzeigen dieser Datenbankdateien wird das Tool Realm Studio empfohlen.

Um Verschlüsselung in einer Realm-Datenbank zu implementieren, kann der folgende Codeausschnitt verwendet werden:

// 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 wird als leichtgewichtige und eingebettete Datenbank-Engine beschrieben, die dem dokumentorientierten (NoSQL) Ansatz folgt. Für iOS und macOS entwickelt, bietet sie die Möglichkeit, Daten nahtlos zu synchronisieren.

Um potenzielle Couchbase-Datenbanken auf einem Gerät zu identifizieren, sollte folgendes Verzeichnis untersucht werden:

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 jedes App-Ordners. Entwickler entscheiden sich jedoch manchmal, diese in der keychain zu speichern, da die erwähnte Cookie-Datei in Backups zugänglich sein kann.

Um die Cookie-Datei zu untersuchen, kannst du this python script verwenden oder objection’s ios cookies get.
Du kannst objection auch verwenden, um diese Dateien in ein JSON-Format zu konvertieren und die Daten zu untersuchen.

...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

By default NSURLSession stores data, such as HTTP requests and responses in the Cache.db database. This database can contain sensitive data, if tokens, usernames or any other sensitive information has been cached. To find the cached information open the data directory of the app (/var/mobile/Containers/Data/Application/<UUID>) and go to /Library/Caches/<Bundle Identifier>. The WebKit cache is also being stored in the Cache.db file. Objection can open and interact with the database with the command sqlite connect Cache.db, as it is a normale SQLite-Datenbank.

Es wird empfohlen, das Caching dieser Daten zu deaktivieren, da sie sensible Informationen in der Anfrage oder Antwort enthalten können. 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 erfolgen. Du kannst diese Methode wie folgt aufrufen:

URLCache.shared.removeAllCachedResponses()

Diese Methode entfernt alle zwischengespeicherten Anfragen und Antworten aus der Datei Cache.db.

  1. Wenn du den Vorteil von Cookies nicht benötigst, wird empfohlen, die Konfigurationseigenschaft .ephemeral von URLSession zu verwenden, die das Speichern von Cookies und Caches deaktiviert.

Apple documentation:

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.

  1. The Cache can also be disabled by setting the Cache Policy to .notAllowed. It will disable storing Cache in any fashion, either in memory or on disk.

Snapshots

Whenever you press the home button, iOS takes a snapshot of the current screen to be able to do the transition to the application on a much smoother way. However, if sensitive data is present in the current screen, it will be saved in the image (which persists across reboots). These are the snapshots that you can also access double tapping the home screen to switch between apps.

Sofern das iPhone nicht jailbroken ist, benötigt der Angreifer Zugriff auf das entsperrte Gerät, um diese Screenshots einsehen zu können. Standardmäßig wird der letzte Snapshot im Sandbox-Verzeichnis der Anwendung in Library/Caches/Snapshots/ oder Library/SplashBoard/Snapshots gespeichert (vertrauenswürdige Computer konnten seit iOX 7.0 nicht auf das Dateisystem zugreifen).

Eine Möglichkeit, dieses unerwünschte Verhalten zu verhindern, besteht darin, vor dem Erstellen des Snapshots einen leeren Bildschirm einzublenden oder die sensiblen Daten zu entfernen — z. B. in der ApplicationDidEnterBackground()-Funktion.

Das folgende Beispiel für eine Gegenmaßnahme setzt einen Standard-Screenshot.

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 gelegt wird. Es verhindert sensible Daten leaks, weil overlayImage.png immer die aktuelle Ansicht überlagern wird.

Keychain

Zum Zugriff auf und zur Verwaltung des iOS keychain stehen Tools wie Keychain-Dumper zur Verfügung, geeignet für jailbroken devices. Zusätzlich bietet Objection den Befehl ios keychain dump für ähnliche Zwecke.

Speichern von Anmeldeinformationen

Die NSURLCredential-Klasse eignet sich ideal zum direkten Speichern sensibler Informationen im keychain und umgeht damit die Notwendigkeit von NSUserDefaults oder anderen Wrappern. Um Credentials nach dem Login zu speichern, wird folgender Swift-Code verwendet:

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

Um diese gespeicherten Anmeldeinformationen zu extrahieren, wird Objection’s Befehl ios nsurlcredentialstorage dump verwendet.

Custom Keyboards and Keyboard Cache

Ab iOS 8.0 können Benutzer benutzerdefinierte keyboard extensions installieren, die unter Settings > General > Keyboard > Keyboards verwaltet werden. Diese keyboards bieten zusätzliche Funktionen, bergen aber das Risiko von keystroke logging und dem Senden von Daten an externe Server, wobei Benutzer über keyboards, die Netzwerkzugriff benötigen, informiert werden. Apps können und sollten die Verwendung von benutzerdefinierten keyboards für die Eingabe sensibler Informationen einschränken.

Security Recommendations:

  • Es wird empfohlen, Third-Party-Keyboards für erhöhte Sicherheit zu deaktivieren.
  • Achte auf die autocorrect und auto-suggestions Features der Standard-iOS-Tastatur, die sensible Informationen in Cache-Dateien wie Library/Keyboard/{locale}-dynamic-text.dat oder /private/var/mobile/Library/Keyboard/dynamic-text.dat speichern könnten. Diese Cache-Dateien sollten regelmäßig auf sensible Daten überprüft werden. Das Zurücksetzen des Keyboard-Wörterbuchs über Settings > General > Reset > Reset Keyboard Dictionary wird empfohlen, um zwischengespeicherte Daten zu löschen.
  • Das Abfangen von Netzwerkverkehr kann aufdecken, ob ein benutzerdefiniertes keyboard Keystrokes remote überträgt.

Preventing Text Field Caching

Die UITextInputTraits protocol bietet Eigenschaften zur Verwaltung von autocorrection und secure text entry, die wesentlich sind, um das Caching sensibler Informationen zu verhindern. Zum Beispiel kann das Deaktivieren von autocorrection und das Aktivieren von secure text entry erreicht werden mit:

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

Außerdem sollten Entwickler sicherstellen, dass Textfelder, insbesondere solche zum Eingeben sensibler Informationen wie Passwörter und PINs, das Caching deaktivieren, indem sie autocorrectionType auf UITextAutocorrectionTypeNo und secureTextEntry auf YES setzen.

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

Logs

Debugging von Code beinhaltet oft die Verwendung von logging. Dabei besteht ein Risiko, da logs sensible Informationen enthalten können. Früher, in iOS 6 und früheren Versionen, waren logs für alle Apps zugänglich, was ein Risiko sensibler Daten leakage darstellte. Jetzt sind Anwendungen darauf beschränkt, nur auf ihre eigenen logs zuzugreifen.

Trotz dieser Beschränkungen kann ein Angreifer mit physischem Zugriff auf ein entsperrtes Gerät dies weiterhin ausnutzen, indem er das Gerät an einen Computer anschließt und die logs ausliest. Es ist wichtig zu beachten, dass logs auch nach der Deinstallation der App auf der Festplatte verbleiben.

Um Risiken zu mindern, wird empfohlen, die App gründlich zu testen, alle Funktionen und Eingaben zu prüfen, um sicherzustellen, dass keine sensiblen Informationen versehentlich geloggt werden.

Beim Überprüfen des Quellcodes der App auf potenzielle leaks, suchen Sie sowohl nach vordefinierten als auch eigenen Logging-Anweisungen, die Schlüsselwörter wie NSLog, NSAssert, NSCAssert, fprintf für eingebaute Funktionen verwenden, sowie nach Erwähnungen von Logging oder Logfile für benutzerdefinierte Implementierungen.

Monitoring System Logs

Apps log verschiedene Informationen, die sensibel sein können. Um diese logs zu überwachen, Tools und Befehle wie:

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

sind nützlich. Zusätzlich bietet Xcode eine Möglichkeit, Konsolenprotokolle zu sammeln:

  1. Öffne Xcode.
  2. Schließe das iOS-Gerät an.
  3. Navigiere zu Window -> Devices and Simulators.
  4. Wähle dein Gerät aus.
  5. Löse das Problem aus, das du untersuchst.
  6. Benutze den Open Console-Button, um die Logs in einem neuen Fenster anzuzeigen.

Für fortgeschrittenes Logging kann das Verbinden mit der Geräte-Shell und die Verwendung von socat eine Echtzeitüberwachung der Logs ermöglichen:

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

Gefolgt von Befehlen zur Beobachtung von Log-Aktivitäten, die beim Diagnostizieren von Problemen oder beim Erkennen möglicher data leakage in Logs äußerst wertvoll sein können.

Backups

Auto-backup-Funktionen sind in iOS integriert und ermöglichen das Erstellen von Kopien der Gerätedaten über iTunes (bis macOS Catalina), Finder (ab macOS Catalina) oder iCloud. Diese Backups umfassen fast alle Gerätedaten, mit Ausnahme hochsensibler Elemente wie Apple Pay-Details und Touch ID-Konfigurationen.

Sicherheitsrisiken

Die Einbeziehung von installierten Apps und deren Daten in Backups wirft das Problem möglicher data leakage und das Risiko auf, dass Änderungen an Backups die App-Funktionalität beeinflussen könnten. Es wird empfohlen, keine sensiblen Informationen im Klartext innerhalb des App-Verzeichnisses oder dessen Unterverzeichnissen zu speichern, um diese Risiken zu mindern.

Dateien von Backups ausschließen

Dateien in Documents/ und Library/Application Support/ werden standardmäßig gesichert. Entwickler können bestimmte Dateien oder Verzeichnisse mithilfe von NSURL setResourceValue:forKey:error: mit dem NSURLIsExcludedFromBackupKey von Backups ausschließen. Diese Praxis ist entscheidend, um zu verhindern, dass sensible Daten in Backups aufgenommen werden.

Tests auf Schwachstellen

Um die Backup-Sicherheit einer App zu prüfen, beginnen Sie damit, ein Backup zu erstellen mit Finder und suchen es anschließend gemäß den Anweisungen in Apple’s official documentation. 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 Kommandozeilen-Tools oder Anwendungen wie iMazing gesucht werden. Bei verschlüsselten Backups kann das Vorhandensein der Verschlüsselung bestätigt werden, indem man den “IsEncrypted”-Schlüssel in der Datei “Manifest.plist” im Stammverzeichnis des Backups überprüft.

<?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>

Beim Umgang mit verschlüsselten Backups können Python-Skripte aus DinoSec’s GitHub repo, wie backup_tool.py und backup_passwd.py, nützlich sein, benötigen aber möglicherweise Anpassungen, um mit den neuesten iTunes-/Finder-Versionen kompatibel zu sein. Das iOSbackup tool ist eine weitere Option, um auf Dateien in passwortgeschützten Backups zuzugreifen.

Modifying App Behavior

Ein Beispiel für das Ändern des App-Verhaltens durch Backup-Modifikationen wird in der Bither bitcoin wallet app gezeigt, 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 gewährt uneingeschränkten Zugriff.

Summary on Memory Testing for Sensitive Data

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 zur Untersuchung des Speichers: creating a memory dump und analyzing the memory in real time. Beide Methoden haben ihre Herausforderungen, einschließlich der Möglichkeit, während des Dump-Prozesses oder der Analyse kritische Daten zu übersehen.

Retrieving and Analyzing a Memory Dump

Für sowohl jailbroken als auch non-jailbroken Geräte ermöglichen Tools wie objection und Fridump das Dumpen des Prozessspeichers einer App. Nach dem Dumpen erfordert die Analyse dieser Daten verschiedene Tools, abhängig von der Art der gesuchten Informationen.

Um Strings aus einem memory dump zu extrahieren, können Befehle wie strings oder rabin2 -zz verwendet werden:

# 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 bestimmten Datentypen oder Mustern, bietet radare2 umfangreiche Suchfunktionen:

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

Laufzeit-Speicheranalyse

r2frida bietet eine leistungsstarke Alternative, um den Speicher einer App in Echtzeit zu inspizieren, ohne einen memory dump zu benötigen. Dieses Tool ermöglicht die Ausführung von Suchbefehlen direkt im Speicher der laufenden Anwendung:

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

Fehlerhafte Kryptographie

Schlechte Prozesse beim Key Management

Einige Entwickler speichern sensible Daten im lokalen Speicher und verschlüsseln sie mit einem im Code hardcoded/predictable Schlüssel. Das sollte nicht gemacht werden, da ein gewisses reversing Angreifern erlauben könnte, die vertraulichen Informationen zu extrahieren.

Verwendung unsicherer und/oder veralteter Algorithmen

Entwickler sollten keine deprecated algorithms verwenden, um Autorisierungs- checks durchzuführen, Daten zu store oder zu send. Einige dieser Algorithmen sind: RC4, MD4, MD5, SHA1… Wenn hashes zum Beispiel zum Speichern von Passwörtern verwendet werden, sollten hashes, die brute-force resistant sind, zusammen mit salt verwendet werden.

Prüfung

Die wichtigsten Checks bestehen darin zu prüfen, ob sich hardcoded passwords/secrets im Code finden lassen, ob diese predictable sind und ob der Code eine Art von weak cryptography-Algorithmen verwendet.

Es ist interessant zu wissen, dass man einige crypto libraries automatisch mit objection monitor kann mit:

ios monitor crypt

Für weitere Informationen zu iOS-Kryptographie-APIs und -Bibliotheken siehe https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

Lokale Authentifizierung

Local authentication spielt eine entscheidende Rolle, besonders wenn es darum geht, den Zugriff an einem entfernten Endpunkt mittels kryptographischer Methoden zu schützen. Entscheidend ist hier, dass lokale Authentifizierungsmechanismen ohne richtige Implementierung umgangen werden können.

Apple’s Local Authentication framework und der keychain bieten Entwicklern robuste APIs, um Benutzer-Authentifizierungsdialoge zu ermöglichen bzw. geheime Daten sicher zu verwalten. Die Secure Enclave sichert Fingerabdruckdaten für Touch ID, während Face ID auf Gesichtserkennung setzt, ohne biometrische Daten zu kompromittieren.

Um Touch ID/Face ID zu integrieren, haben Entwickler zwei API-Optionen:

  • LocalAuthentication.framework für hochstufige Benutzer-Authentifizierung ohne Zugriff auf biometrische Daten.
  • Security.framework für niedrigere Keychain-Services, die geheime Daten mit biometrischer Authentifizierung schützen. Verschiedene open-source wrappers vereinfachen den Keychain-Zugriff.

Caution

However, both LocalAuthentication.framework and Security.framework present vulnerabilities, as they primarily return boolean values without transmitting data for authentication processes, making them susceptible to bypassing (refer to Don’t touch me that way, by David Lindner et al).

Implementierung der lokalen Authentifizierung

Um Nutzer zur Authentifizierung aufzufordern, sollten Entwickler die Methode evaluatePolicy der Klasse LAContext verwenden und zwischen folgenden Optionen wählen:

  • deviceOwnerAuthentication: Fordert Touch ID oder Geräte-Passcode an; schlägt fehl, wenn beides nicht aktiviert ist.
  • deviceOwnerAuthenticationWithBiometrics: Fordert ausschließlich Touch ID an.

Ein erfolgreicher Authentifizierungsversuch wird durch einen booleschen Rückgabewert von evaluatePolicy angezeigt, was auf eine potenzielle Sicherheitslücke hinweist.

Lokale Authentifizierung mit Keychain

Die Implementierung von local authentication in iOS-Apps erfolgt durch Verwendung der Keychain-APIs zum sicheren Speichern geheimer Daten wie Authentifizierungstokens. Dieser Prozess stellt sicher, dass die Daten nur durch den Benutzer zugänglich sind — mittels Geräte-Passcode oder biometrischer Authentifizierung wie Touch ID.

Der Keychain bietet die Möglichkeit, Items mit dem Attribut SecAccessControl zu setzen, das den Zugriff auf das Item so einschränkt, dass der Benutzer erst nach erfolgreicher Authentifizierung per Touch ID oder Geräte-Passcode darauf zugreifen kann. Diese Funktion ist wesentlich zur Erhöhung der Sicherheit.

Im Folgenden befinden sich Codebeispiele in Swift und Objective-C, die zeigen, wie ein String in der Keychain gespeichert und wieder abgerufen werden kann, wobei diese Sicherheitsfunktionen genutzt werden. Die Beispiele zeigen speziell, wie man Access Control so konfiguriert, dass Touch ID erforderlich ist und die Daten nur auf dem Gerät zugänglich sind, auf dem sie eingerichtet wurden, unter der Voraussetzung, dass ein Geräte-Passcode konfiguriert ist.

// 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
}

Jetzt können wir das gespeicherte item aus dem Keychain anfordern. Keychain services werden dem Benutzer den Authentifizierungsdialog anzeigen und data oder nil zurückgeben, je nachdem, ob ein geeigneter Fingerabdruck bereitgestellt wurde oder nicht.

// 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
}

Erkennung

Die Verwendung von Frameworks in einer App lässt sich auch feststellen, indem man die Liste der gemeinsam genutzten dynamischen Bibliotheken der App-Binary analysiert. Dies kann mit otool erfolgen:

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

Wenn LocalAuthentication.framework in einer App verwendet wird, enthält die Ausgabe beide der folgenden Zeilen (denk daran, dass LocalAuthentication.framework intern Security.framework verwendet):

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

Wenn Security.framework verwendet wird, wird nur das zweite angezeigt.

Umgehung des Local Authentication Frameworks

Objection

Durch den Objection Biometrics Bypass, zu finden auf this GitHub page, steht eine Technik zur Überwindung des LocalAuthentication-Mechanismus zur Verfügung. Kern dieses Ansatzes ist die Nutzung von Frida, um die Funktion evaluatePolicy zu manipulieren, sodass sie konstant ein True-Ergebnis zurückliefert, unabhängig vom tatsächlichen Erfolg der Authentifizierung. Dies ist besonders nützlich, um fehlerhafte biometrische Authentifizierungsprozesse zu umgehen.

Um diesen Bypass zu aktivieren, wird der folgende Befehl verwendet:

...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, in der Objection eine Aufgabe registriert, die das Ergebnis der evaluatePolicy-Prüfung effektiv auf True ändert.

Frida

Ein Beispiel für die Verwendung von evaluatePolicy aus 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"];
});
}
}

Um den bypass von Local Authentication zu erreichen, wird ein Frida script geschrieben. Dieses script zielt auf die evaluatePolicy-Prüfung ab und fängt deren callback ab, um sicherzustellen, dass es success=1 zurückgibt. Durch das Ändern des Verhaltens des callbacks wird die Authentifizierungsprüfung effektiv umgangen.

Das untenstehende script wird injiziert, um das Ergebnis der evaluatePolicy-Methode zu ändern. Es verändert das Ergebnis des callbacks so, dass es immer Erfolg anzeigt.

// 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:

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

Offenlegung sensibler Funktionalität durch IPC

iOS Custom URI Handlers / Deeplinks / Custom Schemes

iOS Universal Links

UIActivity Sharing

iOS UIActivity Sharing

UIPasteboard

iOS UIPasteboard

App Extensions

iOS App Extensions

WebViews

iOS WebViews

Serialisation and Encoding

iOS Serialisation and Encoding

Netzwerkkommunikation

Es ist wichtig zu prüfen, dass keine Kommunikation ohne Verschlüsselung stattfindet und dass die Anwendung außerdem das TLS-Zertifikat des Servers korrekt validiert.
Um diese Art von Problemen zu überprüfen, kann man einen Proxy wie Burp verwenden:

iOS Burp Suite Configuration

Hostname-Check

Ein häufiges Problem bei der Validierung des TLS-Zertifikats ist, dass geprüft wird, ob das Zertifikat von einer vertrauenswürdigen CA signiert wurde, aber nicht geprüft wird, ob der Hostname des Zertifikats dem tatsächlich angesprochenen Hostnamen entspricht.
Um dieses Problem mit Burp zu prüfen, können Sie nach dem Vertrauen des Burp CA auf dem iPhone ein neues Zertifikat mit Burp für einen anderen Hostnamen erstellen und dieses verwenden. Wenn die Anwendung weiterhin funktioniert, ist sie verwundbar.

Certificate Pinning

Wenn eine Anwendung SSL Pinning korrekt verwendet, dann funktioniert die Anwendung nur, wenn das Zertifikat dem erwarteten Zertifikat entspricht. Beim Testen einer Anwendung kann das problematisch sein, da Burp sein eigenes Zertifikat ausliefert.
Um diesen Schutz auf einem jailbroken Gerät zu umgehen, können Sie die Anwendung SSL Kill Switch installieren oder Burp Mobile Assistant installieren.

Sie können auch objection’s ios sslpinning disable verwenden.

Sonstiges

  • In /System/Library finden Sie die Frameworks, die vom System und von systemeigenen Anwendungen auf dem Telefon verwendet werden
  • Die vom Benutzer aus dem App Store installierten Anwendungen befinden sich in /User/Applications
  • Und /User/Library enthält Daten, die von Anwendungen auf Benutzerebene gespeichert wurden
  • Sie können auf /User/Library/Notes/notes.sqlite zugreifen, um die in der Anwendung gespeicherten Notizen zu lesen.
  • Innerhalb des Ordners einer installierten Anwendung (/User/Applications/<APP ID>/) finden Sie einige interessante Dateien:
  • iTunesArtwork: Das vom App verwendete Icon
  • iTunesMetadata.plist: Informationen der App, die im App Store verwendet werden
  • /Library/*: Enthält die Einstellungen und den Cache. In /Library/Cache/Snapshots/* finden Sie das Snapshot, das von der Anwendung erstellt wurde, bevor sie in den Hintergrund geschickt wurde.

Hot Patching/Erzwungene Updates

Entwickler können alle Installationen ihrer App aus der Ferne sofort patchen, ohne die Anwendung erneut im App Store einzureichen und auf die Genehmigung zu warten.
Zu diesem Zweck wird üblicherweise JSPatch** verwendet.** Aber es gibt auch andere Optionen wie Siren und react-native-appstore-version-checker.
Dies ist ein gefährlicher Mechanismus, der von böswilligen Drittanbieter-SDKs missbraucht werden könnte; es wird daher empfohlen zu prüfen, welche Methode für automatische Updates verwendet wird (falls vorhanden) und diese zu testen. Sie könnten versuchen, zu diesem Zweck eine frühere Version der App herunterzuladen.

Drittanbieter

Eine große Herausforderung bei 3rd party SDKs ist der Mangel an granularem Kontrollniveau über deren Funktionen. Entwickler stehen vor der Wahl: entweder das SDK zu integrieren und alle seine Funktionen einschließlich potenzieller Sicherheitslücken und Datenschutzprobleme zu akzeptieren, oder auf dessen Vorteile ganz zu verzichten. Oft sind Entwickler nicht in der Lage, Schwachstellen innerhalb dieser SDKs selbst zu patchen. Darüber hinaus können einige SDKs, wenn sie innerhalb der Community Vertrauen gewinnen, anfänglich oder später Malware enthalten.

Die von Drittanbieter-SDKs bereitgestellten Dienste können das Tracking von Benutzerverhalten, die Anzeige von Werbung oder Verbesserungen der User Experience umfassen. Dies birgt jedoch das Risiko, dass Entwickler nicht vollständig über den von diesen Bibliotheken ausgeführten Code informiert sind, was zu möglichen Datenschutz- und Sicherheitsrisiken führt. Es ist entscheidend, die mit Drittanbietern geteilten Informationen auf das Notwendige zu beschränken und sicherzustellen, dass keine sensiblen Daten offengelegt werden.

Die Implementierung von Drittanbieterdiensten erfolgt in der Regel in zwei Formen: als eigenständige Bibliothek oder als vollständiges SDK. Um die Privatsphäre der Nutzer zu schützen, sollten alle mit diesen Diensten geteilten Daten anonymisiert werden, um die Offenlegung von Personal Identifiable Information (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 gemeinsam genutzte Bibliothek ausgeführt werden, die sie verwendet, um zusätzliche Bibliotheken zu entdecken.

otool -L <application_path>

Interessante Schwachstellen & Fallstudien

Air Keyboard Remote Input Injection

Itunesstored Bookassetd Sandbox Escape

Zero Click Messaging Image Parser Chains

Referenzen & Weitere Ressourcen

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks