iOS Pentesting
Usa Trickest per costruire e automatizzare flussi di lavoro facilmente, alimentati dagli strumenti della comunità più avanzati al mondo. Ottieni accesso oggi:
iOS Basics
iOS BasicsTesting Environment
In questa pagina puoi trovare informazioni sul simulatore iOS, emulatori e jailbreaking:
iOS Testing EnvironmentInitial Analysis
Basic iOS Testing Operations
Durante il testing saranno suggerite diverse operazioni (connettersi al dispositivo, leggere/scrivere/caricare/scaricare file, utilizzare alcuni strumenti...). Pertanto, se non sai come eseguire nessuna di queste azioni, per favore, inizia a leggere la pagina:
iOS Basic Testing OperationsPer i seguenti passaggi l'app dovrebbe essere installata nel dispositivo e dovrebbe già aver ottenuto il file IPA dell'applicazione. Leggi la pagina Basic iOS Testing Operations per imparare come fare.
Basic Static Analysis
È consigliato utilizzare lo strumento MobSF per eseguire un'analisi statica automatica sul file IPA.
Identificazione delle protezioni presenti nel binario:
PIE (Position Independent Executable): Quando abilitato, l'applicazione si carica in un indirizzo di memoria casuale ogni volta che viene avviata, rendendo più difficile prevedere il suo indirizzo di memoria iniziale.
Stack Canaries: Per convalidare l'integrità dello stack, un valore ‘canary’ viene posizionato nello stack prima di chiamare una funzione e viene convalidato nuovamente una volta che la funzione termina.
ARC (Automatic Reference Counting): Per prevenire comuni difetti di corruzione della memoria
Binary Crittografato: Il binario dovrebbe essere crittografato
Identificazione di Funzioni Sensibili/Insecure
Algoritmi di Hash Deboli
Funzioni Random Insecure
Funzione ‘Malloc’ Insecure
Funzioni Insecure e Vulnerabili
Basic Dynamic Analysis
Controlla l'analisi dinamica che MobSF esegue. Dovrai navigare tra le diverse visualizzazioni e interagire con esse, ma collegherà diverse classi mentre esegue altre operazioni e preparerà un rapporto una volta completato.
Listing Installed Apps
Usa il comando frida-ps -Uai
per determinare il bundle identifier delle app installate:
Enumerazione di Base & Hooking
Impara come enumerare i componenti dell'applicazione e come hookare metodi e classi con objection:
iOS Hooking With ObjectionStruttura IPA
La struttura di un file IPA è essenzialmente quella di un pacchetto compresso. Rinominando la sua estensione in .zip
, può essere decompresso per rivelarne i contenuti. All'interno di questa struttura, un Bundle rappresenta un'applicazione completamente impacchettata pronta per l'installazione. All'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 firma, garantendo l'integrità di tutti i file nel bundle.Assets.car
: Un archivio compresso che memorizza file di asset come icone.Frameworks/
: Questa cartella ospita le librerie native dell'applicazione, che possono essere sotto forma di file.dylib
o.framework
.PlugIns/
: Questo può includere estensioni all'applicazione, note come file.appex
, anche se non sono sempre presenti. *Core Data
: Viene utilizzato per salvare i dati permanenti della tua applicazione per l'uso offline, per memorizzare dati temporanei e per aggiungere funzionalità di annullamento all'app su un singolo dispositivo. Per sincronizzare i dati su più dispositivi in un singolo account iCloud, Core Data rispecchia automaticamente il tuo schema in un contenitore CloudKit.PkgInfo
: Il filePkgInfo
è un modo alternativo per specificare i codici di tipo e creatore della tua applicazione o bundle.en.lproj, fr.proj, Base.lproj: Sono i pacchetti linguistici che contengono risorse per quelle lingue specifiche e una risorsa predefinita nel caso in cui una lingua non sia supportata.
Sicurezza: La directory
_CodeSignature/
gioca un ruolo critico nella sicurezza dell'app verificando l'integrità di tutti i file inclusi tramite firme digitali.Gestione degli Asset: Il file
Assets.car
utilizza la compressione per gestire in modo efficiente gli asset grafici, cruciale per ottimizzare le prestazioni dell'applicazione e ridurre le sue dimensioni complessive.Frameworks e PlugIns: Queste directory sottolineano la modularità delle applicazioni iOS, consentendo agli sviluppatori di includere librerie di codice riutilizzabili (
Frameworks/
) e di estendere la funzionalità dell'app (PlugIns/
).Localizzazione: La struttura supporta più lingue, facilitando la portata globale dell'applicazione includendo risorse per pacchetti linguistici specifici.
Info.plist
Il Info.plist funge da pietra miliare per le applicazioni iOS, racchiudendo dati di configurazione chiave sotto forma di coppie chiave-valore. Questo file è un requisito non solo per le applicazioni ma anche per le estensioni delle app e i framework inclusi. È 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 Documentazione per Sviluppatori Apple.
Per coloro che desiderano lavorare con questo file in un formato più accessibile, la conversione in XML può essere effettuata senza sforzo utilizzando plutil
su macOS (disponibile nativamente nelle versioni 10.2 e successive) o plistutil
su Linux. I comandi per la conversione sono i seguenti:
Per macOS:
Per Linux:
Tra la miriade di informazioni che il file Info.plist può rivelare, le voci notevoli includono le stringhe di autorizzazione dell'app (UsageDescription
), gli schemi URL personalizzati (CFBundleURLTypes
) e le configurazioni per la Sicurezza del Trasporto dell'App (NSAppTransportSecurity
). Queste voci, insieme ad altre come i tipi di documenti personalizzati esportati/importati (UTExportedTypeDeclarations
/ UTImportedTypeDeclarations
), possono essere facilmente individuate ispezionando il file o utilizzando un semplice comando grep
:
Percorsi dei Dati
Nell'ambiente iOS, le directory sono designate specificamente per applicazioni di sistema e applicazioni 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/
. Queste applicazioni sono assegnate a un identificatore unico noto come UUID a 128 bit, rendendo difficile il compito di localizzare manualmente la cartella di un'app a causa della casualità dei nomi delle directory.
Poiché le applicazioni in iOS devono essere isolate, ogni app avrà anche una cartella all'interno di $HOME/Library/Containers
con CFBundleIdentifier
dell'app come nome della cartella.
Tuttavia, entrambe le cartelle (dati e cartelle contenitore) hanno il file .com.apple.mobile_container_manager.metadata.plist
che collega entrambi i file nella 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 sulla directory per l'app in questione. Di seguito è riportato un esempio di come utilizzare questo comando:
In alternativa, il nome dell'app può essere cercato all'interno di /private/var/containers
utilizzando il comando find
:
Comandi come ps
e lsof
possono essere utilizzati per identificare il processo dell'app e elencare i file aperti, rispettivamente, fornendo informazioni sui percorsi delle directory attive dell'applicazione:
Directory del pacchetto:
AppName.app
Questo è il pacchetto dell'applicazione come visto prima nell'IPA, contiene dati essenziali dell'applicazione, contenuti statici e il binario compilato dell'applicazione.
Questa directory è visibile agli utenti, ma gli utenti non possono scriverci.
Il contenuto in questa directory non è sottoposto a backup.
I contenuti di questa cartella sono utilizzati per validare la firma del codice.
Directory dei dati:
Documents/
Contiene tutti i dati generati dall'utente. L'utente finale dell'applicazione avvia la creazione di questi dati.
Visibile agli utenti e gli utenti possono scriverci.
Il contenuto in questa directory è sottoposto a backup.
L'app può disabilitare i percorsi impostando
NSURLIsExcludedFromBackupKey
.Library/
Contiene tutti i file che non sono specifici per l'utente, come cache, preferenze, cookie e file di configurazione plist.
Le app iOS di solito utilizzano le sottodirectory
Application Support
eCaches
, ma l'app può creare sottodirectory personalizzate.Library/Caches/
Contiene file cache semi-persistenti.
Invisibile agli utenti e gli utenti non possono scriverci.
Il contenuto in questa directory non è sottoposto a backup.
Il sistema operativo può eliminare automaticamente i file di questa directory quando l'app non è in esecuzione e lo spazio di archiviazione è scarso.
Library/Application Support/
Contiene file persistenti necessari per l'esecuzione dell'app.
Invisibile agli utenti e gli utenti non possono scriverci.
Il contenuto in questa directory è sottoposto a backup.
L'app può disabilitare i percorsi impostando
NSURLIsExcludedFromBackupKey
.Library/Preferences/
Utilizzato per memorizzare proprietà che possono persistere anche dopo che un'applicazione è stata riavviata.
Le informazioni vengono salvate, non crittografate, all'interno della sandbox dell'applicazione in un file plist chiamato [BUNDLE_ID].plist.
Tutti i coppie chiave/valore memorizzate utilizzando
NSUserDefaults
possono essere trovate in questo file.tmp/
Utilizza questa directory per scrivere file temporanei che non devono persistere tra i lanci dell'app.
Contiene file cache non persistenti.
Invisibile agli utenti.
Il contenuto in questa directory non è sottoposto a backup.
Il sistema operativo può eliminare automaticamente i file di questa directory quando l'app non è in esecuzione e lo spazio di archiviazione è scarso.
Diamo un'occhiata più da vicino alla directory del pacchetto dell'applicazione iGoat-Swift (.app) all'interno della directory del pacchetto (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
):
Binary Reversing
All'interno della 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
:
Controlla se l'app è crittografata
Vedi se c'è qualche output per:
Disassemblare il binario
Disassemblare la sezione di testo:
Per stampare il segmento Objective-C dell'applicazione di esempio si può usare:
Per ottenere un codice Objective-C più compatto puoi usare class-dump:
Tuttavia, le migliori opzioni per disassemblare il binario sono: Hopper e IDA.
Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti comunitari più avanzati al mondo. Accedi oggi:
Archiviazione Dati
Per saperne di più su come iOS memorizza i dati nel dispositivo, leggi questa pagina:
iOS BasicsI seguenti luoghi per memorizzare informazioni dovrebbero essere controllati subito dopo aver installato l'applicazione, dopo aver verificato tutte le funzionalità dell'applicazione e anche dopo essere disconnessi da un utente e accedere a un altro. L'obiettivo è trovare informazioni sensibili non protette dell'applicazione (password, token), dell'utente attuale e degli utenti precedentemente connessi.
Plist
I file plist 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 aver installato l'app e dopo averla utilizzata intensivamente per vedere se vengono scritti nuovi dati.
Il modo più comune per persistere i dati nei file plist è attraverso l'uso di NSUserDefaults. Questo file plist è salvato all'interno della sandbox dell'app in Library/Preferences/<appBundleID>.plist
La classe NSUserDefaults
fornisce un'interfaccia programmatica per interagire con il sistema predefinito. Il sistema predefinito consente a un'applicazione di personalizzare il proprio comportamento in base alle preferenze dell'utente. I dati salvati da NSUserDefaults
possono essere visualizzati nel pacchetto dell'applicazione. Questa classe memorizza dati in un file plist, ma è destinata ad essere utilizzata con piccole quantità di dati.
Questi dati non possono più essere accessibili direttamente tramite un computer fidato, ma possono essere accessibili eseguendo un backup.
Puoi dumpare le informazioni salvate utilizzando NSUserDefaults
usando ios nsuserdefaults get
di objection.
Per trovare tutti i plist utilizzati dall'applicazione, puoi accedere a /private/var/mobile/Containers/Data/Application/{APPID}
e eseguire:
Per convertire file da XML o formato binario (bplist) a XML, sono disponibili vari metodi a seconda del tuo sistema operativo:
Per gli utenti macOS: Utilizza il comando plutil
. È uno strumento integrato in macOS (10.2+), progettato per questo scopo:
Per gli utenti Linux: Installa prima libplist-utils
, poi usa plistutil
per convertire il tuo file:
All'interno di una sessione Objection: Per analizzare le applicazioni mobili, un comando specifico consente di convertire i file plist direttamente:
Core Data
Core Data
è un framework per gestire il livello del modello degli oggetti nella tua applicazione. Core Data può utilizzare SQLite come suo archivio persistente, ma il framework stesso non è un database.
CoreData non cripta i suoi dati per impostazione predefinita. Tuttavia, è possibile aggiungere uno strato di crittografia aggiuntivo a CoreData. Vedi il GitHub Repo per ulteriori dettagli.
Puoi trovare le informazioni di SQLite Core Data di un'applicazione nel percorso /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
Se riesci ad aprire SQLite e accedere a informazioni sensibili, allora hai trovato una configurazione errata.
YapDatabase
YapDatabase è un archivio chiave/valore costruito su SQLite. Poiché i database Yap sono database sqlite, puoi trovarli utilizzando il comando proposto nella sezione precedente.
Altri Database SQLite
È comune per le applicazioni creare il proprio database sqlite. Potrebbero memorizzare dati sensibili su di essi e lasciarli non crittografati. Pertanto, è sempre interessante controllare ogni database all'interno della directory delle applicazioni. Pertanto, vai alla directory dell'applicazione dove i dati sono salvati (/private/var/mobile/Containers/Data/Application/{APPID}
)
Firebase Real-Time Databases
Gli sviluppatori possono memorizzare e sincronizzare i dati all'interno di un database NoSQL ospitato nel cloud 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 i database Firebase mal configurati qui:
Firebase DatabaseRealm databases
Realm Objective-C e Realm Swift offrono un'alternativa potente per la memorizzazione dei dati, non fornita da Apple. Per impostazione predefinita, memorizzano i dati non crittografati, con la crittografia disponibile tramite configurazione specifica.
I database si trovano in: /private/var/mobile/Containers/Data/Application/{APPID}
. Per esplorare questi file, si possono utilizzare comandi come:
Per visualizzare questi file di database, si consiglia lo strumento Realm Studio.
Per implementare la crittografia all'interno di un database Realm, è possibile utilizzare il seguente frammento di codice:
Couchbase Lite Databases
Couchbase Lite è descritto come un motore di database leggero e integrato che segue l'approccio orientato ai documenti (NoSQL). Progettato per essere nativo su iOS e macOS, offre la possibilità di sincronizzare i dati senza soluzione di continuità.
Per identificare potenziali database Couchbase su un dispositivo, la seguente directory dovrebbe essere ispezionata:
Cookies
iOS memorizza i cookie delle app in Library/Cookies/cookies.binarycookies
all'interno della cartella di ciascuna app. Tuttavia, a volte gli sviluppatori decidono di salvarli nel keychain poiché il file dei cookie può essere accessibile nei backup.
Per ispezionare il file dei cookie puoi usare questo script python o usare ios cookies get
di objection.
Puoi anche usare objection per convertire questi file in un formato JSON e ispezionare i dati.
Cache
Per impostazione predefinita, NSURLSession memorizza i dati, come richieste e risposte HTTP nel database Cache.db. Questo database può contenere dati sensibili, se token, nomi utente o altre informazioni sensibili sono stati memorizzati nella cache. Per trovare le informazioni memorizzate nella cache, apri la directory dei dati dell'app (/var/mobile/Containers/Data/Application/<UUID>
) e vai a /Library/Caches/<Bundle Identifier>
. La cache di WebKit è anche 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, poiché potrebbe contenere informazioni sensibili nella richiesta o nella risposta. La seguente lista mostra diversi modi per raggiungere questo obiettivo:
È consigliato rimuovere le risposte memorizzate nella 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. 2. Se non hai bisogno di utilizzare il vantaggio dei cookie, sarebbe consigliato utilizzare semplicemente la proprietà di configurazione .ephemeral di URLSession, che disabiliterà il salvataggio dei cookie e delle cache.
Un oggetto di configurazione della sessione effimera è simile a una configurazione della sessione predefinita (vedi predefinito), tranne per il fatto che l'oggetto di sessione corrispondente non memorizza cache, archivi di credenziali o dati relativi alla sessione su disco. Invece, i dati relativi alla sessione sono memorizzati nella RAM. L'unica volta in cui una sessione effimera scrive dati su disco è quando le dici di scrivere il contenuto di un URL in un file.
3. La cache può essere disabilitata impostando la Politica di Cache su .notAllowed. Disabiliterà la memorizzazione della cache in qualsiasi modo, sia in memoria che su disco.
Snapshots
Ogni volta che premi il pulsante home, iOS prende uno snapshot dello schermo corrente per poter effettuare la transizione all'applicazione in modo molto più fluido. Tuttavia, se sono presenti dati sensibili nello schermo corrente, verranno salvati nell'immagine (che persiste attraverso riavvii). Questi sono gli snapshot a cui puoi accedere anche facendo doppio tap sulla schermata home per passare tra le app.
A meno che l'iPhone non sia jailbroken, l'attaccante deve avere accesso al dispositivo sbloccato per vedere questi screenshot. Per impostazione predefinita, l'ultimo snapshot è memorizzato nel sandbox dell'applicazione nella cartella Library/Caches/Snapshots/
o Library/SplashBoard/Snapshots
(i computer fidati non possono accedere al filesystem da iOX 7.0).
Un modo per prevenire questo comportamento indesiderato è mettere uno schermo vuoto o rimuovere i dati sensibili prima di prendere lo snapshot utilizzando la funzione ApplicationDidEnterBackground()
.
Di seguito è riportato un esempio di metodo di rimedio che imposterà uno screenshot predefinito.
Swift:
Obiettivo-C:
Questo imposta l'immagine di sfondo su overlayImage.png
ogni volta che l'applicazione viene messa in background. Previene le perdite di dati sensibili perché overlayImage.png
sovrascriverà sempre la vista corrente.
Keychain
Per accedere e gestire il keychain iOS, 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, bypassando la necessità di NSUserDefaults o altri wrapper. Per memorizzare le credenziali dopo il login, viene utilizzato il seguente codice Swift:
Per estrarre queste credenziali memorizzate, viene utilizzato il comando di Objection ios nsurlcredentialstorage dump
.
Tastiere Personalizzate e Cache della Tastiera
Con iOS 8.0 e versioni successive, gli utenti possono installare estensioni di tastiere personalizzate, gestibili sotto Impostazioni > Generale > Tastiera > Tastiere. Sebbene queste tastiere offrano funzionalità estese, comportano un rischio di registrazione dei tasti e trasmissione dei dati a server esterni, anche se gli utenti vengono avvisati riguardo alle tastiere che richiedono accesso alla rete. Le app possono e dovrebbero limitare l'uso di tastiere personalizzate per l'inserimento di informazioni sensibili.
Raccomandazioni di Sicurezza:
Si consiglia di disabilitare le tastiere di terze parti per una maggiore sicurezza.
Fai attenzione alle funzionalità di correzione automatica 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. Si raccomanda di ripristinare il dizionario della tastiera tramite Impostazioni > Generale > Ripristina > Ripristina Dizionario Tastiera per cancellare i dati memorizzati.L'intercettazione del traffico di rete può rivelare se una tastiera personalizzata sta trasmettendo i tasti in remoto.
Prevenire la Cache dei Campi di Testo
Il protocollo UITextInputTraits offre proprietà per gestire la correzione automatica e l'inserimento di testo sicuro, essenziali per prevenire la memorizzazione di informazioni sensibili. Ad esempio, disabilitare la correzione automatica e abilitare l'inserimento di testo sicuro può essere ottenuto con:
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
.
Logs
Il debug del codice spesso comporta l'uso di logging. C'è un rischio coinvolto poiché i log possono contenere informazioni sensibili. In precedenza, in iOS 6 e versioni precedenti, i log erano accessibili a tutte le app, ponendo un rischio di perdita di dati sensibili. Ora, le applicazioni sono limitate ad accedere solo ai propri log.
Nonostante queste restrizioni, un attaccante con accesso fisico a un dispositivo sbloccato può ancora sfruttare questa situazione collegando il dispositivo a un computer e leggendo i log. È importante notare che i log rimangono sul disco anche dopo la disinstallazione dell'app.
Per mitigare i rischi, si consiglia di interagire a fondo con l'app, esplorando tutte le sue funzionalità e input per garantire che nessuna informazione sensibile venga registrata involontariamente.
Quando si esamina il codice sorgente dell'app per potenziali perdite, cercare sia dichiarazioni di logging predefinite che personalizzate utilizzando parole chiave come NSLog
, NSAssert
, NSCAssert
, fprintf
per funzioni integrate, e qualsiasi menzione di Logging
o Logfile
per implementazioni personalizzate.
Monitoring System Logs
Le app registrano vari pezzi di informazione che possono essere sensibili. Per monitorare questi log, strumenti e comandi come:
sono utili. Inoltre, Xcode offre un modo per raccogliere i log della console:
Apri Xcode.
Collega il dispositivo iOS.
Naviga su Finestra -> Dispositivi e Simulatori.
Seleziona il tuo dispositivo.
Attiva il problema che stai investigando.
Usa il pulsante Apri Console per visualizzare i log in una nuova finestra.
Per un logging più avanzato, collegarsi alla shell del dispositivo e utilizzare socat può fornire un monitoraggio dei log in tempo reale:
Seguito da comandi per osservare le attività di log, che possono essere inestimabili per diagnosticare problemi o identificare potenziali perdite di dati nei log.
Usa Trickest per costruire e automatizzare flussi di lavoro facilmente, alimentati dagli strumenti comunitari più avanzati al mondo. Accedi oggi:
Backup
Le funzionalità di auto-backup sono integrate in iOS, facilitando la creazione di copie dei dati del dispositivo tramite iTunes (fino a macOS Catalina), Finder (da macOS Catalina in poi) o iCloud. Questi backup comprendono quasi tutti i dati del dispositivo, escludendo elementi altamente sensibili come i dettagli di Apple Pay e le configurazioni di Touch ID.
Rischi di Sicurezza
L'inclusione di app installate e dei loro dati nei backup solleva la questione della potenziale perdita di dati e il rischio che le modifiche ai backup possano alterare la funzionalità dell'app. Si consiglia di non memorizzare informazioni sensibili in testo semplice all'interno della directory di qualsiasi 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 specifici dai backup utilizzando NSURL setResourceValue:forKey:error:
con NSURLIsExcludedFromBackupKey
. Questa pratica è cruciale per proteggere i dati sensibili dall'essere inclusi nei backup.
Testare per Vulnerabilità
Per valutare la sicurezza del backup di un'app, inizia creando un backup utilizzando Finder, quindi localizzalo seguendo le indicazioni della documentazione ufficiale di Apple. Analizza il backup per dati sensibili o configurazioni che potrebbero essere modificate per influenzare il comportamento dell'app.
Le informazioni sensibili possono essere cercate utilizzando strumenti da riga di comando o applicazioni come iMazing. Per i backup crittografati, la presenza di crittografia può essere confermata controllando la chiave "IsEncrypted" nel file "Manifest.plist" alla radice del backup.
Per gestire i backup crittografati, gli script Python disponibili nel repo GitHub di DinoSec, come backup_tool.py e backup_passwd.py, possono essere utili, sebbene possano richiedere aggiustamenti per la compatibilità con le ultime versioni di iTunes/Finder. Il tool iOSbackup è un'altra opzione per accedere ai file all'interno dei backup protetti da password.
Modificare il Comportamento dell'App
Un esempio di alterazione del comportamento dell'app attraverso modifiche al backup è dimostrato nell'app del portafoglio bitcoin Bither, dove il PIN di blocco dell'interfaccia utente è memorizzato in net.bither.plist
sotto la chiave pin_code. Rimuovendo questa chiave dal plist e ripristinando il backup si rimuove il requisito del PIN, fornendo accesso illimitato.
Riepilogo sui Test di Memoria per Dati Sensibili
Quando si tratta di informazioni sensibili memorizzate nella memoria di un'applicazione, è fondamentale limitare il tempo di esposizione di questi dati. Ci sono due approcci principali per investigare il contenuto della memoria: creare un dump di memoria e analizzare la memoria in tempo reale. Entrambi i metodi presentano le loro sfide, inclusa la possibilità di perdere dati critici durante il processo di dump o analisi.
Recuperare e Analizzare un Dump di Memoria
Per dispositivi jailbroken e non jailbroken, strumenti come objection e Fridump consentono di eseguire il dump della memoria del processo di un'app. Una volta eseguito il dump, l'analisi di questi dati richiede vari strumenti, a seconda della natura delle informazioni che stai cercando.
Per estrarre stringhe da un dump di memoria, possono essere utilizzati comandi come strings
o rabin2 -zz
:
Per un'analisi più dettagliata, inclusa la ricerca di specifici tipi di dati o modelli, radare2 offre ampie capacità di ricerca:
Analisi della Memoria a Runtime
r2frida offre un'alternativa potente per ispezionare la memoria di un'app in tempo reale, senza la necessità di un dump di memoria. Questo strumento consente l'esecuzione di comandi di ricerca direttamente sulla memoria dell'applicazione in esecuzione:
Criptografia Rovinata
Processi di Gestione delle Chiavi Scadenti
Alcuni sviluppatori salvano dati sensibili nello storage locale e li crittografano con una chiave hardcoded/predicibile nel codice. Questo non dovrebbe essere fatto poiché un po' di reverse engineering potrebbe consentire agli attaccanti di estrarre le informazioni riservate.
Uso di Algoritmi Insicuri e/o Obsoleti
Gli sviluppatori non dovrebbero utilizzare algoritmi obsoleti per eseguire controlli di autorizzazione, memorizzare o inviare dati. Alcuni di questi algoritmi sono: RC4, MD4, MD5, SHA1... Se i hash vengono utilizzati per memorizzare le password, ad esempio, dovrebbero essere utilizzati hash resistenti a brute-force con sale.
Controllo
I principali controlli da eseguire sono per verificare se puoi trovare password/segreti hardcoded nel codice, o se sono predicibili, e se il codice sta utilizzando qualche tipo di algoritmi di crittografia debole.
È interessante sapere che puoi monitorare alcune librerie crypto automaticamente utilizzando objection con:
Per maggiori informazioni sulle API e librerie crittografiche iOS, accedi a https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography
Autenticazione Locale
L'autenticazione locale gioca un ruolo cruciale, specialmente quando si tratta di proteggere l'accesso a un endpoint remoto attraverso metodi crittografici. L'essenza qui è che senza una corretta implementazione, i meccanismi di autenticazione locale possono essere elusi.
Il framework di Autenticazione Locale di Apple e il keychain forniscono API robuste per consentire ai sviluppatori di facilitare i dialoghi di autenticazione degli utenti e gestire in modo sicuro i dati segreti, rispettivamente. Il Secure Enclave protegge l'ID delle impronte digitali 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 API:
LocalAuthentication.framework
per l'autenticazione utente di alto livello senza accesso ai dati biometrici.Security.framework
per l'accesso ai servizi di keychain di basso livello, proteggendo i dati segreti con autenticazione biometrica. Vari wrapper open-source semplificano l'accesso al keychain.
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 (riferirsi a Don't touch me that way, di David Lindner et al).
Implementazione dell'Autenticazione Locale
Per richiedere agli utenti l'autenticazione, gli sviluppatori dovrebbero utilizzare il metodo evaluatePolicy
all'interno della classe LAContext
, scegliendo tra:
deviceOwnerAuthentication
: Richiede Touch ID o codice di accesso del dispositivo, fallendo se nessuno dei due è abilitato.deviceOwnerAuthenticationWithBiometrics
: Richiede esclusivamente Touch ID.
Un'autenticazione riuscita è indicata da un valore di ritorno booleano da evaluatePolicy
, evidenziando un potenziale difetto di sicurezza.
Autenticazione Locale utilizzando il Keychain
Implementare l'autenticazione locale nelle app iOS comporta l'uso delle API del keychain per memorizzare in modo sicuro dati segreti come i token di autenticazione. Questo processo garantisce che i dati possano essere accessibili solo dall'utente, utilizzando il proprio codice di accesso 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 con successo tramite Touch ID o codice di accesso del dispositivo. Questa funzionalità è cruciale per migliorare la sicurezza.
Di seguito sono riportati esempi di codice in Swift e Objective-C che dimostrano come salvare e recuperare una stringa dal/al keychain, sfruttando queste funzionalità di sicurezza. Gli esempi mostrano specificamente come impostare il controllo degli accessi 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 codice di accesso del dispositivo.
Ora possiamo richiedere l'elemento salvato dal portachiavi. I servizi del portachiavi presenteranno la finestra di dialogo di autenticazione all'utente e restituiranno i dati o nil a seconda che sia stata fornita o meno un'impronta digitale adeguata.
Rilevamento
L'uso di framework in un'app può essere rilevato analizzando l'elenco delle librerie dinamiche condivise del binario dell'app. Questo può essere fatto utilizzando otool
:
Se LocalAuthentication.framework
è utilizzato in un'app, l'output conterrà entrambe le seguenti righe (ricorda che LocalAuthentication.framework
utilizza Security.framework
sotto il cofano):
Se viene utilizzato Security.framework
, verrà mostrato solo il secondo.
Bypass del Framework di Autenticazione Locale
Objection
Attraverso il Bypass Biometrics di Objection, situato in questa pagina GitHub, è disponibile una tecnica per superare il meccanismo di LocalAuthentication. Il nucleo di questo approccio implica l'uso di Frida per manipolare la funzione evaluatePolicy
, garantendo che restituisca costantemente un risultato True
, indipendentemente dal reale successo dell'autenticazione. Questo è particolarmente utile per eludere processi di autenticazione biometrica difettosi.
Per attivare questo bypass, viene impiegato il seguente comando:
Questo comando avvia una sequenza in cui Objection registra un'attività che altera effettivamente l'esito del controllo evaluatePolicy
a True
.
Frida
Un esempio di utilizzo di evaluatePolicy
dall'applicazione DVIA-v2:
Per ottenere il bypass dell'Autenticazione Locale, è stato scritto uno script Frida. Questo script mira al controllo evaluatePolicy, intercettando il suo callback per garantire 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. Cambia il risultato del callback per indicare sempre il successo.
Per iniettare lo script Frida e bypassare l'autenticazione biometrica, viene utilizzato il seguente comando:
Esposizione di Funzionalità Sensibili Tramite IPC
Gestori URI Personalizzati / Deeplinks / Schemi Personalizzati
iOS Custom URI Handlers / Deeplinks / Custom SchemesLink Universali
iOS Universal LinksCondivisione UIActivity
iOS UIActivity SharingUIPasteboard
iOS UIPasteboardEstensioni App
iOS App ExtensionsWebViews
iOS WebViewsSerializzazione e Codifica
iOS Serialisation and EncodingComunicazione di Rete
È importante verificare che non ci sia comunicazione senza crittografia e anche che l'applicazione stia correttamente validando il certificato TLS del server. Per controllare questi tipi di problemi puoi utilizzare un proxy come Burp:
iOS Burp Suite ConfigurationControllo del Nome Host
Un problema comune nella validazione del certificato TLS è controllare che il certificato sia stato firmato da una CA fidata, ma non controllare se il nome host del certificato è il nome host a cui si sta accedendo. Per controllare questo problema utilizzando Burp, dopo aver fidato la CA di Burp nell'iPhone, puoi creare un nuovo certificato con Burp per un nome host diverso e usarlo. Se l'applicazione continua a funzionare, allora qualcosa è vulnerabile.
Certificato Pinning
Se un'applicazione utilizza correttamente il SSL Pinning, allora l'applicazione funzionerà solo se il certificato è quello previsto. Quando si testa un'applicazione questo potrebbe essere un problema poiché Burp servirà il proprio certificato. Per bypassare questa protezione all'interno di 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 sistemaLe applicazioni installate dall'utente dall'App Store si trovano all'interno di
/User/Applications
E il
/User/Library
contiene i dati salvati dalle applicazioni a livello utentePuoi accedere a
/User/Library/Notes/notes.sqlite
per leggere le note salvate all'interno dell'applicazione.All'interno della cartella di un'applicazione installata (
/User/Applications/<APP ID>/
) puoi trovare alcuni file interessanti:iTunesArtwork
: L'icona utilizzata dall'appiTunesMetadata.plist
: Info dell'app utilizzate nell'App Store/Library/*
: Contiene le preferenze e la cache. In/Library/Cache/Snapshots/*
puoi trovare lo snapshot eseguito sull'applicazione prima di inviarla in background.
Hot Patching/Aggiornamento Forzato
Gli sviluppatori possono patchare tutte le installazioni della loro app istantaneamente senza dover reinviare l'applicazione all'App Store e aspettare che venga approvata. A questo scopo si utilizza solitamente JSPatch. Ma ci sono anche altre opzioni come Siren e react-native-appstore-version-checker. Questo è un meccanismo pericoloso che potrebbe essere abusato da SDK di terze parti malevoli, quindi è consigliato controllare quale metodo viene utilizzato per l'aggiornamento automatico (se presente) e testarlo. Potresti provare a scaricare una versione precedente dell'app a questo scopo.
Terze Parti
Una sfida significativa con gli SDK di terze parti è la mancanza di controllo granulare sulle loro funzionalità. Gli sviluppatori si trovano di fronte a una scelta: integrare l'SDK e accettare tutte le sue caratteristiche, comprese le potenziali vulnerabilità di sicurezza e le preoccupazioni sulla privacy, oppure rinunciare completamente ai suoi benefici. Spesso, gli sviluppatori non sono in grado di patchare le vulnerabilità all'interno di questi SDK. Inoltre, man mano che gli SDK guadagnano fiducia all'interno della comunità, alcuni potrebbero iniziare a contenere malware.
I servizi forniti dagli SDK di terze parti possono includere il tracciamento del comportamento degli utenti, la visualizzazione di pubblicità o miglioramenti dell'esperienza utente. Tuttavia, questo 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 i servizi di terze parti a ciò che è necessario e garantire che nessun dato sensibile venga esposto.
L'implementazione di servizi di terze parti di solito avviene in due forme: una libreria autonoma o un SDK completo. Per proteggere la privacy degli utenti, qualsiasi dato condiviso con questi servizi dovrebbe essere anonymizzato per prevenire la divulgazione di Informazioni Personali Identificabili (PII).
Per identificare le librerie utilizzate da un'applicazione, il comando otool
può essere impiegato. Questo strumento dovrebbe essere eseguito contro l'applicazione e ciascuna libreria condivisa che utilizza per scoprire librerie aggiuntive.
Riferimenti e Altre Risorse
OWASP iGoat https://github.com/OWASP/igoat <<< Versione Objective-C https://github.com/OWASP/iGoat-Swift <<< Versione Swift
Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti della comunità più avanzati al mondo. Accedi Oggi:
Last updated