iOS Pentesting
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente, impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
iOS Basics
iOS BasicsTesting Environment
En esta página puedes encontrar información sobre el simulador de iOS, emuladores y jailbreaking:
iOS Testing EnvironmentInitial Analysis
Basic iOS Testing Operations
Durante la prueba se van a sugerir varias operaciones (conectar al dispositivo, leer/escribir/subir/bajar archivos, usar algunas herramientas...). Por lo tanto, si no sabes cómo realizar alguna de estas acciones, por favor, comienza a leer la página:
iOS Basic Testing OperationsPara los siguientes pasos la aplicación debe estar instalada en el dispositivo y ya debe haber obtenido el archivo IPA de la aplicación. Lee la página Basic iOS Testing Operations para aprender cómo hacer esto.
Basic Static Analysis
Se recomienda usar la herramienta MobSF para realizar un Análisis Estático automático al 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.
Stack Canaries: Para validar la integridad de la pila, se coloca un valor de ‘canario’ en la pila antes de llamar a una función y se valida nuevamente una vez que la función termina.
ARC (Automatic Reference Counting): Para prevenir fallos comunes de corrupción de memoria
Binary Encriptado: El binario debe estar encriptado
Identificación de Funciones Sensibles/Inseguras
Algoritmos de Hashing Débiles
Funciones Aleatorias Inseguras
Función ‘Malloc’ Insegura
Funciones Inseguras y Vulnerables
Basic Dynamic Analysis
Revisa el análisis dinámico que realiza MobSF. Necesitarás navegar a través de las diferentes vistas e interactuar con ellas, pero estará enganchando varias clases al hacer otras cosas y preparará un informe una vez que hayas terminado.
Listing Installed Apps
Utiliza el comando frida-ps -Uai
para determinar el identificador de paquete de las aplicaciones instaladas:
Enumeración Básica y Hooking
Aprende a enumerar los componentes de la aplicación y cómo hookear métodos y clases con objection:
iOS Hooking With ObjectionEstructura de IPA
La estructura de un archivo IPA es esencialmente la de un paquete comprimido. Al renombrar su extensión a .zip
, se puede descomprimir para revelar su contenido. Dentro de esta estructura, un Bundle representa una aplicación completamente empaquetada lista para la instalación. Dentro, 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 archivos de recursos como íconos.Frameworks/
: Esta carpeta alberga las bibliotecas nativas de la aplicación, que pueden estar en forma de archivos.dylib
o.framework
.PlugIns/
: Esto puede incluir extensiones a 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 almacenar datos temporales en caché y para agregar funcionalidad de deshacer a tu aplicación en un solo dispositivo. Para sincronizar datos en múltiples dispositivos en una sola cuenta de iCloud, Core Data refleja automáticamente tu esquema a un contenedor de CloudKit.PkgInfo
: El archivoPkgInfo
es 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 predeterminado en caso de que un idioma no esté soportado.
Seguridad: El directorio
_CodeSignature/
juega un papel crítico en la seguridad de la aplicación al verificar la integridad de todos los archivos empaquetados a través de firmas digitales.Gestión de Activos: El archivo
Assets.car
utiliza compresión para gestionar de manera eficiente los activos gráficos, crucial para optimizar el rendimiento de la aplicación y reducir su tamaño total.Frameworks y PlugIns: Estos directorios subrayan la modularidad de las aplicaciones iOS, permitiendo a los desarrolladores incluir bibliotecas de código reutilizables (
Frameworks/
) y extender la funcionalidad de la aplicación (PlugIns/
).Localización: La estructura soporta múltiples idiomas, facilitando el alcance global de la aplicación al incluir recursos para paquetes de idiomas específicos.
Info.plist
El Info.plist sirve como una piedra angular para las aplicaciones iOS, encapsulando datos de configuración clave en forma de pares clave-valor. Este archivo es un requisito no solo para aplicaciones, sino también para extensiones de aplicaciones y frameworks empaquetados dentro. Está estructurado en formato XML o binario y contiene información crítica que abarca desde permisos de la aplicación hasta configuraciones de seguridad. Para una exploración detallada de las claves disponibles, se puede consultar la Documentación para Desarrolladores de Apple.
Para aquellos que buscan trabajar con este archivo en un formato más accesible, la conversión a XML se puede lograr fácilmente mediante el uso de plutil
en macOS (disponible de forma nativa en versiones 10.2 y posteriores) o plistutil
en Linux. Los comandos para la conversión son los siguientes:
Para macOS:
Para Linux:
Entre la miríada de información que el archivo Info.plist puede revelar, las entradas notables incluyen cadenas de permisos de la aplicación (UsageDescription
), esquemas de URL personalizados (CFBundleURLTypes
), y configuraciones para la seguridad del transporte de aplicaciones (NSAppTransportSecurity
). Estas entradas, junto con otras como tipos de documentos personalizados exportados/importados (UTExportedTypeDeclarations
/ UTImportedTypeDeclarations
), pueden ser localizadas fácilmente inspeccionando el archivo o empleando un simple comando grep
:
Rutas de Datos
En el entorno de 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 aplicaciones instaladas por el usuario se colocan en /var/mobile/containers/Data/Application/
. Estas aplicaciones se asignan un identificador único conocido como UUID de 128 bits, lo que hace que la tarea de localizar manualmente la carpeta de una aplicación sea un desafío debido a la aleatoriedad de los nombres de los directorios.
Como las aplicaciones en iOS deben estar en un entorno aislado, cada aplicación también tendrá una carpeta dentro de $HOME/Library/Containers
con el CFBundleIdentifier
de la aplicación como nombre de la carpeta.
Sin embargo, ambas carpetas (carpetas de datos y de contenedores) tienen el archivo .com.apple.mobile_container_manager.metadata.plist
que vincula ambos archivos en la clave MCMetadataIdentifier
).
Para facilitar el descubrimiento del directorio de instalación de una aplicación instalada por el usuario, la herramienta objection proporciona un comando útil, env
. Este comando revela información detallada del directorio para la aplicación en cuestión. A continuación se muestra un ejemplo de cómo usar este comando:
Alternativamente, el nombre de la aplicación se puede buscar dentro de /private/var/containers
utilizando el comando find
:
Los comandos como ps
y lsof
también se pueden utilizar para identificar el proceso de la aplicación y listar los archivos abiertos, respectivamente, proporcionando información sobre las rutas de directorio activas de la aplicación:
Directorio del paquete:
AppName.app
Este es el Paquete de Aplicación 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 en este directorio no se respalda.
Los contenidos de esta carpeta se utilizan para validar la firma del 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 en este directorio se respalda.
La aplicación puede deshabilitar rutas configurando
NSURLIsExcludedFromBackupKey
.Library/
Contiene todos los archivos que no son específicos del usuario, como cachés, preferencias, cookies y archivos de configuración de lista de propiedades (plist).
Las aplicaciones de iOS suelen usar los subdirectorios
Application Support
yCaches
, pero la aplicación puede crear subdirectorios personalizados.Library/Caches/
Contiene archivos en caché semi-persistentes.
Invisible para los usuarios y los usuarios no pueden escribir en él.
El contenido en este directorio no se respalda.
El sistema operativo puede eliminar automáticamente los archivos de este directorio cuando la aplicación no está en ejecución y el espacio de almacenamiento es bajo.
Library/Application Support/
Contiene archivos persistentes necesarios para ejecutar la aplicación.
Invisible para los usuarios y los usuarios no pueden escribir en él.
El contenido en este directorio se respalda.
La aplicación puede deshabilitar rutas configurando
NSURLIsExcludedFromBackupKey
.Library/Preferences/
Se utiliza para almacenar propiedades que pueden persistir incluso después de que se reinicie una 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
NSUserDefaults
se pueden encontrar en este archivo.tmp/
Utiliza este directorio para escribir archivos temporales que no necesitan persistir entre lanzamientos de la aplicación.
Contiene archivos en caché no persistentes.
Invisible para los usuarios.
El contenido en este directorio no se respalda.
El sistema operativo puede eliminar automáticamente los archivos de este directorio cuando la aplicación no está en ejecución y el espacio de almacenamiento es bajo.
Veamos más de cerca el Paquete de Aplicación de iGoat-Swift (.app) dentro del directorio del Paquete (/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
):
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
:
Verifica si la aplicación está encriptada
Mira si hay alguna salida para:
Desensamblando el binario
Desensamblar la sección de texto:
Para imprimir el segmento de Objective-C de la aplicación de muestra se puede usar:
Para obtener un código Objective-C más compacto, puedes usar class-dump:
Sin embargo, las mejores opciones para desensamblar el binario son: Hopper y IDA.
Usa Trickest para construir y automatizar flujos de trabajo fácilmente, impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
Almacenamiento de Datos
Para aprender sobre cómo iOS almacena datos en el dispositivo, lee esta página:
iOS BasicsLos siguientes lugares para almacenar información deben ser revisados justo después de instalar la aplicación, después de verificar todas las funcionalidades de la aplicación e incluso después de cerrar sesión de un usuario y entrar en uno diferente. El objetivo es encontrar información sensible no protegida de la aplicación (contraseñas, tokens), del usuario actual y de usuarios que han iniciado sesión anteriormente.
Plist
Los archivos plist 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 aplicación y después de usarla intensivamente para ver si se escriben nuevos datos.
La forma más común de persistir datos en archivos plist es a través del uso de NSUserDefaults. Este archivo plist se guarda dentro del sandbox de la aplicación en Library/Preferences/<appBundleID>.plist
La clase NSUserDefaults
proporciona una interfaz programática para interactuar con el sistema predeterminado. El sistema predeterminado permite que una aplicación personalice su comportamiento de acuerdo con las preferencias del usuario. Los datos guardados por NSUserDefaults
pueden ser vistos en el paquete de la aplicación. Esta clase almacena datos en un archivo plist, pero está destinada a ser utilizada con pequeñas cantidades de datos.
Estos datos no pueden ser accedidos directamente a través de una computadora de confianza, pero pueden ser accedidos realizando una copia de seguridad.
Puedes volcar la información guardada usando NSUserDefaults
utilizando ios nsuserdefaults get
de objection.
Para encontrar todos los plist utilizados por la aplicación, puedes acceder a /private/var/mobile/Containers/Data/Application/{APPID}
y ejecutar:
Para convertir archivos de formato XML o binario (bplist) a XML, hay varios métodos disponibles según su sistema operativo:
Para usuarios de macOS: Utilice el comando plutil
. Es una herramienta integrada en macOS (10.2+), diseñada para este propósito:
Para usuarios de Linux: Instala libplist-utils
primero, luego usa plistutil
para convertir tu archivo:
Dentro de una sesión de Objection: Para analizar aplicaciones móviles, un comando específico te permite convertir archivos plist directamente:
Core Data
Core Data
es un marco para gestionar la capa de modelo de objetos en tu aplicación. Core Data puede usar SQLite como su almacenamiento persistente, pero el marco en sí no es una base de datos.
CoreData no cifra sus datos por defecto. Sin embargo, se puede agregar una capa de cifrado adicional a CoreData. Consulta el GitHub Repo para más detalles.
Puedes encontrar la información de SQLite Core Data de una aplicación en la ruta /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
Si puedes abrir el SQLite y acceder a información sensible, entonces encontraste una mala configuración.
YapDatabase
YapDatabase es un almacén de clave/valor construido sobre SQLite. Como las bases de datos Yap son bases de datos sqlite, puedes encontrarlas utilizando el comando propuesto en la sección anterior.
Otras Bases de Datos SQLite
Es común que las aplicaciones creen su propia base de datos sqlite. Pueden estar almacenando datos sensibles en ellas y dejándolos sin cifrar. Por lo tanto, siempre es interesante revisar cada base de datos dentro del directorio de las aplicaciones. Por lo tanto, ve al directorio de la aplicación donde se guardan los datos (/private/var/mobile/Containers/Data/Application/{APPID}
)
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 verificar bases de datos de Firebase mal configuradas aquí:
Firebase DatabaseRealm databases
Realm Objective-C y Realm Swift ofrecen una alternativa poderosa para el almacenamiento de datos, no proporcionada por Apple. Por defecto, almacenan datos sin cifrar, con cifrado disponible a través de una configuración específica.
Las bases de datos se encuentran en: /private/var/mobile/Containers/Data/Application/{APPID}
. Para explorar estos archivos, se pueden utilizar comandos como:
Para ver estos archivos de base de datos, se recomienda la herramienta Realm Studio.
Para implementar la encriptación dentro de una base de datos Realm, se puede usar el siguiente fragmento de código:
Bases de datos de Couchbase Lite
Couchbase Lite se describe como un motor de base de datos liviano y embebido que sigue el enfoque orientado a documentos (NoSQL). Diseñado para ser nativo de iOS y macOS, ofrece la capacidad de sincronizar datos sin problemas.
Para identificar posibles bases de datos de Couchbase en un dispositivo, se debe inspeccionar el siguiente directorio:
Cookies
iOS almacena las cookies de las aplicaciones en Library/Cookies/cookies.binarycookies
dentro de la carpeta de cada aplicación. Sin embargo, los desarrolladores a veces deciden guardarlas en el keychain ya que el mencionado archivo de cookies puede ser accedido en copias de seguridad.
Para inspeccionar el archivo de cookies, puedes usar este script de python o usar ios cookies get
de objection.
También puedes usar objection para convertir estos archivos a un formato JSON e inspeccionar los datos.
Cache
Por defecto, NSURLSession almacena datos, como solicitudes y respuestas HTTP en la base de datos Cache.db. Esta base de datos puede contener datos sensibles, si se han almacenado en caché tokens, nombres de usuario u otra información sensible. Para encontrar la información en caché, abre el directorio de datos de la aplicación (/var/mobile/Containers/Data/Application/<UUID>
) y ve a /Library/Caches/<Bundle Identifier>
. La caché de WebKit también se almacena en el archivo Cache.db. Objection puede abrir e interactuar con la base de datos con el comando sqlite connect Cache.db
, ya que es una base de datos SQLite normal.
Se recomienda deshabilitar el almacenamiento en caché de estos datos, ya que puede contener información sensible en la solicitud o respuesta. La siguiente lista muestra diferentes formas de lograr esto:
Se recomienda eliminar las respuestas en caché después de cerrar sesión. Esto se puede hacer con el método proporcionado por Apple llamado
removeAllCachedResponses
. Puedes llamar a este método de la siguiente manera:
URLCache.shared.removeAllCachedResponses()
Este método eliminará todas las solicitudes y respuestas en caché del archivo Cache.db. 2. Si no necesitas aprovechar las cookies, se recomienda simplemente usar la propiedad de configuración .ephemeral de URLSession, que deshabilitará el guardado de cookies y cachés.
Un objeto de configuración de sesión efímera es similar a una configuración de sesión predeterminada (ver predeterminado), excepto que el objeto de sesión correspondiente no almacena cachés, almacenes de credenciales ni ningún dato relacionado con la sesión en el disco. En su lugar, los datos relacionados con la sesión se almacenan en RAM. La única vez que una sesión efímera escribe datos en el disco es cuando le indicas que escriba el contenido de una URL en un archivo.
3. La caché también se puede deshabilitar configurando la política de caché a .notAllowed. Esto deshabilitará el almacenamiento de caché de cualquier manera, ya sea en memoria o en disco.
Snapshots
Cada vez que presionas el botón de inicio, iOS toma una instantánea de la pantalla actual para poder hacer la transición a la aplicación de una manera mucho más fluida. Sin embargo, si hay datos sensibles presentes en la pantalla actual, se guardarán en la imagen (que persiste a través de reinicios). Estas son las instantáneas a las que también puedes acceder tocando dos veces la pantalla de inicio para cambiar entre aplicaciones.
A menos que el iPhone esté jailbroken, el atacante necesita tener acceso al dispositivo desbloqueado para ver estas capturas de pantalla. Por defecto, la última instantánea se almacena en el sandbox de la aplicación en la carpeta Library/Caches/Snapshots/
o Library/SplashBoard/Snapshots
(los ordenadores de confianza no pueden acceder al sistema de archivos desde iOS 7.0).
Una forma de prevenir este mal comportamiento es poner una pantalla en blanco o eliminar los datos sensibles antes de tomar la instantánea utilizando la función ApplicationDidEnterBackground()
.
El siguiente es un método de remediación de ejemplo que establecerá una captura de pantalla predeterminada.
Swift:
Objetivo-C:
Esto establece la imagen de fondo a overlayImage.png
cada vez que la aplicación se envía al fondo. Previene filtraciones de datos sensibles porque overlayImage.png
siempre sobrescribirá la vista actual.
Keychain
Para acceder y gestionar el llavero de iOS, hay herramientas como Keychain-Dumper disponibles, adecuadas para dispositivos con jailbreak. 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 llavero, evitando la necesidad de NSUserDefaults u otros envoltorios. Para almacenar credenciales después del inicio de sesión, se utiliza el siguiente código Swift:
Para extraer estas credenciales almacenadas, se utiliza el comando de Objection ios nsurlcredentialstorage dump
.
Teclados Personalizados y Caché de Teclado
Con iOS 8.0 en adelante, los usuarios pueden instalar extensiones de teclado personalizadas, que son gestionables en Configuración > General > Teclado > Teclados. Aunque estos teclados ofrecen funcionalidad extendida, representan un riesgo de registro de pulsaciones y transmisión de datos a servidores externos, aunque se notifica a los usuarios sobre los teclados que requieren acceso a la red. Las aplicaciones pueden, y deben, restringir el uso de teclados personalizados para la entrada de información sensible.
Recomendaciones de Seguridad:
Se aconseja deshabilitar teclados de terceros para mejorar la seguridad.
Tenga en cuenta las funciones de autocorrección y autocompletado del teclado predeterminado de iOS, que podrían almacenar información sensible en archivos de caché ubicados en
Library/Keyboard/{locale}-dynamic-text.dat
o/private/var/mobile/Library/Keyboard/dynamic-text.dat
. Estos archivos de caché deben ser revisados regularmente en busca de datos sensibles. Se recomienda restablecer el diccionario del teclado a través de Configuración > General > Restablecer > Restablecer Diccionario del Teclado para borrar datos en caché.Interceptar el tráfico de red puede revelar si un teclado personalizado está transmitiendo pulsaciones de teclas de forma remota.
Prevención de Caché en Campos de Texto
El protocolo UITextInputTraits ofrece propiedades para gestionar la autocorrección y la entrada de texto segura, esenciales para prevenir el almacenamiento en caché de información sensible. Por ejemplo, deshabilitar la autocorrección y habilitar la entrada de texto segura se puede lograr con:
Además, los desarrolladores deben asegurarse de que los campos de texto, especialmente aquellos para ingresar información sensible como contraseñas y PINs, desactiven la caché configurando autocorrectionType
en UITextAutocorrectionTypeNo
y secureTextEntry
en YES
.
Registros
Depurar código a menudo implica el uso de registro. Hay un riesgo involucrado ya que los registros pueden contener información sensible. Anteriormente, en iOS 6 y versiones anteriores, los registros eran accesibles para todas las aplicaciones, lo que planteaba un riesgo de filtración de datos sensibles. Ahora, las aplicaciones están restringidas a acceder solo a sus propios registros.
A pesar de estas restricciones, un atacante con acceso físico a un dispositivo desbloqueado aún puede explotar esto conectando el dispositivo a una computadora y leyendo los registros. Es importante notar que los registros permanecen en el disco incluso después de la desinstalación de la aplicación.
Para mitigar riesgos, se aconseja interactuar a fondo con la aplicación, explorando todas sus funcionalidades e inputs para asegurar que no se esté registrando inadvertidamente información sensible.
Al revisar el código fuente de la aplicación en busca de posibles filtraciones, busca tanto declaraciones de registro predefinidas como personalizadas utilizando palabras clave como NSLog
, NSAssert
, NSCAssert
, fprintf
para funciones integradas, y cualquier mención de Logging
o Logfile
para implementaciones personalizadas.
Monitoreo de Registros del Sistema
Las aplicaciones registran varias piezas de información que pueden ser sensibles. Para monitorear estos registros, herramientas y comandos como:
son útiles. Además, Xcode proporciona una forma de recopilar registros de consola:
Abre Xcode.
Conecta el dispositivo iOS.
Navega a Ventana -> Dispositivos y Simuladores.
Selecciona tu dispositivo.
Activa el problema que estás investigando.
Usa el botón Abrir Consola para ver los registros en una nueva ventana.
Para un registro más avanzado, conectarse al shell del dispositivo y usar socat puede proporcionar monitoreo de registros en tiempo real:
Seguido de comandos para observar actividades de registro, lo que puede ser invaluable para diagnosticar problemas o identificar posibles filtraciones de datos en los registros.
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente, impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
Copias de seguridad
Las funciones de copia de seguridad automática están integradas en iOS, facilitando la creación de copias de datos del dispositivo a través de iTunes (hasta macOS Catalina), Finder (desde macOS Catalina en adelante) o iCloud. Estas copias de seguridad 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 la posible filtración de datos y el riesgo de que las modificaciones en la copia de seguridad puedan alterar la funcionalidad de la aplicación. Se aconseja no almacenar información sensible en texto plano dentro del directorio de cualquier aplicación o sus subdirectorios para mitigar estos riesgos.
Exclusión de 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 de seguridad utilizando NSURL setResourceValue:forKey:error:
con la clave NSURLIsExcludedFromBackupKey
. Esta práctica es crucial para proteger datos sensibles de ser incluidos en las copias de seguridad.
Pruebas de vulnerabilidades
Para evaluar la seguridad de la copia de seguridad de una aplicación, comienza por crear una copia de seguridad usando Finder, luego localízala utilizando la guía de la documentación oficial de Apple. Analiza la copia de seguridad en busca de datos sensibles o configuraciones que podrían ser alteradas para afectar el comportamiento de la aplicación.
Se puede buscar información sensible utilizando herramientas de línea de comandos o aplicaciones como iMazing. Para copias de seguridad encriptadas, se puede confirmar la presencia de encriptación verificando la clave "IsEncrypted" en el archivo "Manifest.plist" en la raíz de la copia de seguridad.
Para tratar con copias de seguridad encriptadas, los scripts de Python disponibles en el repositorio de GitHub de DinoSec, como backup_tool.py y backup_passwd.py, pueden ser útiles, aunque potencialmente requiriendo ajustes para la compatibilidad con las últimas versiones de iTunes/Finder. La herramienta iOSbackup es otra opción para acceder a archivos dentro de copias de seguridad protegidas por contraseña.
Modificando el Comportamiento de la Aplicación
Un ejemplo de alterar el comportamiento de la aplicación a través de modificaciones en la copia de seguridad se demuestra en la aplicación de billetera bitcoin Bither, donde el PIN de bloqueo de la interfaz de usuario se almacena dentro de net.bither.plist
bajo la clave pin_code. Eliminar esta clave del plist y restaurar la copia de seguridad elimina el requisito del PIN, proporcionando acceso sin restricciones.
Resumen sobre Pruebas de Memoria para Datos Sensibles
Al tratar con información sensible almacenada en la memoria de una aplicación, es crucial limitar el tiempo de exposición de estos 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.
Recuperando y Analizando un Volcado de Memoria
Para dispositivos con jailbreak y sin jailbreak, herramientas como objection y Fridump permiten el volcado de la memoria del proceso de una aplicación. Una vez volcado, analizar estos datos requiere varias herramientas, dependiendo de la naturaleza de la información que estás buscando.
Para extraer cadenas de un volcado de memoria, se pueden usar comandos como strings
o rabin2 -zz
:
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:
Análisis de Memoria en Tiempo de Ejecución
r2frida proporciona una alternativa poderosa para inspeccionar la memoria de una aplicación en tiempo real, sin necesidad de un volcado de memoria. Esta herramienta permite la ejecución de comandos de búsqueda directamente en la memoria de la aplicación en ejecución:
Criptografía Rota
Procesos de Gestión de Claves Deficientes
Algunos desarrolladores guardan datos sensibles en el almacenamiento local y los encriptan con una clave codificada/predictible en el código. Esto no debería hacerse, ya que algún proceso de reversión podría permitir a los atacantes extraer la información confidencial.
Uso de Algoritmos Inseguros y/o Obsoletos
Los desarrolladores no deberían usar algoritmos obsoletos para realizar verificaciones de autorización, almacenar o enviar datos. Algunos de estos algoritmos son: RC4, MD4, MD5, SHA1... Si se utilizan hashes para almacenar contraseñas, por ejemplo, se deberían usar hashes resistentes a fuerza bruta con sal.
Verificación
Las principales verificaciones a realizar son encontrar si puedes encontrar contraseñas/secretos codificados en el código, o si son predecibles, y si el código está utilizando algún tipo de algoritmos de criptografía débil.
Es interesante saber que puedes monitorear algunas bibliotecas crypto automáticamente usando objection con:
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 salvaguardar el acceso en un punto final remoto a través de métodos criptográficos. La esencia aquí es que sin una implementación adecuada, los mecanismos de autenticación local pueden ser eludidos.
El framework de Autenticación Local de Apple y el keychain proporcionan APIs robustas para que los desarrolladores faciliten diálogos de autenticación de usuarios y manejen datos secretos de manera segura, respectivamente. El Secure Enclave asegura la identificación por huella digital para Touch ID, mientras que Face ID se basa en el reconocimiento facial sin comprometer los datos biométricos.
Para integrar Touch ID/Face ID, los desarrolladores tienen dos opciones de API:
LocalAuthentication.framework
para autenticación de usuario de alto nivel sin acceso a datos biométricos.Security.framework
para acceso a servicios de keychain de bajo nivel, asegurando datos secretos con autenticación biométrica. Varios wrappers de código abierto hacen que el acceso al keychain sea más simple.
Sin embargo, tanto LocalAuthentication.framework
como Security.framework
presentan vulnerabilidades, ya que principalmente devuelven valores booleanos sin transmitir datos para procesos de autenticación, lo que los hace susceptibles a eludir (consulta Don't touch me that way, by David Lindner et al).
Implementando Autenticación Local
Para solicitar a los usuarios la autenticación, 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 de retorno booleano de evaluatePolicy
, destacando una posible falla de seguridad.
Autenticación Local usando Keychain
Implementar autenticación local en aplicaciones iOS implica el uso de APIs de keychain para almacenar de manera segura datos secretos como tokens de autenticación. Este proceso asegura que los datos solo puedan ser accedidos por el usuario, utilizando su código de acceso del dispositivo o autenticación biométrica como Touch ID.
El keychain ofrece la capacidad de establecer elementos con el atributo SecAccessControl
, que restringe el acceso al elemento hasta que el usuario se autentique con éxito a través de Touch ID o el código de acceso del dispositivo. Esta característica es crucial para mejorar la seguridad.
A continuación se presentan ejemplos de código en Swift y Objective-C que demuestran cómo guardar y recuperar una cadena del keychain, aprovechando estas características de seguridad. Los ejemplos muestran específicamente cómo configurar el control de acceso para requerir autenticación de Touch ID y asegurar que los datos sean accesibles solo en el dispositivo en el que se configuraron, bajo la condición de que se haya configurado un código de acceso del dispositivo.
Ahora podemos solicitar el elemento guardado del llavero. Los servicios de llavero presentarán el diálogo de autenticación al usuario y devolverán datos o nil dependiendo de si se proporcionó una huella digital adecuada o no.
Detección
El uso de frameworks en una aplicación también se puede detectar analizando la lista de bibliotecas dinámicas compartidas del binario de la aplicación. Esto se puede hacer utilizando otool
:
Si se utiliza LocalAuthentication.framework
en una aplicación, la salida contendrá ambas líneas siguientes (recuerde que LocalAuthentication.framework
utiliza Security.framework
en segundo plano):
Si se utiliza Security.framework
, solo se mostrará el segundo.
Bypass del Marco de Autenticación Local
Objection
A través del Objection Biometrics Bypass, ubicado en esta página de GitHub, se dispone de una técnica para superar el mecanismo de LocalAuthentication. El núcleo de este enfoque implica aprovechar Frida para manipular la función evaluatePolicy
, asegurando que siempre produzca 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:
Este comando inicia una secuencia donde Objection registra una tarea que altera efectivamente el resultado de la verificación evaluatePolicy
a True
.
Frida
Un ejemplo de un uso de evaluatePolicy
de la aplicación DVIA-v2:
Para lograr el bypass de la Autenticación Local, se escribe un script de Frida. Este script apunta a la verificación de evaluatePolicy, interceptando su callback para asegurar que devuelva success=1. Al alterar el comportamiento del callback, la verificación de autenticación se elude efectivamente.
El script a continuación se inyecta para modificar el resultado del método evaluatePolicy. Cambia el resultado del callback para indicar siempre éxito.
Para inyectar el script de Frida y eludir la autenticación biométrica, se utiliza el siguiente comando:
Exposición de Funcionalidades Sensibles a Través de IPC
Controladores de URI Personalizados / Deeplinks / Esquemas Personalizados
iOS Custom URI Handlers / Deeplinks / Custom SchemesEnlaces Universales
iOS Universal LinksCompartición UIActivity
iOS UIActivity SharingUIPasteboard
iOS UIPasteboardExtensiones de Aplicaciones
iOS App ExtensionsWebViews
iOS WebViewsSerialización y Codificación
iOS Serialisation and EncodingComunicación de Red
Es importante verificar que no se esté realizando ninguna comunicación sin cifrado y también que la aplicación esté validando correctamente el certificado TLS del servidor. Para verificar este tipo de problemas, puedes usar un proxy como Burp:
iOS Burp Suite ConfigurationVerificación de Nombre de Host
Un problema común al validar el certificado TLS es verificar que el certificado fue firmado por una CA confiable, pero no verificar si el nombre de host del certificado es el nombre de host que se está accediendo. Para verificar 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, algo es vulnerable.
Fijación de Certificados
Si una aplicación está utilizando correctamente la Fijación de SSL, entonces la aplicación solo funcionará si el certificado es el que se espera. Al probar una aplicación, esto podría 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's ios sslpinning disable
Miscelánea
En
/System/Library
puedes encontrar los frameworks instalados en el teléfono utilizados por aplicaciones del sistema.Las aplicaciones instaladas por el usuario desde la App Store se encuentran dentro de
/User/Applications
.Y el
/User/Library
contiene datos guardados por las aplicaciones a nivel de usuario.Puedes acceder a
/User/Library/Notes/notes.sqlite
para 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 ícono utilizado por la aplicación.iTunesMetadata.plist
: Información de la aplicación utilizada en la App Store./Library/*
: Contiene las preferencias y caché. En/Library/Cache/Snapshots/*
puedes encontrar la instantánea realizada a la aplicación antes de enviarla al fondo.
Hot Patching/Actualización Forzada
Los desarrolladores pueden parchear todas las instalaciones de su aplicación instantáneamente sin tener que volver a enviar la aplicación a la App Store y esperar a que sea aprobada. Para este propósito, generalmente se utiliza 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 verificar qué método se utiliza para la actualización automática (si lo hay) y probarlo. Podrías intentar descargar una versión anterior de la aplicación 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 las posibles vulnerabilidades de seguridad y preocupaciones de privacidad, o renunciar a sus beneficios por completo. A menudo, los desarrolladores no pueden parchear vulnerabilidades dentro de estos SDKs por sí mismos. Además, a medida que los SDKs ganan confianza dentro de la comunidad, algunos pueden comenzar a contener malware.
Los servicios proporcionados por los SDKs de terceros pueden incluir seguimiento del comportamiento del usuario, exhibición de anuncios o mejoras en la experiencia del usuario. Sin embargo, esto introduce un riesgo, ya que los desarrolladores pueden no ser completamente conscientes del código ejecutado por estas bibliotecas, lo que lleva a posibles riesgos de privacidad y seguridad. Es crucial limitar la información compartida con servicios de terceros a lo que es necesario y asegurarse de que no se exponga información sensible.
La implementación de servicios de terceros generalmente viene en dos formas: una biblioteca independiente o un SDK completo. Para proteger la privacidad del usuario, cualquier dato compartido con estos servicios debe ser anonimizado para evitar la divulgación de Información Personal Identificable (PII).
Para identificar las bibliotecas que utiliza una aplicación, se puede emplear el comando otool
. Esta herramienta debe ejecutarse contra la aplicación y cada biblioteca compartida que utiliza para descubrir bibliotecas adicionales.
Referencias y Más Recursos
OWASP iGoat https://github.com/OWASP/igoat <<< Versión de Objective-C https://github.com/OWASP/iGoat-Swift <<< Versión de Swift
Usa Trickest para construir y automatizar flujos de trabajo fácilmente impulsados por las herramientas comunitarias más avanzadas del mundo. Obtén acceso hoy:
Last updated