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

Testumgebung

Auf dieser Seite finden Sie Informationen über den iOS Simulator, Emulatoren und jailbreaking:

iOS Testing Environment

Erste Analyse

Grundlegende iOS-Testoperationen

Während des Tests werden verschiedene Operationen vorgeschlagen (Verbindung zum Gerät herstellen, Dateien lesen/schreiben/upload/download, Tools verwenden…). Wenn Sie also nicht wissen, wie eine dieser Aktionen ausgeführt wird, lesen Sie bitte die Seite:

iOS Basic Testing Operations

Tip

Für die folgenden Schritte sollte die App auf dem Gerät installiert sein und Sie sollten bereits die IPA-Datei der Anwendung erhalten haben.
Lesen Sie die Basic iOS Testing Operations Seite, um zu erfahren, wie das geht.

Grundlegende statische Analyse

Einige interessante Decompiler für iOS-IPA-Dateien:

Es wird empfohlen, das Tool MobSF zu verwenden, um eine automatische statische Analyse der IPA-Datei durchzuführen.

Identifikation von Schutzmechanismen im Binary:

  • PIE (Position Independent Executable): Wenn aktiviert, wird die Anwendung bei jedem Start in eine zufällige Speicheradresse geladen, wodurch es schwieriger wird, die anfängliche Speicheradresse vorherzusagen.
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • 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 überprüft, sobald die Funktion endet.
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): Um häufige Speicher-Korruptionsfehler zu verhindern
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

Identifikation von sensiblen/unsicheren 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"
  • Unsichere ‘malloc’-Funktion
# On the iOS device
otool -Iv <app> | grep -w "_malloc"

# On linux
grep -iER "_malloc"
  • Unsichere und verwundbare Funktionen
# 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"

Häufige Jailbreak-Erkennungsmethoden

  • File System Checks: Prüfen Sie auf das Vorhandensein gängiger Jailbreak-Dateien und -Verzeichnisse, wie z. B. /Applications/Cydia.app oder /Library/MobileSubstrate/MobileSubstrate.dylib.
  • Sandbox Violations: Versuchen, auf eingeschränkte Bereiche des Dateisystems zuzugreifen, die auf nicht-gejailbreakten Geräten blockiert sein sollten.
  • API Checks: Prüfen Sie, ob es möglich ist, verbotene Aufrufe wie fork() zu verwenden, um einen Child-Prozess zu erzeugen, oder system(), um zu sehen, ob /bin/sh existiert.
  • Process Checks: Überwachen Sie das Vorhandensein bekannter jailbreak-bezogener Prozesse, wie Cydia, Substrate oder ssh.
  • Kernel Exploits: Prüfen Sie auf das Vorhandensein von Kernel-Exploits, die häufig bei Jailbreaks verwendet werden.
  • Environment Variables: Untersuchen Sie Umgebungsvariablen auf Hinweise auf einen Jailbreak, wie DYLD_INSERT_LIBRARIES.
  • Libraries Check: Prüfen Sie die Bibliotheken, die in den App-Prozess geladen sind.
  • Check schemes: Wie canOpenURL(URL(string: "cydia://")).

Häufige Anti-Debugging-Erkennungsmethoden

  • Check for Debugger Presence: Verwenden Sie sysctl oder andere Methoden, um zu prüfen, ob ein Debugger angehängt ist.
  • Anti-Debugging APIs: Suchen Sie nach Aufrufen an Anti-Debugging-APIs wie ptrace oder SIGSTOP, z. B. ptrace(PT_DENY_ATTACH, 0, 0, 0).
  • Timing Checks: Messen Sie die Zeit für bestimmte Operationen und suchen Sie nach Abweichungen, die auf Debugging hindeuten könnten.
  • Memory Checks: Untersuchen Sie den Speicher nach bekannten Debugger-Artefakten oder Modifikationen.
  • Environment Variables: Prüfen Sie Umgebungsvariablen, die auf eine Debugging-Sitzung hinweisen könnten.
  • Mach Ports: Erkennen Sie, ob Mach-Exception-Ports von Debuggern verwendet werden.

