iOS Pentesting

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Nozioni di base iOS

iOS Basics

Ambiente di test

In questa pagina puoi trovare informazioni su iOS simulator, emulators e jailbreaking:

iOS Testing Environment

Analisi iniziale

Operazioni di base per il testing iOS

Durante il testing verranno suggerite diverse operazioni (connettersi al dispositivo, leggere/scrivere/caricare/scaricare file, usare alcuni strumenti…). Pertanto, se non sai come eseguire una di queste azioni, per favore inizia leggendo la pagina:

iOS Basic Testing Operations

Tip

Per i passaggi seguenti l’app dovrebbe essere installata sul dispositivo e dovrebbe essere già stato ottenuto il file IPA dell’applicazione.
Leggi la pagina Basic iOS Testing Operations per imparare come farlo.

Analisi statica di base

Alcuni interessanti decompilatori di file IPA per iOS:

Si raccomanda di usare lo strumento MobSF per eseguire un’analisi statica automatica sul file IPA.

Identificazione delle protezioni presenti nel binario:

  • PIE (Position Independent Executable): When enabled, the application loads into a random memory address every-time it launches, making it harder to predict its initial memory address.
otool -hv <app-binary> | grep PIE   # It should include the PIE flag
  • Stack Canaries: To validate the integrity of the stack, a ‘canary’ value is placed on the stack before calling a function and is validated again once the function ends.
otool -I -v <app-binary> | grep stack_chk   # It should include the symbols: stack_chk_guard and stack_chk_fail
  • ARC (Automatic Reference Counting): To prevent common memory corruption flaws
otool -I -v <app-binary> | grep objc_release   # It should include the _objc_release symbol
  • Encrypted Binary: The binary should be encrypted
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT   # The cryptid should be 1

Identificazione di funzioni sensibili/insicure

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

Metodi comuni per il rilevamento del jailbreak

  • File System Checks: Controlli del file system: cercare la presenza di file e directory comuni del jailbreak, come /Applications/Cydia.app o /Library/MobileSubstrate/MobileSubstrate.dylib.
  • Sandbox Violations: Violazioni della sandbox: provare ad accedere ad aree del file system ristrette, che dovrebbero essere bloccate sui dispositivi non jailbroken.
  • API Checks: Controlli API: verificare se è possibile usare chiamate proibite come fork() per creare un processo figlio o system() per vedere se /bin/sh esiste.
  • Process Checks: Controlli dei processi: monitorare la presenza di processi noti legati al jailbreak, come Cydia, Substrate, o ssh.
  • Kernel Exploits: Exploit del kernel: verificare la presenza di exploit del kernel comunemente usati nei jailbreak.
  • Environment Variables: Variabili di ambiente: ispezionare le variabili di ambiente alla ricerca di segni di jailbreak, come DYLD_INSERT_LIBRARIES.
  • Libraries Check: Controllo delle librerie: verificare le librerie caricate nel processo dell’app.
  • Check schemes: Controllare gli scheme: come canOpenURL(URL(string: "cydia://")).

Metodi comuni di rilevamento anti-debugging

  • Check for Debugger Presence: Verifica della presenza del debugger: usare sysctl o altri metodi per controllare se un debugger è attaccato.
  • Anti-Debugging APIs: API anti-debugging: cercare chiamate ad API anti-debugging come ptrace o SIGSTOP come ptrace(PT_DENY_ATTACH, 0, 0, 0).
  • Timing Checks: Controlli di timing: misurare il tempo impiegato da alcune operazioni e cercare discrepanze che possano indicare un debugging.
  • Memory Checks: Controlli di memoria: ispezionare la memoria alla ricerca di artefatti o modifiche note dei debugger.
  • Environment Variables: Variabili di ambiente: controllare variabili di ambiente che possono indicare una sessione di debugging.
  • Mach Ports: Mach Ports: rilevare se le mach exception ports sono utilizzate dai debugger.

Analisi dinamica di base

Dai un’occhiata all’analisi dinamica che MobSF esegue. Dovrai navigare tra le varie viste e interagire con esse, ma eseguirà hook di diverse classi e preparerà un report una volta terminato.

Elenco delle app installate

Usa il comando frida-ps -Uai per determinare il bundle identifier delle app installate:

$ 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

Impara come enumerate the components of the application e come hook methods and classes facilmente con objection:

iOS Hooking With Objection

Struttura IPA

