Sécurité des systèmes d`exploitation
Transcription
Sécurité des systèmes d`exploitation
Sécurité des systèmes d'exploitation 1 Introduction Le système de fichiers est devenu la partie la plus exposée du système d'exploitation : de plus en plus d'informations sont confiées à des systèmes d'exploitation régissant des ordinateurs connectés en réseau, d'où de plus en plus d'attaques possibles (hackers, virus), d'où une mise en oeuvre de la protection des données. 1.1 Causes de dysfonctionnement 2 types de causes de dysfonctionnement du système d'exploitation : ● volontaires : erreurs de conception du S.E. luimême, erreurs matérielles ● involontaires : opérateur malveillant (ex: fraudes informatiques => 150 millions d'euros perdus aux USA en 1 an) Il est donc nécessaire d'avoir un système de fichiers stable, d'où par exemple une mise en oeuvre de sauvegarde permettant l'éventuelle reconstruction de fichiers perdus. 1.2 Virus 95000 programmes malveillants, alors que le nombre de virus réellement en circulation serait de quelques milliers. 1. Fonctionnement des virus : reproduction + modification Le virus est un programme (ou une suite d'instructions cachées) qui se reproduit à partir de son code. Il entraîne souvent des troubles de fonctionnement, des pannes majeures, et contaminent d'autres systèmes informatiques. Un virus est dangereux uniquement lorsqu'il réussit à s'exécuter sur un disque dur. 2. Familles de virus Différents types de virus. ● Virus de boot (sous DOS) : 1er virus qui utilisent les zones d'exécution automatiques des disques durs et disquettes (ex : secteur de démarrage) pour se propager. Leur reproduction consiste à se propager ensuite sur toutes les disquettes qui seront introduites dans le système infecté. ● Virus exécutables (sous Windows) : ils insèrent leur propre code à l'intérieur des fichiers programmes. Leur reproduction consiste ensuite, lorsque le fichier infecté est exécuté, à rechercher d'autres programmes à infecter. ● Macrovirus : ils ont été développés avec le langage VBA. Une fois lancé, un tel virus se copie dans chaque document modifié ou créé (qui appelle alors un fichier NORMAL.DOT contenant le modèle par défaut, et c'est dans ce fichier que le virus copie ses macros). ● Vers (=worms) : ce sont des programmes qui se propagent en utilisant des réseaux (peer to peer, mail, ...). Ils n'ont pas besoin de programme hôte pour se reproduire. Ils se servent de différentes sources d'information mises à leur disposition pour « trouver » et « infiltrer » comme les failles humaines (ouverture de fichiers attachés), les failles logicielles (carnet d'adresses du logiciel mail, fichier tmp internet, ...). Leur action est surtout de se reproduire pour saturer, détruire, offrir un point d'accès caché (ex : envoi d'un script par mail). Souvent il n'y a qu'une seule copie sur le disque de l'hôte, donc il suffit de le détruire (si on le trouve) pour que le système ne soit plus infecté. ● Cheval de troie : ce n'est pas vraiment un virus. Il est introduit intentionnellement par une personne (1 pirate) dans un système en vue de détruire ou récupérer des données confidentielles (entreprises, personnelles, ...), c'est un logiciel d'apparence légitime. Il ne se reproduit pas et cible LA machine dont il prend le contrôle. Il pose le problème du coup des fichiers partagés. ● Logiciel espion (=spyware) : c'est un logiciel malveillant qui s'installe dans un ordinateur pour collecter des données. ● Composeur d'attaque : c'est un logiciel permettant de brancher un ordinateur à un autre, au réseau (souvent il faut composer un numéro de téléphone pour brancher l'ordinateur au réseau). Ce sont des logiciels qui sont souvent légaux (souvent inclus dans le système d'exploitation), mais parfois on peut en trouver des malveillants. 1.3 Sécurité du S.E. Il est difficile de définir précisément ce qu'on entend par protection d'un S.E., tant les facteurs sont nombreux. La sécurité consiste à protéger tout ce par quoi l'information peut être modifiée, divulguée ou détruite. 1. Degré de protection d'un S.E. Le degré de protection d'un S.E. dépend de 2 facteurs fondamentaux : ● le degré de protection des informations qu'il manipule; ● le degré de confiance de son logiciel, notamment celui qui supporte les processus système (ex: UNIX a une grande confiance en l'utilisateur). 2. Fiabilité d'un logiciel Un logiciel sera fiable quand il satisfait correctement ses spécifications et quand il est capable de résister à un environnement imprévu (pannes matérielles, données erronées, ...) soit en corrigeant l'anomalie, soit en la signalant, mais en évitant que les erreurs se propagent et contaminent tout le système. On étudiera les solutions de 2 types de problème : ● le premier problème traite des erreurs sur les fichiers (notamment les accès aux fichiers) : une solution sera de confiner les erreurs en contrôlant les accès aux entités du S.E., par des domaines de protection ● le deuxième problème concernera plus spécifiquement les données et les manières de les protéger, et de vérifier leur intégrité et leur authenticité, pour les données qui transitent dans le système (réseau, ...), on utilisera les systèmes cryptographiques. 2 Protection des S.E. 2.1 Généralités sur le contrôle d'accès Dans un S.E., il convient de contrôler très précisément que l'utilisation des ressources s'effectue dans le cadre prévu ; tout particulièrement en multiprogrammation où un utilisateur ne doit pas pouvoir consulter les informations confidentielles d'un autre, ni modifier le code d'un processus système. Ce contrôle est mis à 2 niveaux : 1. niveau logique : le modèle de protection Au niveau logique on va définir l'ensemble des règles qui définissent les accès autorisés ou non aux ressources. Ces règles peuvent avoir des origines diverses : soit elles sont fixées à la conception du S.E., soit elles sont introduites par les utilisateurs sur les entités qu'ils créent (fichiers, programmes, ...). On parle du modèle de protection. 2. niveau physique : les mécanismes de protection Au niveau physique, on applique le modèle de protection, c'est le rôle des mécanismes de protection qui vont réaliser la correspondance entre le modèle de protection et sa réalisation physique. Remarque : autant il est souhaitable que les règles d'accès puissent être modifiées pour une meilleure adéquation à des situations qui peuvent être très variées (modèle de protection facilement modifiable), autant les mécanismes de protection doivent être fixes afin d'être plus facilement contrôlables. Ils doivent de plus être indépendants des règles qu'ils permettent de réaliser. 2.2 Représentation du modèle de protection Le modèle de protection d'un S.E. Est le cadre général qui définit les interactions entre ses éléments. La conception du S.E. peut être résumée comme la somme de 2 ensembles : ● ensemble d'entités actives = on parle de sujets (processus) ● ensemble d'entités accessibles = on parle d'objets qui sont les ressources matérielles (U.C., périphériques, ...) et les ressources logicielles (fichiers, programmes, sémaphores, ...) Définitions : ● le modèle de protection définit quels sujets ont accès à quels objets suivant quelles modalités d'accès. ● Les droits d'accès seront définis par un couple (nom d'un objet, modalités d'accès) (ex : (fichier, R) ; (imprimante, afficher) ; (processus P0, appeler) Le modèle de protection doit fixer, à tout instant, les droits d'accès dont dispose chaque sujet (processus), cet ensemble des droits d'accès s'appelle le domaine de protection du sujet (processus). Exemple : D1 = {(fichier F1, R), (fichier F1, W), (fichier F1, ouvrir), (imprimante, afficher), (fichier F1, fermer)} Une représentation possible du modèle de protection est une matrice dont les lignes sont indexées par les sujets (processus) et les colonnes par les objets, l'intersection de 2 cases contient l'ensemble des droits d'accès sur cet objet par ce processus, on parle de matrice d'accès (voir exemple ci dessous). Remarque : un objet peut être commun à 2 domaines, avec éventuellement des droits d'accès différents. OBJETS Fichier F1 Processus 1 SUJETS Lire Segment 1 Exécuter Segment 2 Processus 1 Lire Exécuter Editeur Entrer Processus 2 Lire Ecrire Entrer Processus 3 Lire Entrer Entrer Ecrire Exécuter Matrice d'accès (d'après J.Beauquier « Systèmes d'exploitation : Concepts et Algorithmes ») 1. Domaines de protection restreints Très souvent les processus se décomposent en plusieurs modules et il est fréquent que certains droits d'accès ne soient utilisés que dans certains modules. Si l'un des modules est incorrectement programmé (ou s'il se produit un accident de matériel pendant l'exécution), et si le module s'effectue dans le domaine de protection complet, cela peut endommager des objets auxquels il n'avait pas accès ! Donc une solution est de faire en sorte que chaque module s'exécute dans le domaine de protection le plus réduit possible, ainsi en cas de panne un objet non utile au module (donc absent du domaine de protection lié au module) ne sera pas endommagé. On parle alors de domaines de protection restreints. La restriction des domaines de protection implique que l'on soit capable de faire évoluer dynamiquement le domaine de protection d'un processus. 2. Gestion des domaines de protection restreints : solution Pour gérer ces domaines de protection, il va falloir modifier la matrice d'accès, soit : ● de manière à modifier le domaine de protection en ajoutant ou en supprimant des droits d'accès dynamiquement, au « fil des modules » auxquels le processus accède ; ● de manière à créer une nouvelle ligne associée au nouveau domaine de protection, et de faire correspondre cette nouvelle ligne au processus. Fichier F1 Domaine 1 Lire Segment 1 Exécuter Segment 2 Processus 1 Lire Exécuter Entrer Domaine 2 Lire Ecrire Domaine 3 Editeur Domaine 2 Entrer Domaine 3 Entrer Entrer Lire Ecrire Exécuter Entrer Entrer Entrer Où processus 1 → domaine 1, processus 2 → domaine 2, processus 3 → domaine 3 Un processus qui s'exécute dans un domaine i peut en changer pour le domaine de protection j (ex : processus 1 s'exécute dans le domaine 1, mais pourra s'exécuter dans le domaine 2 ou 3 (« entrer »)) 3. Avantages des domaines de protection restreints Parce qu'un processus peut changer aisément de domaine de protection, le système de contrôle d'accès doit être souple et adaptable. La souplesse est un grand avantage. En effet contre la pensée que rigidité rime avec fiabilité, voilà quelques arguments : • le degré de protection d'un système dépend de son maillon faible : la rigidité peut laisser sans contrôle une « porte dérobée » • si les mesures sont trop pesantes et pénalisent les performances du sytème, l'expérience prouve que des moyens sont recherchés et introduits pour les contourner, donc ne seront pas utilisés • il est intéressant de pouvoir modifier les contrôles selon les utilisateurs (différences entre le superuser et l'utilisateur λ) • dans un système souple, on peut introduire des restrictions particulières d'accès tenant à l'identité du sujet et de l'objet. Pour cela il suffit de créer un nouveau type abstrait (objet+modalités d'accès) sans pour autant introduire des mesures de contrôle supplémentaires • certains problèmes ne supportent pas la rigidité des mesures : ex du problème « cheval de troie » ou « confinement » • « cheval de troie » : un programme peut être un cheval de troie (réaliser des opérations non prévues dans ses spécifications) en profitant du domaine de protection étendu d'un utilisateur (pour copier, détruire, ... des données confidentielles). La lutte contre un éventuel cheval de troie est d'exécuter chaque module dans un domaine de protection restreint afin de ne pas pouvoir tirer profit des droits étendus d'un utilisateur ou des objets qu'il possède. • « problème du confinement » : malgré les domaines restreints, un programme exécuté à la demande d'un utilisateur qui n'est pas propriétaire peut retenir une information confidentielle contenue dans ses paramètres (par exemple : un compilateur peut garder trace des programmes qu'il compile). Ce problème n'est pas résolu mais la solution exige certainement des mesures les plus souples possibles. 2.3 Mécanismes de contrôle Il faut s'assurer par des mécanismes de contrôle que chaque accès réel est bien spécifié dans la matrice d'accès. Ces mécanismes se divisent en 3 groupes que nous allons présenter ciaprès. 1. Accès hiérarchiques La forme la plus simple d'accès hiérarchique repose sur 2 modes : ● mode système : qui correspond à une exécution dans un domaine de protection constitué de tous les droits d'accès possibles du S.E. ; appliqué aux processus système ; ex : UNIX : superuser. ● mode utilisateur : qui correspond à un domaine de protection qui dépend du choix fait d'un sousensemble d'instructions ; tout essai par un processus d'effectuer un accès non autorisé est détecté par le matériel qui génère alors une interruption. Le mode d'exécution est indiqué par un bit du mot d'état de l'U.C. correspondant au mode d'exécution, ce bit étant testé avant l'exécution de chaque processus. Un S.E. basé sur ce mode est MULTICS qui prévoit plusieurs domaines de protection possibles qui sont ordonnés par inclusion ensembliste suivant une structure d'anneaux. Un anneau correspondra donc à un domaine de protection Di avec les règles suivantes : • Di ⅽ Dj si j<i • un processus s'exécutant dans un domaine de numéro i pourra s'exécuter dans un domaine de numéro j tel que j > i ; au contraire un processus s'exécutant dans un domaine de numéro i ne pourra s'exécuter dans un domaine de numéro f tel que f > i sans passer par un « guichet ». Ce guichet permet de contrôler plus aisément à quels objets les processus peuvent accéder (ex : en ADA chaque procédure possède une liste de variables visibles qui sont les seules accessibles par d'autres procédures). • Lorsqu'il n'y a que 2 anneaux, on est sur un modèle « maître/esclave ». Le problème de cette structure en anneaux, est que les domaines sont inclus et non séparés, donc ne permettent pas d'appliquer le principe du « moindre privilège » (= « un programme ne peut pas endommager un objet auquel il n'a pas accès »). 2. Liste de contrôles d'accès : ACL La matrice d'accès va être implantée colonne par colonne sous forme de listes. Chaque liste est associée à un objet et contient des éléments (couples) du type : (processus, ensemble de modalités d'accès) Quand un processus veut accéder à un objet, on regarde dans sa liste correspondante si on trouve le nom du processus en regard de la modalité d'accès demandée. Avantage : c'est pratique pour protéger des objets ayant un créateur ou un propriétaire unique, comme par exemple des fichiers (cf UNIX). Cette liste peut être modifiée comme bon semble au propriétaire. Inconvénient : cette méthode ne permet pas de changer aisément de domaine de protection puisqu'il faut repérer dans toutes les listes de tous les objets concernés les droits d'accès à modifier. 3. Liste de capacités La matrice d'accès va être implantée ligne par ligne. Une capacité sera un « ticket d'entrée » qui porte le nom d'un objet et qui par un pointeur spécifie son adresse. Elle est créée par un processus spécial du S.E. Sans capacité il est physiquement impossible d'obtenir l'adresse de l'objet. La possession d'une capacité par un sujet, est une condition nécessaire et suffisante d'accès à l'objet référencé par la capacité. Nom objet Modalités d'accès Pointeur d'adresse ------------------------------------------------> OBJET Aucune modification, exceptée une diminution des modalités d'accès, ne peut être faite sur une capacité. Quand un objet est créé, alors une capacité est rajoutée dans la liste associée au sujet, et le sujet possesseur d'une capacité peut en faire des copies. Le domaine de protection d'un processus est décrit par la liste des capacités (ou Cliste) que ce processus possède à un instant donné. Pour changer de domaine, il doit changer de Cliste. i. Domaines de protection restreints Pour pouvoir changer de domaines de protection, la Cliste doit devenir ellemême un objet avec comme modalité d'accès « Entrer » et le pointeur pointera sur la Cliste appelée. Exemple : appel d'une procédure par un processus : le processus doit posséder une capacité permettant d'accéder à la Cliste de la procédure appelée ; et au retour de la procédure, le processus revient dans le domaine de protection initial. ii. Protection des capacités La possession d'une capacité donne l'accès à l'objet qu'elle référence, mais la protection des capacités se fera au niveau matériel. 2 solutions : • par étiquetage : chaque mot mémoire possède un bit indiquant si le contenu est une capacité ou une donnée ordinaire (d'autres bits peuvent être ajoutés pour savoir si l'objet est un booléen, une instruction, ...) • par partition : uniquement avec une mémoire segmentée. Chaque segment est désigné au départ comme contenant soit des données, soit des capacités. iii. Adressage par capacité L'adresse logique d'un segment est un couple formé par une capacité et une valeur indiquant le déplacement dans le segment : la capacité permet de récupérer l'adresse du segment, et le déplacement de récupérer le mot. Avec des capacités, changer de domaine de protection n'est pas plus compliqué que de transmettre des paramètres à une procédure. 3 Protection des données : cryptographie 3.1 Introduction Les systèmes cryptographiques offrent un moyen de protéger les données, transmises sur des canaux de communication ou stockées dans les mémoires primaires et secondaires. Elle permet : ● d'assurer le secret des données ● de garantir leur authenticité La technique pour réaliser ces objectifs est d'utiliser une fonction de codage et une fonction de décodage. fct codage donnée claire > fct décodage donnée codée > donnée claire Souvent les données sont représentées par leur écriture binaire (ex: code ASCII), d'où le fait que les fonctions de codage et décodage sont des fonctions sur des entiers et s'obtiennent : • en choisissant des méthodes générales de codage et de décodage dépendantes de certains paramètres, • et en fixant les valeurs de ces paramètres appelés clés. Ex : Jules César avait choisi comme fonction de codage de remplacer les lettres par leurs « décalées » d'un certain nombre de positions (modulo 26) avec comme clé=2 (ici la méthode de décodage était la même que celle de codage, seule la clé change =2). texte clair : « le chat boit » > texte codé : « ng ejcr dqkr » Posons alors : ● C : fonction de codage, K' clé de codage ● D : fonction de décodage, K'' clé de décodage ● CK' et DK'' sont donc des fonctions qui à un entier binaire font correspondre un entier binaire et qui vérifient DK''[CK'(M)] = M Nous pouvons alors définir les conditions permettant d'assurer le secret et de garantir l'authenticité des données. • • Conditions permettant d'assurer le secret des données : ✔ la connaissance de CK'(M) ne permet pas de calculer M ✔ la connaissance de CK'(M) et de M ne permet pas de calculer DK'' Conditions permettant de garantir l'authenticité des données : ✔ la connaissance de CK'(M) et de M ne permet pas de calculer CK' ✔ sans connaître la fonction de codage CK', il est impossible de construire un entier M', tel que DK''(M') soit un entier associé à une donnée ayant une signification en clair. Attention : l'expression « ne permet pas de calculer » signifie « de calculer » en un temps raisonnable (ex : une clé a pu être « cassée » sur un réseau de 600 machines en 6 mois). 3.2 Systèmes cryptographiques à clés publiques et signatures digitales Cette technique permet le secret et l'authenticité des données de plusieurs utilisateurs sans nécessiter la protection des clés de codage. Un système cryptographique à clés publiques est fondé sur une méthode de codage C et de décodage D qui sont publiques. Chaque utilisateur a une clé publique de codage A' et une clé privée de décodage A'' (bien entendu la connaissance de A' ne peut pas permettre de trouver A'' et viceversa). Les fonctions C et D doivent satisfaire bien entendu : DA''[CA'(M)] = M et CA'[DA''(M)] = M • permet de garder le secret : Si l'utilisateur A veut communiquer à l'utilisateur B la donnée représentée par M, il code M avec la clé publique de B, et construit ainsi C B'(M), il n'y a plus que B qui puisse décoder cette donnée en utilisant la fonction de décodage et sa clé privée. • permet d'assurer l'authenticité des données : Si l'utilisateur A veut « signer » la provenance des données envoyées à B alors il suffit que A applique la fonction de décodage avec sa clé privée DA'' sur CB'(M), alors lorsque B recevra les données en provenance de A il appliquera d'abord la fonction de codage avec la clé publique de A, puis de décodage avec sa clé privée, ou viceversa : CB' DA'' CA' DB'' M > CB'(M) > DA''[CB'(M)] > CA'[DA''[CB'(M)]] = CB'(M) > DB''[CB'(M)] = M clé publique clé privée clé publique clé privée de B de A de A de B donnée envoyée