Grundlegende dynamische Analyse

Schauen Sie sich die dynamische Analyse an, die MobSF durchführt. Sie müssen durch die verschiedenen Ansichten navigieren und mit ihnen interagieren; dabei hookt es mehrere Klassen und führt weitere Aktionen aus und erstellt am Ende einen Bericht.

Auflisten installierter Apps

Verwenden Sie 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

Basic Enumeration & Hooking

Lerne, wie man enumerate the components of the application und wie man mit objection einfach hook methods and classes:

iOS Hooking With Objection

IPA-Struktur

Die Struktur einer IPA file entspricht im Wesentlichen der einer zipped package. Durch Umbenennen der Erweiterung in .zip kann sie decompressed werden, um ihren Inhalt sichtbar zu machen. Innerhalb dieser Struktur steht ein Bundle für eine vollständig verpackte Anwendung, die zur Installation bereit ist. Im Inneren findet sich ein Verzeichnis namens <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/: 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, bekannt als .appex-Dateien, die jedoch nicht immer vorhanden sind. * Core Data: Es wird verwendet, um permanente Daten der 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 einzigen iCloud-Account zu synchronisieren, spiegelt Core Data automatisch das Schema in einen CloudKit-Container.
  • PkgInfo: Die PkgInfo-Datei ist eine alternative Möglichkeit, die Type- und Creator-Codes Ihrer Anwendung oder Ihres Bundles anzugeben.
  • en.lproj, fr.proj, Base.lproj: Sind die Sprachpakete, die Ressourcen für die jeweiligen Sprachen enthalten, sowie eine Standardressource für den Fall, dass eine Sprache nicht unterstützt wird.
  • Security: Das Verzeichnis _CodeSignature/ spielt eine entscheidende Rolle für die Sicherheit der App, indem es die Integrität aller gebündelten Dateien über digitale Signaturen verifiziert.
  • Asset Management: Die Datei Assets.car verwendet Kompression, um grafische Assets effizient zu verwalten, was für die Optimierung der Anwendungsleistung und die Verringerung der Gesamtgröße entscheidend ist.
  • Frameworks and PlugIns: Diese Verzeichnisse unterstreichen die Modularität von iOS-Anwendungen, da Entwickler wiederverwendbare Codebibliotheken (Frameworks/) einbinden und die Funktionalität der App erweitern (PlugIns/) können.
  • Localization: Die Struktur unterstützt mehrere Sprachen und erleichtert so die globale Verbreitung von Anwendungen, indem Ressourcen für bestimmte Sprachpakete enthalten sind.

Info.plist

Die Info.plist fungiert als Eckpfeiler für iOS-Anwendungen und kapselt wichtige Konfigurationsdaten in Form von key-value-Paaren. Diese Datei ist nicht nur für Anwendungen erforderlich, sondern auch für App-Erweiterungen und Frameworks, die im Bundle enthalten sind. Sie ist entweder im XML- oder im binären Format strukturiert und enthält kritische Informationen von App-Berechtigungen bis hin zu Sicherheitskonfigurationen. Für eine detaillierte Übersicht über verfügbare Keys kann auf die Apple Developer Documentation verwiesen werden.

Für diejenigen, die mit dieser Datei in einem zugänglicheren Format arbeiten möchten, kann die XML-Konvertierung mühelos mit plutil auf macOS (nativ verfügbar ab Version 10.2) oder plistutil unter Linux erreicht werden. Die Befehle für die Konvertierung sind wie folgt:

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

Unter den zahlreichen Informationen, die die Info.plist-Datei preisgeben kann, gehören zu den bemerkenswerten Einträgen 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), lassen sich mühelos durch Inspektion der Datei oder mit einem einfachen grep-Befehl finden:

$ grep -i <keyword> Info.plist

Datenpfade

In der iOS-Umgebung sind Verzeichnisse speziell für Systemanwendungen und benutzerinstallierte Anwendungen vorgesehen. Systemanwendungen liegen im Verzeichnis /Applications, während benutzerinstallierte 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älligen Verzeichnisnamen erschwert.

