web-dev-qa-db-fra.com

Garder les secrets de root sur Linux

Je cherche des moyens de durcir un système Linux afin que même en obtenant un accès root complet (par des moyens légitimes ou non légitimes), certains secrets restent inaccessibles. Mais d'abord un peu d'histoire.

De nombreux modèles de sécurité Linux différents (SELinux, TOMOYO, etc.) se concentrent sur la limitation de ce que les processus peuvent faire par stratégie et en s'assurant qu'ils n'ont pas besoin d'un accès root complet. Ils visent à garder tous les exploits contenus afin que d'autres parties du système ne puissent pas être compromises. Cependant, il semble que ceux-ci ne s'attaquent pas directement au cas où la racine complète a déjà été acquise - ou, encore plus, à garder les secrets de l'utilisateur root valide. Il semble que ceux-ci peuvent généralement être désactivés par la vraie racine au moment de l'exécution.

Une autre approche consiste à limiter les moyens d'obtenir la racine complète sans restriction - par exemple, ne pas autoriser tous les accès à un utilisateur racine connecté à distance, mais nécessitant une connexion à partir de la console physique. Cependant, ce n'est pas mon objectif non plus - l'hypothèse est que de telles protections ont déjà été surmontées et que la racine est aussi légitime que possible.

Il est évident que toute personne ayant un accès physique à la machine peut obtenir tout ce qui est stocké sur le disque dur et peut-être aussi tout ce qui est stocké en mémoire. Il est également évident que si l'utilisateur root a le pouvoir de modifier les binaires ou les images du noyau, aucune promesse de sécurité ne peut être donnée après le redémarrage. Je ne m'intéresse qu'aux attaques qui peuvent être faites sans redémarrer le système.

De plus, pendant le processus de démarrage, les secrets seront très probablement transmis à travers de nombreux endroits et de nombreuses fonctions critiques de sécurité sont nécessaires. C'est bien sûr génial si les secrets peuvent également être protégés pendant le processus de démarrage, mais ce qui me suffit, c'est une étape pendant le démarrage où les privilèges élevés peuvent être supprimés et après quoi il n'y a aucun moyen de les récupérer.

Donc, avec ces limitations, quelles sont les façons sous Linux d'empêcher l'utilisateur root complet d'accéder à certains secrets?

  • Peut-il y avoir des fichiers sur le système de fichiers qui ne sont pas accessibles même à la racine complète par tous les moyens, mais accessibles à certains processus? Certains processus en cours d'exécution, ou même de nouveaux processus démarrés par les processus ayant actuellement accès?

  • Les secrets peuvent-ils être conservés en mémoire en exécutant des processus afin que même la racine complète ne puisse y accéder par aucun moyen? Ces secrets peuvent-ils être transmis à de nouveaux processus par certains moyens que la racine ne peut pas affecter?

C'est une question difficile à écrire pour que j'obtienne des réponses pertinentes pour moi, donc je vais essayer de modifier la question pour être plus spécifique si nécessaire.


Les choses évidentes qui viennent à l'esprit qui doivent être limitées seraient:

  • Désactiver l'accès à/proc/mem

  • Désactiver l'accès à/proc/<pid>/mem

  • Désactivez l'accès à/proc/<pid>/fd/*

  • Désactiver le chargement des modules (uniquement après le chargement de certains modules, de préférence)

  • Désactivez l'accès ptrace à tout processus

56
Nakedible

En fait, il est possible de restreindre root si on est prêt à définir une telle restriction comme faisant fondamentalement confiance au système d'exploitation. Cela peut être fait en utilisant SELinux (que je sache) et probablement d'autres systèmes de ce type. Le meilleur exemple que j'ai vu de SELinux utilisé de cette manière est celui de Russell Coker Play SELinux Machine .

Pour un bref aperçu de son fonctionnement, le nom "root" n'est pas spécial sous Unix. L'UID 0 est. L'UID 0 signifie "faire confiance à tout ce que je dis". Cela s'applique spécifiquement au modèle d'accès standard utilisé sur Unices, Unixen ou quelle que soit la façon dont vous pluralisez "Unix".

LSM, ou Linux Security Modules, vous permet de vous connecter à peu près à tout et d'auditer/refuser les actions comme bon vous semble. Dans le cas de SELinux, les autorisations SELinux sont vérifiées après les autorisations Unix, donc votre flux ressemble à ceci:

Event ----> Has Unix Permissions? ---> Has SELinux Permissions? ---> Let it happen