La struttura di un IPA file è essenzialmente quella di un zipped package. Rinominando la sua estensione in .zip, può essere decompresso per rivelarne il contenuto. All’interno di questa struttura, un Bundle rappresenta un’applicazione completamente pacchettizzata pronta per l’installazione. Al suo interno troverai una directory chiamata <NAME>.app, che racchiude le risorse dell’applicazione.

  • Info.plist: Questo file contiene dettagli di configurazione specifici dell’applicazione.
  • _CodeSignature/: Questa directory include un file plist che contiene una signature, garantendo l’integritĂ  di tutti i file nel bundle.
  • Assets.car: Un archivio compresso che memorizza file di asset come le icone.
  • Frameworks/: Questa cartella ospita le librerie native dell’applicazione, che possono essere sotto forma di file .dylib o .framework.
  • PlugIns/: Può includere estensioni dell’applicazione, note come file .appex, anche se non sono sempre presenti. * Core Data: Viene usato per salvare i dati permanenti della tua applicazione per l’uso offline, per mettere in cache dati temporanei e per aggiungere funzionalitĂ  di undo alla tua app su un singolo dispositivo. Per sincronizzare i dati su piĂš dispositivi sotto lo stesso account iCloud, Core Data rispecchia automaticamente il tuo schema in un container CloudKit.
  • PkgInfo: Il file PkgInfo è un modo alternativo per specificare i type e creator codes della tua applicazione o bundle.
  • en.lproj, fr.proj, Base.lproj: Sono i pacchetti di lingua che contengono risorse per quelle lingue specifiche, e una risorsa di default nel caso una lingua non sia supportata.
  • Sicurezza: La directory _CodeSignature/ svolge un ruolo critico nella sicurezza dell’app verificando l’integritĂ  di tutti i file inclusi tramite signature digitali.
  • Gestione degli asset: Il file Assets.car usa la compressione per gestire in modo efficiente gli asset grafici, cruciale per ottimizzare le prestazioni dell’applicazione e ridurne le dimensioni complessive.
  • Frameworks e PlugIns: Queste directory sottolineano la modularitĂ  delle applicazioni iOS, permettendo agli sviluppatori di includere librerie di codice riutilizzabile (Frameworks/) e di estendere la funzionalitĂ  dell’app (PlugIns/).
  • Localizzazione: La struttura supporta piĂš lingue, facilitando la diffusione globale dell’app includendo risorse per specifici pacchetti linguistici.

Info.plist

L’Info.plist funge da pietra angolare per le applicazioni iOS, racchiudendo dati di configurazione chiave sotto forma di coppie key-value. Questo file è richiesto non solo per le applicazioni, ma anche per le app extension e i framework inclusi nel bundle. È strutturato in formato XML o binario e contiene informazioni critiche che vanno dai permessi dell’app alle configurazioni di sicurezza. Per un’esplorazione dettagliata delle chiavi disponibili, è possibile fare riferimento alla Apple Developer Documentation.

Per chi vuole lavorare con questo file in un formato piÚ accessibile, la conversione in XML può essere ottenuta facilmente usando plutil su macOS (disponibile nativamente su versioni 10.2 e successive) o plistutil su Linux. I comandi per la conversione sono i seguenti:

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

Tra la miriade di informazioni che il file Info.plist può rivelare, voci rilevanti includono le stringhe di permesso dell’app (UsageDescription), schemi di URL personalizzati (CFBundleURLTypes) e le configurazioni per App Transport Security (NSAppTransportSecurity). Queste voci, insieme ad altre come i tipi di documento personalizzati esportati/importati (UTExportedTypeDeclarations / UTImportedTypeDeclarations), possono essere facilmente individuate ispezionando il file o usando un semplice comando grep:

$ grep -i <keyword> Info.plist

Percorsi dei dati

Nell’ambiente iOS, le directory sono designate specificamente per le applicazioni di sistema e le app installate dall’utente. Le applicazioni di sistema risiedono nella directory /Applications, mentre le app installate dall’utente sono collocate sotto /var/mobile/containers/Data/Application/. A queste applicazioni viene assegnato un identificatore univoco noto come 128-bit UUID, rendendo difficile individuare manualmente la cartella di un’app a causa della casualità dei nomi delle directory.

Warning

Poiché le applicazioni in iOS devono essere sandboxed, ogni app avrà anche una cartella all’interno di $HOME/Library/Containers con il CFBundleIdentifier dell’app come nome della cartella.

Tuttavia, entrambe le cartelle (cartella dei dati e cartella dei container) contengono il file .com.apple.mobile_container_manager.metadata.plist che collega entrambe tramite la chiave MCMetadataIdentifier).

Per facilitare la scoperta della directory di installazione di un’app installata dall’utente, lo strumento objection fornisce un comando utile, env. Questo comando rivela informazioni dettagliate sulle directory per l’app in questione. Di seguito un esempio di come usare questo comando:

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

In alternativa, il nome dell’app può essere cercato all’interno di /private/var/containers usando il comando find:

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

Comandi come ps e lsof possono anche essere utilizzati per identificare il processo dell’app e per elencare i file aperti, rispettivamente, fornendo informazioni sui percorsi di directory attivi dell’applicazione:

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

Directory del Bundle:

  • AppName.app
  • Questo è il bundle dell’applicazione come visto prima nell’IPA; contiene dati essenziali dell’applicazione, contenuti statici e il binario compilato dell’app.
  • Questa directory è visibile agli utenti, ma gli utenti non possono scriverci.
  • Il contenuto di questa directory non viene sottoposto a backup.
  • Il contenuto di questa cartella viene usato per validare la firma del codice.