Warning

Da Anwendungen in iOS sandboxed sein müssen, hat jede App außerdem einen Ordner in $HOME/Library/Containers, wobei der Ordnername dem CFBundleIdentifier der App entspricht.

Allerdings enthalten beide Ordner (Data- und Container-Ordner) die Datei .com.apple.mobile_container_manager.metadata.plist, die beide Dateien über den Schlüssel MCMetadataIdentifier verknüpft).

Um das Auffinden des Installationsverzeichnisses einer benutzerinstallierten App zu erleichtern, bietet das objection tool den nützlichen Befehl env. Dieser Befehl zeigt detaillierte Verzeichnisinformationen für die betreffende App an. Im Folgenden ein Beispiel, wie man diesen Befehl verwendet:

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 find-Befehl durchsucht werden:

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

Befehle wie ps und lsof können ebenfalls verwendet werden, um jeweils den Prozess der App zu identifizieren und geöffnete Dateien aufzulisten, wodurch Einblicke in die aktiven Verzeichnispfade der Anwendung ermöglicht werden:

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

Bundle directory:

  • AppName.app
  • Dies ist das Application Bundle, wie zuvor in der 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 darin schreiben.
  • Inhalt in diesem Verzeichnis wird nicht gesichert.
  • Der Inhalt dieses Ordners wird verwendet, um die Code-Signatur zu validieren.

Data directory:

  • Documents/
  • Enthält alle vom Benutzer erzeugten Daten. Der Endanwender der Anwendung initiiert die Erstellung dieser Daten.
  • Für Benutzer sichtbar und Benutzer können darin schreiben.
  • Inhalt in diesem Verzeichnis wird gesichert.
  • Die App kann Pfade ausschließen, 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 in der Regel die Unterverzeichnisse Application Support und Caches, die App kann jedoch eigene Unterverzeichnisse anlegen.
  • Library/Caches/
  • Enthält semi-persistent cached files.
  • Für Benutzer unsichtbar und Benutzer können nicht darin schreiben.
  • Inhalt in diesem Verzeichnis wird nicht gesichert.
  • Das OS kann die Dateien dieses Verzeichnisses automatisch löschen, wenn die App nicht läuft und der Speicher knapp wird.
  • Library/Application Support/
  • Enthält persistente Dateien, die für den Betrieb der App notwendig sind.
  • Für Benutzer unsichtbar und Benutzer können nicht darin schreiben.
  • Inhalt in diesem Verzeichnis wird gesichert.
  • Die App kann Pfade ausschließen, indem sie NSURLIsExcludedFromBackupKey setzt.
  • Library/Preferences/
  • Wird zum Speichern von Eigenschaften verwendet, die auch nach einem Neustart der Anwendung bestehen bleiben.
  • Informationen werden unverschlüsselt innerhalb der Anwendungssandbox in einer plist-Datei namens [BUNDLE_ID].plist gespeichert.
  • Alle Schlüssel/Wert-Paare, die mit NSUserDefaults gespeichert wurden, sind in dieser Datei zu finden.
  • tmp/
  • Verwende dieses Verzeichnis, um temporäre Dateien zu schreiben, die zwischen App-Starts nicht erhalten bleiben müssen.
  • Enthält nicht-persistente gecachte Dateien.
  • Für Benutzer unsichtbar.
  • Inhalt in diesem Verzeichnis wird nicht gesichert.
  • Das OS kann die Dateien dieses Verzeichnisses automatisch löschen, wenn die App nicht läuft und der Speicher knapp wird.

Let’s take a closer look at iGoat-Swift’s Application Bundle (.app) directory inside the Bundle directory (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app):

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

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

Binary Reversing

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

Disassemblieren des binary

Disassemblieren der 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 den Objective-C-Abschnitt 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;
};

However, the best options to disassemble the binary are: Hopper and IDA.

Datenspeicherung

To learn about how iOS stores data in the device read this page:

iOS Basics

Warning

