Cours MIT "Sécurité des systèmes informatiques". Conférence 6: «Opportunités», partie 3

Institut de technologie du Massachusetts. Cours magistral # 6.858. "Sécurité des systèmes informatiques." Nikolai Zeldovich, James Mickens. 2014 année


Computer Systems Security est un cours sur le développement et la mise en œuvre de systèmes informatiques sécurisés. Les conférences couvrent les modèles de menace, les attaques qui compromettent la sécurité et les techniques de sécurité basées sur des travaux scientifiques récents. Les sujets incluent la sécurité du système d'exploitation (OS), les fonctionnalités, la gestion du flux d'informations, la sécurité des langues, les protocoles réseau, la sécurité matérielle et la sécurité des applications Web.

Cours 1: «Introduction: modèles de menace» Partie 1 / Partie 2 / Partie 3
Conférence 2: «Contrôle des attaques de pirates» Partie 1 / Partie 2 / Partie 3
Conférence 3: «Débordements de tampon: exploits et protection» Partie 1 / Partie 2 / Partie 3
Conférence 4: «Séparation des privilèges» Partie 1 / Partie 2 / Partie 3
Conférence 5: «D'où viennent les systèmes de sécurité?» Partie 1 / Partie 2
Conférence 6: «Opportunités» Partie 1 / Partie 2 / Partie 3

Public: si cet UID fournit un accès en lecture seule à ce fichier et que vous avez également un descripteur de fichier, alors si vous perdez l' UID , pouvez-vous toujours obtenir l'autorisation de lire ce fichier?

Professeur: oui, car il apparaîtra dans les catalogues. Parce que dès que vous ajoutez la fonctionnalité au fichier, c'est tout. Il vous est ouvert avec des privilèges spéciaux et ainsi de suite. Mais le problème est qu'ils ont cette conception hybride.

Autrement dit, disent-ils - vous pouvez vraiment ajouter des fonctionnalités aux répertoires et vous pouvez ouvrir un nouveau fichier, car vous travaillez en parallèle. Il se peut que vous ajoutiez la fonctionnalité à un répertoire, tel que / etc , mais vous n'avez pas un accès obligatoire à tous les fichiers du répertoire / etc. Mais dès que vous entrez dans le mode fonctionnalités, vous pouvez essayer d'ouvrir ces fichiers, sachant que vous avez accès au répertoire / etc. Après tout, il est déjà ouvert, alors pourquoi ne me donnez-vous pas un fichier appelé «mot de passe» situé dans ce répertoire?



Et puis le noyau doit décider s'il vous autorise à ouvrir le fichier dans ce répertoire en mode lecture ou écriture, ou ce que vous avez. Je pense donc que c'est le seul endroit où vous avez encore besoin de ce privilège externe, car ils ont essayé de créer un design compatible, où ils ont utilisé une sémantique pas trop naturelle pour décrire le fonctionnement des répertoires. Cela semble être le seul endroit où les principes de configuration d'un système de fichiers Unix restent.

Public: existe-t-il d'autres lieux de ce type?

Professeur: bonne question. Je pense que je devrai obtenir leur code source précédent pour comprendre ce qui se passe, mais la plupart des autres situations ne nécessitent pas vraiment de vérification UID . Parce que, par exemple, il n'est pas utilisé pour les réseaux. Ce sont probablement les opérations habituelles du système de fichiers - si vous avez un segment de mémoire partagée, il vous suffit de l'ouvrir et c'est tout.

Public: Pourriez-vous expliquer à nouveau quel est exactement l'ID utilisateur, si vous disposez de la fonctionnalité de capacité ?

Professeur: c'est important lorsque vous avez la possibilité de cataloguer. La question est, que vous offre cette opportunité? Prenons une interprétation, par exemple, l'état des capacités d'un système propre, pas Capsicum . Si dans un tel système vous avez la possibilité d'avoir un répertoire, vous avez alors un accès inconditionnel à tous les fichiers de ce répertoire.