La prochaine étape à comprendre est qu'il existe, ou a existé historiquement, différentes versions de la politique SELinux. Avant d'entrer dans les détails, comprenez que dans SELinux:

  • les inodes ont des types, suffixés _t, qui pourrait également être appelé domaines; et
  • les utilisateurs ont des rôles, suffixés _r.

Ensemble, ils contrôlent l'action qu'un utilisateur dans un rôle donné peut faire et ce qu'un processus dans un domaine donné peut faire.

Maintenant, il existe trois principales politiques SELinux:

  1. ciblé. Il s'agit de la politique par défaut pour les postes de travail comme Fedora. L'idée de ciblé est que les services système critiques et les démons sont exécutés dans des domaines, mais une grande partie de ce que vous, l'utilisateur final, exécutez dans unconfined_u:unconfined_r:unconfined_t. Aucun prix pour deviner ce que cela signifie - si les autorisations Unix fonctionnent, SELinux est en fait un pass-through.
  2. strict. Cette politique implique la suppression de unconfined_u entièrement. Ce n'est pas un processus facile, en particulier sur le bureau Linux (c'est-à-dire init 5). Plus précisément, le modèle de sécurité X11 n'est pas génial et nécessite souvent unconfined_t pour certaines applications. Vous pouvez le faire , mais je m'attendrais à ce que le travail avec X11 soit plus difficile (mais pas impossible), en particulier lors de l'exécution d'applications GUI qui nécessitent root. Un projet est en cours pour prendre en charge les fonctionnalités de type SELinux dans X, appelé XACE (X Access Control Extensions) .
  3. MLS. MLS signifie sécurité à plusieurs niveaux et signifie la fin de la chaîne d'autorisation: user_u:system_r:httpd_content_t.s0-s2:c5-c7, c'est-à-dire que les nombres s et c signifient réellement quelque chose. Plus précisément, ils forment une configuration pas de lecture, pas d'écriture de telle sorte que, sauf si le processus s'exécute à un certain niveau, les informations qu'ils peuvent voir seront limitées. L'idée de ce niveau d'information est de protéger les actifs classés - SELinux a été initialement développé par la NSA, vraisemblablement à cette fin.

Voilà donc votre parcours. Maintenant, selon les pages web (voir FAQ ) root is UID 0 on the play machine; cependant, root est configuré pour s'exécuter comme user_r et non sysadm_r dans le strict politique. Cela signifie que l'utilisateur ne sera pas autorisé à exécuter des fonctions administratives à partir du shell.

Ce qui serait intéressant de savoir, alors, c'est le statut des autres processus qui nécessitent root. Vraisemblablement, ces processus ont été correctement étiquetés et ont des politiques qui leur permettent l'accès dont ils ont besoin. La question devient alors comment administrer le système et l'un de ces processus peut-il lancer un shell dans le contexte de cet utilisateur. Si cela peut arriver, vous pouvez toujours gérer un exploit.

Puisque la machine de jeu est actuellement en panne (au moment de la rédaction), je travaille sur des hypothèses ici; mais essentiellement, vous auriez besoin d'un processus exécuté dans sysadm_r et avec UID 0 comme cible pour un exploit. En supposant qu'un tel processus existe et soit exploitable, vous pouvez toujours accéder à root. Quant à pouvoir encore administrer via root, il y a deux options auxquelles je peux penser:

  • Soit il y a une transition de confiance qui signifie que root peut alors passer à sysadm_r (moins sécurisé) ou
  • Sur différents niveaux d'exécution, une politique différente s'applique, donc pour administrer la machine, on définit le niveau d'exécution sur 1 et la politique ne restreint pas root. Je suppose ici.

Sommaire

Si votre question est "puis-je le faire facilement et en toute sécurité maintenant?" La réponse est non. Si votre question est "Je suis prêt à en apprendre davantage sur SELinux, à me taire avec ma distribution et à supporter beaucoup de choses qui ne fonctionnent pas", la réponse est qu'il est possible de restreindre root beaucoup plus que votre installation moyenne. Cela dit, cela ne vous rend en aucun cas invulnérable aux exploits - cela ne rend pas impossible pour un utilisateur de contourner ce contrôle d'accès supplémentaire, que ce soit par logiciel ou physiquement.

Alors oui, vous pouvez rendre les choses invisibles à la racine; cependant, mis à part le fardeau technique supplémentaire, les mêmes mises en garde s'appliquent à toute configuration de contrôle d'accès pour tout utilisateur normal - il n'y a pas de solution miracle.