Directory dei dati:

  • Documents/
  • Contiene tutti i dati generati dall’utente. L’utente finale dell’app avvia la creazione di questi dati.
  • Visibile agli utenti e gli utenti possono scriverci.
  • Il contenuto di questa directory viene incluso nel backup.
  • L’app può escludere percorsi impostando NSURLIsExcludedFromBackupKey.
  • Library/
  • Contiene tutti i file che non sono specifici dell’utente, come caches, preferences, cookies, e file di configurazione property list (plist).
  • Le app iOS solitamente usano le sottodirectory Application Support e Caches, ma l’app può creare sottodirectory personalizzate.
  • Library/Caches/
  • Contiene file di cache semi-persistenti.
  • Invisibile agli utenti e gli utenti non possono scriverci.
  • Il contenuto di questa directory non viene sottoposto a backup.
  • Il sistema operativo può eliminare automaticamente i file in questa directory quando l’app non è in esecuzione e lo spazio di archiviazione è limitato.
  • Library/Application Support/
  • Contiene file persistenti necessari per l’esecuzione dell’app.
  • Invisibile agli utenti e gli utenti non possono scriverci.
  • Il contenuto di questa directory è incluso nel backup.
  • L’app può escludere percorsi impostando NSURLIsExcludedFromBackupKey.
  • Library/Preferences/
  • Usata per memorizzare proprietĂ  che possono persistere anche dopo il riavvio dell’applicazione.
  • Le informazioni vengono salvate, non cifrate, all’interno del sandbox dell’applicazione in un file plist chiamato [BUNDLE_ID].plist.
  • Tutte le coppie chiave/valore memorizzate con NSUserDefaults si trovano in questo file.
  • tmp/
  • Usa questa directory per scrivere file temporanei che non devono persistere tra i lanci dell’app.
  • Contiene file di cache non persistenti.
  • Invisibile agli utenti.
  • Il contenuto di questa directory non viene sottoposto a backup.
  • Il sistema operativo può eliminare automaticamente i file in questa directory quando l’app non è in esecuzione e lo spazio di archiviazione è limitato.

Diamo uno sguardo più da vicino alla directory Application Bundle (.app) di iGoat-Swift all’interno della directory del Bundle (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app):

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

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

Binary Reversing

Dentro la cartella <application-name>.app troverai un file binario chiamato <application-name>. Questo è il file che verrà eseguito. Puoi eseguire un’ispezione di base del binario con lo strumento otool:

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

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

Verifica se l’app è crittografata

Verifica se c’è qualche output per:

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

Disassemblare il binario

Disassemblare la sezione text:

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

Per stampare il Objective-C segment dell’applicazione di esempio si può usare:

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

Per ottenere un codice Objective-C piĂš compatto puoi usare class-dump:

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

#pragma mark Named Structures

struct CGPoint {
double _field1;
double _field2;
};

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

struct CGSize {
double _field1;
double _field2;
};

Tuttavia, le migliori opzioni per disassemblare il binario sono: Hopper e IDA.

Archiviazione dei dati

Per imparare come iOS memorizza i dati sul dispositivo leggi questa pagina:

iOS Basics

Warning

I seguenti posti dove salvare informazioni dovrebbero essere controllati subito dopo l’installazione dell’applicazione, dopo aver verificato tutte le funzionalità dell’applicazione e anche dopo essersi disconnessi da un utente e aver effettuato l’accesso con un altro.
L’obiettivo è trovare informazioni sensibili non protette dell’applicazione (password, token), dell’utente corrente e degli utenti precedentemente connessi.

Plist

plist files sono file XML strutturati che contengono coppie chiave-valore. È un modo per memorizzare dati persistenti, quindi a volte potresti trovare informazioni sensibili in questi file. È consigliato controllare questi file dopo l’installazione dell’app e dopo un uso intensivo per vedere se vengono scritti nuovi dati.

Il modo più comune per persistere dati in file plist è l’uso di NSUserDefaults. Questo file plist viene salvato all’interno della sandbox dell’app in Library/Preferences/<appBundleID>.plist

La classe NSUserDefaults fornisce un’interfaccia programmativa per interagire con il sistema dei default. Il sistema dei default permette a un’applicazione di personalizzare il suo comportamento in base alle preferenze utente. I dati salvati da NSUserDefaults possono essere visualizzati nel bundle dell’applicazione. Questa classe memorizza dati in un file plist, ma è pensata per piccole quantità di dati.

Non è piÚ possibile accedere direttamente a questi dati tramite un computer attendibile, ma è possibile accedervi eseguendo un backup.

Puoi dump le informazioni salvate da NSUserDefaults utilizzando il comando objection ios nsuserdefaults get

Per trovare tutti i plist utilizzati dall’applicazione puoi accedere a /private/var/mobile/Containers/Data/Application/{APPID} ed eseguire:

find ./ -name "*.plist"