Die folgenden Orte zum Speichern von Informationen sollten sofort nach der Installation der Anwendung, nach dem Überprüfen aller Funktionalitäten der Anwendung und sogar nach dem Ausloggen eines Benutzers und Einloggen eines anderen überprüft werden.
Ziel ist es, nicht geschützte sensible Informationen der Anwendung (passwords, tokens), des aktuellen Benutzers und zuvor angemeldeter Benutzer zu finden.

Plist

plist files are structured XML files that contains key-value pairs. It’s a way to store persistent data, so sometimes you may find sensitive information in these files. It’s recommended to check these files after installing the app and after using intensively it to see if new data is written.

The most common way to persist data in plist files is through the usage of NSUserDefaults. This plist file is saved inside the app sandbox in Library/Preferences/<appBundleID>.plist

The NSUserDefaults class provides a programmatic interface for interacting with the default system. The default system allows an application to customize its behaviour according to user preferences. Data saved by NSUserDefaults can be viewed in the application bundle. This class stores data in a plist file, but it’s meant to be used with small amounts of data.

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

You can dump the information saved using NSUserDefaults using objection’s ios nsuserdefaults get

To find all the plist of used by the application you can access to /private/var/mobile/Containers/Data/Application/{APPID} and run:

find ./ -name "*.plist"

Um Dateien vom XML or binary (bplist) Format in XML zu konvertieren, stehen je nach Betriebssystem verschiedene Methoden zur Verfügung:

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

$ plutil -convert xml1 Info.plist

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

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

Innerhalb einer Objection Session: Zur Analyse mobiler Anwendungen ermöglicht ein bestimmter Befehl die direkte Konvertierung von plist files:

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 Model-Schicht der Objekte in Ihrer Anwendung. Core Data can use SQLite as its persistent store, aber das Framework selbst ist keine Datenbank.
CoreData verschlüsselt seine Daten nicht standardmäßig. Es kann jedoch eine zusätzliche Verschlüsselungsebene zu CoreData hinzugefügt werden. Siehe das GitHub Repo für weitere Details.

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, dann haben Sie 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, kannst du sie mit dem im vorherigen Abschnitt vorgeschlagenen Befehl finden.

Other SQLite Databases

Es ist üblich, dass Anwendungen eigene sqlite-Datenbanken erstellen. Sie können dabei sensible Daten speichern und unverschlüsselt lassen. Daher ist es immer interessant, jede Datenbank im Anwendungsordner zu prüfen. Gehe deshalb 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

Entwickler können über Firebase Real-Time Databases store and sync data innerhalb einer NoSQL cloud-hosted database. Im JSON-Format gespeichert, werden die Daten in Echtzeit an alle 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, eine Verschlüsselung ist über eine spezifische Konfiguration verfügbar.

Die Datenbanken befinden sich unter: /private/var/mobile/Containers/Data/Application/{APPID}. Um diese Dateien zu untersuchen, kann man Befehle wie die folgenden verwenden:

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 Betrachten dieser Datenbankdateien wird das Tool Realm Studio empfohlen.

Um Verschlüsselung innerhalb 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. Als native Lösung für iOS und macOS konzipiert, bietet es die Möglichkeit, Daten nahtlos zu synchronisieren.

Um potenzielle Couchbase-Datenbanken auf einem Gerät zu identifizieren, sollte das folgende 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 speichern sie jedoch manchmal im keychain, da die erwähnte Cookie-Datei in Backups zugänglich sein kann.

Um die Cookies-Datei zu inspizieren, 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. Diese Datenbank kann sensitive data enthalten, wenn Tokens, Benutzernamen oder andere sensible Informationen zwischengespeichert wurden. Um die gecachten Informationen zu finden, öffne das Data-Verzeichnis der App (/var/mobile/Containers/Data/Application/<UUID>) und navigiere zu /Library/Caches/<Bundle Identifier>. The WebKit cache is also being stored in the Cache.db file. Objection kann die Datenbank mit dem Befehl sqlite connect Cache.db öffnen und damit interagieren, da es sich um eine normal SQLite database handelt.

