Publié: septembre 7, 2023
Comprendre les changements apportés au bitcode d'Apple : renforcer la sécurité des applications grâce à la protection ARM
Niveau
Tout le monde est au courant. C'est le sujet de conversation du moment. Apple supprime le bitcode intégré dans Xcode 15. Le roi est mort ; vive le roi !
Le bitcode embarqué semblait initialement conçu pour permettre aux développeurs de soumettre une seule application compatible avec tous les produits Apple. Il masquait en grande partie les difficultés liées à la gestion des différentes architectures de processeurs. Bien qu'il soit clair depuis un certain temps qu'Apple souhaite standardiser toute sa gamme de produits sur l'architecture arm64, le bitcode embarqué facilitait la compatibilité multiplateforme et offrait à Apple un contrôle important sur le processus de compilation des applications distribuées sur l'App Store. Cette fonctionnalité n'a pas rencontré le succès escompté par Apple, mais sa suppression a provoqué un véritable séisme dans tout son écosystème de développement.
Quelques rumeurs, frôlant parfois la panique, ont circulé au sein de la communauté de la sécurité concernant un possible abandon total de LLVM par Apple. Ce changement réduit légèrement la dépendance d'Apple à LLVM, mais cela ne signifie pas nécessairement qu'Apple envisage de faire migrer la communauté open source Swift hors de LLVM. Ce serait un changement majeur, synonyme de disparition pour les protections du bitcode à la compilation. Swift est présenté comme le premier projet open source sur le site web d'Apple, et ses développeurs continuent d'y contribuer régulièrement. Leur dernier système d'exploitation, xrOS (surnommé « iMask »), a déjà été intégré à leur fork de LLVM. Bien qu'Apple n'hésite pas à opérer des changements radicaux, rien n'indique pour l'instant un abandon de LLVM. Même si cela reste possible, cela ne semble pas être une réalité à court terme, et toute affirmation contraire paraîtrait malhonnête. Les solutions actuelles reposant sur le bitcode à la compilation sont maintenues, et nous continuons de soutenir et de développer activement notre solution de protection des applications pour les produits Apple. Cela dit, les outils de protection qui s'intègrent au moment de la compilation sont nettement plus difficiles à intégrer et sont fragiles lorsqu'ils sont exposés à des modifications de la chaîne d'outils.
Avantages de la post-construction par rapport à la construction au moment de la construction
La possibilité, voire la recommandation, qu'avait Apple d'intégrer du bitcode dans un binaire a profondément transformé les outils de protection contre le bitcode. Les intégrations à la compilation sont instables, nécessitent une maintenance importante liée à Xcode et sont source de difficultés pour les organisations. Les outils de protection à la compilation ont tendance à limiter, voire à empêcher, la capacité d'une organisation à modifier ou à mettre à jour son système de compilation. La protection post-compilation représente l'avenir, mais cet avenir ne repose plus sur le bitcode. Reste la protection au niveau de l'assembleur. Bien que l'assembleur puisse être complexe et difficile à modifier, il offre une protection plus flexible, non limitée par des chaînes d'outils spécifiques et proposant un éventail de fonctionnalités plus large.
Avantages du code binaire par rapport à l'assembleur
L'un des principaux atouts du bitcode réside dans sa représentation (quasi) indépendante du processeur. Cet atout est désormais moins pertinent, Apple standardisant tous ses produits autour du jeu d'instructions arm64. Ce changement permet à tous les outils de protection Apple de se concentrer exclusivement sur l'assembleur arm64. Ce jeu d'instructions est une norme robuste et bien établie, permettant une approche plus ciblée pour contrer les analyses statiques et dynamiques. Bien qu'il soit plus difficile d'appliquer des protections aux binaires Mach-O, principalement en raison d'une analyse imparfaite, le résultat est une protection renforcée. Nos outils de protection ARM obscurcissent efficacement l'environnement et ajoutent des protections dynamiques aux packages d'applications IPA et Xcarchive. La protection de l'assembleur natif permet une stratégie de sécurité plus complète. Tous les binaires du package d'application peuvent être protégés en une seule opération. La protection des frameworks construits avec Swift Package Manager devient ainsi triviale, au lieu d'être extrêmement complexe, voire impossible.
Assemblage ARM
Le jeu d'instructions arm64 (plus précisément la version armv8) n'est pas excessivement complexe et se révèle remarquablement efficace. Il présente des avantages majeurs par rapport à l'assembleur x86 en matière d'analyse et d'obfuscation. Surtout, toutes les instructions arm64 font exactement quatre octets. De plus, l'utilisation de données dans le code est relativement rare (à l'exception des tables de commutation). Ces deux caractéristiques simplifient considérablement l'analyse binaire. Comme le dit l'adage : « Une analyse binaire complète est la première étape d'une stratégie d'obfuscation robuste. »
L'une de nos techniques d'obfuscation les plus efficaces pour contrer l'analyse statique est le découpage. Décomposer une sous-routine en plusieurs centaines de fragments et les disperser peut considérablement entraver l'analyse du flux de contrôle. Si leur déplacement est complexe, leur connexion correcte l'est encore plus. En interne, nous appelons ces connexions des « sauts » ; malheureusement, tous les sauts ne se valent pas. La prévisibilité étant l'ennemie de la sécurité, il est crucial d'utiliser tous les types de sauts. L'instruction AB (Branch), par exemple, a une plage de +/-128 Mo, tandis que l'instruction BR (Branch to Register) a une plage binaire. Cependant, l'instruction BR nécessite un registre contenant l'adresse de destination. Or, tous les registres ne sont pas adaptés. safe écrire à tous les points de l'exécution d'un binaire, et certains, comme x18, ne le font jamais safe L'utilisation de toutes les instructions de contrôle de flux est complexe. Trouver la plus appropriée est un véritable défi. Lorsque le découpage est combiné à des dizaines de milliers d'obfuscations par substitution d'instructions, les attaquants doivent naviguer avec une dextérité impressionnante dans Ghidra pour accéder à une simple sous-routine.
Activation des protections hybrides
L'écosystème des applications hybrides est assez complexe, et heureusement, les protections au niveau de l'assembly permettent des protections hybrides plus simples et plus complètes. Les applications Flutter ne peuvent pas exploiter les solutions de protection du bitcode, car le système de compilation de Flutter n'y a pas accès. De même, .NET 7+ de Microsoft avec MAUI limite également la possibilité de générer du bitcode. Flutter et d'autres frameworks hybrides utilisent cependant la compilation AoT pour créer des binaires arm64. Les protections ARM post-compilation peuvent obfusquer et ajouter une protection active à ces binaires, comme pour toute autre application iOS. Les protections fonctionnent immédiatement pour la quasi-totalité des packages d'applications iOS. Permettre aux équipes de développement de protéger tous les binaires de leur package d'application en un seul appel, voilà ce que signifie un véritable changement de paradigme vers la gauche.
Comment le post-build peut s'intégrer à l'intégration continue
Un CI/CD DevSecOps Le pipeline est désormais une norme industrielle bien établie, et rien n'est plus frustrant que de déboguer les problèmes de compilation au sein de ce pipeline. L'ajout d'un simple appel à un système CI/CD juste après la compilation, mais juste avant les tests, constitue une intégration simple et rapide, et permet de maintenir le développement, les tests et les déploiements fluides. DevOps Les équipes travaillent à plein régime. La protection post-compilation peut s'intégrer au pipeline CI/CD standard. Ainsi, il n'est pas nécessaire d'installer et de licencier les outils de protection sur chaque poste de développement, ni de les exécuter à chaque compilation. Nous avons constaté d'innombrables problèmes causés par les protections au moment de la compilation, même dans des environnements CI/CD bien conçus. Opter pour une solution de sécurité post-compilation permet aux équipes de maîtriser et de modifier leur processus de compilation, tout en garantissant le bon déroulement des exécutions CI/CD et la satisfaction des équipes de développement. Nos équipes apprécient le vert ; après tout, il figure dans notre logo. Enfin, n'oubliez jamais : un pointeur de pile aligné sur 16 octets permet d'éviter l'erreur EXC_BAD_ACCESS.
Explorez plus en détail l'avenir de la sécurité des applications iOS avec ARM Protection et comment elle peut safeProtégez vos applications contre les menaces en constante évolution grâce à notre blog.Présentation d'ARM Protection : une solution révolutionnaire pour la sécurité des applications iOS
Vous aimerez aussi
Comment respecter (et dépasser !) la norme IEEE 1735
Le mois dernier, j'ai reçu un courriel de recrutement d'une personne prétendant…
Les trois arguments les plus convaincants contre la cryptographie en boîte blanche – et pourquoi ils sont à côté de la plaque.
Dans la première partie de cette série, nous avons examiné où…
La sécurité de votre matériel fonctionne. Ce n'est pas le problème.
On entend régulièrement une version de cette objection : « Nous sommes déjà…