Oh et auto-promotion flagrante: vous pourriez aimer mon article de blog sur stockage de secrets dans le logiciel . C'est sur le blog de stackexchange de sécurité, donc je ne me sens pas si mal de promouvoir cela. Essentiellement, comme vous pouvez le voir, il existe des mécanismes pour rendre la vie beaucoup plus difficile à un attaquant (et à vous), mais en fin de compte, c'est un cas de "tortues tout le long", c'est-à-dire fondamentalement impossible à faire.

33
user2213

J'ai dû résoudre ce problème auparavant, lorsque j'ai été approché par un client souhaitant sécuriser les "messages privés" entre les utilisateurs d'un site Web. Il est possible de protéger certaines données dans certaines circonstances, mais cela est raisonnablement limité.

Mon approche était de simplement stocker une version cryptée de la note sur le serveur, et de la lui envoyer (une fois authentifiée bien sûr), puis de la décrypter entièrement côté client. Cela signifie que même en cas de compromis total sur la sécurité du serveur (c'est-à-dire l'accès root), les notes sont restées sécurisées. Les limites de ceci cependant:

  • Les données protégées ne sont sécurisées que jusqu'au point de compromis, et pas plus tard. Selon la méthode utilisée pour chiffrer les informations, un serveur enraciné peut inciter l'utilisateur à révéler les clés de déchiffrement (injection JavaScript ou pour les clients GUI natifs, émettre une mise à jour client compromise) ou à intercepter les clés de déchiffrement (si les clés sont basées) sur la même méthode que l'authentification de l'utilisateur, comme un mot de passe, ils peuvent être interceptés lors du processus d'authentification côté serveur).
  • La transmission nécessite une parfaite confidentialité avant, sinon les données cryptées pourraient être interceptées, stockées, puis décryptées après compromis, comme indiqué ci-dessus.
  • Cela ne protège rien si le client est également compromis. À moins que vous ne traitez les données chiffrées entièrement dans votre propre tête (et si vous le pouvez, vous méritez un trophée ou quelque chose), vous allez donner des données sensibles à quelque chose, et rien n'est - parfaitement sans compromis.
  • Il n'y a aucun moyen d'utiliser ces données côté serveur (c'est-à-dire à des fins d'indexation) à moins que des métadonnées déchiffrables/en texte brut soient stockées à côté, ce qui peut révéler des informations supplémentaires.

Essentiellement, cela limite les utilisations potentielles de ce scénario et il existe encore des faiblesses, mais il est possible qu'il fonctionne dans certaines situations. Le hachage de mot de passe est un exemple (raisonnablement) réussi de `` protection contre les compromis root '', dans la mesure où même un accès physique ne révélera pas les mots de passe d'un utilisateur (sauf bien sûr si ce mot de passe est transmis après compromis).

Il y a d'autres exemples dans ce fil qui méritent également d'être examinés, mais réfléchissez au scénario de traitement côté client, en utilisant le serveur simplement comme un service de stockage sécurisé.

TC

14
TC Fox

Peut-il y avoir des fichiers sur le système de fichiers qui ne sont pas accessibles même à la racine complète par tous les moyens, mais accessibles à certains processus? Certains processus en cours d'exécution, ou même de nouveaux processus démarrés par les processus ayant actuellement accès?

Non. Quand un processus peut y accéder, il en est de même pour root. Si vous voulez faire de telles choses, vous devrez modifier fortement l'ensemble du système, peut-être un système qui démarre un noyau immuable à partir d'un périphérique en lecture seule et qui refuse à la racine certains accès aux fichiers/mémoire tout en les autorisant pour d'autres utilisateurs que la racine peut ' t imiter.

Les secrets peuvent-ils être conservés en mémoire en exécutant des processus afin que même la racine complète ne puisse y accéder par aucun moyen? Ces secrets peuvent-ils être transmis à de nouveaux processus par certains moyens que la racine ne peut pas affecter?

Voir la réponse ci-dessus.

Vous ne pouvez pas, par définition, restreindre l'accès à root. Si vous limitez l'accès de root, ce n'est plus un utilisateur root.

Si je voulais refuser l'accès root aux secrets, j'essaierais de les cacher. Conteneurs cryptographiques, peut-être cachés dans la mémoire d'échange ou ailleurs et uniquement accessibles avec un mot de passe ou une autre sorte de stéganographie. Il est sacrément difficile de trouver une aiguille dans une botte de foin, bien que ce ne soit pas impossible.