Per convertire file dal formato XML o binario (bplist) a XML, sono disponibili vari metodi a seconda del sistema operativo:

Per utenti macOS: Utilizzare il comando plutil. È uno strumento integrato in macOS (10.2+), progettato per questo scopo:

$ plutil -convert xml1 Info.plist

Per utenti Linux: Installa libplist-utils prima, poi usa plistutil per convertire il tuo file:

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

Within an Objection Session: Per analizzare le applicazioni mobile, un comando specifico permette di convertire direttamente i plist files:

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

Core Data

Core Data è un framework per la gestione dello strato modello degli oggetti nella tua applicazione. Core Data can use SQLite as its persistent store, ma il framework di per sÊ non è un database.
CoreData non cripta i suoi dati per impostazione predefinita. Tuttavia, è possibile aggiungere un ulteriore livello di crittografia a CoreData. See the GitHub Repo for more details.

Puoi trovare le informazioni SQLite di Core Data di un’applicazione nel percorso /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support

Se riesci ad aprire il file SQLite e ad accedere a informazioni sensibili, allora hai trovato una misconfigurazione.

-(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 è un key/value store costruito su SQLite.
PoichĂŠ i database Yap sono database SQLite, puoi trovarli usando il comando proposto nella sezione precedente.

Altri database SQLite

È comune che le applicazioni creino il proprio database SQLite. Potrebbero memorizzare dati sensibili in essi e lasciarli non crittografati. Perciò conviene sempre controllare ogni database presente nella directory dell’applicazione. Vai quindi nella directory dell’applicazione dove i dati vengono salvati (/private/var/mobile/Containers/Data/Application/{APPID})

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

Firebase Real-Time Databases

Gli sviluppatori possono memorizzare e sincronizzare dati all’interno di un database cloud-hosted NoSQL tramite Firebase Real-Time Databases. Memorizzati in formato JSON, i dati vengono sincronizzati a tutti i client connessi in tempo reale.

Puoi trovare come controllare database Firebase mal configurati qui:

Firebase Database

Realm databases

Realm Objective-C and Realm Swift offrono un’alternativa potente per l’archiviazione dei dati, non fornita da Apple. Per impostazione predefinita, essi memorizzano i dati non criptati, con la crittografia disponibile tramite configurazione specifica.

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

Per visualizzare questi file di database, si raccomanda lo strumento Realm Studio.

Per implementare la crittografia all’interno di un database Realm, può essere utilizzato il seguente snippet di codice:

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

Database Couchbase Lite

Couchbase Lite è descritto come un motore di database leggero e incorporato che segue l’approccio orientato ai documenti (NoSQL). Progettato per essere nativo su iOS e macOS, offre la possibilità di sincronizzare i dati in modo trasparente.

Per identificare potenziali database Couchbase su un dispositivo, dovrebbe essere ispezionata la seguente directory:

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

Cookies

iOS memorizza i cookie delle app in Library/Cookies/cookies.binarycookies all’interno della cartella di ciascuna app. Tuttavia, gli sviluppatori a volte decidono di salvarli nel keychain poiché il suddetto file dei cookie può essere accessibile nei backup.

Per ispezionare il file dei cookie puoi usare this python script o usare objection con ios cookies get.
Puoi anche usare objection per convertire questi file in formato JSON e analizzare i dati.

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

Di default NSURLSession memorizza dati, come richieste e risposte HTTP in Cache.db. Questo database può contenere dati sensibili, se token, nomi utente o qualsiasi altra informazione sensibile è stata memorizzata nella cache. Per trovare le informazioni in cache apri la directory dei dati dell’app (/var/mobile/Containers/Data/Application/<UUID>) e vai in /Library/Caches/<Bundle Identifier>. La WebKit cache è anch’essa memorizzata nel file Cache.db. Objection può aprire e interagire con il database con il comando sqlite connect Cache.db, poiché è un normale database SQLite.

È consigliato disabilitare la memorizzazione nella cache di questi dati, in quanto possono contenere informazioni sensibili nella richiesta o nella risposta. La lista seguente mostra diversi modi per ottenere questo:

  1. È consigliato rimuovere le risposte in cache dopo il logout. Questo può essere fatto con il metodo fornito da Apple chiamato removeAllCachedResponses. Puoi chiamare questo metodo come segue:

URLCache.shared.removeAllCachedResponses()

Questo metodo rimuoverĂ  tutte le richieste e risposte memorizzate nella cache dal file Cache.db.

  1. Se non hai bisogno del vantaggio dei cookie, è consigliabile usare la proprietà di configurazione .ephemeral di URLSession, che disabiliterà il salvataggio di cookie e cache.

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. La cache può essere anche disabilitata impostando la Cache Policy su .notAllowed. Questo disabiliterà la memorizzazione della cache in qualsiasi forma, sia in memoria che su disco.

Snapshots

Ogni volta che premi il tasto Home, iOS scatta un’istantanea della schermata corrente per permettere una transizione più fluida all’app. Tuttavia, se nella schermata corrente sono presenti dati sensibili, saranno salvati nell’immagine (che persiste attraverso i riavvii). Queste sono le istantanee cui puoi accedere anche facendo doppio tap sul tasto Home per passare tra le app.

A meno che l’iPhone non sia jailbroken, l’attaccante deve avere l’accesso al dispositivo sbloccato per vedere questi screenshot. Per impostazione predefinita l’ultima istantanea è memorizzata nella sandbox dell’app in Library/Caches/Snapshots/ o nella cartella Library/SplashBoard/Snapshots (i computer trusted non possono accedere al filesystem da iOX 7.0).

Un modo per prevenire questo comportamento dannoso è mostrare una schermata vuota o rimuovere i dati sensibili prima che venga scattata l’istantanea usando la funzione ApplicationDidEnterBackground().

Di seguito un esempio di metodo di mitigazione che imposterĂ  uno screenshot di default.

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];
}