Sous Unix, ce n'est généralement pas le cas. Vous pouvez ouvrir le répertoire sous / etc , mais il contient de nombreux fichiers système dans lesquels des informations confidentielles peuvent être stockées, par exemple, la clé privée du serveur. Et le fait que vous puissiez ouvrir et faire défiler ce répertoire ne signifie pas que vous ne pouvez pas ouvrir de fichiers dans ce répertoire. Autrement dit, en ayant accès au répertoire, vous avez accès aux fichiers.

Dans Capsicum , si vous ouvrez le répertoire / etc , puis passez en mode fonctionnalité, les événements suivants se produisent. Vous dites: «Je ne sais pas ce qu'est ce répertoire. J'ajoute juste un descripteur de fichier. " Il existe un fichier appelé "clé". Pourquoi n'ouvrez-vous pas ce fichier "clé" ? Tout simplement parce qu'à ce moment-là, vous ne voulez probablement pas que ce processus basé sur les fonctionnalités ouvre ce fichier, car vous n'en avez pas besoin. Bien que cela vous permette de contourner les autorisations Unix pour le fichier.

Par conséquent, je pense que les auteurs de cet article ont soigneusement abordé le développement d'un système qui ne violerait pas les mécanismes de sécurité existants.

Public: c'est-à-dire que vous dites que dans certains cas, vous pouvez utiliser une combinaison de ces deux facteurs de sécurité? Autrement dit, bien que l'utilisateur puisse modifier le fichier dans le répertoire, à quels fichiers accède-t-il en fonction de son ID utilisateur?

Professeur: oui, exactement. En pratique, dans Capsicum , avant de passer en mode fonctionnalités, vous devez deviner les fichiers dont vous aurez besoin ultérieurement. Vous pouvez avoir besoin de bibliothèques partagées, de fichiers texte, de modèles, de connexions réseau, etc. Par conséquent, vous ouvrez tout cela à l'avance. Et il n'est pas toujours nécessaire de savoir de quel fichier vous avez besoin. Ces gars ont donc fait en sorte que vous puissiez simplement ouvrir le descripteur de fichier du répertoire et afficher les fichiers dont vous avez besoin plus tard. Cependant, il se peut que ces fichiers n'aient pas les mêmes autorisations que vous. C'est précisément pour cette raison qu'une combinaison de deux facteurs de sécurité est utilisée - la vérification des capacités et de l' uid utilisateur. Cela fait donc partie du mécanisme du noyau.



Pourquoi ont-ils besoin d'une bibliothèque comme libcapsicum ? Je pense qu'il y a deux choses principales qu'ils prennent en charge dans cette bibliothèque.

L'un d'eux est qu'ils implémentent une fonction appelée lch_start , que vous devez utiliser à la place de la fonction cap_enter . Une autre fonction fournie par libcapsicum est le concept de listes fd, qui est utilisé pour passer des descripteurs de fichiers par des nombres. Le but de ces listes fd est facile à expliquer. Il s'agit essentiellement d'une généralisation de la façon dont Unix gère et transmet les descripteurs de fichiers entre les processus. Sous Unix et Linux traditionnel, que vous utilisez aujourd'hui, certains descripteurs de fichiers lui sont transmis au démarrage du processus. Vous ouvrez simplement certains descripteurs de fichiers avec des valeurs entières de cette table et démarrez le processus enfant dont vous avez besoin. Ou vous exécutez un binaire spécifique, et il hérite de tous ces emplacements ouverts dans la table fd . Cependant, il n'y a pas d'autre bonne façon de nommer ces choses que d'utiliser des nombres comme noms.

Prenons un exemple dans lequel l'emplacement 0 sera utilisé pour l'entrée, l'emplacement 1 pour la sortie, l'emplacement 2 pour l'impression des messages d'erreur. Voilà comment cela fonctionne sur Unix . Et cela fonctionne très bien si vous transférez simplement ces trois fichiers ou trois flux de données vers le processus.



