Macaron Une porte dérobée pour JavaEE - Philippe PRADOS
←
→
Transcription du contenu de la page
Si votre navigateur ne rend pas la page correctement, lisez s'il vous plaît le contenu de la page ci-dessous
Curriculum Vitae » Philippe PRADOS » Architecte, Consultant » Expert sécurité applicative » Nombreuses publications 2
Le risque » Combien faut-il payer pour convaincre un développeur d'insérer un code malveillant ? 10.000$ US ? » « La plupart des agressions dont sont victimes les entreprises viennent de l’intérieur. Les différentes études estiment ce chiffre aux alentours de 80%. » Pascal Courtin, chef de la Brigade d’Enquête sur les Fraudes aux Technologies de l’Information » Cas réels de « traitrise », » Un site US de e-commerce développé en inde. Un développeur a ajouté du code pour lister toutes les informations bancaires. » Utilisation frauduleuse de milliers de cartes bancaires. » e-bay, » Modem Alcatel ADSL » Ministère des finances » TS Ameritrade (2007) » ... 3
Les travaux de recherche Atos Origin » Plusieurs mois de recherche pour identifier différentes techniques d'attaques » Résistant aux audits classiques » Résistant à tous les outils de protection (firewall réseau ou applicatif) » Identification de nouvelles failles » La porte dérobée « macaron » » Permet des attaques internes au projet (présence d'un traite) » Ou des attaques externes ! » lors de l'intégration de composants logiciels. » Travaux viennent d'être publiés » Symposium sur la Sécurité des Technologies de l'Information et des Communications (Juin 2009) » Publication dans MISC (magazine de référence) et GNU Linux Mag 4
Backdoor JavaEE » L'affaire Kerviel à démontré que les attaques peuvent venir de l'intérieur. » Les développeurs peuvent volontairement laisser des portes dérobés permettant une exploitation inhabituelle de l'application if (contribuable.equals("philippe") impot=(byte)impot; » Comment s'en protéger ? » Quelles techniques sont utilisées ? 6
À la place du pirate » Pour étudier les possibilités d'injecter des portes dérobées dans les applications JavaEE nous allons nous positionner - pour la bonne cause - dans l'optique d'un pirate. » Quels sont les objectifs ? » Quels sont les moyens de détection à contourner ? » Quels sont les solutions de protection ? 7
Une porte dérobée » Doit résister à un audit du code de l'application » La découverte est sinon possible par chaque développeur qui participe au projet » Doit résister aux évolutions futures du code » Il ne doit pas y avoir de dépendance avec le code existant. Une évolution de l'application ne doit pas faire échec à la porte dérobée. » Doit contourner le firewall réseau et le firewall applicatif » La communication avec la porte doit être invisible. » Contourner les outils d'analyse de vulnérabilité dans le byte-code, par propagation de teinture sur les variables. 9
Objectifs » Résister aux audits applicatifs » Le code de la porte dérobée ne doit pas être présent dans les sources ; » L'application ne doit pas l'invoquer ; » Solution: - Présent dans une archive déclarée saine (JAR). - Utilisation de pièges pour exécution implicite de code » Résister aux évolutions future du code » Le code doit être actif, quelque soit l'application pervertie. » Solution: - Utiliser des attaques génériques, exploitant les spécifications JavaEE » Doit contourner le firewall réseau et le firewall applicatif » Solution: - Simuler une navigation légitime de l'application » Contourner les outils d'analyse de vulnérabilité dans le byte-code » Utiliser du code d'échappement des analyses de code. 10
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Les pièges » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 11
Les pièges : Initialisation de la porte dérobé » La porte dérobé doit pouvoir démarrer alors que le code applicatif ignore sa présence. » Il faut utiliser une technique permettant une exécution de code par la simple présence de l'archive JAR » Plusieurs pièges : » Surcharge d'une classe » Ajout d'un fichier de paramétrage » Exploitation d'un « Ressource Bundle » » Exploitation des « services » » Exploitation de l'AOP » Utilisation des annotations 12
Piège : Surcharge de classes » Dupliquer une classe de l'application ou d'une autre librairie pour enrichir son comportement » Les classes sont recherchées dans toutes les librairies, les unes après les autres. » Si la librairie de la porte dérobée à la chance d'être avant la librairie originale, le code de la porte dérobée s'exécute a'.class a.class 13
Piège : Surcharge de classes » Inconvénient : » Le code de la porte dérobée est fortement dépendant du code original ; » Il est difficile de propager les traitements sur l'original en mode « hook » ; » La modification de l'original peut entraîner le plantage de l'application ; » L'exécution n'est pas garantie. Cela dépend de l'ordre de sélection des archives par la JVM » Approche rejetée 14
Piège : Paramétrage » Utilisation de fichiers de paramétrages » Certains frameworks recherchent des fichiers de paramètres à différents endroits dans les archives. » Ces fichiers possèdent des noms de classes. » En plaçant un fichier de paramètre dans un lieu prioritaire, il est possible d'injecter du code » Et de déléguer le comportement à la classe originale. 15
Piège : Paramétrage » Exemple : Axis (Invocation de Web-services) » recherche le fichier client-config.wsdd » Dans : - /WEB-INF/ - /WEB-INF/ - / » Ce dernier indique les classes en charge des transports lors de l'invocation d'un service Web » La présence du fichier dans la racine d'une archive quelconque suffit à injecter du code lors de l'invocation du premier service Web 16
Piège : ResourceBundle 1/4 » Pour gérer les messages en plusieurs langues, Java utilise des ResourcesBundles. » L'algorithme recherche un fichier .properties suivant différents critères de langues. 17
Piège : ResourceBundle 2/4 » ResourceBundle.getBundle("Messages") » Lecture de fichier .properties (clef/valeur) Messages_fr_FR.properties Messages_fr.properties Messages.properties 18
Piège : ResourceBundle 3/4 » ResourceBundle.getBundle("Messages") » Mais avant cela, recherche de classes Messages_fr_FR.class Messages_fr_FR.properties Messages_fr.class Messages_fr.properties Messages.class Messages.properties 19
Piège : ResourceBundle 4/4 » Simuler un comportement classique, tous en ajoutant du code public static class messages extends PropertyResourceBundle { public messages() throws IOException { super(messages.class.getResourceAsStream( '/'+messages.class.getName() .replace('.','/')+".properties")); System.err.println( "*** Backdoor-JavaEE start via"+ " the RessourceBundle "+getClass().getName()); } } 20
Pièges : Exploitation des services » Fichier META-INF/services/xxx » Permet aux archives de proposer des implémentations de services » Utilisé par les parseurs XML, Log4j, et tous les composants JavaEE » Un service peut détourner un parseur XML pour modifier le flux avant son analyse. » Permet l'injection de paramètres complémentaires pour les frameworks (Log4j, Spring, etc.). 21
Piège : AOP » Les « aspect » sont décrit dans un fichier aop.xml » C'est une technologie naturelle d'injection de code » Il est alors facile d'injecter du traitement n'importe où, » Entre autre, dans toutes les servlets. 22
Piège : Annotation » De plus en plus de framework utilisent l'annotation pour identifier des classes et des instances à initialiser. » C'est un objectif de l'annotation : réduire la paramétrage. » Par exemple, Spring instancie les classes étant annotées de @Component ou @Repository. » Contrainte : Il faut déclarer une classe dans un répertoire consulté par l'application lors de son initialisation. » Contrainte levée avec les spécifications Servlet 3.0. » Toutes les classes sont consultées pour les nouvelles annotations (@Filter) 23
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Les pièges » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 24
Les droits lors de l'exécution du piège » Le code du piège n'a pas toujours les droits nécessaires à la mise en place judicieuse de la porte dérobée. » Si la porte dérobée ne bénéficie pas d'un environnement idéal pour installer tous le nécessaire, elle doit augmenter ses privilèges. » Les privilèges peuvent être des droits à des API (Sécurité Java2) » ou pouvoir accéder à des classes du serveur d'application. » Les classes sont isolées dans des ClassLoaders différents » Les applications n'ont pas accès à toutes les classes du serveur d'application Communs Serveur d'application Applications Applications 25
Augmentation de privilèges » La porte dérobée doit s'insérer dans l'application et y rester après un redémarrage, avec plus de privilège. » Une copie d'une archive dans un répertoire plus privilégié permettra d'augmenter les droits du code (répertoire des archives de Tomcat) » La technique de ResourceBundle sur une ressource de Tomcat permet l'injection de code lors du redémarrage du serveur d'application. » Technique parfois nécessaire en Tomcat 5, mais plus en Tomcat 6 ! 26
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Les pièges » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 27
Où insérer la porte dérobée ? » L'idéal est de pouvoir l'injecter dans chaque requête pour y détecter une clef spécifique ouvrant la porte. » Plusieurs stratégies : » Ajout d'un filtre JavaEE » Ajouter dynamiquement une Valve Tomcat » Injection par XML » Injection par Autoproxy » Injection par Aspect » Injection lors de la compilation 28
Injection : Ajout d'un filtre JavaEE 1/2 » Le serveur Tomcat dé-zip les archives des composants dans un répertoire de travail. » Le piège de la porte dérobé » retrouve le fichier web.xml du cache de Tomcat » Injecte un filtre JavaEE dans ce fichier » Le filtre sera présent après un redémarrage de Tomcat » Avec les Servlet 3.0 : » nouvelle API : ServletContext.addFilter(...) » Ou web-fragment.xml 29
Injection : Ajout d'un filtre JavaEE 1/2 » Le filtre JavaEE capture toute les requêtes ... BackDoor BackDoorFilter BackDoor /* ... 30
Injection : Valve Tomcat » Tomcat propose des Valves (filtres spécifiques) pouvant être ajoutée dynamiquement via une requête JMX » Avec Tomcat 5, » Nécessite une augmentation de privilège (pour avoir accès à la classe Valve) » Ou présence de l'attribut privileged="true" dans » Avec Tomcat 6, » Toujours possible, si le serveur n'utilise pas la sécurité Java2 31
Injection : Parseur XML » En déclarant un service, » Détournement d'un parseur XML pour modifier le flux avant analyse par les frameworks » Permet l'injection de dans Spring, la manipulation des logs, etc. » Pas de solution de protection autre que l'application du patch JDK que nous avons publié. 32
Injection : Auto-Proxy » Les proxies du JDK où généré par CGLIB, permettent d'injecter du code dans les singletons. » Le privilège suppressAccessChecks permet alors de modifier les singletons. » Et même de modifier des instances immuables « String » 33
Injection : Aspect » La programmation par Aspect permet naturellement l'injection de code dans l'application. » Si la fonctionnalité est présente globalement (via l'agent AspectJ), » Tous le flux de traitement vers les requêtes ou les fichiers JSP peuvent être détournés. @Aspect public static class BackDoorAspect { @Around("execution(void doGet(..))" + "|| execution(void doPost(..))" + "|| execution(void service(..))" + "|| execution(void _jspService(..))") public void backdoor(ProceedingJoinPoint pjp) throws Throwable { ... } } 34
Injection : Servlet 3.0 » Les nouvelles annotations permettent naturellement les injections » De servlet » De filtre, » De session listener » Etc. » Plus les technologies évolues, plus les attaques sont faciles. 35
Injection : lors de la compilation » JSR268 est un service, permettant d'ajouter des plugins lors de la compilation » Permet » l'ajout de classe, » de librairie » De fichiers de paramètres » voir la modification du byte code d'une classe compilée ! » L'audit du code source ne révèle rien. » La vérification des composants et leurs signatures ne révèle rien ! » Il faut décompiler le code pour trouver l'attaque ! 36
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Les pièges » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 37
Détection de l'ouverture » Sur la présence d'une clef dans un champ quelconque de n'importe quel formulaire : » détournement du traitement vers la porte dérobée » La clef est le mot MACARON en écriture Elit :« M4c4r0n » 38
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Initialisation » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 39
Évasion des firewall applicatif » Les firewalls applicatifs détectent : » Les URLs utilisées via une liste blanche » La liste des champs pour les URLs et les contraintes de format (chiffre/lettre, taille, etc.) » La vitesse des requêtes (n requêtes par secondes maximum pour un humain). Attention, les robots violent cette contrainte. » Une liste noire de mot clef dans les réponses. 40
Pour contourner... » Le filtre utilise une URL standard de l'application, celle utilisée pour insérer la clef. » La communication s'effectue en remplissant un formulaire avec une valeur spéciale (conforme aux contraintes des champs) » Les agents de la porte dérobées n'utilisent alors que cette URL, en soumettant toujours le même formulaire, avec les mêmes valeurs. » Sauf pour un seul champ qui sert de transport » Le code injecté capture les requêtes avant l'application. » Et offre différents services d'attaques en exploitant AJAX. 41
Le scénario d'attaque est le suivant » Étape 1 : Si nécessaire, augmentation des privilèges » Utilisation d'un piège » Déplacement de l'archive de la porte dérobée » Attente d'un redémarrage du serveur d'application » Étape 2 : Installation effective de la porte dérobé » Utilisation d'un piège avec plus de privilèges » Injection d'un filtre sur toutes les requêtes » Détection de la clef pour détourner le flux de traitement des requêtes » Étape 3 : Utilisation des agents disponibles, suivant les privilèges accordés à l'application. 42
Sommaire » Objectif du pirate » Démonstration » Implémentation » Propagation » Les pièges » Solutions » Augmentation des privilèges » Exécution » Détection de l'ouverture » Discrétion » Les agents 43
Les agents » Différents agents d'analyses sont disponibles » History (les dernières requêtes) » JNDI (Annuaire d'objets : DB, files, etc.) » JMX (Outils de gestions dynamique du serveur) » JDBC (Base de donnée) » Java (Compilation et exécution dynamique de code) » Shell (Pour exploiter le serveur) 44
Sommaire » Objectif du pirate » Implémentation » Démonstration » Propagation » Solutions 45
Demonstration La démo 46
Diffusion » Le code est un bon exemple de ce que peut faire un développeur inconvenant » Pour vérifier que les protections sont en place, il faut les chalenger » Le code proposé sert à cela (POC) » Il vous permet de qualifier votre environnement » Il est diffusé en archive non hostile, pas en source. 47
Diffusion = risque ? » « Vous diffusez un code de pirate ! » » Pour éviter des usages malvenus, le code est techniquement fortement protégé contre la décompilation. » Un pirate étant capable de le décompiler est capable de l'écrire, et cela plus rapidement ;-) » Il est volontairement très verbeux. Les logs présents reçoivent un message signalant clairement sa présence et ce qu'il fait. 48
Diffusion = risque ? » La clef est codé en « dur » et ne peut pas être modifiée » Une simple règle du firewall permet alors d'interdire son usage depuis le réseau. » Il suffit de détecter le mot « M4c4r0n » pour couper la communication. 49
Le code à vocation « preuve de concept » » Il peut être utilisé pour qualifier l'environnement d'exécution » Les sources n'étant pas publique, rien ne garantie qu'il n'y a pas de deuxième porte dérobée dans le code (bon reflex!). » J'affirme que ce n'est pas le cas, mais vous ne pouvez le vérifier sans une étude approfondie. » Conclusion : ne pas l'utiliser en production » Vous avez alors saisie le message important de cette présentation 50
Sommaire » Objectif du pirate » Implémentation » Démonstration » Propagation » Solutions 51
Injection de la porte dans un projet » Attaque interne (présence d'un traite) : » Injecter le code dans une archive d'un Open Source ou non, utilisé par le projet » Déclarer une dépendance MAVEN dans un des composants du projet » ... » Attaque externe : » Déclarer une dépendance MAVEN dans le repository standard de MAVEN. » Attaquer le compte d'un contributeur et injecter la porte dans un composant Open Source » Possible même si le composant en question n'est pas présent en production ! (via le JSR269) » Ainsi, tous les projets injectent la porte dérobée ! 52
Sommaire » Objectif du pirate » Implémentation » Démonstration » Propagation » Solutions 53
Pourquoi ce risque » Risque inhérents aux développements Java actuels » Confiance absolue accordée » aux développeurs, » prestataires, » composants tiers. » Des solutions existent, mais » Ignorées des développeurs » Complexes à appliquer 54
Solutions » Atos Origin propose avec « Macaron » trois outils d'aide à l'identification et au renforcement des développements » Expertise pratiquement unique d'Atos Origin sur le sujet. » Seulement deux publications (approches complémentaires) » « Macaron » en Juin 2009 au SSTIC par Philippe Prados, Atos Origin » « Entreprise Java Rootkits » en Aout 2009 par Jeff Williams au BlackHat 55
Les solutions Java » Java possède un mode « sécurisé » limitant fortement les possibilités de la porte dérobée » Correctement utilisé, la porte dérobée ne peut s'installer en tant que filtre et capturer tous le trafic. » Permet de confiner le code serveur dans un « bac à sable » » Lorsque la sécurité Java est activé, les APIs disponibles sont limitées » Les classes du serveurs d'applications ont tous les privilèges, mais pas les applications hébergées 56
L'utilisation de la sécurité Java » Dans ce mode, » les projets doivent déclarer des privilèges pour leurs projets (accès à certains répertoires, certaines machines du réseau, etc.) » Attention, l'ouverture de privilèges peut également permettre les portes dérobées. » Il faut ouvrir les privilèges pour chaque archive et non globalement pour l'application. » Ainsi, un droit offert à un framework n'est pas disponible pour la porte dérobée. » Mais, cette information est rarement disponible. » Seul un test permet d'ouvrir, au fur et à mesure, l'ensemble des droits nécessaires à l'application » Macaron-policy facilite la gestion des privilèges 57
Archives scellée » Java permet également de sceller les packages dans les archives. » Ainsi, si la sécurité Java est active, toutes les classes d'un package doivent venir de la même archive. » Protège des attaques par remplacement de classes. » Macaron-seal facilite le scellement de tous les composants 58
Dans la vraie vie » Les serveurs d'applications utilisent rarement la sécurité Java2 » Pourquoi ? » Les développeurs ne connaissent pas » N'ayant jamais testé ce mode, ils ne savent pas les droits minimums nécessaires. » Dans le doute, pour ne pas faire planter l'application, tous les privilèges sont ouverts » Cela complexifie l'installation des composants car il faut modifier un fichier global du serveur d'application (*.policy). » Impact sur les performances sur-estimé 59
Tomcat » Tomcat propose un paramètre pour utiliser la sécurité Java2. » ./catalina.sh run -security » Il aurait été préférable d'avoir la sécurité par défaut, et un paramètre pour la supprimer. » Les droits peuvent être spécialisés pour chaque composant applicatif. 60
JBoss » JBoss ne propose pas la sécurité Java 2 ! » Le wiki indique comment modifier le script de lancement pour ajouter les droits » Mais, par défaut, il n'est pas possible d'indiquer des droits différents pour chaque composant ou chaque archive. » Un paramètre permet de modifier cela. » Par défaut, sous JBoss, la porte dérobée est pratiquement toujours possible ! 61
Détection » Différent symptôme peuvent éveiller les soupçons : » La présence de classes ou de package de même nom dans des archives différentes » La présence de fichiers de même nom à des emplacement différents » La présence de fichiers de même nom avec des extensions différentes dans les mêmes répertoires. » La présence de certaines annotations » Macaron-audit permet d'identifier les risques 62
Deux patchs à OpenJDK 6 sont proposés » Pour contrer les attaques » RessourceBundle » ServiceLocator » Deux patchs sont proposés. » SUN et Tomcat travaillent sur ces vulnérabilités, sur la base de nos patchs 63
Conclusion » Vous n'êtes pas obligé de faire confiance aux développeurs » Imposez l'utilisation de la sécurité Java2 dès les phases de développement » Ne faite pas confiance aux repositories » Limité au maximum les droits ouverts aux projets et aux composants » Testez l'utilisation de la porte dérobée « macaron » dans votre projet. » Il suffit d'ajouter une archive. Il n'est pas nécessaire de modifier le code. » En production, vous pourrez alors choisir d'activer ou non la sécurité, suivant le niveau d'alerte du moment. 64
Offre » Macaron-audit » « Vos développements Java vous exposent-ils à ce risque » ? » Audit par sondage ou complet des dév. Java » Utilisation des outils + analyse d'un expert » Rapport détaillé » Failles détectées, criticité » Comment y remédier » Macaron-best practices » Mise en place des processus préventifs et de l'outillage » Rédaction de charte de développement » Coaching des équipes de développement » Macaron-fix in » Recherche de preuves » Option « durcissement des dév. » dans nos offres de TMA 65
Questions ? 66
Pour plus d’informations, contacter : Philippe PRADOS +33 (0)6 70 03 89 60 macaron@prados.fr Atos Origin 18 avenue d'Alsace 92926, Paris la Défense Cedex www.atosorigin.fr
Vous pouvez aussi lire