Es wird recommended to disable Caching this data, da sie sensible Informationen in der Anfrage oder Antwort enthalten kann. Die folgende Liste zeigt verschiedene Möglichkeiten, dies zu erreichen:

  1. Es wird empfohlen, gecachte 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 gecachten Anfragen und Antworten aus der Cache.db-Datei.

  1. Wenn du den Vorteil von Cookies nicht benötigst, ist es empfehlenswert, einfach 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. Cache kann auch deaktiviert werden, indem die Cache Policy auf .notAllowed gesetzt wird. Dadurch wird das Speichern des Cache in jeglicher Form deaktiviert, weder im Arbeitsspeicher noch auf der Festplatte.

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. Wenn sich jedoch sensitive data auf dem aktuellen Bildschirm befindet, wird diese im image gespeichert (und persists across reboots). Dies sind die Snapshots, auf die du auch zugreifen kannst, indem du zweimal die Home-Taste drückst, um zwischen Apps zu wechseln.

Sofern das iPhone nicht jailbroken ist, benötigt der attacker Zugriff auf das device (entsperrt), um diese Screenshots sehen zu können. Standardmäßig wird der letzte Snapshot im Sandbox-Verzeichnis der Anwendung in Library/Caches/Snapshots/ oder Library/SplashBoard/Snapshots gespeichert (trusted computers können ab 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 anzuzeigen oder sensible Daten zu entfernen, z. B. in der Funktion ApplicationDidEnterBackground().

Das Folgende ist eine Beispiel-Remediation-Methode, die einen Standard-Screenshot setzt.

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, sobald die Anwendung in den Hintergrund geht. Es verhindert sensible Daten leaks, weil overlayImage.png immer die aktuelle Ansicht überschreibt.

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 Credentials

Die NSURLCredential-Klasse ist ideal, um sensible Informationen direkt im keychain zu speichern und damit die Notwendigkeit von NSUserDefaults oder anderen Wrappers zu umgehen. Um Credentials nach dem Login zu speichern, wird der folgende 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.

Benutzerdefinierte Tastaturen und Tastatur-Cache

Seit iOS 8.0 können Benutzer benutzerdefinierte keyboard extensions installieren, die unter Settings > General > Keyboard > Keyboards verwaltet werden können. Obwohl diese Tastaturen erweiterte Funktionen bieten, bergen sie das Risiko von keystroke logging und der Übertragung von Daten an externe Server, wobei Benutzer über Tastaturen, die Netzwerkzugriff erfordern, informiert werden. Apps können und sollten die Verwendung benutzerdefinierter Tastaturen für die Eingabe sensibler Informationen einschränken.

Sicherheitsempfehlungen:

  • Es wird empfohlen, Tastaturen von Drittanbietern zur erhöhten Sicherheit zu deaktivieren.
  • Achten Sie auf die Autokorrektur- und Auto-Vorschlagsfunktionen der Standard-iOS-Tastatur, die sensible Informationen in Cache-Dateien unter 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 Dictionary über Settings > General > Reset > Reset Keyboard Dictionary wird empfohlen, um zwischengespeicherte Daten zu löschen.
  • Das Abfangen von Netzwerkverkehr kann aufdecken, ob eine benutzerdefinierte Tastatur keystrokes remote überträgt.

Verhindern des Caching von Textfeldern

Die UITextInputTraits protocol bietet Eigenschaften zur Steuerung von autocorrection und secure text entry, die wichtig sind, um das Caching sensibler Informationen zu verhindern. Beispielsweise kann das Deaktivieren von autocorrection und das Aktivieren von secure text entry wie folgt erreicht werden:

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

Beim Debugging von Code wird häufig logging verwendet. Dabei besteht ein Risiko, da logs sensitive Informationen enthalten können. Früher, in iOS 6 und älteren Versionen, waren logs für alle Apps zugänglich, was das Risiko eines sensiblen Datenleaks darstellte. Jetzt dürfen Anwendungen nur noch auf ihre eigenen logs zugreifen.

Trotz dieser Einschränkungen kann ein attacker 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. Wichtig ist zu beachten, dass logs 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 testen, um sicherzustellen, dass keine sensiblen Informationen versehentlich geloggt werden.

Beim Durchsehen des Quellcodes der App auf mögliche leaks, achten Sie auf sowohl vordefinierte als auch benutzerdefinierte logging-Anweisungen, die Keywords wie NSLog, NSAssert, NSCAssert, fprintf für eingebaute Funktionen verwenden, sowie auf Erwähnungen von Logging oder Logfile für benutzerdefinierte Implementierungen.

Überwachung von System Logs

Apps loggen verschiedene Informationen, die sensibel sein können. Um diese logs zu überwachen, eignen sich 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, console logs zu sammeln:

  1. Öffne Xcode.
  2. Verbinde das iOS-Gerät.
  3. Gehe 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 logs in einem neuen Fenster anzuzeigen.

Für fortgeschrittenes Logging kann die Verbindung zur Geräteshell und die Verwendung von socat eine Echtzeit-Logüberwachung ermöglichen:

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

Gefolgt von Befehlen, um Log-Aktivitäten zu beobachten, was beim Diagnostizieren von Problemen oder beim Identifizieren potenzieller data leakage in Logs sehr wertvoll sein kann.

Backups

Auto-backup features 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 nahezu alle Gerätedaten, ausgenommen hochsensible Elemente wie Apple Pay-Details und Touch ID-Konfigurationen.

Security Risks

Die Einbeziehung von installierten Apps und deren Daten in Backups wirft das Problem einer potenziellen data leakage auf und das Risiko, dass Änderungen am Backup die Funktionalität der App beeinflussen könnten. Es wird empfohlen, sensible Informationen nicht im Klartext im Verzeichnis einer App oder dessen Unterverzeichnissen zu speichern, um diese Risiken zu minimieren.

Excluding Files from Backups

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

Testing for Vulnerabilities

Um die Backup-Sicherheit einer App zu bewerten, erstellen Sie zunächst ein Backup mit Finder und finden Sie es anschließend mithilfe der Anleitung in Apple’s official documentation. Analysieren Sie das Backup auf sensible Daten oder Konfigurationen, die verändert werden könnten, um das Verhalten der App zu beeinflussen.

Sensible Informationen lassen sich mit Kommandozeilentools oder Anwendungen wie iMazing suchen. Bei verschlüsselten Backups lässt sich das Vorhandensein der Verschlüsselung bestätigen, indem man den Schlüssel “IsEncrypted” in der Datei “Manifest.plist” im Stammverzeichnis des Backups prü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 im DinoSec’s GitHub repo, wie backup_tool.py und backup_passwd.py, nützlich sein, erfordern jedoch 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 dafür, wie sich das Verhalten einer App durch Änderungen am Backup beeinflussen lässt, zeigt die Bither bitcoin wallet app, in der der UI-Lock-PIN in net.bither.plist unter dem Schlüssel pin_code 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 gehalten werden, ist es entscheidend, die Expositionsdauer dieser Daten zu begrenzen. Es gibt zwei Hauptansätze, um den Speicherinhalt zu untersuchen: Erstellen eines Memory-Dumps und Echtzeit-Analyse des Speichers. Beide Methoden haben ihre Herausforderungen, einschließlich der Möglichkeit, während des Dump-Vorgangs oder der Analyse kritische Daten zu verpassen.

Retrieving and Analyzing a Memory Dump

Sowohl für jailbroken als auch nicht-jailbroken Geräte erlauben Tools wie objection und Fridump das Dumpen des Prozessspeichers einer App. Nach dem Dump erfordert die Analyse dieser Daten verschiedene Tools, abhängig von der Art der gesuchten Informationen.

Um Strings aus einem Speicher-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]> /?
...