Imposta l’immagine di sfondo su overlayImage.png ogni volta che l’applicazione viene inviata in background. Previene i leaks di dati sensibili perché overlayImage.png sovrascriverà sempre la vista corrente.

Keychain

Per accedere e gestire l’iOS keychain, sono disponibili strumenti come Keychain-Dumper, adatti per dispositivi jailbroken. Inoltre, Objection fornisce il comando ios keychain dump per scopi simili.

Memorizzazione delle credenziali

La classe NSURLCredential è ideale per salvare informazioni sensibili direttamente nel keychain, evitando la necessità di NSUserDefaults o altri wrapper. Per memorizzare le credenziali dopo il login, viene utilizzato il seguente codice Swift:

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

Per estrarre queste credenziali memorizzate, si utilizza il comando di Objection ios nsurlcredentialstorage dump.

Custom Keyboards and Keyboard Cache

A partire da iOS 8.0, gli utenti possono installare estensioni di tastiera personalizzate, gestibili tramite Impostazioni > Generali > Tastiera > Tastiere. Pur offrendo funzionalità estese, queste tastiere possono registrare i battiti e trasmettere dati a server esterni; tuttavia gli utenti vengono avvisati quando una tastiera richiede l’accesso alla rete. Le app possono, e dovrebbero, limitare l’uso di tastiere personalizzate per l’inserimento di informazioni sensibili.

Security Recommendations:

  • Si consiglia di disabilitare le tastiere di terze parti per aumentare la sicurezza.
  • Prestare attenzione alle funzionalitĂ  di autocorrezione e suggerimenti automatici della tastiera iOS predefinita, che potrebbero memorizzare informazioni sensibili in file di cache situati in Library/Keyboard/{locale}-dynamic-text.dat o /private/var/mobile/Library/Keyboard/dynamic-text.dat. Questi file di cache dovrebbero essere controllati regolarmente per dati sensibili. Per cancellare i dati memorizzati nella cache è consigliato reimpostare il dizionario della tastiera tramite Impostazioni > Generali > Ripristina > Reimposta dizionario tastiera.
  • L’intercettazione del traffico di rete può rivelare se una tastiera personalizzata sta trasmettendo le battute di tastiera a server remoti.

Preventing Text Field Caching

The UITextInputTraits protocol offers properties to manage autocorrection and secure text entry, essential for preventing sensitive information caching. For example, disabling autocorrection and enabling secure text entry can be achieved with:

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

Inoltre, gli sviluppatori dovrebbero assicurarsi che i campi di testo, specialmente quelli per l’inserimento di informazioni sensibili come password e PIN, disabilitino la memorizzazione nella cache impostando autocorrectionType su UITextAutocorrectionTypeNo e secureTextEntry su YES.

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

Logs

Il debug del codice spesso comporta l’uso del logging. C’è un rischio perché i logs possono contenere informazioni sensibili. In passato, in iOS 6 e versioni precedenti, i logs erano accessibili a tutte le app, comportando il rischio di sensitive data leakage. Ora, le applicazioni sono limitate ad accedere solo ai propri logs.

Nonostante queste restrizioni, un attaccante con accesso fisico a un dispositivo sbloccato può comunque sfruttare la situazione collegando il dispositivo a un computer e leggendo i logs. È importante notare che i logs rimangono sul disco anche dopo la disinstallazione dell’app.

Per mitigare i rischi, è consigliabile interagire approfonditamente con l’app, esplorando tutte le sue funzionalità e input per assicurarsi che nessuna informazione sensibile venga logged inavvertitamente.

Quando si analizza il codice sorgente dell’app alla ricerca di potenziali leaks, cercare sia dichiarazioni di logging predefinite sia custom usando parole chiave come NSLog, NSAssert, NSCAssert, fprintf per funzioni built-in, e qualsiasi riferimento a Logging o Logfile per implementazioni custom.

Monitoring System Logs

Le app registrano varie informazioni che possono essere sensibili. Per monitorare questi logs, strumenti e comandi come:

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