Mais dans Capsicum, il arrive que vous «parcouriez» beaucoup plus de descripteurs de fichiers sur votre chemin. Ainsi, lorsque vous transmettez un descripteur de fichier pour certains fichiers, vous passez par un descripteur de fichier pour une connexion réseau, un descripteur pour une bibliothèque partagée que vous possédez, etc. La gestion de tous ces chiffres est assez fastidieuse. Par conséquent, en fait, libcapsicum offre la possibilité d' extraire du nom de ces descripteurs de fichiers passés entre les processus en utilisant un nom hiérarchique utilisé à la place de ces entiers obscurs.
C'est l'une des choses simples qu'ils fournissent dans leur bibliothèque. Je peux donc passer le descripteur de fichier au processus et lui donner un nom, peu importe le numéro indiqué. Cette méthode est beaucoup plus simple.

Ils ont encore un autre mécanisme de lancement de sandbox plus complexe. Il s'agit de lch , l' API hôte sandbox qui est utilisée au lieu de simplement entrer dans le mode des fonctionnalités de capacité . Pourquoi avaient-ils besoin de quelque chose de plus qu'une simple entrée dans un mode opportunité? Qu'est-ce qui vous dérange généralement lors de la création d'un bac à sable?

Public: probablement, lch efface toutes les choses héritées afin d'assurer un démarrage "propre" du système.

Professeur: oui. Je pense qu'ils sont inquiets d'essayer de prendre en compte tout ce à quoi le bac à sable a accès. Le fait est que si vous appelez simplement cap_enter , techniquement, au niveau du mécanisme du noyau, cela fonctionnera. Non? Cela vous empêche simplement de découvrir de nouvelles opportunités.

Mais le problème est qu'il peut y avoir de nombreuses choses existantes auxquelles le processus a déjà accès.

Par conséquent, je pense que l'exemple le plus simple est la présence de descripteurs de fichiers ouverts que vous avez oubliés, et ils seront simplement hérités par ce processus.



Par exemple, ils ont envisagé tcpdump . Tout d'abord, ils ont changé tcpdump en appelant simplement cap_enter avant même qu'ils ne soient sur le point d'analyser toutes les connexions réseau entrantes. D'une certaine manière, cela fonctionne bien car vous ne pouvez pas obtenir plus de fonctionnalités de capacité . Mais ensuite, en regardant le descripteur de fichier ouvert, ils ont réalisé que vous avez un accès complet au terminal utilisateur, car vous avez un descripteur de fichier ouvert pour lui. Pour que vous puissiez intercepter toutes les frappes que l'utilisateur effectue, etc. Ce n'est donc probablement pas un bon plan pour tcpdump . Parce que vous ne voulez pas que quelqu'un intercepte votre activité au clavier.

Par conséquent, dans le cas de tcpdump, ils ont modifié manuellement les descripteurs de fichiers et y ont ajouté quelques bits de fonctionnalités pour limiter les types d'opérations que vous pouvez effectuer. Si vous vous souvenez, dans Capsicum, la fonctionnalité a également ces bits supplémentaires indiquant la classe d'opérations qui peuvent être effectuées pour un descripteur de fichier donné. Ainsi, ils supposent essentiellement que le descripteur de fichier est 0. Il pointe vers le terminal utilisateur tty. Au départ, c'était juste un pointeur direct sur la structure tty dans le noyau. Afin de limiter le type d'opérations pouvant être effectuées pour ce descripteur, ils ont introduit une structure bêta intermédiaire de capacités au milieu. Ainsi, le descripteur de fichier pointe vers cette structure de capacités, et il pointe déjà vers le vrai fichier auquel vous essayez d'accéder. Et cette structure de capacités contient des bits ou des autorisations restrictives pour un objet descripteur de fichier qui peut être implémenté.

