iOS Pentesting
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Fundamentos de iOS
Entorno de pruebas
En esta página puedes encontrar información sobre el iOS simulator, emulators y jailbreaking:
Análisis inicial
Operaciones básicas de pruebas en iOS
Durante las pruebas se van a sugerir varias operaciones (conectarse al dispositivo, leer/escribir/subir/descargar archivos, usar algunas herramientas…). Por lo tanto, si no sabes cómo realizar alguna de estas acciones, por favor, comienza leyendo la página:
Tip
Para los siguientes pasos la app debe estar instalada en el dispositivo y debe haberse obtenido previamente el archivo IPA de la aplicación.
Lee la página Operaciones básicas de pruebas en iOS para aprender cómo hacerlo.
Análisis estático básico
Algunos decompiladores interesantes de archivos IPA para iOS:
Se recomienda usar la herramienta MobSF para realizar un análisis estático automático del archivo IPA.
Identificación de protecciones presentes en el binario:
- PIE (Position Independent Executable): Cuando está habilitado, la aplicación se carga en una dirección de memoria aleatoria cada vez que se inicia, lo que dificulta predecir su dirección de memoria inicial.
otool -hv <app-binary> | grep PIE # It should include the PIE flag
- Stack Canaries: Para validar la integridad de la pila, se coloca un valor ‘canary’ en la pila antes de llamar a una función y se valida de nuevo una vez que la función termina.
otool -I -v <app-binary> | grep stack_chk # It should include the symbols: stack_chk_guard and stack_chk_fail
- ARC (Automatic Reference Counting): Para prevenir fallos comunes de corrupción de memoria
otool -I -v <app-binary> | grep objc_release # It should include the _objc_release symbol
- Encrypted Binary: El binario debe estar cifrado
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # The cryptid should be 1
Identificación de funciones sensibles/inseguras
- Algoritmos de hashing débiles
# 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"
- Funciones aleatorias inseguras
# 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"
- Función ‘Malloc’ insegura
# On the iOS device
otool -Iv <app> | grep -w "_malloc"
# On linux
grep -iER "_malloc"
- Funciones inseguras y vulnerables
# 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"
Métodos comunes de detección de jailbreak
- File System Checks: Busca la presencia de archivos y directorios comunes de jailbreak, como
/Applications/Cydia.appo/Library/MobileSubstrate/MobileSubstrate.dylib. - Sandbox Violations: Intenta acceder a áreas restringidas del sistema de archivos, lo que debería estar bloqueado en dispositivos no-jailbroken.
- API Checks: Comprueba si es posible usar llamadas prohibidas como
fork()para crear un proceso hijo osystem()para ver si /bin/sh existe. - Process Checks: Monitorea la presencia de procesos conocidos relacionados con jailbreak, como
Cydia,Substrateossh. - Kernel Exploits: Comprueba la presencia de exploits del kernel que se usan comúnmente en jailbreaks.
- Environment Variables: Inspecciona variables de entorno en busca de señales de jailbreak, como
DYLD_INSERT_LIBRARIES. - Libraries Check: Revisa las libs que están cargadas en el proceso de la app.
- Check schemes: Como
canOpenURL(URL(string: "cydia://")).
Métodos comunes de detección anti-debugging
- Check for Debugger Presence: Usa
sysctlu otros métodos para comprobar si hay un debugger adjunto. - Anti-Debugging APIs: Busca llamadas a APIs anti-debugging como
ptraceoSIGSTOP, por ejemploptrace(PT_DENY_ATTACH, 0, 0, 0). - Timing Checks: Mide el tiempo que tardan ciertas operaciones y busca discrepancias que puedan indicar depuración.
- Memory Checks: Inspecciona la memoria en busca de artefactos o modificaciones conocidas de debuggers.
- Environment Variables: Comprueba variables de entorno que puedan indicar una sesión de depuración.
- Mach Ports: Detecta si los mach exception ports están siendo usados por debuggers.
Análisis dinámico básico
Revisa el análisis dinámico que realiza MobSF. Necesitarás navegar por las distintas vistas e interactuar con ellas; hará hooking de varias clases, entre otras cosas, y preparará un informe cuando termines.
Listado de apps instaladas
Usa el comando frida-ps -Uai para determinar el bundle identifier de las apps instaladas:
$ 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
Aprende cómo enumerate the components of the application y cómo fácilmente hook methods and classes con objection:
IPA Structure
La estructura de un IPA file es esencialmente la de un zipped package. Renombrando su extensión a .zip, puede ser decompressed para revelar su contenido. Dentro de esta estructura, un Bundle representa una aplicación completamente empaquetada lista para la instalación. En su interior encontrarás un directorio llamado <NAME>.app, que encapsula los recursos de la aplicación.
Info.plist: Este archivo contiene detalles de configuración específicos de la aplicación._CodeSignature/: Este directorio incluye un archivo plist que contiene una firma, asegurando la integridad de todos los archivos en el bundle.Assets.car: Un archivo comprimido que almacena recursos como iconos.Frameworks/: Esta carpeta alberga las librerías nativas de la aplicación, que pueden estar en forma de archivos.dylibo.framework.PlugIns/: Puede incluir extensiones de la aplicación, conocidas como archivos.appex, aunque no siempre están presentes. *Core Data: Se utiliza para guardar los datos permanentes de tu aplicación para uso offline, para cachear datos temporales y para añadir funcionalidad de undo en tu app en un solo dispositivo. Para sincronizar datos entre múltiples dispositivos en una misma cuenta de iCloud, Core Data refleja automáticamente tu esquema en un contenedor CloudKit.PkgInfo: El archivoPkgInfoes una forma alternativa de especificar los códigos de tipo y creador de tu aplicación o bundle.- en.lproj, fr.proj, Base.lproj: Son los paquetes de idioma que contienen recursos para esos idiomas específicos, y un recurso por defecto en caso de que un idioma no esté soportado.
- Security: El directorio
_CodeSignature/juega un papel crítico en la seguridad de la app al verificar la integridad de todos los archivos incluidos mediante firmas digitales. - Asset Management: El archivo
Assets.carutiliza compresión para gestionar eficientemente los assets gráficos, crucial para optimizar el rendimiento de la aplicación y reducir su tamaño total. - Frameworks and PlugIns: Estos directorios subrayan la modularidad de las aplicaciones iOS, permitiendo a los desarrolladores incluir librerías de código reutilizable (
Frameworks/) y ampliar la funcionalidad de la app (PlugIns/). - Localization: La estructura soporta múltiples idiomas, facilitando el alcance global de la aplicación al incluir recursos para packs de idioma específicos.
Info.plist
El Info.plist sirve como piedra angular para las aplicaciones iOS, encapsulando datos de configuración clave en forma de pares key-value. Este archivo es obligatorio no solo para aplicaciones, sino también para las extensiones de app y frameworks incluidos. Está estructurado en XML o en formato binario y contiene información crítica que va desde permisos de la app hasta configuraciones de seguridad. Para una exploración detallada de las keys disponibles, se puede consultar la Apple Developer Documentation.
Para quienes quieran trabajar con este archivo en un formato más accesible, la conversión a XML puede lograrse fácilmente usando plutil en macOS (disponible nativamente en las versiones 10.2 y posteriores) o plistutil en Linux. Los comandos para la conversión son los siguientes:
- Para macOS:
$ plutil -convert xml1 Info.plist
- Para Linux:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Entre la miríada de información que el archivo Info.plist puede revelar, las entradas más relevantes incluyen cadenas de permisos de la app (UsageDescription), esquemas de URL personalizados (CFBundleURLTypes) y configuraciones para App Transport Security (NSAppTransportSecurity). Estas entradas, junto con otras como tipos de documento personalizados exportados/importados (UTExportedTypeDeclarations / UTImportedTypeDeclarations), pueden localizarse fácilmente inspeccionando el archivo o usando un simple comando grep:
$ grep -i <keyword> Info.plist
Rutas de datos
En el entorno iOS, los directorios están designados específicamente para aplicaciones del sistema y aplicaciones instaladas por el usuario. Las aplicaciones del sistema residen en el directorio /Applications, mientras que las apps instaladas por el usuario se colocan bajo /var/mobile/containers/Data/Application/. A estas aplicaciones se les asigna un identificador único conocido como UUID de 128 bits, lo que hace que la tarea de localizar manualmente la carpeta de una app sea difícil debido a la aleatoriedad de los nombres de directorio.
Warning
Como las aplicaciones en iOS deben estar sandboxed, cada app también tendrá una carpeta dentro de
$HOME/Library/Containerscon elCFBundleIdentifierde la app como nombre de carpeta.Sin embargo, ambas carpetas (data & container folders) tienen el archivo
.com.apple.mobile_container_manager.metadata.plistque enlaza ambos archivos en la claveMCMetadataIdentifier).
Para facilitar el descubrimiento del directorio de instalación de una app instalada por el usuario, la herramienta objection proporciona un comando útil, env. Este comando revela información detallada de directorios para la app en cuestión. A continuación hay un ejemplo de cómo usar este 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
Alternativamente, el nombre de la app puede buscarse dentro de /private/var/containers usando el comando find:
find /private/var/containers -name "Progname*"
Comandos como ps y lsof también pueden utilizarse para identificar el proceso de la app y listar archivos abiertos, respectivamente, proporcionando información sobre las rutas de directorio activas de la aplicación:
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1
Directorio Bundle:
- AppName.app
- Este es el Application Bundle como se vio antes en el IPA, contiene datos esenciales de la aplicación, contenido estático así como el binario compilado de la aplicación.
- Este directorio es visible para los usuarios, pero los usuarios no pueden escribir en él.
- El contenido de este directorio no se respalda.
- El contenido de esta carpeta se usa para validar la firma de código.
Directorio de datos:
- Documents/
- Contiene todos los datos generados por el usuario. El usuario final de la aplicación inicia la creación de estos datos.
- Visible para los usuarios y los usuarios pueden escribir en él.
- El contenido de este directorio se respalda.
- La app puede excluir rutas estableciendo
NSURLIsExcludedFromBackupKey. - Library/
- Contiene todos los archivos que no son específicos del usuario, como caches, preferences, cookies, y archivos de configuración plist.
- Las apps iOS usualmente usan los subdirectorios
Application SupportyCaches, pero la app puede crear subdirectorios personalizados. - Library/Caches/
- Contiene archivos cache semi-persistentes.
- Invisible para los usuarios y los usuarios no pueden escribir en él.
- El contenido de este directorio no se respalda.
- El SO puede borrar automáticamente los archivos de este directorio cuando la app no está en ejecución y el espacio de almacenamiento es escaso.
- Library/Application Support/
- Contiene archivos persistentes necesarios para ejecutar la app.
- Invisible para los usuarios y los usuarios no pueden escribir en él.
- El contenido de este directorio se respalda.
- La app puede excluir rutas estableciendo
NSURLIsExcludedFromBackupKey. - Library/Preferences/
- Se usa para almacenar propiedades que pueden persistir incluso después de reiniciar la aplicación.
- La información se guarda, sin cifrar, dentro del sandbox de la aplicación en un archivo plist llamado [BUNDLE_ID].plist.
- Todos los pares clave/valor almacenados usando
NSUserDefaultspueden encontrarse en este archivo. - tmp/
- Usa este directorio para escribir archivos temporales que no necesitan persistir entre lanzamientos de la app.
- Contiene archivos cache no persistentes.
- Invisible para los usuarios.
- El contenido de este directorio no se respalda.
- El SO puede borrar automáticamente los archivos de este directorio cuando la app no está en ejecución y el espacio de almacenamiento es escaso.
Veamos más de cerca el directorio Application Bundle (.app) de iGoat-Swift dentro del directorio 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 de la carpeta <application-name>.app encontrarás un archivo binario llamado <application-name>. Este es el archivo que será ejecutado. Puedes realizar una inspección básica del binario con la herramienta 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)
[...]
Comprueba si la app está cifrada
Comprueba si hay alguna salida para:
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
Desensamblando el binario
Desensamblar la sección .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
Para imprimir el segmento Objective-C de la aplicación de ejemplo se puede usar:
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
Para obtener un código Objective-C más compacto puedes usar 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;
};
Sin embargo, las mejores opciones para desensamblar el binario son: Hopper and IDA.
Almacenamiento de datos
Para aprender cómo iOS almacena datos en el dispositivo lee esta página:
Warning
Los siguientes lugares para almacenar información deben revisarse inmediatamente después de instalar la aplicación, tras comprobar todas las funcionalidades de la aplicación e incluso después de cerrar sesión de un usuario e iniciar sesión con otro.
El objetivo es encontrar información sensible no protegida de la aplicación (contraseñas, tokens), del usuario actual y de usuarios que hayan iniciado sesión anteriormente.
Plist
plist files son archivos XML estructurados que contienen pares clave-valor. Es una forma de almacenar datos persistentes, por lo que a veces puedes encontrar información sensible en estos archivos. Se recomienda revisar estos archivos después de instalar la app y tras usarla intensivamente para ver si se escribe nueva información.
La forma más común de persistir datos en archivos plist es mediante el uso de NSUserDefaults. Este archivo plist se guarda dentro del sandbox de la app en Library/Preferences/<appBundleID>.plist
La clase NSUserDefaults proporciona una interfaz programática para interactuar con el sistema por defecto. El sistema por defecto permite que una aplicación personalice su comportamiento según las preferencias del usuario. Los datos guardados por NSUserDefaults pueden verse en el bundle de la aplicación. Esta clase almacena datos en un archivo plist, pero está pensada para usarse con pequeñas cantidades de datos.
Estos datos ya no pueden ser accedidos directamente desde un equipo de confianza, pero pueden obtenerse realizando un backup.
Puedes hacer un dump de la información guardada usando NSUserDefaults empleando objection: ios nsuserdefaults get
Para encontrar todos los plist usados por la aplicación puedes acceder a /private/var/mobile/Containers/Data/Application/{APPID} y ejecutar:
find ./ -name "*.plist"
Para convertir archivos en formato XML o binary (bplist) a XML, hay varios métodos disponibles según tu sistema operativo:
Para usuarios de macOS: Utiliza el comando plutil. Es una herramienta integrada en macOS (10.2+), diseñada para este propósito:
$ plutil -convert xml1 Info.plist
Para usuarios de Linux: Instale libplist-utils primero, luego use plistutil para convertir su archivo:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
Dentro de una sesión de Objection: Para analizar aplicaciones móviles, un comando específico permite convertir archivos plist directamente:
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
Core Data
Core Data es un framework para gestionar la capa de modelo de objetos en tu aplicación. Core Data can use SQLite as its persistent store, pero el framework en sí no es una base de datos.
CoreData no cifra sus datos por defecto. Sin embargo, se puede añadir una capa adicional de cifrado a CoreData. Consulta el GitHub Repo para más detalles.
You can find the SQLite Core Data information of an application in the path /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
Si puedes abrir el SQLite y acceder a información sensible, entonces has encontrado una configuración incorrecta.
-(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 es un almacén key/value construido sobre SQLite.
Como las bases de datos Yap son bases de datos SQLite, puedes encontrarlas usando el comando propuesto en la sección anterior.
Other SQLite Databases
Es común que las aplicaciones creen su propia base de datos SQLite. Pueden estar almacenando datos sensibles en ellas y dejarlos sin cifrar. Por lo tanto, siempre es interesante revisar cada base de datos dentro del directorio de la aplicación. Ve al directorio de la aplicación donde se guardan los datos (/private/var/mobile/Containers/Data/Application/{APPID})
find ./ -name "*.sqlite" -or -name "*.db"
Firebase Real-Time Databases
Los desarrolladores pueden almacenar y sincronizar datos dentro de una base de datos NoSQL alojada en la nube a través de Firebase Real-Time Databases. Almacenados en formato JSON, los datos se sincronizan con todos los clientes conectados en tiempo real.
Puedes encontrar cómo comprobar Firebase databases mal configuradas aquí:
Realm databases
Realm Objective-C and Realm Swift ofrecen una alternativa potente para el almacenamiento de datos que no proporciona Apple. Por defecto, almacenan datos sin cifrar, con cifrado disponible mediante una configuración específica.
Las bases de datos están ubicadas en: /private/var/mobile/Containers/Data/Application/{APPID}. Para explorar estos archivos, se pueden utilizar comandos como:
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*"
Para ver estos archivos de base de datos, se recomienda la herramienta Realm Studio.
Para implementar cifrado dentro de una base de datos Realm, se puede usar el siguiente fragmento de código:
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
let config = Realm.Configuration(encryptionKey: getKey())
do {
let realm = try Realm(configuration: config)
// Use the Realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}
Couchbase Lite Bases de datos
Couchbase Lite se describe como un motor de base de datos ligero y embebido que sigue el enfoque orientado a documentos (NoSQL). Diseñado para ser nativo en iOS y macOS, ofrece la capacidad de sincronizar datos de forma transparente.
Para identificar posibles bases de datos Couchbase en un dispositivo, se debe inspeccionar el siguiente directorio:
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
Cookies
iOS almacena las cookies de las aplicaciones en la Library/Cookies/cookies.binarycookies dentro de la carpeta de cada app. Sin embargo, algunos desarrolladores a veces deciden guardarlas en el keychain ya que el mencionado archivo de cookies puede ser accedido en las copias de seguridad.
Para inspeccionar el archivo de cookies puedes usar this python script o usar objection’s ios cookies get.
También puedes usar objection para convertir estos archivos a un formato JSON e inspeccionar los datos.
...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
Por defecto NSURLSession almacena datos, como HTTP requests and responses in the Cache.db database. Esta base de datos puede contener sensitive data, si tokens, usernames u otra información sensible se ha almacenado en caché. Para encontrar la información en caché abre el directorio de datos de la app (/var/mobile/Containers/Data/Application/<UUID>) y ve a /Library/Caches/<Bundle Identifier>. El WebKit cache is also being stored in the Cache.db file. Objection puede abrir e interactuar con la base de datos con el comando sqlite connect Cache.db, ya que es una normal SQLite database.
It is recommended to disable Caching this data, as it may contain sensitive information in the request or response. The following list below shows different ways of achieving this:
- It is recommended to remove Cached responses after logout. This can be done with the provided method by Apple called
removeAllCachedResponsesYou can call this method as follows:
URLCache.shared.removeAllCachedResponses()
This method will remove all cached requests and responses from Cache.db file.
- If you don’t need to use the advantage of cookies it would be recommended to just use the .ephemeral configuration property of URLSession, which will disable saving cookies and Caches.
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.
- Cache can be also disabled by setting the Cache Policy to .notAllowed. It will disable storing Cache in any fashion, either in memory or on disk.
Instantáneas
Cada vez que pulsas el botón Home, iOS toma una snapshot of the current screen para poder realizar la transición a la aplicación de forma más suave. Sin embargo, si hay datos sensibles en la pantalla actual, se guardarán en la imagen (la cual persiste a través de reinicios). Estas son las instantáneas a las que también puedes acceder al pulsar dos veces el botón Home para cambiar entre apps.
A menos que el iPhone tenga jailbreak, el atacante necesita tener acceso al dispositivo desbloqueado para ver estas capturas. Por defecto, la última snapshot se almacena en el sandbox de la aplicación en Library/Caches/Snapshots/ o en la carpeta Library/SplashBoard/Snapshots (los ordenadores de confianza no pueden acceder al sistema de archivos desde iOX 7.0).
Una forma de evitar este comportamiento es mostrar una pantalla en blanco o eliminar los datos sensibles antes de tomar la snapshot usando la función ApplicationDidEnterBackground().
A continuación hay un método de remediación de ejemplo que establecerá una captura predeterminada.
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];
}
Esto establece la imagen de fondo a overlayImage.png cada vez que la aplicación pasa a segundo plano. Evita leaks de datos sensibles porque overlayImage.png siempre sobrescribirá la vista actual.
Keychain
Para acceder y gestionar el keychain de iOS, hay herramientas como Keychain-Dumper disponibles, adecuadas para dispositivos jailbroken. Además, Objection proporciona el comando ios keychain dump para propósitos similares.
Almacenamiento de credenciales
La clase NSURLCredential es ideal para guardar información sensible directamente en el keychain, evitando la necesidad de NSUserDefaults u otros wrappers. Para almacenar credenciales después del login, se usa el siguiente código Swift:
NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
Para extraer estas credenciales almacenadas, se utiliza el comando de Objection ios nsurlcredentialstorage dump.
Teclados personalizados y caché del teclado
A partir de iOS 8.0, los usuarios pueden instalar extensiones de teclado personalizadas, que se gestionan en Ajustes > General > Teclado > Teclados. Aunque estos teclados ofrecen funcionalidad ampliada, suponen un riesgo de keystroke logging y de transmisión de datos a servidores externos; no obstante, los usuarios son avisados sobre teclados que requieren acceso a la red. Las apps pueden, y deben, restringir el uso de teclados personalizados para la introducción de información sensible.
Recomendaciones de seguridad:
- Se recomienda deshabilitar teclados de terceros para mejorar la seguridad.
- Tenga en cuenta las funciones de autocorrección y sugerencias automáticas del teclado por defecto de iOS, que podrían almacenar información sensible en archivos de caché ubicados en
Library/Keyboard/{locale}-dynamic-text.dato/private/var/mobile/Library/Keyboard/dynamic-text.dat. Estos archivos de caché deben revisarse periódicamente en busca de datos sensibles. Se recomienda restablecer el diccionario del teclado vía Ajustes > General > Restablecer > Restablecer diccionario del teclado para borrar los datos en caché. - Interceptar el tráfico de red puede revelar si un teclado personalizado está transmitiendo keystrokes de forma remota.
Prevención del almacenamiento en caché de campos de texto
The UITextInputTraits protocol ofrece propiedades para gestionar la autocorrección y secure text entry, esenciales para prevenir el almacenamiento en caché de información sensible. Por ejemplo, desactivar la autocorrección y activar secure text entry se puede lograr con:
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;
Además, los desarrolladores deben asegurarse de que los campos de texto, especialmente los destinados a introducir información sensible como contraseñas y PINs, desactiven el almacenamiento en caché estableciendo autocorrectionType a UITextAutocorrectionTypeNo y secureTextEntry a YES.
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
Logs
Depurar código a menudo implica el uso de logging. Existe un riesgo involucrado ya que logs pueden contener información sensible. Anteriormente, en iOS 6 y versiones anteriores, los logs eran accesibles para todas las apps, lo que suponía un riesgo de leak de datos sensibles. Ahora, las aplicaciones están restringidas a acceder solo a sus logs.
A pesar de estas restricciones, un attacker con acceso físico a un dispositivo desbloqueado todavía puede explotarlo conectando el dispositivo a un ordenador y leyendo los logs. Es importante tener en cuenta que los logs permanecen en el disco incluso después de la desinstalación de la app.
Para mitigar los riesgos, se aconseja interactuar a fondo con la app, explorando todas sus funcionalidades e entradas para asegurarse de que no se esté registrando información sensible inadvertidamente.
Al revisar el código fuente de la app en busca de posibles leaks, busca tanto declaraciones predefinidas como declaraciones de logging personalizadas usando palabras clave como NSLog, NSAssert, NSCAssert, fprintf para funciones integradas, y cualquier mención de Logging o Logfile para implementaciones personalizadas.
Monitoring System Logs
Las apps registran diversa información que puede ser sensible. Para monitorizar estos logs, herramientas y comandos como:
idevice_id --list # To find the device ID
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
son útiles. Además, Xcode proporciona una forma de recopilar registros de la consola:
- Abre Xcode.
- Conecta el dispositivo iOS.
- Navega a Window -> Devices and Simulators.
- Selecciona tu dispositivo.
- Reproduce el problema que estás investigando.
- Usa el botón Open Console para ver los registros en una nueva ventana.
Para un registro más avanzado, conectarse al shell del dispositivo y usar socat puede proporcionar monitorización de registros en tiempo real:
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
Seguido de comandos para observar las actividades de los logs, lo cual puede ser invaluable para diagnosticar problemas o identificar posibles leak de datos en los registros.
Copias de seguridad
Auto-backup features están integradas en iOS, facilitando la creación de copias de los datos del dispositivo a través de iTunes (hasta macOS Catalina), Finder (a partir de macOS Catalina) o iCloud. Estas copias abarcan casi todos los datos del dispositivo, excluyendo elementos altamente sensibles como los detalles de Apple Pay y las configuraciones de Touch ID.
Riesgos de seguridad
La inclusión de aplicaciones instaladas y sus datos en las copias de seguridad plantea el problema de un posible data leak y el riesgo de que modificaciones en la copia puedan alterar la funcionalidad de la app. Se recomienda no almacenar información sensible en texto plano dentro del directorio de cualquier app o sus subdirectorios para mitigar estos riesgos.
Excluir archivos de las copias de seguridad
Los archivos en Documents/ y Library/Application Support/ se respaldan por defecto. Los desarrolladores pueden excluir archivos o directorios específicos de las copias usando NSURL setResourceValue:forKey:error: con la NSURLIsExcludedFromBackupKey. Esta práctica es crucial para proteger datos sensibles de ser incluidos en las copias de seguridad.
Pruebas para detectar vulnerabilidades
Para evaluar la seguridad de las copias de una app, comienza por crear una copia usando Finder, y luego ubícala siguiendo la guía de Apple’s official documentation. Analiza la copia en busca de datos sensibles o configuraciones que podrían alterarse y afectar el comportamiento de la app.
La información sensible puede buscarse usando herramientas de línea de comandos o aplicaciones como iMazing. Para backups cifrados, la presencia de cifrado puede confirmarse comprobando la clave “IsEncrypted” en el archivo “Manifest.plist” en la raíz de la copia.
<?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>
Para manejar backups cifrados, los scripts Python disponibles en DinoSec’s GitHub repo, como backup_tool.py y backup_passwd.py, pueden ser útiles, aunque posiblemente requieran ajustes para ser compatibles con las versiones más recientes de iTunes/Finder. La herramienta iOSbackup es otra opción para acceder a archivos dentro de backups protegidos con contraseña.
Modifying App Behavior
Un ejemplo de alterar el comportamiento de una app mediante modificaciones del backup se demuestra en la Bither bitcoin wallet app, donde el PIN de bloqueo de la UI se guarda dentro de net.bither.plist bajo la clave pin_code. Eliminar esta clave del plist y restaurar el backup quita el requisito del PIN, proporcionando acceso sin restricciones.
Summary on Memory Testing for Sensitive Data
Al tratar con información sensible almacenada en la memoria de una aplicación, es crucial limitar el tiempo de exposición de esos datos. Hay dos enfoques principales para investigar el contenido de la memoria: crear un volcado de memoria y analizar la memoria en tiempo real. Ambos métodos tienen sus desafíos, incluyendo la posibilidad de perder datos críticos durante el proceso de volcado o análisis.
Retrieving and Analyzing a Memory Dump
Tanto para dispositivos jailbroken como no jailbroken, herramientas como objection y Fridump permiten volcar la memoria del proceso de una app. Una vez volcada, analizar estos datos requiere varias herramientas, dependiendo de la naturaleza de la información que se busque.
Para extraer strings de un volcado de memoria, se pueden usar comandos como strings o rabin2 -zz:
# Extracting strings using strings command
$ strings memory > strings.txt
# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt
Para un análisis más detallado, incluyendo la búsqueda de tipos de datos o patrones específicos, radare2 ofrece amplias capacidades de búsqueda:
$ r2 <name_of_your_dump_file>
[0x00000000]> /?
...
Análisis de memoria en tiempo de ejecución
r2frida proporciona una alternativa potente para inspeccionar la memoria de una aplicación en tiempo real, sin necesitar un memory dump. Esta herramienta permite la ejecución de comandos de búsqueda directamente en la memoria de la aplicación en ejecución:
$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>
Criptografía rota
Procesos deficientes de gestión de claves
Algunos desarrolladores guardan datos sensibles en el almacenamiento local y los cifran con una clave hardcoded/predictable en el código. Esto no debería hacerse, ya que cierto reversing podría permitir a los atacantes extraer la información confidencial.
Uso de algoritmos inseguros y/o obsoletos
Los desarrolladores no deberían usar deprecated algorithms para realizar checks de autorización, store o send datos. Algunos de estos algoritmos son: RC4, MD4, MD5, SHA1… Si se utilizan hashes para almacenar contraseñas, por ejemplo, deben emplearse hashes resistentes a brute-force con salt.
Comprobación
Las principales comprobaciones a realizar son buscar si puedes encontrar contraseñas/secretos hardcoded en el código, si estos son predictable, y si el código está utilizando algún tipo de algoritmos weak de cryptography.
Es interesante saber que puedes monitor algunas crypto libraries automáticamente usando objection con:
ios monitor crypt
Para más información sobre las APIs y bibliotecas criptográficas de iOS accede a https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography
Autenticación local
La autenticación local juega un papel crucial, especialmente cuando se trata de proteger el acceso en un endpoint remoto mediante métodos criptográficos. La esencia aquí es que, sin una implementación adecuada, los mecanismos de autenticación local pueden ser eludidos.
Apple’s Local Authentication framework y el keychain proporcionan APIs robustas para que los desarrolladores faciliten diálogos de autenticación al usuario y manejen datos secretos de forma segura, respectivamente. El Secure Enclave protege la identificación por huella para Touch ID, mientras que Face ID se basa en reconocimiento facial sin comprometer los datos biométricos.
Para integrar Touch ID/Face ID, los desarrolladores tienen dos opciones de API:
LocalAuthentication.frameworkpara autenticación de usuario a alto nivel sin acceso a los datos biométricos.Security.frameworkpara acceso a servicios de keychain a bajo nivel, asegurando datos secretos con autenticación biométrica. Various open-source wrappers make keychain access simpler.
Caution
However, both
LocalAuthentication.frameworkandSecurity.frameworkpresent vulnerabilities, as they primarily return boolean values without transmitting data for authentication processes, making them susceptible to bypassing (refer to Don’t touch me that way, by David Lindner et al).
Implementando autenticación local
Para solicitar la autenticación de los usuarios, los desarrolladores deben utilizar el método evaluatePolicy dentro de la clase LAContext, eligiendo entre:
deviceOwnerAuthentication: Solicita Touch ID o el código de acceso del dispositivo, fallando si ninguno está habilitado.deviceOwnerAuthenticationWithBiometrics: Solicita exclusivamente Touch ID.
Una autenticación exitosa se indica mediante un valor booleano devuelto por evaluatePolicy, lo que resalta un posible fallo de seguridad.
Autenticación local usando Keychain
Implementar la autenticación local en apps iOS implica el uso de las APIs de keychain para almacenar de forma segura datos secretos como tokens de autenticación. Este proceso asegura que los datos solo puedan ser accedidos por el usuario, usando su código de acceso del dispositivo o autenticación biométrica como Touch ID.
El keychain ofrece la capacidad de establecer ítems con el atributo SecAccessControl, que restringe el acceso al ítem hasta que el usuario se autentique correctamente mediante Touch ID o el código de acceso del dispositivo. Esta característica es crucial para mejorar la seguridad.
A continuación hay ejemplos de código en Swift y Objective-C que demuestran cómo guardar y recuperar una cadena en/desde el keychain, aprovechando estas características de seguridad. Los ejemplos muestran específicamente cómo configurar el control de acceso para requerir autenticación Touch ID y garantizar que los datos sean accesibles solo en el dispositivo en el que se configuraron, bajo la condición de que exista un código de acceso 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
}
Ahora podemos solicitar el elemento guardado del keychain. Los servicios del keychain mostrarán el diálogo de autenticación al usuario y devolverán data o nil dependiendo de si se proporcionó una fingerprint adecuada o no.
// 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
}
Detección
El uso de frameworks en una aplicación también puede detectarse analizando la lista de bibliotecas dinámicas compartidas del binario de la aplicación. Esto se puede hacer usando otool:
$ otool -L <AppName>.app/<AppName>
Si LocalAuthentication.framework se usa en una aplicación, la salida contendrá las dos líneas siguientes (recuerda que LocalAuthentication.framework usa Security.framework internamente):
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security
If Security.framework is used, only the second one will be shown.
Bypass del Framework LocalAuthentication
Objection
A través del Objection Biometrics Bypass, ubicado en esta página de GitHub, está disponible una técnica para superar el mecanismo LocalAuthentication. El núcleo de este enfoque consiste en aprovechar Frida para manipular la función evaluatePolicy, asegurando que devuelva consistentemente un resultado True, independientemente del éxito real de la autenticación. Esto es particularmente útil para eludir procesos de autenticación biométrica defectuosos.
Para activar este bypass, se emplea el siguiente 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
Este comando inicia una secuencia donde Objection registra una tarea que efectivamente altera el resultado de la comprobación evaluatePolicy a True.
Frida
Un ejemplo del uso de evaluatePolicy de 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"];
});
}
}
Para lograr el bypass de la Autenticación local, se escribe un script de Frida. Este script apunta a la comprobación evaluatePolicy, interceptando su callback para asegurar que devuelva success=1. Al alterar el comportamiento del callback, la verificación de autenticación queda efectivamente omitida.
El script siguiente se inyecta para modificar el resultado del método evaluatePolicy. Cambia el resultado del callback para que siempre indique éxito.
// 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!");
}
Para inyectar el script de Frida y bypass la autenticación biométrica, se utiliza el siguiente comando:
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
Exposición de Funcionalidades Sensibles a través de IPC
Manejadores URI personalizados / Deeplinks / Esquemas personalizados
iOS Custom URI Handlers / Deeplinks / Custom Schemes
Universal Links
Compartir UIActivity
UIPasteboard
Extensiones de App
WebViews
Serialización y Codificación
iOS Serialisation and Encoding
Comunicación de red
Es importante comprobar que no haya comunicación sin cifrado y también que la aplicación esté correctamente validando el certificado TLS del servidor.
Para comprobar este tipo de problemas puedes usar un proxy como Burp:
Comprobación del nombre de host
Un problema común al validar el certificado TLS es comprobar que el certificado fue firmado por una CA de confianza, pero no comprobar si el nombre de host del certificado es el nombre de host al que se está accediendo.
Para comprobar este problema usando Burp, después de confiar en la CA de Burp en el iPhone, puedes crear un nuevo certificado con Burp para un nombre de host diferente y usarlo. Si la aplicación sigue funcionando, entonces está vulnerable.
Certificate Pinning
Si una aplicación está usando correctamente SSL Pinning, entonces la aplicación solo funcionará si el certificado es el esperado. Al probar una aplicación esto puede ser un problema, ya que Burp servirá su propio certificado.
Para eludir esta protección en un dispositivo con jailbreak, puedes instalar la aplicación SSL Kill Switch o instalar Burp Mobile Assistant
También puedes usar objection ios sslpinning disable
Miscelánea
- En
/System/Librarypuedes encontrar los frameworks instalados en el teléfono usados por las aplicaciones del sistema - Las aplicaciones instaladas por el usuario desde el App Store se encuentran en
/User/Applications - Y
/User/Librarycontiene datos guardados por las aplicaciones a nivel de usuario - Puedes acceder a
/User/Library/Notes/notes.sqlitepara leer las notas guardadas dentro de la aplicación. - Dentro de la carpeta de una aplicación instalada (
/User/Applications/<APP ID>/) puedes encontrar algunos archivos interesantes: iTunesArtwork: El icono usado por la aplicacióniTunesMetadata.plist: Información de la aplicación usada en el App Store/Library/*: Contiene las preferencias y la caché. En/Library/Cache/Snapshots/*puedes encontrar la instantánea realizada a la aplicación antes de enviarla al segundo plano.
Hot Patching/Enforced Updateing
Los desarrolladores pueden parchear remotamente todas las instalaciones de su app al instante sin tener que volver a enviar la aplicación al App Store y esperar a que sea aprobada.
Para este propósito normalmente se usa JSPatch. Pero también hay otras opciones como Siren y react-native-appstore-version-checker.
Este es un mecanismo peligroso que podría ser abusado por SDKs de terceros maliciosos, por lo tanto se recomienda comprobar qué método se usa para la actualización automática (si lo hay) y probarlo. Puedes intentar descargar una versión anterior de la app para este propósito.
Terceros
Un desafío significativo con los SDKs de terceros es la falta de control granular sobre sus funcionalidades. Los desarrolladores se enfrentan a una elección: integrar el SDK y aceptar todas sus características, incluidas posibles vulnerabilidades de seguridad y problemas de privacidad, o renunciar por completo a sus beneficios. A menudo, los desarrolladores no pueden parchear las vulnerabilidades dentro de estos SDKs por sí mismos. Además, a medida que los SDKs ganan confianza en la comunidad, algunos pueden comenzar a contener malware.
Los servicios proporcionados por SDKs de terceros pueden incluir seguimiento del comportamiento del usuario, visualización de anuncios o mejoras de la experiencia de usuario. Sin embargo, esto introduce un riesgo ya que los desarrolladores pueden no estar completamente al tanto del código que ejecutan estas librerías, lo que conlleva posibles riesgos de privacidad y seguridad. Es crucial limitar la información compartida con los servicios de terceros a lo estrictamente necesario y asegurarse de que no se exponga ningún dato sensible.
La implementación de servicios de terceros suele presentarse en dos formas: una librería independiente o un SDK completo. Para proteger la privacidad del usuario, cualquier dato compartido con estos servicios debe estar anonimizado para evitar la divulgación de Personal Identifiable Information (PII).
Para identificar las librerías que usa una aplicación, se puede emplear el comando otool. Esta herramienta debe ejecutarse contra la aplicación y cada librería compartida que use para descubrir librerías adicionales.
otool -L <application_path>
Vulnerabilidades interesantes y estudios de caso
Air Keyboard Remote Input Injection
Itunesstored Bookassetd Sandbox Escape
Zero Click Messaging Image Parser Chains
Referencias y más recursos
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering
- iOS & Mobile App Pentesting - INE
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/
- https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage
- https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060
- https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064
- https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054
- https://github.com/ivRodriguezCA/RE-iOS-Apps/ Curso gratuito de IOS(https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)
- https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577
- https://www.slideshare.net/RyanISI/ios-appsecurityminicourse
- https://github.com/prateek147/DVIA
- https://github.com/prateek147/DVIA-v2
- https://github.com/OWASP/MSTG-Hacking-Playground%20
- OWASP iGoat https://github.com/OWASP/igoat <<< versión Objective-C https://github.com/OWASP/iGoat-Swift <<< versión Swift
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/nabla-c0d3/ssl-kill-switch2
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


