V3.1 Programmation sécurisée Classes de vulnérabilités « If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization. » -- Gerald Weinberg - http://en.wikipedia.org/wiki/Gerald_Weinberg Conception www.failblog.org Conception • Vulnérabilité de conception : vulnérabilité dans l’architecture de l’application ou les choix « stratégiques » de l’application – Agencement des composants – Choix des modèles d’application / des protocoles Conception • Exemples de cas d’erreur de conception : – Faible séparation des tâches et des opérations Si une opération est compromise alors l’ensemble des opérations est impacté – Absence d’approche modulaire Périmètre du programme à sécuriser est plus important / fragmenté Redondance du code et donc des vulnérabilités – Mauvais choix des algorithmes et des normes utilisées Implémentation • Erreur dans l’implémentation: écart entre les spécifications et l’implémentation d’une fonctionnalité – Un attaquant va exploiter un défaut d’implémentation d’un protocole réseau, d’un algorithme, etc. – Il est nécessaire de connaitre parfaitement le langage de programmation et ses pièges • Certains langages plus « faciles » que d’autres – Exemple: C vs Java • Importance de la relecture du code – Exemple MS : 1 développeur = 1 relecteur – Adhérence à la sécurité du système d’exploitation : • Utilisation des bibliothèques spécifiques au système Implémentation • Erreur dans le code : – créer par le développeur (cas le plus courant) – créer par un outil automatique et à modifier/adapter par le développeur – créer par un outil automatique et non modifié par le développeur • Exemple: ATL et vulnérabilité ATL • Erreurs d’implémentation abordées en détail par la suite Implémentation • TP : Mise en place d’un environnement de développement sous Windows – Windows 7 (utilisation exclusive pour des tests) – Visual Studio 2013 – Virtual Box : • réseau en NAT • disque IDE attaché sur le fichier distribué – Hello World Configuration • Erreur lors de la configuration ou l’intégration du logiciel – Ruine les étapes préalables : architecture et implémentation sécurisées • Intégration/Déploiement : – Un logiciels possède toujours un configuration « par défaut » • Partir du principe qu’il s’agit de la configuration la plus rencontrée – importance de « securiser par défaut » – Une méthode d’installation / déploiement accompagne logiciel • Existence d’un guide ou d’une procédure automatique pour que le logiciel soit installé comme prévu • Prévoir la sécurité de la configuration de l’environnement notamment si le logiciel repose sur d’autres applications Configuration • Exemples de vulnérabilités : – Exemple 1 : le déploiement final entraîne une vulnérabilité critique. Par défaut, l’application nécessite que l’utilisateur soit administrateur du poste alors qu’elle supporte un utilisateur standard – Exemple 2 : L’application repose sur un serveur FTP pour la transmission d’information. La mauvaise configuration de ce serveur permet la lecture du disque complet – Exemple 3 : Le guide d’installation contient les mots de passe d’exemple utilisée par les utilisateurs Configuration • Bon usage de l’application par les utilisateurs : – Vérifier les possibilités offertes à l’utilisateur (volontaire / involontaire) Exemple: suppression de la base de données – Droits par défaut de l’utilisateur sur l’application/le système Exemple: Respect du principe de moindre privilège – Guide utilisateur / sensibilisation Exemple: Vérifier sa diffusion et en particulier ses mises à jour Typologie des vulnérabilités • Classification des vulnérabilités par impact : – Disponibilité / Confidentialité / Intégrité – Preuve – Divulgation de données personnelles : cas particulier d’attaque en confidentialité mais généralement à traiter à part Typologie des vulnérabilités • Tentative de normalisation des vulnérabilités logicielles par CVE Common Vulnerabilities and Exposures : – Vecteur d’accès : • local, réseau, réseau adjacent – Complexité de l’attaque : • faible, moyenne, élevée – Niveau d’authentification requis : • Non-authentifié, une seule authentification, multiples authentifications – Impact D I C : • Aucun, Partiel, Complet – Existence d’un exploit (métrique temporelle) : • Inconnu, PoC, Fonctionnel – Existence d’un correctif (métrique temporelle) : • Oui, Temporaire, Paramètre atténuant le risque, non-disponible Exploitabilité • Indicateur « terrain » pour déterminer si une vulnérabilité peut être utilisée par un attaquant ou non – ou Probabilité d’exploitation • Affine la notion de criticité • Catégories : – Exploitation fiable : il est aisé pour un attaquant d’exploiter la vulnérabilité et de manière fiable – Exploitation probable : même que précédemment avec une probabilité d’exploitation (par exemple 1 fois sur 10) – Exploitation impossible • Donne une priorité sur : – les corrections à réaliser sur le code (implémentation) – les correctifs à appliquer pour une application (déploiement) Exploitabilité • Type d’exploitation : – Navigateur – Programme utilisateur – Noyau – Matériel Importance de l’environnement d’exécution du logiciel Importance de l’environnement d’exécution du logiciel • Environnement dans lequel évolue l’application : – A prendre en compte dès la conception car il permet de définir les domaines et frontières de confiance • Environnement réseau : – Problématique de sécurisation bien connue : cloisonnement, séparation des services, filtrage, documentation, procédures – Difficultés: configuration des équipements, conception de l’architecture – Pour l’application : • Définir les zones contrôlées/filtrées : utilisateur authentifié, DMZ, Internet, Extranet, etc. • Authentification des accès • Sécurité des flux utilisés : utilisation du chiffrement ou non Importance de l’environnement d’exécution du logiciel • Environnement système: – Sécurité largement dépendante des possibilités offertes par l’éditeur: de mieux en mieux protégé par défaut – Difficultés : configuration des systèmes, maîtrise des évolutions – Pour l’application : • Utiliser les possibilités offertes par le système d’exploitation pour limiter l’exploitabilité d’une attaque – Exemple : Sandbox, protection préventive Importance de l’environnement d’exécution du logiciel • Le langage de programmation : en théorie les possibilités ne sont pas dépendantes d’un langage…en pratique le langage influe sur les choix du développeur : – Facilité d’expression d’une fonctionnalité, d’un algorithme – Richesse et maturité des bibliothèques existantes – Environnement de développement et d’exécution • Existence d’un IDE : édition, génération, debugger • Multiplateforme (Windows, Linux, Android, etc.) – Communauté : forum, assistance – Code compilé : natif / bytecode • Exécution native / machine virtuelle Importance de l’environnement d’exécution du logiciel • Catégorie de langage : – Possibilité de manipulation sur le système / programme : • Modification de la mémoire (du code lui-même) – Typage : respect des variables déclarées • Polymorphisme de type : void • Cast – Vérification de l’exécution par une machine virtuelle – Utilisation : embarqué, bas niveau, script, Web, statistique, calcul formel, etc. – Paradigme : impératif, objet, fonctionnel Importance de l’environnement d’exécution du logiciel • Modèle de compilation (cas du C) : – Rappels : création d’un programme Quelles sont les étapes de création d’un programme du code source à l’exécutable ? Importance de l’environnement d’exécution du logiciel • Modèle de compilation (cas du C) : – Rappels : création d’un programme 1. Pré-processeur • .c 2. Compilateur / Optimisation • .o .obj 3. Édition des liens ou Linker • .exe a.out .dll Importance de l’environnement d’exécution du logiciel • Modèle de compilation (omission du linker) : – Existence quasi systématique d’un préprocesseur – Compilation pure : Code source Compilateur Code exécutable Demande exécution – Interprétation pure : Code source Interpréteur Demande exécution Exécution Exécution Importance de l’environnement d’exécution du logiciel • Modèle de compilation : – Compilation et interprétation mixte : Code source Translateur Code intermédiaire Demande exécution Machine virtuelle Exécution Exemple : application Web • Pré requis : – Sécuriser le réseau : routeur, pare-feu, switch • Protection périmétrique pour une stratégie de défense en profondeur du réseau – Sécuriser les systèmes d’exploitation : correctifs, services, protocole, comptes, permissions sur les fichiers, partages, journalisation, … – Sécuriser le support de l’application : serveur d’application, « framework », … Exemple : application Web • Quelques catégories de vulnérabilités pour une application Web : – Entrée des utilisateurs (filtrage, validation, rejet) – Authentification – Autorisation (contrôle d’accès sur les objets) – Gestion des données – Gestion des sessions – Utilisation de la cryptographie – Journalisation Exemple : application Web • Filtrage des entrées utilisateur : http://test.app/lecture_pdf.php?file=monpdf.pdf Sécurité du réseau ? du système ? de l’application ? Exemple : application Web • Droit d’accès : https://test.app/lecture_pdf.php?id=12 Cas particulier des portes dérobées • Vulnérabilité du générateur de nombre aléatoire Debian (prévisible) : – Modification spécifique du paquet Debian Openssl (2006) introduisant une vulnérabilité : • Vulnérabilité découverte en 2008 (théorie du « many eyes » ?) – Les clés générées avec cette version de Openssl sont prévisibles • SSH, OpenVPN, DNSSEC, X509 – 2014 : on trouve encore des clés générées par ce paquet… http://www.debian.org/security/2008/dsa-1571 Cas particulier des portes dérobées • Origine de la vulnérabilité : – Facile à retrouver à posteriori : traçabilité des actions de mainteneurs debian • SVN – Utilisation de Valgrind : ne plus faire apparaître d’erreur lors de la compilation du paquet • 2 lignes de code à supprimer pour « résoudre le problème » • …2 lignes de code d’initialisation du générateur aléatoire ! – Graine prise dans un ensemble de 32767 possibilités • Conclusion : ne jamais corriger un bug que l’on ne comprend pas • Est-ce une porte dérobée ? Cas particulier des portes dérobées • Porte dérobée (backdoor) : fonctionnalité volontairement intégrée au logiciel pour accéder/révéler un secret du logiciel – Backdoor créée par le concepteur du logiciel ou une personne tierce – Intention pas forcément malveillante – Impact important pour la sécurité du logiciel • Modèle de sécurité « court-circuité » – Cas le plus souvent rencontré : accéder à une interface d’administration, simplifier un problème complexe, passer outre un contrôle d’accès, etc. Cas particulier des portes dérobées • Exemple : Backdoor du routeur Dlink – Cas d’une backdoor non malveillante (?) – L’utilisation d’un user-agent spécifique permet d’administrer le routeur sans authentification préalable – Fonctionnalité « sans doute » légitime afin de reprogrammer le périphérique http://www.devttys0.com/2013/10/reverse-engineering-a-d-linkbackdoor/ Cas particulier des portes dérobées • Exemple : backdoor du noyau Linux introduite de manière malveillante … schedule(); goto repeat; } + if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) + retval = -EINVAL; retval = -ECHILD; end_wait4: current->state = TASK_RUNNING; … Source : http://lwn.net/Articles/57135/ Cas particulier des portes dérobées • Pratique à bannir du point de vue de la sécurité : – Si elle a pour objectif de réduire un problème complexe : • Revoir la conception de l’application – Si elle a pour objectif de fournir un moyen de secours d’administrer la solution : • Prévoir un mécanisme d’authentification robuste intégré à la solution • Gestion de risques : – elle sera découverte tôt ou tard – elle peut se retourner contre son créateur – (elle jette le discrédit sur un produit) Cas particulier des portes dérobées • Risque pour l’application : introduction d’une backdoor par un tiers malveillant • Caractéristiques d’une backdoor malveillante : – Empreinte faible sur l’application : sans modification du fonctionnement de l’application, taille du code réduite – Accusation impossible (deniability) : impossible de savoir si la backdoor est volontaire ou non • Rien ne distingue une vulnérabilité d’une backdoor – Cercle très restreint des personnes ayant connaissance Cas particulier des portes dérobées • Considération à prendre en compte : – Interopérabilité : gage d’un niveau de confiance – Logiciel source fermé : plus difficile à vérifier – Logiciel source ouverte : la difficulté à introduire une backdoor est proportionnelle à la taille du projet (vraiment ?) – Confiance dans le compilateur : backdoor dans un code compilé mais sans modifier le code source Cas particulier des portes dérobées • Menace réelle sur les applications stratégiques • Protéger son logiciel contre l’introduction malveillante de backdoor : – Protection du code source : • industrialiser la modification du code : pas d’accès direct au code source mais via des outils déediés (SVN, CVS, etc.) • Journalisation centralisée des accès aux codes sources : authentification des développeurs et des administrateurs – Audit du code source en se focalisant sur l’utilité de certaines fonctionnalités (couverture du code) – Protection de la génération du logiciel : compilation du programme dans un environnement sécurisé (éventuellement déconnecté) – Utilisation des logiciels issus de l’éditeur – Utiliser des applications en bac-à-sable pour limiter l’impact d’une backdoor : la sécurité repose sur le « broker process »