Ainsi, avec la saisie de données standard dans tcpdump, vous ne pouvez rien faire avec. Vous pouvez juste voir qu'il existe, et c'est tout. Pour le descripteur de fichier de sortie, ils ont fourni une opportunité lorsque vous pouvez y écrire quelque chose, mais ne pouvez pas modifier l'enregistrement, c'est-à-dire que vous ne pouvez pas annuler les modifications apportées.



Alors, quoi d'autre pourriez-vous vous soucier du lancement du bac à sable ? Je pense à l'état du descripteur de fichier. Y a-t-il autre chose qui compte? Je pense que sur Unix ce sont des descripteurs de fichiers et de la mémoire.

Une autre chose est que ces gars-là craignent que dans votre espace d'adressage, des données confidentielles ne soient attribuées plus tôt. Et le processus que vous allez isoler dans le bac à sable peut lire toute la mémoire disponible. Donc, s'il y a une sorte de mot de passe que vous avez vérifié plus tôt, lorsque l'utilisateur se connecte et que vous n'avez pas encore effacé la mémoire, ce processus pourra le lire et faire quelque chose d '«intéressant».

Ils ont résolu ce problème de cette façon: dans lch_start, vous devez exécuter un programme "frais". Vous prenez le programme et vous y mettez tous les arguments, tous les descripteurs de fichiers que vous voulez lui fournir. Ensuite, vous démarrez un nouveau processus ou lancez l'opération de réinitialisation de l'intégralité de l'espace mémoire virtuelle. Et puis, il ne fait aucun doute que ce processus ne recevra aucun privilège supplémentaire pour affecter l'ensemble des données confidentielles. C'est exactement ce que vous avez transmis à la fonction lch_start , en termes de noms binaires, d'arguments et de capacités de programme.

Public: que se passe-t-il si le processus que vous démarrez contient setuid binaire = 0 ?

Professeur: Je pense que ces gars-là n'utilisent pas de «binaires» setuid en mode fonctionnalité pour éviter certaines interactions étranges qui peuvent apparaître. Ils implémentent cette règle: vous pouvez avoir un programme setuid qui obtient ses privilèges du binaire setuid , puis il peut appeler cap_enter ou lch_start . Mais une fois que vous êtes en mode fonctionnalités, vous ne pouvez pas restaurer de préférences supplémentaires.

En principe, cela pourrait fonctionner, mais ce serait très étrange. Parce que, si vous vous en souvenez, la seule chose où l' UID compte lorsque vous êtes en mode fonctionnalité est d'ouvrir des fichiers dans un répertoire. Par conséquent, il n'est pas clair si c'est vraiment un excellent plan pour des privilèges supplémentaires ou s'il y a des défauts.

Public: Plus tôt, nous avons expliqué pourquoi la bibliothèque ne prend pas vraiment en charge une séparation stricte entre les deux facteurs de sécurité. Mais nous n'avons pas besoin d'utiliser lch_start ?

Professeur: c'est vrai. Supposons que vous ayez quelque chose comme tcpdump ou gzip - c'est une autre chose avec laquelle ils travaillent. Vous supposez que l'application n'est probablement pas compromise, et il existe une fonction de base de l'application, et vous vous souciez de la façon dont elle se comporte dans le bac à sable. Dans le cas de tcpdump, il s'agit d'une analyse des paquets provenant du réseau, dans le cas de gzip, il s'agit de décompresser les fichiers. Et jusqu'à un certain point, vous supposez que le processus fait tout correctement et qu'il n'y aura pas de vulnérabilités. Par conséquent, vous lui faites confiance pour exécuter lch_start et pensez qu'il créera correctement l'image, configurera correctement toutes les fonctionnalités, puis se limitera à tout autre appel système en dehors du mode capacités.

Et puis vous lancez des choses dangereuses. Mais à ce moment-là, l'installation était correcte et vous n'avez aucun moyen de sortir de ce bac à sable. Donc, je pense que vous devez voir comment vous pouvez réellement utiliser le mode fonctionnalité pour les applications sandbox.