sono utili. Inoltre, Xcode fornisce un modo per raccogliere i log della console:

  1. Apri Xcode.
  2. Collega il dispositivo iOS.
  3. Vai su Window -> Devices and Simulators.
  4. Seleziona il tuo dispositivo.
  5. Riproduci il problema che stai indagando.
  6. Usa il pulsante Open Console per visualizzare i log in una nuova finestra.

Per un logging piÚ avanzato, collegarsi alla shell del dispositivo e usare socat può fornire il monitoraggio dei log in tempo reale:

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

Segue una serie di comandi per osservare le attivitĂ  dei log, utilissimi per diagnosticare problemi o identificare potenziali data leakage nei log.

Backup

Le funzionalitĂ  di backup automatico sono integrate in iOS, permettendo la creazione di copie dei dati del dispositivo tramite iTunes (fino a macOS Catalina), Finder (da macOS Catalina in poi) o iCloud. Questi backup includono quasi tutti i dati del dispositivo, esclusi elementi altamente sensibili come i dettagli di Apple Pay e le configurazioni di Touch ID.

Rischi per la sicurezza

L’inclusione delle app installate e dei loro dati nei backup solleva il problema di potenziali data leakage e il rischio che modifiche al backup possano alterare la funzionalità dell’app. Si consiglia di non memorizzare informazioni sensibili in testo in chiaro all’interno della directory di un’app o delle sue sottodirectory per mitigare questi rischi.

Escludere file dai backup

I file in Documents/ e Library/Application Support/ vengono salvati nei backup per impostazione predefinita. Gli sviluppatori possono escludere file o directory specifiche dai backup usando NSURL setResourceValue:forKey:error: con la chiave NSURLIsExcludedFromBackupKey. Questa pratica è fondamentale per proteggere i dati sensibili dall’inclusione nei backup.

Test per vulnerabilitĂ 

Per valutare la sicurezza del backup di un’app, inizia creando un backup usando Finder, quindi individualo seguendo le indicazioni della documentazione ufficiale Apple. Analizza il backup alla ricerca di dati sensibili o configurazioni che potrebbero essere alterati per influenzare il comportamento dell’app.

Le informazioni sensibili possono essere ricercate usando strumenti da riga di comando o applicazioni come iMazing. Per i backup criptati, è possibile confermare la presenza della cifratura verificando la chiave “IsEncrypted” nel file “Manifest.plist” alla radice del backup.

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

For dealing with encrypted backups, Python scripts available in DinoSec’s GitHub repo, like backup_tool.py and backup_passwd.py, may be useful, albeit potentially requiring adjustments for compatibility with the latest iTunes/Finder versions. The iOSbackup tool is another option for accessing files within password-protected backups.

Modifying App Behavior

An example of altering app behavior through backup modifications is demonstrated in the Bither bitcoin wallet app, where the UI lock PIN is stored within net.bither.plist under the pin_code key. Removing this key from the plist and restoring the backup removes the PIN requirement, providing unrestricted access.

Summary on Memory Testing for Sensitive Data

Quando si trattano informazioni sensibili memorizzate nella memoria di un’applicazione, è fondamentale limitare il tempo di esposizione di questi dati. Ci sono due approcci principali per esaminare il contenuto della memoria: creare un dump della memoria e analizzare la memoria in tempo reale. Entrambi i metodi presentano delle difficoltà, incluso il rischio di perdere dati critici durante il processo di dump o l’analisi.

Retrieving and Analyzing a Memory Dump

Per dispositivi jailbroken e non-jailbroken, strumenti come objection e Fridump permettono di eseguire il dump della memoria di un processo dell’app. Una volta ottenuto il dump, analizzare questi dati richiede vari strumenti, a seconda della natura delle informazioni che si stanno cercando.

To extract strings from a memory dump, commands such as strings or rabin2 -zz can be used:

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

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

Per un’analisi più dettagliata, inclusa la ricerca di tipi di dati specifici o pattern, radare2 offre ampie capacità di ricerca:

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

Analisi della memory in tempo reale

r2frida fornisce un’alternativa potente per ispezionare la memory di un’app in tempo reale, senza bisogno di un memory dump. Questo strumento permette l’esecuzione di comandi di ricerca direttamente sulla memory dell’applicazione in esecuzione:

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

Crittografia debole

Processi di gestione delle chiavi inadeguati

Alcuni sviluppatori salvano dati sensibili nello storage locale e li cifrano con una chiave hardcoded/predictable nel codice. Questo non dovrebbe essere fatto, poichĂŠ il reverse engineering potrebbe permettere a un attaccante di estrarre le informazioni confidenziali.

Uso di algoritmi insicuri e/o deprecati

Gli sviluppatori non dovrebbero usare algoritmi deprecati per eseguire controlli di autorizzazione (checks), memorizzare o inviare dati. Alcuni di questi algoritmi sono: RC4, MD4, MD5, SHA1… Se vengono usati hash per memorizzare password, dovrebbero essere utilizzati hash resistenti al brute-force con salt.

