Publicado: septiembre 7, 2023
Cómo adaptarse a los cambios de Bitcode de Apple: Reforzando la seguridad de las apps con ARM Protection
Conjunto de niveles
Todo el mundo lo sabe. Es el tema de conversación del momento. Apple elimina el bitcode integrado en Xcode 15. El rey ha muerto; ¡viva el rey!
El código de bits integrado parecía originalmente diseñado para permitir a los desarrolladores enviar una sola aplicación compatible con todos los productos de Apple. El código de bits simplifica en gran medida la gestión de las diferentes arquitecturas de procesadores. Si bien desde hace tiempo está claro que Apple pretendía estandarizar toda su línea de productos en arm64, el código de bits integrado podría utilizarse para facilitar la compatibilidad multiplataforma y otorgar a Apple un control considerable sobre el proceso de compilación de las aplicaciones distribuidas en la App Store. Esta función no tuvo la acogida que Apple hubiera deseado, pero su eliminación ha tenido un gran impacto en todo su ecosistema de desarrollo.
En la comunidad de seguridad, algunos miembros han mencionado, con cierto tono alarmista, la posibilidad de que Apple abandone LLVM por completo. Este cambio reduce ligeramente la dependencia de Apple en LLVM en general, pero eso no significa necesariamente que Apple pretenda migrar a la comunidad de código abierto de Swift fuera de LLVM. Eso supondría un cambio radical y la desaparición de las protecciones de bitcode en tiempo de compilación. Swift figura como el primer proyecto de código abierto en el sitio web de Apple, y sus desarrolladores siguen contribuyendo regularmente. Su sistema operativo más reciente, xrOS (similar a iMask), ya se ha añadido a su bifurcación de LLVM. Si bien Apple no teme realizar cambios drásticos, no hay indicios adicionales que sugieran un abandono de LLVM. Aunque es posible, no parece una realidad a corto plazo, y cualquier afirmación en sentido contrario suena poco sincera. Las soluciones actuales que dependen del bitcode en tiempo de compilación no desaparecerán, y seguimos dando soporte y desarrollando activamente nuestra actual Protección de Aplicaciones para productos Apple. Dicho esto, las herramientas de protección que se integran en tiempo de compilación son significativamente más difíciles de integrar y son frágiles cuando se exponen a cambios en la cadena de herramientas.
Ventajas de la postconstrucción frente al tiempo de construcción
La capacidad original de Apple para incrustar bitcode en un binario, y su recomendación al respecto, supusieron un cambio radical para las herramientas de protección de bitcode. Las integraciones en tiempo de compilación son inestables, requieren un mantenimiento importante relacionado con Xcode y generan muchos problemas a las organizaciones. Las herramientas de protección en tiempo de compilación suelen afectar negativamente, o incluso impedir, la capacidad de una organización para modificar o actualizar su sistema de compilación. La protección posterior a la compilación es el futuro, pero ese futuro ya no incluye bitcode. Esto nos lleva a la protección a nivel de ensamblado. Si bien el ensamblado puede ser complejo y difícil de modificar, el resultado final es una protección más flexible que no está limitada por cadenas de herramientas específicas y ofrece una gama más amplia de capacidades de protección.
Ventajas del código binario frente al ensamblaje
Una de las principales ventajas del bitcode es su representación (en su mayoría) independiente del procesador. Esta ventaja pierde relevancia ahora que Apple está estandarizando todos sus productos en torno al conjunto de instrucciones arm64. Este cambio permite que todas las herramientas de protección basadas en Apple se centren exclusivamente en el ensamblador arm64. El conjunto de instrucciones arm64 es un estándar sólido y bien conocido, lo que permite un enfoque más preciso para contrarrestar el análisis estático y dinámico. Si bien es más difícil aplicar protecciones a los binarios Mach-O, principalmente debido a un análisis imperfecto, el resultado final es una protección más robusta. Nuestras herramientas de protección basadas en ARM ofuscan con éxito y añaden protecciones ambientales dinámicas a los paquetes de aplicaciones IPA y Xcarchive. Proteger el ensamblador nativo permite una estrategia de seguridad más completa. Todos los binarios del paquete de la aplicación se pueden proteger en un único proceso. Proteger los frameworks creados con Swift Package Manager se vuelve trivial en lugar de extremadamente complejo o imposible.
Ensamblaje de brazo
El conjunto de instrucciones arm64 (específicamente la versión armv8) no es excesivamente complejo y es sorprendentemente eficiente. Presenta importantes ventajas sobre el ensamblador x86 en cuanto a análisis y ofuscación. Lo más importante es que todas las instrucciones arm64 tienen exactamente cuatro bytes. Además, la presencia de datos en el código no es muy común (excepto en las tablas de conmutación). Estas dos características simplifican enormemente el análisis binario. Como dice el refrán: «Un análisis binario exhaustivo es el primer paso de una estrategia de ofuscación sólida».
Una de nuestras técnicas de ofuscación más efectivas para contrarrestar el análisis estático es la fragmentación. Descomponer una sola subrutina en cientos de partes y dispersarlas puede dificultar enormemente el análisis del flujo de control. Si bien moverlas es difícil, conectarlas correctamente lo es aún más. Internamente, llamamos a estas conexiones "saltos"; lamentablemente, no todos los saltos son iguales. La predictibilidad es el enemigo de la seguridad, por lo que utilizar todos los tipos de saltos es fundamental. La instrucción AB (Salto), por ejemplo, solo tiene un rango de +/-128 MB, mientras que una instrucción BR (Salto a Registro) tiene un rango binario. Sin embargo, una instrucción BR requiere un registro que contenga la dirección al que saltar. No todos los registros son compatibles. safe escribir en cualquier punto de la ejecución de un binario, y algunos, como x18, nunca lo hacen. safe su uso es complejo. Todas las instrucciones de control de flujo tienen ventajas e inconvenientes, y encontrar la adecuada para cada tarea es todo un reto. Cuando se combina la fragmentación con decenas de miles de sustituciones de instrucciones para ofuscar el código, los atacantes tienen que moverse con la destreza de un campeón mundial de Pogopalooza para leer una sola subrutina.
Habilitación de protecciones híbridas
El panorama de las aplicaciones híbridas es bastante complejo, y afortunadamente, las protecciones a nivel de ensamblado permiten una protección híbrida más sencilla y completa. Las aplicaciones Flutter no pueden aprovechar las soluciones de protección de bitcode, ya que su sistema de compilación no ofrece una ruta para acceder a él. Del mismo modo, .NET 7+ de Microsoft con MAUI también limita la capacidad de generar bitcode. Sin embargo, Flutter y otros frameworks híbridos utilizan la compilación AoT para generar binarios arm64. Las protecciones ARM posteriores a la compilación pueden ofuscar y añadir protección activa a estos binarios, al igual que a cualquier otra aplicación iOS. Las protecciones funcionan sin problemas para casi todos los paquetes de aplicaciones iOS. Permitir a los equipos de desarrollo proteger todos los binarios de su paquete de aplicación con una sola llamada es un verdadero ejemplo de integración de código en el desarrollo.
Cómo la post-compilación puede integrarse en la CI
Un CI/CD DevSecOps El pipeline es ahora un estándar industrial bien conocido, y nada es más frustrante que depurar problemas de compilación en dicho pipeline. Añadir una sola llamada a un sistema CI/CD justo después de la compilación, pero antes de las pruebas, es una integración sencilla que mantiene el desarrollo, las pruebas y DevOps Los equipos trabajan a toda velocidad. La protección posterior a la compilación puede integrarse en el flujo de trabajo habitual de CI/CD. Esto significa que no es necesario instalar ni licenciar las herramientas de protección en cada máquina de desarrollador ni ejecutarlas en cada compilación de desarrollo. Hemos observado innumerables problemas causados por las protecciones en tiempo de compilación en entornos de CI/CD bien diseñados. Al implementar una solución de seguridad posterior a la compilación, los equipos pueden controlar y modificar su proceso de compilación, manteniendo la CI/CD funcionando correctamente y a los equipos de desarrollo satisfechos. A nuestros equipos les gusta el color verde; al fin y al cabo, está en nuestro logotipo. Por último, recuerde siempre: un puntero de pila alineado a 16 bytes evita el error EXC_BAD_ACCESS.
Explora más a fondo el futuro de la seguridad de las aplicaciones iOS con ARM Protection y cómo puede safeProteja sus aplicaciones contra las amenazas en constante evolución en nuestro blog.Presentamos ARM Protection: Un cambio radical para la seguridad de las aplicaciones iOS.
También puede interesarle
Lo que la prensa convencional no entiende sobre Mythos
Hemos visto cómo algunas historias sobre ciberseguridad han llegado a los medios de comunicación...
Ataques de IA con agentes: El agente Smith ha salido de su retiro.
Los atacantes de Nature-Free Evolution siguen ampliando los límites de la IA…
Combatir el fuego con fuego: usar la IA para combatir la IA
Los ataques a aplicaciones aumentaron al 83% en enero de 2025, frente al 65% de hace apenas…