Nous avons donc parlé un peu de tcpdump . Comment isolez-vous ce processus? Un autre exemple intéressant est le programme gzip , qui compresse et décompresse les fichiers. Alors pourquoi s'inquiètent-ils du bac à sable? Je pense qu'ils craignent que le code de décompression ne soit potentiellement bogué, ou qu'il puisse y avoir des erreurs dans la gestion de la mémoire, la gestion du tampon pendant la décompression, etc.



Une autre question intéressante est pourquoi les changements pour gzip semblent beaucoup plus compliqués que pour tcpdump ? Je pense que cela est dû à la façon dont l'application est structurée en interne, non? Par conséquent, si vous avez une application qui a simplement compressé un fichier ou décompressé un fichier, il est normal de simplement la lancer sans la changer en mode fonctionnalités. Vous lui donnez simplement une nouvelle norme pour décompresser quelque chose, et la norme fournit des données décompressées à la sortie, et cela fonctionnera bien.

Le problème, comme cela arrive presque toujours avec de telles méthodes sandbox, est que l'application a en fait une logique de processus beaucoup plus complexe. Par exemple, gzip peut compresser plusieurs fichiers à la fois, etc. Et dans ce cas, vous avez une sorte de processus principal à la tête de l'application, qui a en fait des droits supplémentaires pour ouvrir plusieurs fichiers, les emballer, etc. Et la logique de base doit souvent être un autre processus de support. Dans le cas de gzip, l' application n'était pas structurée de sorte que la compression et la décompression agissaient comme des processus distincts. Par conséquent, ils ont dû changer l'implémentation du noyau gzip et une certaine structure de l'application elle-même afin qu'en plus de simplement transférer des données vers la fonction de décompression, elles soient envoyées via un appel RPC ou écrites dans une sorte de descripteur de fichier. Cela visait à empêcher les problèmes de tiers de se produire et à déballer sans pratiquement aucun privilège. La seule chose que gzip pouvait faire en même temps était de renvoyer les données décompressées ou compressées au processus qui les appelait.

Une autre chose à faire est de savoir comment utiliser Capsicum dans OKWS ? Qu'en pensez-vous? Serait-ce utile? Les gars OKWS seraient-ils heureux de passer à FreeBSD parce qu'il est tellement plus facile à utiliser? Comment utiliseriez-vous Capsicum sur FreeBSD ?

Public: On pourrait se débarrasser de certaines restrictions strictes.

Professeur: oui, c'est vrai, on pourrait les remplacer complètement par la présence d'un répertoire de descripteurs de fichiers et de capacités. Vous n'auriez pas besoin de configurer un chroot déroutant. Au lieu d'utiliser chroot avec beaucoup de petites choses, vous pouvez simplement définir soigneusement les autorisations. Vous pouvez simplement ouvrir les fichiers dont vous avez besoin. Cela semble donc être un gros plus.

Ensuite, dans OKWS , vous avez le service de lancement OK , qui devrait démarrer tous les processus parents. Dès qu'ils meurent, le signal revient à okld pour redémarrer le processus "mort". Et cette chose devrait être exécutée en root , car elle devait isoler les processus dans le bac à sable. Mais il y a un certain nombre de choses dans OKWS qui pourraient être améliorées avec Capsicum .

Par exemple, vous pouvez accorder à okld beaucoup moins de privilèges. Parce que, par exemple, pour obtenir le port 80, vous avez besoin des privilèges root. Mais après cela, vous pouvez mettre tout le reste en toute sécurité dans le bac à sable, car les droits root ne sont plus nécessaires. C'est donc plutôt cool. Vous pouvez peut-être même déléguer au processus le droit de répondre aux demandes de quelqu'un d'autre, par exemple, un processus de surveillance du système qui n'a que ce descripteur de processus ou descripteur de processus pour le processus enfant et chaque fois qu'un tel processus se bloque, il en démarre un nouveau. Par conséquent, je pense que la possibilité de créer un sandbox sans privilèges root est très utile.