Analyse des Speichers zur Laufzeit

r2frida bietet eine leistungsfähige Alternative, um den Speicher einer App in Echtzeit zu untersuchen, ohne ein 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>

Broken Cryptography

Schlechte Schlüsselverwaltungsprozesse

Einige Entwickler speichern sensible Daten im lokalen Speicher und verschlüsseln sie mit einem Schlüssel, der im Code hardcoded/vorhersehbar ist. Das sollte nicht gemacht werden, da ein Reverse-Engineering es Angreifern ermöglichen kann, die vertraulichen Informationen zu extrahieren.

Verwendung unsicherer und/oder veralteter Algorithmen

Entwickler sollten keine deprecated algorithms verwenden, um Autorisations-checks durchzuführen, Daten zu store oder zu send. Einige dieser Algorithmen sind: RC4, MD4, MD5, SHA1… Wenn hashes z. B. zur Speicherung von Passwörtern verwendet werden, sollten gegen Brute-Force resistente Hashes mit Salt eingesetzt werden.

Check

Die Hauptprüfungen bestehen darin, zu finden, ob sich hardcoded Passwörter/Secrets im Code befinden, ob diese predictable sind und ob der Code irgendeine Art von weak cryptography-Algorithmen verwendet.

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

ios monitor crypt

Für weitere Informationen über iOS kryptographische APIs und Bibliotheken besuchen Sie 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 mittels kryptographischer Methoden zu schützen. Entscheidend ist, dass lokale Authentifizierungsmechanismen ohne korrekte Implementierung umgangen werden können.