Verifica

Le principali verifiche da effettuare sono trovare se ci sono password/secret hardcoded nel codice, se queste sono predictable, e se il codice sta usando qualche tipo di weak crittografia.

È interessante sapere che puoi monitor alcune crypto libraries automaticamente usando objection con:

ios monitor crypt

Per maggiori informazioni sulle API e le librerie crittografiche iOS consulta https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography

Local Authentication

L’autenticazione locale riveste un ruolo cruciale, specialmente quando riguarda la protezione dell’accesso a un endpoint remoto tramite metodi crittografici. L’essenza è che, senza una corretta implementazione, i meccanismi di autenticazione locale possono essere aggirati.

Apple’s Local Authentication framework e il keychain forniscono API robuste agli sviluppatori per gestire rispettivamente i dialog di autenticazione utente e la gestione sicura di dati segreti. Il Secure Enclave protegge l’ID impronta per Touch ID, mentre Face ID si basa sul riconoscimento facciale senza compromettere i dati biometrici.

Per integrare Touch ID/Face ID, gli sviluppatori hanno due scelte di API:

  • LocalAuthentication.framework per l’autenticazione utente ad alto livello senza accesso ai dati biometrici.
  • Security.framework per l’accesso a servizi keychain a livello piĂš basso, proteggendo i dati segreti con autenticazione biometrica. Vari open-source wrappers semplificano l’accesso al keychain.

Caution

Tuttavia, sia LocalAuthentication.framework che Security.framework presentano vulnerabilità, poiché restituiscono principalmente valori booleani senza trasmettere dati per i processi di autenticazione, rendendoli suscettibili a bypass (vedi Don’t touch me that way, by David Lindner et al).

Implementing Local Authentication

Per richiedere agli utenti l’autenticazione, gli sviluppatori dovrebbero utilizzare il metodo evaluatePolicy della classe LAContext, scegliendo tra:

  • deviceOwnerAuthentication: Richiede Touch ID o il passcode del dispositivo; fallisce se nessuno dei due è abilitato.
  • deviceOwnerAuthenticationWithBiometrics: Richiede esclusivamente Touch ID.

Un’autenticazione riuscita è indicata da un valore booleano restituito da evaluatePolicy, evidenziando una potenziale falla di sicurezza.

Local Authentication using Keychain

Implementare l’autenticazione locale nelle app iOS implica l’uso delle keychain APIs per memorizzare in modo sicuro dati segreti come token di autenticazione. Questo processo garantisce che i dati possano essere accessibili solo dall’utente, utilizzando il passcode del dispositivo o l’autenticazione biometrica come Touch ID.

Il keychain offre la possibilità di impostare elementi con l’attributo SecAccessControl, che limita l’accesso all’elemento fino a quando l’utente non si autentica correttamente tramite Touch ID o il passcode del dispositivo. Questa funzionalità è fondamentale per migliorare la sicurezza.

Di seguito sono riportati esempi di codice in Swift e Objective-C che mostrano come salvare e recuperare una stringa nel/dal keychain, sfruttando queste funzionalità di sicurezza. Gli esempi mostrano specificamente come configurare il controllo di accesso per richiedere l’autenticazione Touch ID e garantire che i dati siano accessibili solo sul dispositivo su cui sono stati impostati, a condizione che sia configurato un passcode del dispositivo.

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

Ora possiamo richiedere l’elemento salvato dal keychain. I servizi keychain presenteranno la finestra di autenticazione all’utente e restituiranno data o nil a seconda che sia stata fornita o meno una fingerprint adatta.

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

Rilevamento

L’utilizzo di framework in un’app può essere rilevato anche analizzando la lista di librerie dinamiche condivise del binario dell’app. Questo può essere fatto usando otool:

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

Se LocalAuthentication.framework è usato in un’app, l’output conterrà entrambe le seguenti righe (ricorda che LocalAuthentication.framework usa Security.framework sotto il cofano):

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

Se viene usato Security.framework, verrĂ  mostrato solo il secondo.

Local Authentication Framework Bypass

Objection

Through the Objection Biometrics Bypass, located at this GitHub page, a technique is available for overcoming the LocalAuthentication mechanism. Il nucleo di questo approccio consiste nell’utilizzare Frida per manipolare la funzione evaluatePolicy, facendo sì che restituisca sempre True, indipendentemente dall’effettivo successo dell’autenticazione. Questo è particolarmente utile per eludere processi di autenticazione biometrica difettosi.

Per attivare questo bypass, viene usato il seguente comando:

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

Questo comando avvia una sequenza in cui Objection registra un’attività che altera efficacemente l’esito del controllo evaluatePolicy in True.

Frida

Un esempio di utilizzo di evaluatePolicy da 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"];
});
}
}

Per ottenere il bypass di Local Authentication, viene scritto uno script Frida. Questo script prende di mira il controllo evaluatePolicy, intercettando il suo callback per assicurarsi che restituisca success=1. Alterando il comportamento del callback, il controllo di autenticazione viene effettivamente bypassato.