Public: vous pouvez attribuer à chaque processus un descripteur de fichier qui vous permet d'ajouter uniquement des entrées au journal.

Professeur: oui, et c'est plutôt cool. Comme nous l'avons dit la dernière fois, oklogd peut "gâcher" le fichier journal. Et qui sait ce que le noyau lui permettra de faire quand il aura le descripteur de fichier du fichier journal lui-même. Cependant, nous pouvons déterminer plus précisément les capacités du descripteur de fichier en lui donnant un fichier journal et en indiquant qu'il ne peut qu'écrire mais pas rechercher quoi que ce soit. Ainsi, nous obtenons la fonction d'ajout uniquement si vous n'êtes qu'un «écrivain» pour ce fichier. C'est très pratique. Vous pouvez donner au processus les autorisations pour écrire dans le fichier, mais pas le lire, ce qui est très difficile à faire uniquement en utilisant les autorisations Unix .

Capsicum ?

: , , , . , , , .

: , . Capsicum , , . .

: , , okld . , .

: , . . , , Capability , . , , , , , .
, OKWS . . , , , . .

, , «». , . , , , , . .
: «» , , ?

: , FreeBSD . , - , . FreeBSD Casper , , Capability . , «».

- , , , - , , Casper .



, «» . . , , , Casper - .

, , - . , Unix FD . , . , , .

, FreeBSD , DNS . DNS -, «». , tcpdump . tcpdump , IP-. , , DNS -.

, , DNS- DNS-, . Casper , DNS-.

, , , Capsicum? ? ? , , . Capsicum , ?

tcpdump GZIP , , . ?



: , , , . , Capability .

: , . Capsicum , , . , , . , , , , Capsicum , .

, «». , TCP — helper , , , , . , , , .

: , .

: , . . , . lth_start , . , , , - .

, , Capsicum . , , , . Unix - , .

, . , . , , . , .

, Chrome . , , , Unix, -, Unix .

, ?

: .

: . . , . , , , , .

Unix , . , . , . . , .

. Linux , setcall , , . , Capsicum , , Capsicum , . Linux setcall , . , , Linux .

, — , , , , . , - , «//», . Capsicum où vous pouvez démarrer le processus pour un fichier spécifique, et non pour l'ensemble du répertoire personnel.


La version complète du cours est disponible ici .

Merci de rester avec nous. Aimez-vous nos articles? Vous voulez voir des matériaux plus intéressants? Soutenez-nous en passant une commande ou en le recommandant à vos amis, une réduction de 30% pour les utilisateurs Habr sur un analogue unique de serveurs d'entrée de gamme que nous avons inventés pour vous: Toute la vérité sur VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbps à partir de 20 $ ou comment diviser le serveur? (les options sont disponibles avec RAID1 et RAID10, jusqu'à 24 cœurs et jusqu'à 40 Go de DDR4).

3 mois gratuits lors du paiement d'un nouveau Dell R630 pour une période de six mois - 2 x Intel Deca-Core Xeon E5-2630 v4 / 128GB DDR4 / 4x1TB HDD ou 2x240GB SSD / 1Gbps 10 TB - à partir de 99,33 $ par mois , uniquement jusqu'à fin août, commandez peut être ici .

Dell R730xd 2 fois moins cher? Nous avons seulement 2 x Intel Dodeca-Core Xeon E5-2650v4 128 Go DDR4 6x480 Go SSD 1 Gbps 100 TV à partir de 249 $ aux Pays-Bas et aux États-Unis! Pour en savoir plus sur la création d'un bâtiment d'infrastructure. classe utilisant des serveurs Dell R730xd E5-2650 v4 coûtant 9 000 euros pour un sou?

Source: https://habr.com/ru/post/fr418221/


All Articles