Volver a actualizaciones
Nuevo releaseAug 5, 2026

IOSSecuritySuite v2.3.0

Biblioteca Swift de seguridad y anti-manipulación para plataforma iOS

Compartir

⭐️ ¿Quieres convertirte en un Ingeniero de Seguridad de Aplicaciones iOS certificado? ⭐️

Consulta nuestro curso práctico y completamente en línea en: https://courses.securing.pl/courses/iase

iASE logo

Descripción de ISS

ISS logo

por @_r3ggi

🌏 iOS Security Suite es una librería avanzada y fácil de usar de seguridad de plataforma y anti-manipulación, escrita en Swift puro. Si desarrollas para iOS y quieres proteger tu aplicación según el estándar OWASP MASVS, capítulo v8, ¡entonces esta librería podría ahorrarte mucho tiempo! 🚀

Lo que ISS detecta:

  • Jailbreak 🧨
  • Depurador adjunto 👨🏻‍🚀
  • Si una aplicación se ejecutó en un emulador 👽
  • Herramientas comunes de ingeniería inversa ejecutándose en el dispositivo 🔭

Configuración

Hay 4 formas de empezar a usar IOSSecuritySuite

1. Agregar fuente

Agrega los archivos IOSSecuritySuite/*.swift a tu proyecto

2. Configurar con CocoaPods

pod 'IOSSecuritySuite'

3. Configurar con Carthage

github "securing/IOSSecuritySuite"

4. Configurar con Swift Package Manager

.package(url: "https://github.com/securing/IOSSecuritySuite.git", from: "1.5.0")

Actualizar Info.plist

Después de agregar ISS a tu proyecto, también necesitarás actualizar tu Info.plist principal. Hay una verificación en el módulo de detección de jailbreak que usa el método canOpenURL(_:) y requiere especificar las URLs que se consultarán.

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>undecimus</string>
    <string>sileo</string>
    <string>zbra</string>
    <string>filza</string>
</array>

Precios

Consulta nuestra licencia EULA para más detalles.

Resumen: Si tu empresa emplea:

  • 0-99 personas - uso gratuito
  • 100-1000 - 3k EUR/año
  • 1000+ - 10k EUR/año

Si quieres vender un módulo que use iOS Security Suite (no se usa directamente en tu aplicación) - 10k EUR/año

Aviso

iOS Security Suite está diseñado para usarse en iOS/iPadOS. No debe usarse en Macs con Apple Silicon.

Cómo usar

Módulo detector de jailbreak

  • El método más simple devuelve Verdadero/Falso si solo quieres saber si el dispositivo está jailbroken o no
if IOSSecuritySuite.amIJailbroken() {
	print("Este dispositivo está jailbroken")
} else {
	print("Este dispositivo no está jailbroken")
}
  • Detallado, si también quieres saber qué indicadores fueron identificados
let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage()
if jailbreakStatus.jailbroken {
	print("Este dispositivo está jailbroken")
	print("Porque: \(jailbreakStatus.failMessage)")
} else {
	print("Este dispositivo no está jailbroken")
}

El failMessage es una cadena que contiene indicadores separados por comas, como se muestra en el siguiente ejemplo: sileo:// Esquema de URL detectado, Archivo sospechoso existe: /Library/MobileSubstrate/MobileSubstrate.dylib, Fork pudo crear un nuevo proceso

  • Detallado y filtrable, si también quieres, por ejemplo, identificar dispositivos que estuvieron jailbroken en el pasado pero ahora no lo están
let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailedChecks()
if jailbreakStatus.jailbroken {
   if (jailbreakStatus.failedChecks.contains { $0.check == .existenceOfSuspiciousFiles }) && (jailbreakStatus.failedChecks.contains { $0.check == .suspiciousFilesCanBeOpened }) {
         print("Este es un dispositivo realmente jailbroken")
   }
}

Módulo detector de depurador

let amIDebugged: Bool = IOSSecuritySuite.amIDebugged()

Denegar depurador por completo

IOSSecuritySuite.denyDebugger()

Módulo detector de emulador

let runInEmulator: Bool = IOSSecuritySuite.amIRunInEmulator()

Módulo detector de herramientas de ingeniería inversa

  • El método más simple devuelve Verdadero/Falso si solo quieres saber si el dispositivo tiene evidencia de ingeniería inversa
if IOSSecuritySuite.amIReverseEngineered() {
  print("Este dispositivo tiene evidencia de ingeniería inversa")
} else {
  print("Este dispositivo no tiene evidencia de ingeniería inversa")
}
  • Detallado y filtrable, si también quieres la lista de verificaciones realizadas
let reverseStatus = IOSSecuritySuite.amIReverseEngineeredWithFailedChecks()
if reverseStatus.reverseEngineered {
   // consulta reverseStatus.failedChecks para más detalles
}

Módulo detector de proxy del sistema

Ahora también puedes detectar si una aplicación está conectada a una VPN

let amIProxied: Bool = IOSSecuritySuite.amIProxied(considerVPNConnectionAsProxy: true)

Módulo detector de modo de bloqueo

let amIInLockdownMode: Bool = IOSSecuritySuite.amIInLockdownMode()

Funcionalidades experimentales

Módulo detector de hooks en tiempo de ejecución

let amIRuntimeHooked: Bool = amIRuntimeHook(dyldWhiteList: dylds, detectionClass: SomeClass.self, selector: #selector(SomeClass.someFunction), isClassMethod: false)

Módulo de denegación de hooks de símbolos

// Si queremos denegar el hook de símbolo de una función Swift, tenemos que pasar el nombre mangled de esa función
denySymbolHook("$s10Foundation5NSLogyySS_s7CVarArg_pdtF")   // denegando el hook de la función NSLog
NSLog("Hello Symbol Hook")
     
denySymbolHook("abort") 
abort()

Módulo detector de MSHook

// Declaración de función
func someFunction(takes: Int) -> Bool {
	return false
} 

// Definiendo FunctionType : @convention(thin) indica una referencia de función "thin", que usa la convención de llamada de Swift sin parámetros especiales "self" o "context".
typealias FunctionType = @convention(thin) (Int) -> (Bool)

// Obteniendo la dirección del puntero de la función que queremos verificar
func getSwiftFunctionAddr(_ function: @escaping FunctionType) -> UnsafeMutableRawPointer {
	return unsafeBitCast(function, to: UnsafeMutableRawPointer.self)
}

let funcAddr = getSwiftFunctionAddr(someFunction)
let amIMSHooked = IOSSecuritySuite.amIMSHooked(funcAddr)

Módulo de denegación de MSHook

// Declaración de función
func denyDebugger(value: Int) {
}

// Definiendo FunctionType : @convention(thin) indica una referencia de función "thin", que usa la convención de llamada de Swift sin parámetros especiales "self" o "context".
typealias FunctionType = @convention(thin) (Int)->()

// Obteniendo la dirección de la función original
let funcDenyDebugger: FunctionType = denyDebugger 
let funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)


if let originalDenyDebugger = denyMSHook(funcAddr) {
// Llama a la función original con 1337 como argumento Int
     unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)
 } else {
     denyDebugger()
 }

Módulo verificador de integridad de archivos

// Determina si la aplicación ha sido manipulada
if IOSSecuritySuite.amITampered([.bundleID("biz.securing.FrameworkClientApp"),
    .mobileProvision("2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3"),
    .machO("IOSSecuritySuite", "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc")]).result {
    print("He sido manipulado.")
}
else {
    print("No he sido manipulado.")
}

// Verificar manualmente el valor hash SHA256 de un dylib cargado
if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom("IOSSecuritySuite")), hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" {
    print("No he sido manipulado.")
}
else {
    print("He sido manipulado.")
}
 
// Verificar el valor hash SHA256 del ejecutable principal
// Consejo: Tu aplicación puede recuperar este valor del servidor
if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == "tu-valor-hash-del-ejecutable-de-la-aplicación" {
    print("No he sido manipulado.")
}
else {
    print("He sido manipulado.")
}

Módulo de detección de puntos de interrupción

func denyDebugger() {
    // Establece un punto de interrupción aquí
}
     
typealias FunctionType = @convention(thin) ()->()
let func_denyDebugger: FunctionType = denyDebugger   // `: FunctionType` es obligatorio
let func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)
let hasBreakpoint = IOSSecuritySuite.hasBreakpointAt(func_addr, functionSize: nil)

if hasBreakpoint {
    print("Se encontró un punto de interrupción en la función especificada")
} else {
    print("No se encontró un punto de interrupción en la función especificada")
}

Módulo de detección de puntos de vigilancia

// Establece un punto de interrupción en la función testWatchpoint
func testWatchpoint() -> Bool{
		// lldb: watchpoint set expression ptr
    var ptr = malloc(9)
    // lldb: watchpoint set variable count
    var count = 3
    return IOSSecuritySuite.hasWatchpoint()
}

Consideraciones de seguridad

Antes de usar este y otros verificadores de seguridad de plataforma, debes entender que:

  • ¡Incluir esta herramienta en tu proyecto no es lo único que debes hacer para mejorar la seguridad de tu aplicación! Puedes leer un documento técnico general de seguridad móvil aquí.
  • Detectar si un dispositivo está jailbroken se realiza localmente en el dispositivo. ¡Esto significa que cualquier detector de jailbreak puede ser omitido (¡incluso este)!
  • Se considera que el código Swift es más difícil de manipular dinámicamente que Objective-C. Dado que esta librería está escrita en Swift puro, los métodos de IOSSecuritySuite no deberían estar expuestos al runtime de Objective-C (lo que hace más difícil sortearlos ✅). Debes saber que un atacante aún puede usar MSHookFunction/MSFindSymbol en símbolos de Swift y cambiar dinámicamente el flujo de ejecución del código Swift.

Contribución ❤️

¡Sí, por favor! Si tienes una mejor idea o simplemente quieres mejorar este proyecto, contáctame en Twitter o LinkedIn. ¡Las pull requests son más que bienvenidas!

Agradecimientos especiales: 👏🏻

  • kubajakowski por señalar el problema con el método canOpenURL(_:)
  • olbartek por la revisión de código y pull request
  • benbahrenburg por varias mejoras en ISS
  • fotiDim por agregar nuevas rutas de archivos a verificar
  • gcharita por agregar soporte para Swift Package Manager
  • rynaardb por crear el método amIJailbrokenWithFailedChecks()
  • undeaDD por varias mejoras en ISS
  • fnxpt por agregar múltiples detecciones de JB
  • TannerJin por los módulos de detección MSHook, RuntimeHook, SymbolHook y Watchpoint
  • NikoXu por agregar el módulo de integridad de archivos
  • hellpf por corregir un problema de socket colgante
  • Ant-tree por mejorar la resistencia a hooks
  • izmcm por implementar el método amIReverseEngineeredWithFailedChecks()
  • sanu por proporcionar nuevas verificaciones de archivos
  • marsepu por una PR bien hecha con nuevas mejoras
  • mkj-is por una PR que mejora el rendimiento de ISS 🚄
  • LongXiangGuo por una PR que agrega el manifiesto de privacidad
  • Coeur por mejoras y correcciones de errores en ISS
  • Adobels por ajustar ISS a los nuevos requisitos de Apple

TODO

  • Investigar la detección de Installer5 y Zebra Package Manager (alternativas a Cydia)
  • Detector de hidejb de Dopamine

Licencia

Consulta el archivo LICENSE.

Referencias

Al crear esta herramienta utilicé:

Categorías