Lo script qui sotto viene iniettato per modificare il risultato del metodo evaluatePolicy. Modifica il risultato del callback in modo che indichi sempre successo.

// 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!");
}

Per iniettare lo script Frida e bypassare l’autenticazione biometrica, viene utilizzato il seguente comando:

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

Esposizione di funzionalitĂ  sensibili tramite 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

Comunicazione di rete

È importante verificare che non ci siano comunicazioni senza cifratura e anche che l’applicazione stia correttamente validando il certificato TLS del server.
Per controllare questo tipo di problemi puoi usare un proxy come Burp:

iOS Burp Suite Configuration

Hostname check

Un problema comune nella validazione del certificato TLS è verificare che il certificato sia stato firmato da una CA di fiducia, ma non controllare se l’hostname del certificato corrisponde all’hostname effettivamente raggiunto.
Per verificare questo problema usando Burp, dopo aver affidato la CA di Burp sull’iPhone, puoi creare un nuovo certificato con Burp per un hostname diverso e usarlo. Se l’app continua a funzionare, allora è vulnerabile.

Certificate Pinning

Se un’applicazione usa correttamente lo SSL Pinning, allora l’app funzionerà solo se il certificato è quello previsto. Quando si testa un’applicazione questo potrebbe essere un problema poiché Burp presenterà il proprio certificato.
Per bypassare questa protezione su un dispositivo jailbroken, puoi installare l’applicazione SSL Kill Switch o installare Burp Mobile Assistant

Puoi anche usare objection’s ios sslpinning disable

Varie

  • In /System/Library puoi trovare i framework installati nel telefono utilizzati dalle applicazioni di sistema
  • Le applicazioni installate dall’utente tramite App Store si trovano in /User/Applications
  • E /User/Library contiene i dati salvati dalle applicazioni a livello utente
  • Puoi accedere a /User/Library/Notes/notes.sqlite per leggere le note salvate dall’applicazione.
  • All’interno della cartella di un’applicazione installata (/User/Applications/<APP ID>/) puoi trovare alcuni file interessanti:
  • iTunesArtwork: l’icona usata dall’app
  • iTunesMetadata.plist: informazioni dell’app usate nell’App Store
  • /Library/*: contiene le preferenze e la cache. In /Library/Cache/Snapshots/* puoi trovare lo snapshot effettuato sull’applicazione prima di mandarla in background.

Hot Patching/Enforced Updateing

Gli sviluppatori possono correggere automaticamente tutte le installazioni della loro app da remoto istantaneamente senza dover reinviare l’app all’App Store e aspettare l’approvazione.
A questo scopo è solitamente usato JSPatch. Ma ci sono altre opzioni anche come Siren e react-native-appstore-version-checker.
Questo è un meccanismo pericoloso che potrebbe essere abusato da SDK di terze parti maligni, quindi è consigliato verificare quale metodo viene usato per l’aggiornamento automatico (se presente) e testarlo. Potresti provare a scaricare una versione precedente dell’app per questo scopo.

Terze parti

Una sfida significativa con gli 3rd party SDKs è la mancanza di controllo granulare sulle loro funzionalità. Gli sviluppatori si trovano davanti a una scelta: integrare l’SDK e accettare tutte le sue funzionalità, incluse potenziali vulnerabilità di sicurezza e problemi di privacy, oppure rinunciare completamente ai suoi benefici. Spesso gli sviluppatori non sono in grado di correggere le vulnerabilità all’interno di questi SDK da soli. Inoltre, man mano che gli SDK guadagnano fiducia nella comunità, alcuni potrebbero iniziare a contenere malware.

I servizi forniti da SDK di terze parti possono includere il tracciamento del comportamento dell’utente, la visualizzazione di annunci o miglioramenti dell’esperienza utente. Tuttavia, ciò introduce un rischio poiché gli sviluppatori potrebbero non essere pienamente consapevoli del codice eseguito da queste librerie, portando a potenziali rischi per la privacy e la sicurezza. È fondamentale limitare le informazioni condivise con servizi di terze parti a quanto strettamente necessario e assicurarsi che non venga esposto alcun dato sensibile.

L’implementazione di servizi di terze parti di solito avviene in due forme: una libreria standalone o un SDK completo. Per proteggere la privacy degli utenti, qualsiasi dato condiviso con questi servizi dovrebbe essere anonimizzato per prevenire la divulgazione di Personal Identifiable Information (PII).

Per identificare le librerie utilizzate da un’applicazione si può usare il comando otool. Questo strumento dovrebbe essere eseguito sull’applicazione e su ogni libreria condivisa che utilizza per scoprire librerie aggiuntive.

otool -L <application_path>

VulnerabilitĂ  interessanti & Casi di studio

Air Keyboard Remote Input Injection

Itunesstored Bookassetd Sandbox Escape

Riferimenti e altre risorse

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks