TL; DR . Dans cet article, nous explorons les schémas de renforcement qui fonctionnent dès le départ sur cinq distributions Linux populaires. Pour chacun, nous avons pris la configuration par défaut du noyau, téléchargé tous les packages et analysé les schémas de protection dans les fichiers binaires joints. Nous considérons les distributions d'OpenSUSE 12.4, Debian 9, CentOS, RHEL 6.10 et 7, ainsi que Ubuntu 14.04, 12.04 et 18.04 LTS.
Les résultats confirment que même les schémas de base, tels que les canaris de pile et le code indépendant de la position, ne sont pas encore utilisés par tout le monde. La situation est encore pire pour les compilateurs lorsqu'il s'agit de se protéger contre des vulnérabilités comme le choc des piles, qui ont été mises à l'honneur en janvier après la publication d'
informations sur les vulnérabilités dans systemd . Mais tout n'est pas si désespéré. Dans une partie importante des binaires, des méthodes de protection de base sont implémentées et leur nombre augmente de version en version.
La vérification a montré que le plus grand nombre de méthodes de protection est implémenté dans Ubuntu 18.04 au niveau du système d'exploitation et de l'application, suivi de Debian 9. D'autre part, dans OpenSUSE 12.4, CentOS 7 et RHEL 7, des schémas de protection de base sont également mis en œuvre et la protection contre les collisions de pile est appliquée encore plus largement. avec un ensemble de packages beaucoup plus dense par défaut.
Présentation
Il est difficile de fournir un logiciel de haute qualité. Malgré le grand nombre d'outils avancés pour l'analyse de code statique et l'analyse dynamique à l'exécution, ainsi que des progrès significatifs dans le développement de compilateurs et de langages de programmation, les logiciels modernes souffrent toujours de vulnérabilités qui sont constamment exploitées par les cybercriminels. La situation est encore pire dans les écosystèmes qui incluent un code hérité. Dans de tels cas, nous sommes non seulement confrontés au problème éternel de trouver d'éventuelles erreurs exploitées, mais nous sommes également limités par des cadres de compatibilité descendante rigides, qui nécessitent souvent de maintenir un code limité, voire pire, vulnérable ou bogué.
C'est là que les méthodes de durcissement entrent en jeu. Nous ne pouvons pas empêcher certains types d'erreurs, mais nous pouvons rendre la vie d'un attaquant plus difficile et résoudre partiellement le problème en empêchant ou en empêchant le
fonctionnement de ces erreurs. Une telle protection est utilisée dans tous les systèmes d'exploitation modernes, cependant, les méthodes varient considérablement en complexité, efficacité et performances: des canaris de pile et
ASLR aux protections
CFI et
ROP à part entière. Dans cet article, nous examinerons les méthodes de protection utilisées dans les distributions Linux les plus populaires dans la configuration par défaut, et étudierons également les propriétés des binaires distribués via les systèmes de gestion de packages de chaque distribution.
CVE et sécurité
Nous avons tous vu des articles avec des titres comme «Applications les plus vulnérables de l'année» ou «Systèmes d'exploitation les plus vulnérables». Généralement, ils fournissent des statistiques sur le nombre total d'enregistrements de vulnérabilité tels que
CVE (Common Vulnerability and Exposures) obtenus à partir de la
National Vulnerability Database (NVD) du
NIST et d'autres sources. Par la suite, ces applications ou systèmes d'exploitation sont classés selon le nombre de CVE. Malheureusement, bien que les CVE soient très utiles pour suivre les problèmes et informer les fournisseurs et les utilisateurs, ils en disent peu sur la véritable sécurité des logiciels.
Par exemple, considérons le nombre total de CVE au cours des quatre dernières années pour le noyau Linux et les cinq distributions de serveurs les plus populaires, à savoir Ubuntu, Debian, Red Hat Enterprise Linux et OpenSUSE.
Fig. 1Que nous apprend ce tableau? Est-ce que plus de CVE signifie qu'une distribution est plus vulnérable qu'une autre? Il n'y a pas de réponse. Par exemple, dans cet article, vous verrez que Debian implémente des mécanismes de sécurité plus rigoureux que, disons, OpenSUSE ou RedHat Linux, et pourtant Debian a plus de CVE. Cependant, ils ne signifient pas nécessairement une sécurité affaiblie: même avoir un CVE ne dit pas si la vulnérabilité est
exploitable . Les scores de gravité donnent une idée de la
probabilité d' exploitation de la vulnérabilité, mais en fin de compte, l'exploitabilité dépend en grande partie de la protection présente dans les systèmes affectés, ainsi que des ressources et des capacités des attaquants. De plus, le manque de rapports CVE ne dit rien sur les autres vulnérabilités
non enregistrées ou inconnues . La différence de CVE peut s'expliquer non par la qualité du logiciel, mais par d'autres facteurs, notamment les ressources allouées aux tests ou la taille de la base d'utilisateurs. Dans notre exemple, plus de CVE Debian peuvent simplement indiquer que Debian fournit plus de packages logiciels.
Bien sûr, le système CVE fournit des informations utiles qui vous permettent de créer des protections appropriées. Mieux nous comprenons les raisons de l'échec du programme, plus il est facile d'identifier les modes de fonctionnement possibles et de développer des mécanismes de
détection et de réponse appropriés. Dans la fig. La figure 2 montre les catégories de vulnérabilité pour toutes les distributions au cours des quatre dernières années (
source ). Il est immédiatement évident que la plupart des CVE appartiennent aux catégories suivantes: déni de service (DoS), exécution de code, débordement, corruption de mémoire, fuite d'informations (exfiltration) et élévation de privilèges. Bien que de nombreux CVE soient couverts plusieurs fois dans différentes catégories, en général, les mêmes problèmes persistent d'année en année. Dans la prochaine partie de l'article, nous évaluerons l'utilisation de différents schémas de protection pour empêcher l'exploitation de ces vulnérabilités.
Fig. 2Les tâches
Dans cet article, nous avons l'intention de répondre aux questions suivantes:
- Quelle est la sécurité de diverses distributions Linux? Quels mécanismes de défense existent dans le noyau et les applications de l'espace utilisateur?
- Comment l'adoption de mécanismes de protection pour diverses distributions a-t-elle évolué au fil du temps?
- Quelles sont les dépendances moyennes des packages et des bibliothèques pour chaque distribution?
- Quelles protections sont mises en œuvre pour chaque binaire?
Choix des distributions
Il s'avère qu'il est difficile de trouver des statistiques précises sur les installations de distribution, car dans la plupart des cas, le nombre de téléchargements n'indique pas le nombre d'installations réelles. Cependant, les variantes Unix constituent la majorité des systèmes de serveurs (69,2% sur les serveurs Web, selon les
statistiques de W3techs et d'autres sources), et leur part est en constante augmentation. Ainsi, pour notre étude, nous nous sommes concentrés sur les distributions prêtes à l'emploi sur la plateforme
Google Cloud . En particulier, nous avons choisi le système d'exploitation suivant:
Distribution / version | Le noyau | Construire |
---|
OpenSUSE 12.4 | 4.12.14-95.3-défaut | # 1 SMP mer. 5 déc. 06:00:48 UTC 2018 (63a8d29) |
Debian 9 (étirement) | 4.9.0-8-amd64 | # 1 SMP Debian 4.9.130-2 (2018-10-27) |
CentOS 6.10 | 2.6.32-754.10.1.el6.x86_64 | # 1 SMP mar 15 janv.17: 07: 28 UTC 2019 |
CentOS 7 | 3.10.0-957.5.1.el7.x86_64 | # 1 SMP ven. 1 févr 14:54:57 UTC 2019 |
Red Hat Enterprise Linux Server 6.10 (Santiago) | 2.6.32-754.9.1.el6.x86_64 | # 1 SMP mer 21 nov 15:08:21 EST 2018 |
Red Hat Enterprise Linux Server 7.6 (Maipo) | 3.10.0-957.1.3.el7.x86_64 | # 1 SMP jeu. 15 nov. 17:36:42 UTC 2018 |
Ubuntu 14.04 (Trusty Tahr) | 4.4.0–140-générique | # 166 ~ 04/14/1-Ubuntu SMP sam 17 nov 01:52:43 UTC 20 ... |
Ubuntu 16.04 (Xenial Xerus) | 4.15.0-1026-gcp | # 27 ~ 16.04.1-Ubuntu SMP ven. 7 déc. 09:59:47 UTC 2018 |
Ubuntu 18.04 (Bionic Beaver) | 4.15.0-1026-gcp | # 27-Ubuntu SMP jeu 6 déc 18:27:01 UTC 2018 |
Tableau 1Analyse
Nous examinerons la configuration du noyau par défaut, ainsi que les propriétés des packages disponibles via le gestionnaire de packages de chaque package de distribution prêt à l'emploi. Ainsi, nous ne considérons que les packages des miroirs par défaut de chaque distribution, en ignorant les packages des référentiels instables (par exemple, 'tester' les miroirs dans Debian) et les packages tiers (par exemple, les packages Nvidia des miroirs standard). De plus, nous ne considérons pas les compilations de noyau personnalisées ou les configurations de sécurité avancées.
Analyse de configuration du noyau
Nous avons utilisé un script d'analyse basé sur le
vérificateur gratuit kconfig . Nous considérons les options de protection prêtes à l'emploi pour les distributions nommées et les comparons avec la liste du
Kernel Self-Defense Project (KSPP). Pour chaque paramètre de configuration, le tableau 2 décrit le paramètre souhaité: une coche est destinée aux distributions conformes aux recommandations KSSP (pour une explication des termes, voir
ici ; dans les prochains articles, nous vous dirons combien de ces méthodes de protection sont apparues et comment pirater le système en leur absence).


En général, les noyaux les plus récents ont des paramètres plus rigoureux prêts à l'emploi. Par exemple, CentOS 6.10 et RHEL 6.10 sur le noyau 2.6.32 n'ont pas la plupart des fonctions critiques implémentées dans les nouveaux noyaux, telles que
SMAP , les autorisations RWX fortes, la randomisation des adresses ou la protection contre la copie2. Il convient de noter que de nombreuses options de configuration du tableau sont absentes dans les anciennes versions du noyau et ne sont pas applicables en réalité - cela est toujours indiqué dans le tableau comme le manque de protection appropriée. De même, si le paramètre de configuration n'est pas disponible dans cette version, et pour des raisons de sécurité, ce paramètre doit être désactivé, cela est considéré comme une configuration raisonnable.
Autre point d'interprétation des résultats: certaines configurations de noyau qui augmentent la surface d'attaque peuvent être utilisées simultanément pour la sécurité. Ces exemples incluent les uprobes et kprobes, les modules du noyau et BPF / eBPF. Notre recommandation est d'utiliser les mécanismes ci-dessus pour fournir une réelle protection, car ils ne sont pas triviaux à utiliser, et leur fonctionnement suppose que les acteurs malveillants sont déjà ancrés dans le système. Mais si ces options sont activées, l'administrateur système doit surveiller activement l'abus.
En étudiant plus en détail les entrées du tableau 2, nous constatons que les noyaux modernes offrent plusieurs options de protection contre l'exploitation de vulnérabilités telles que la fuite d'informations et le débordement de pile / tas. Cependant, nous remarquons que même les distributions populaires les plus récentes n'ont pas encore implémenté une protection plus sophistiquée (par exemple, avec des correctifs
grsecurity ) ou une protection moderne contre les attaques de réutilisation de code (par exemple, en
combinant la randomisation avec des schémas comme R ^ X pour le code ). Pire encore, même ces défenses plus avancées ne protègent pas contre une gamme complète d'attaques. Ainsi, il est crucial pour les administrateurs système de compléter les configurations intelligentes avec des solutions qui offrent la détection et la prévention des exploits lors de l'exécution.
Analyse d'application
Il n'est pas surprenant que différentes distributions aient des caractéristiques différentes des packages, des options de compilation, des dépendances de bibliothèque, etc. Des différences existent même pour
les distributions et les packages
liés avec un petit nombre de dépendances (par exemple, coreutils dans Ubuntu ou Debian). Pour évaluer les différences, nous avons téléchargé tous les packages disponibles, extrait leur contenu et analysé les fichiers binaires et les dépendances. Pour chaque package, nous avons suivi les autres packages dont il dépend, et pour chaque binaire, nous avons suivi ses dépendances. Cette section résume les résultats.
Distributions
Au total, nous avons téléchargé 361 556 packages pour toutes les distributions, en extrayant uniquement les packages des miroirs par défaut. Nous avons ignoré les packages sans fichiers exécutables ELF, tels que les codes source, les polices, etc. Après le filtrage, 129 569 packages restaient contenant un total de 584 457 fichiers binaires. La distribution des packages et des fichiers entre les distributions est illustrée à la fig. 3.
Fig. 3Vous remarquerez peut-être que plus la distribution est moderne, plus elle contient de packages et de fichiers binaires, ce qui est logique. Dans le même temps, les packages Ubuntu et Debian incluent beaucoup plus de fichiers binaires (modules exécutables et dynamiques et bibliothèques) que CentOS, SUSE et RHEL, ce qui affecte potentiellement la surface d'attaque d'Ubuntu et Debian (il convient de noter que les chiffres reflètent tous les binaires de toutes les versions). package, c'est-à-dire que certains fichiers sont analysés plusieurs fois). Ceci est particulièrement important lorsque l'on considère les dépendances entre les packages. Ainsi, une vulnérabilité dans le binaire d'un même package peut affecter de nombreuses parties de l'écosystème, tout comme une bibliothèque vulnérable peut affecter tous les fichiers binaires qui l'importent. Comme point de référence, regardons la distribution du nombre de dépendances entre les packages dans différents OS:
Fig. 4Dans presque toutes les distributions, 60% des packages ont au moins 10 dépendances. De plus, certains packages ont plus de dépendances (plus de 100). La même chose s'applique aux dépendances de packages inverses: comme prévu, plusieurs packages sont utilisés par de nombreux autres packages dans la distribution, de sorte que les vulnérabilités de ces quelques favoris présentent un risque élevé. À titre d'exemple, le tableau suivant répertorie les 20 packages avec le nombre maximal de dépendances inverses dans SLES, Centos 7, Debian 9 et Ubuntu 18.04 (chaque case indique le package et le nombre de dépendances inverses).
Tableau 3Un fait intéressant. Bien que tous les systèmes d'exploitation analysés soient conçus pour l'architecture x86_64 et pour la plupart des packages, l'architecture est définie comme x86_64 et x86, mais les packages contiennent souvent des fichiers binaires pour d'autres architectures, comme le montre la Fig. 5.
Fig. 5Dans la section suivante, nous allons approfondir les caractéristiques des binaires analysés.
Statistiques de protection binaire
Au minimum, vous devez étudier l'ensemble de base des options de protection pour les fichiers binaires existants. Plusieurs distributions Linux sont livrées avec des scripts qui effectuent de telles vérifications. Par exemple, dans Debian / Ubuntu, il existe un tel script. Voici un exemple de son travail:
$ hardening-check $(which docker) /usr/bin/docker: Position Independent Executable: yes Stack protected: yes Fortify Source functions: no, only unprotected functions found! Read-only relocations: yes Immediate binding: yes
Le script vérifie cinq
fonctions de protection :
- Position Independent Executable (PIE): indique si la section de texte du programme peut être déplacée en mémoire pour obtenir une randomisation si ASLR est activé dans le noyau.
- Stack Protected: si les canaris de pile sont inclus pour se protéger contre les attaques par collision de pile.
- Fortifier la source: si les fonctions non sécurisées (par exemple strcpy) sont remplacées par leurs homologues plus sûres, et les appels vérifiés lors de l'exécution sont remplacés par leurs homologues non vérifiés (par exemple memcpy au lieu de __memcpy_chk).
- Relocations en lecture seule (RELRO): Indique si les entrées de la table des mouvements sont marquées en lecture seule si elles ont fonctionné avant le début de l'exécution.
- Liaison immédiate: si l'éditeur de liens d'exécution autorise tous les mouvements avant de démarrer le programme (cela équivaut à une RELRO complète).
Les mécanismes ci-dessus sont-ils suffisants? Malheureusement non. Il existe des moyens connus de contourner toutes les défenses ci-dessus, mais plus la défense est stricte, plus la barre de l'attaquant est élevée. Par exemple, les
solutions de contournement RELRO sont plus difficiles à appliquer si PIE et la liaison immédiate sont en vigueur. De même, un ASLR complet nécessite un travail supplémentaire pour créer un exploit fonctionnel. Cependant, des attaquants sophistiqués sont prêts à affronter de telles défenses: leur absence va essentiellement accélérer le piratage. Par conséquent, il est impératif que ces mesures soient considérées comme le
minimum nécessaire.
Nous voulions étudier combien de fichiers binaires dans les distributions en question sont protégés par ceux-ci, ainsi que trois autres méthodes:
- Un bit non exécutable ( NX ) empêche l'exécution dans toute région qui ne devrait pas être exécutable, comme un tas de pile, etc.
- RPATH / RUNPATH indique le chemin d'exécution utilisé par le chargeur dynamique pour trouver les bibliothèques appropriées. Le premier est obligatoire pour tout système moderne: son absence permet aux attaquants d'écrire arbitrairement la charge utile en mémoire et de l'exécuter telle quelle. Pour la seconde, des configurations incorrectes du chemin d'exécution aident à l'introduction de code non fiable, ce qui peut entraîner un certain nombre de problèmes (par exemple, une escalade de privilèges , ainsi que d' autres problèmes ).
- La protection contre les collisions de pile offre une protection contre les attaques qui font chevaucher la pile avec d'autres zones de mémoire (comme un tas). Étant donné les récents exploits abusant des vulnérabilités de collision de tas dans systemd , nous avons jugé approprié d'inclure ce mécanisme dans notre ensemble de données.
Alors, sans plus tarder, passons aux chiffres. Les tableaux 4 et 5 contiennent respectivement une analyse des fichiers exécutables et des bibliothèques de diverses distributions.
- Comme vous pouvez le voir, la protection NX est implémentée partout, à de rares exceptions près. En particulier, son utilisation plus faible dans les distributions Ubuntu et Debian peut être notée par rapport à CentOS, RHEL et OpenSUSE.
- Les canaris empilés ne sont pas disponibles dans de nombreux endroits, en particulier dans les distributions avec de vieux noyaux. Des progrès ont été constatés dans les récentes distributions de Centos, RHEL, Debian et Ubuntu.
- À l'exception de Debian et Ubuntu 18.04, la plupart des distributions ont un mauvais support PIE.
- La protection contre les collisions de pile est mal implémentée dans OpenSUSE, Centos 7 et RHEL 7 et est pratiquement absente du reste.
- Toutes les distributions avec des noyaux modernes ont un support RELRO, Ubuntu 18.04 ouvrant la voie, Debian occupant la deuxième place.
Comme déjà mentionné, les métriques de ce tableau sont moyennes sur toutes les versions du fichier binaire. Si vous ne regardez que les dernières versions des fichiers, les nombres seront différents (par exemple, voyez la
progression de Debian avec l'implémentation de PIE ). De plus, la plupart des distributions, généralement lors du calcul des statistiques, vérifient la protection de seulement quelques fonctions en code binaire, et dans notre analyse, le pourcentage réel de fonctions renforcées est indiqué. Par conséquent, si 5 des 50 fonctions sont protégées dans le binaire, nous lui donnerons une note de 0,1, ce qui correspond à 10% des fonctions renforcées.
Tableau 4. Caractéristiques de protection des fichiers exécutables illustrés à la fig. 3 (implémentation des fonctions correspondantes en pourcentage du nombre total de fichiers exécutables)
Tableau 5. Caractéristiques de protection des bibliothèques illustrées à la Fig. 3 (implémentation des fonctions correspondantes en pourcentage du nombre total de bibliothèques)Y a-t-il donc des progrès? Il y en a certainement: cela peut être vu à partir des statistiques des distributions individuelles (par exemple,
Debian ), ainsi que des tableaux ci-dessus. Comme exemple sur la fig. La figure 6 montre l'implémentation de mécanismes de défense dans trois distributions Ubuntu LTS 5 consécutives (nous avons omis les statistiques de protection contre les collisions de pile). Nous remarquons que de version en version, de plus en plus de fichiers prennent en charge les canaris empilés, et également de plus en plus de fichiers binaires sont fournis avec une protection RELRO complète.
Fig. 6Malheureusement, un certain nombre de fichiers exécutables dans différentes distributions ne disposent toujours d'aucune des protections ci-dessus. Par exemple, en regardant Ubuntu 18.04, vous pouvez voir le binaire ngetty (remplacement de getty), ainsi que les shells mksh et lksh, l'interpréteur picolisp, les packages nvidia-cuda-toolkit (un package populaire pour les applications accélérées par GPU telles que les frameworks d'apprentissage machine) et klibc -utils. De même, le binaire mandos-client (un outil d'administration qui vous permet de redémarrer automatiquement les machines avec des systèmes de fichiers cryptés), ainsi que rsh-redone-client (ré-implémentation de rsh et rlogin) sont livrés sans protection NX, bien qu'ils aient des droits SUID :(. En outre, Plusieurs binaires suid n'ont pas de protection de base, tels que les canaris de pile (par exemple, le binaire Xorg.wrap du package Xorg).
Résumé et remarques finales
Dans cet article, nous avons mis en évidence plusieurs fonctionnalités de sécurité des distributions Linux modernes. L'analyse a montré que la dernière distribution Ubuntu LTS (18.04) implémentait en moyenne la meilleure protection au niveau du système d'exploitation et des applications parmi les distributions avec des noyaux relativement nouveaux, tels que Ubuntu 14.04, 12.04 et Debian 9. Cependant, les distributions CentOS, RHEL et OpenSUSE discutées dans notre kit par défaut, un ensemble plus dense de packages est publié et les dernières versions (CentOS et RHEL) ont un pourcentage plus élevé de protection contre les collisions de pile par rapport aux concurrents basés sur Debian (Debian et Ubuntu). En comparant les versions CentOS et RedHat, nous remarquons de grandes améliorations dans la mise en œuvre des canaries de pile et RELRO des versions 6 à 7, mais en moyenne CentOS a plus de fonctionnalités que RHEL. En général, toutes les distributions doivent accorder une attention particulière à la protection PIE, qui, à l'exception de Debian 9 et Ubuntu 18.04, est implémentée dans moins de 10% des fichiers binaires de notre ensemble de données.
Enfin, il convient de noter: bien que nous ayons fait la recherche manuellement, il existe de nombreux outils de sécurité (par exemple,
Lynis ,
Tiger ,
Hubble ) qui effectuent des analyses et aident à éviter les configurations dangereuses. Malheureusement, même une protection forte dans des configurations raisonnables ne garantit pas l'absence d'exploits. C'est pourquoi nous sommes fermement convaincus qu'il est essentiel d'assurer
une surveillance et une prévention fiables des attaques en temps réel , en se concentrant sur les modèles opérationnels et en les prévenant.