6
Falcon

Il existe un certain nombre de façons indirectes par lesquelles root peut finir par exécuter du code arbitraire. Vous pouvez les désactiver, et en effet certains cadres de sécurité peuvent les désactiver, mais ils paralysent la capacité de root à effectuer des tâches d'administration.

Par exemple, root peut lire et écrire directement sur les disques, en contournant toutes sortes d'autorisations de système de fichiers. Vous pouvez retirer cette capacité, mais root ne pourra pas déplacer un système de fichiers complet vers un nouveau disque en cas d'urgence.

Root peut charger des modules du noyau, et peut ainsi faire tout ce que le noyau peut faire. Vous pouvez supprimer cette capacité, mais vous empêchez ensuite de charger des pilotes pour les supports enfichables à chaud. (Cela peut être souhaitable dans 0,001% des installations Unix, mais ce n'est pas le cas général.)

Root peut mettre à jour les exécutables qui permettent aux utilisateurs de se connecter, tels que login ou sshd. Ces démons gèrent l'authentification des utilisateurs, donc si vous contrôlez leur code, vous pouvez injecter une porte dérobée. Vous pouvez retirer cette capacité, mais root ne pourra pas effectuer de mises à niveau de sécurité.

Root peut créer et supprimer des utilisateurs et modifier les informations d'authentification: si vous pouvez modifier /etc/passwd pour ajouter un compte, vous pouvez également le modifier pour créer temporairement un compte sans mot de passe. Vous pouvez supprimer cette capacité en rendant certains fichiers en lecture seule, même pour root, mais vous vous retrouverez alors avec un système où vous ne pouvez pas créer ou supprimer des comptes d'utilisateur sans redémarrer.

Les cadres de sécurité créent efficacement des utilisateurs root limités qui ne sont root que dans un sous-ensemble du système - root uniquement dans une machine virtuelle, pas dans le "vrai" système. Cette racine limitée perd la possibilité d'effectuer des tâches d'administration sur le système réel. Je pense que la virtualisation est ce que vous recherchez.

Ceci est relativement facile à réaliser en utilisant un système selinux "à deux clés": root n'a aucune autorisation pour faire quoi que ce soit, et un autre utilisateur sans autorisation root ne, donc pour changer des choses, vous devez d'abord être le autre utilisateur non root, vous "su" à root pour effectuer le changement.

Aucun utilisateur isolé ne peut rien voir ou faire quoi que ce soit.

J'utilise ça. Ça marche vraiment bien.

3
cnd

Le besoin réel n'est pas bien défini dans la question, mais deux solutions potentielles auxquelles on fait allusion n'ont pas été mentionnées:

  • Conteneurs
  • HSM

Les conteneurs - qui ne sont bien sûr qu'une approche plus sensible à l'architecture de ce qui a été fait au coup par coup avec des outils comme les prisons et SELinux - peuvent être pertinents dans le contexte d'un recadrage de la question - existe-t-il un moyen qu'une logique de type Unix Le système peut être exposé à des attaquants, de sorte qu'il peut être compromis par les racines, mais les secrets du système physique sont toujours protégés. Avec les conteneurs, nous nous rapprochons de cet objectif. Un article récent du groupe de sécurité NCC mérite d'être lu: https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/june/container_whitepaper.pdf

Les HSM sont des dispositifs de chiffrement matériel qui empêchent la récupération des clés de déchiffrement via des méthodes physiques ou logiques, donc peut être une réponse à la question recadrée car j'ai des secrets que je dois déchiffrer en toute sécurité, que dois-je faire avec les clés.

2
Jonah Benton

Comme l'a dit Falcon, l'utilisateur root par définition a accès à toutes ces choses, ou ce n'est plus l'utilisateur root.

Le noyau contrôle tout le matériel, donc une fois que vous êtes root, vous avez le même accès. Vous avez vraiment besoin de virtualisation, votre utilisateur root n'est donc que root pour le système d'exploitation virtualisé sur lequel il s'exécute et certains hyperviseurs se trouvent en dehors de cela root. (pour ne pas dire que les hyperviseurs ne sont pas exploitables, mais ce que vous essayez de faire est équivalent à cela).

2
Bradley Kreider

Avez-vous essayé Grsecurity? Il peut effectivement restreindre les utilisateurs root de toutes les manières possibles. https://grsecurity.net/

Grsecurity, couplé à PaX fait de votre box une forteresse imprenable ... si vous le faites correctement

2
Jauzsika