Apple’s Local Authentication framework und die keychain bieten Entwicklern jeweils 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 preiszugeben.

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

  • LocalAuthentication.framework für Authentifizierung auf hoher Ebene ohne Zugriff auf biometrische Daten.
  • Security.framework für niedrigere keychain-Services und das Schützen geheimer Daten mittels biometrischer Authentifizierung. Verschiedene open-source wrappers vereinfachen den Zugriff auf die keychain.

Caution

Allerdings weisen sowohl LocalAuthentication.framework als auch Security.framework Schwachstellen auf, da sie hauptsächlich boolesche Werte zurückgeben, ohne Daten für Authentifizierungsprozesse zu übertragen, wodurch sie anfällig für Umgehungen werden (siehe Don’t touch me that way, by David Lindner et al).

Implementierung der lokalen Authentifizierung

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

  • deviceOwnerAuthentication: Fordert Touch ID oder Geräte-Passcode an; scheitert, wenn keines von beiden aktiviert ist.
  • deviceOwnerAuthenticationWithBiometrics: Fordert ausschließlich Touch ID an.

Eine erfolgreiche Authentifizierung wird durch einen booleschen Rückgabewert von evaluatePolicy angezeigt, was eine potenzielle Sicherheitslücke darstellt.

Lokale Authentifizierung mit der Keychain

Die Implementierung von lokaler Authentifizierung in iOS-Apps beinhaltet die Nutzung der keychain APIs, um geheime Daten wie Authentifizierungs-Token sicher zu speichern. Dieser Prozess stellt sicher, dass die Daten nur vom Benutzer über dessen Geräte-Passcode oder biometrische Authentifizierung wie Touch ID zugänglich sind.

Die keychain bietet die Möglichkeit, Einträge mit dem Attribut SecAccessControl zu versehen, das den Zugriff auf den Eintrag solange einschränkt, bis der Benutzer sich erfolgreich per Touch ID oder Geräte-Passcode authentifiziert. Diese Funktion ist entscheidend zur Erhöhung der Sicherheit.

Nachfolgend sind Codebeispiele in Swift und Objective-C, die zeigen, wie ein String in der keychain gespeichert und abgerufen wird, wobei diese Sicherheitsfunktionen genutzt werden. Die Beispiele zeigen konkret, wie Access Control so eingerichtet wird, dass Touch ID zur Authentifizierung erforderlich ist und die Daten nur auf dem Gerät zugänglich sind, auf dem sie eingerichtet wurden, vorausgesetzt, es ist ein Geräte-Passcode konfiguriert.

// 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 den gespeicherten Eintrag 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 Nutzung von Frameworks in einer App lässt sich auch dadurch erkennen, dass man die Liste der gemeinsam genutzten dynamischen Bibliotheken der App-Binärdatei analysiert. Dies kann mit otool durchgeführt werden:

$ 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 Security.framework unter der Haube verwendet):

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

If Security.framework is used, only the second one will be shown.

Local Authentication Framework Bypass

Objection

Durch den Objection Biometrics Bypass, zu finden auf this GitHub page, steht eine Technik zur Umgehung des LocalAuthentication-Mechanismus zur Verfügung. Der Kern dieses Ansatzes besteht darin, Frida zu verwenden, um die Funktion evaluatePolicy zu manipulieren, sodass sie konstant ein True-Ergebnis liefert, 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, bei der Objection eine Aufgabe registriert, die effektiv das Ergebnis der evaluatePolicy-Prüfung 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-Skript geschrieben. Dieses Skript zielt auf die evaluatePolicy-Prüfung und fängt deren Callback ab, um sicherzustellen, dass er success=1 zurückgibt. Durch das Ändern des Callback-Verhaltens wird die Authentifizierungsprüfung effektiv umgangen.

Das folgende Skript wird injiziert, um das Ergebnis der evaluatePolicy-Methode zu verändern. Es ändert das Callback-Ergebnis 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 injecten und die biometrische Authentifizierung zu bypassen, wird folgender 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 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:

iOS Burp Suite Configuration

Hostname-Prüfung

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

Certificate Pinning

Wenn eine Anwendung SSL Pinning korrekt verwendet, funktioniert sie nur, wenn das Zertifikat dem erwarteten Zertifikat entspricht. Beim Testen einer Anwendung kann das problematisch sein, da Burp sein eigenes Zertifikat bereitstellt.
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

Sonstiges

  • In /System/Library finden Sie die Frameworks, die vom System für systemeigene Anwendungen 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.
  • Im Ordner einer installierten Anwendung (/User/Applications/<APP ID>/) finden Sie einige interessante Dateien:
  • iTunesArtwork: Das Icon, das von der App verwendet wird
  • iTunesMetadata.plist: Informationen der App, die im App Store verwendet werden
  • /Library/*: Enthält die Präferenzen und den Cache. In /Library/Cache/Snapshots/* finden Sie den Snapshot, der von der Anwendung erstellt wurde, bevor sie in den Hintergrund geschickt wurde.

Hot Patching/Enforced Updateing

Entwickler können alle Installationen ihrer App aus der Ferne sofort patchen, ohne die App erneut im App Store einzureichen und auf die Genehmigung zu warten.
Zu diesem Zweck wird häufig JSPatch verwendet. Es gibt jedoch auch andere Optionen wie Siren und react-native-appstore-version-checker.
Dies ist ein gefährlicher Mechanismus, der von bösartigen Drittanbieter-SDKs missbraucht werden könnte; daher wird 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 erhebliche Herausforderung bei 3rd party SDKs ist die fehlende granulare Kontrolle über ihre Funktionen. Entwickler stehen vor der Wahl: entweder das SDK zu integrieren und alle seine Features zu akzeptieren — einschließlich potenzieller Sicherheitslücken und Datenschutzbedenken — oder auf dessen Vorteile komplett zu verzichten. Oft sind Entwickler nicht in der Lage, Schwachstellen in diesen SDKs selbst zu patchen. Zudem können SDKs, sobald sie Vertrauen in der Community gewinnen, anfänglich harmlose Bibliotheken später Malware enthalten.

Die von Drittanbieter-SDKs bereitgestellten Dienste können Nutzerverhaltens-Tracking, Anzeigen oder Verbesserungen der User Experience umfassen. Das birgt jedoch ein Risiko, da Entwickler möglicherweise nicht vollständig wissen, welcher Code von diesen Bibliotheken ausgeführt wird, 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 in der Regel in zwei Formen: als eigenständige Bibliothek oder als komplettes SDK. Zum Schutz der Privatsphäre der Nutzer sollten sämtliche an diese Dienste übermittelten 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 eingesetzt werden. Dieses Tool sollte gegen die Anwendung und jede verwendete Shared Library ausgeführt werden, um zusätzliche Bibliotheken zu entdecken.

otool -L <application_path>

Interessante Schwachstellen & Fallstudien

Air Keyboard Remote Input Injection

Itunesstored Bookassetd Sandbox Escape

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