n°2
Transcription
n°2
________________________________________________________________________________ Télécom SudParis Etat de l’art sur les rootkits ________________________________________________________________________________ 1 ________________________________________________________________________________ VAP SSR 2008-2009 Sommaire Table des figures---------------------------------------------------------------------------------------------p. Introduction-------------------------------------------------------------------------------------------------p. Chapitre I : Définition du terme rootkit--------------------------------------------------------------p. 1) Le fonctionnement d’un OS ---------------------------------------------------------------------------p. 2) Le rootkit --------------------------------------------------------------------------------------------------p. Chapitre II : Présenttation des trois familles de rotkits---------------------------------------- p. 1) L'user-mode rootkit----------------------------------------------------------------------------------- p. a) Définition------------------------------------------------------------------------------------ p. b) Exemple pratique (Hacker Defender) ------------------------------------------------- p. 2) Le kernel-mode rootkit------------------------------------------------------------------------------- p. a) Définition ---------------------------------------------------------------------------------- p. b) Exemple pratique (FU rootkit) -------------------------------------------------------- p. 3) Le virtual machine-mode rootkit ------------------------------------------------------------------ p. a) Définition ---------------------------------------------------------------------------------- p. b) Exemple pratique (SubVirt rootkit) -------------------------------------------------- p. 4) Le firmware-mode rootkit ----------------------------------------------------------------------------p. a) Défintion ---------------------------------------------------------------------------------------p. b) Exemple pratique (ACPI rootkit) -------------------------------------------------------p. ________________________________________________________________________________ 2 ________________________________________________________________________________ Chapitre III : Les parades ------------------------------------------------------------------------------- p. 1) Surveillance du système-----------------------------------------------------------------------------p. 2) Détection des rootkits en "user-mode" ----------------------------------------------------------------p. a) Contrôle d’intégrité ------------------------------------------------------------------------p. b) Recherche des sigantures ------------------------------------------------------------------p. 3) Détection des rootkits en "kernel-mode" ----------------------------------------------------------p. a) Paramètrage du noyau (prévention) ---------------------------------------------------p. b) Vérification de la mémoire (détection) ------------------------------------------------p. 4) Détection des rootkits en mode virtuel ------------------------------------------------------------p. 5) Détection des rootkits en mode firmware----------------------------------------------------------p. Conclusion -------------------------------------------------------------------------------------------------- p. Bibliographie ----------------------------------------------------------------------------------------------- p. Annexes ------------------------------------------------------------------------------------------------------ p. ________________________________________________________________________________ 3 ________________________________________________________________________________ Tables des figures ________________________________________________________________________________ 4 ________________________________________________________________________________ Introduction Durant ces dernières années, l’utilisation d’Internet s’est développée d’une façon exponentielle. Actuellement, l’accès à Internet est facilement fourni aux particuliers et les entreprises ouvrent de plus en plus leurs systèmes d’information à leurs fournisseurs de services ou encore leurs partenaires. Les nouvelles technologies ayant facilité l’accès à l’information, il est ainsi fondamental de gérer les risques inhérents à l’ouverture des réseaux. En effet, la malveillance a toujours existé et hélas existera sans doute toujours. Ainsi, la sécurité informatique et des réseaux s’inscrit dans un cadre de sécurité globale dans l’optique de protéger les ressources de l’utilisateur notamment, les entreprises. Aujourd’hui, le piratage informatique est une réalité quotidienne qui s’adapte constamment aux évolutions perpétuelles du secteur des TIC. Les pirates font preuve d’une créativité croissante pour faire face aux différents mécanismes de protection mis en place par les éditeurs de logiciels. Pour les personnes malveillantes, ceci constitue une source de motivation supplémentaire dans le but de contourner les contre-mesures et exploiter les ainsi les vulnérabilités identifiées. Si on s’intéresse de plus près au cas des applications informatiques, on constate qu’il existe en moyenne 5 à 50 bugs par 1000 lignes de code. Nous pouvons donc facilement imaginer le nombre d’attaques possibles contre un système d’exploitation tel que Windows Vista (70 millions ligne de code !). Par conséquent, une vulnérabilité logicielle génère une menace. D’où le risque d’attaque par divers techniques développées par les pirates : social engineering, vol de mots de passe, force brute, dénis de service, usage de backdoor, usurpation d’identité, les virus, le spam, les chevaux de troie, les vers et enfin les rootkits. Dans ce document, nous nous focaliserons exclusivement sur les attaques effectuées par le biais des rootkits. Tout d’abord, nous allons commencer par définir le terme rootkit, la ________________________________________________________________________________ 5 ________________________________________________________________________________ vulnérabilité identifiée et le risque associée. Ensuite, les quatre grandes familles de rootkits seront également évoquées avec des exemples pratiques illustrant le mode de fonctionnement de ces logiciels malicieux et leurs impacts sur les applications informatiques. Puis, les différentes techniques de parade seront développées dans le but d’expliquer comment un simple utilisateur pourrait se prémunir des effets néfastes engendrés par les attaques par rootkits. Enfin, cet état de l’art sera conclu par une réflexion générale sur la problématique des rootkits. Chapitre I : Définition du terme rootkit 1) a) Fonctionnement des OS Notion du noyau et d’espace utilisateur Le noyau (kernel) assure le rôle d'intermédiaire dans l'utilisation des ressources matérielles pour permettre aux applications de tourner (allocations des ressources, ordonnancement, priorités, etc...). Le noyau opère donc avec un niveau de privilèges illimité, puisqu'il administre directement l'utilisation physique de la machine. Son code s'exécute donc dans un espace mémoire isolé de celui utilisé par les applications courantes de haut-niveau, qui elles ont un niveau de privilège plus bas. Ce modèle de fonctionnement partagé par les systèmes d'exploitation (OS) est le modèle des "ring", ou la ring 0 représente le noyau, et la ring 3 l'espace utilisateur. De fait, l'architecture x86 n'utilise que les rings 0 et 3. Avec le développement des méthodes de virtualisation, on a pris l'habitude de désigner la couche "hyperviseur" (celle qui virtualise) comme étant le ring -1, c'est à dire, virtualisant le noyau. Lors de son déroulement, un programme de l'espace utilisateur ayant besoin de faire exécuter du code avec les privilèges du noyau exécute un "appel système" (syscall), qui indique littéralement que le programme fait "appel" au kernel. b) Appels système Le syscall est donc une fonction appelée depuis l'espace utilisateur, et destinée à lui renvoyer un résultat: la totalité des applications des systèmes d'exploitation est donc entièrement dépendante de l'exécution de ces appels systèmes au niveau noyau. Ainsi, un programme se chargeant d'écrire sur le disque, indépendamment de son implémentation de haut-niveau (en C, en JAVA...), utilisera nécessairement des syscalls comme open, create, write..., qui écriront concrètement sur le disque, sous le contrôle du noyau, des pilotes propres à ce disque, etc... Le niveau intermédiaire est constitué de ________________________________________________________________________________ 6 ________________________________________________________________________________ librairies sous UNIX (libc, glibc), ou d'API sous Windows. Cette hiérarchie dans les étapes d'exécution des programmes, et cette dépendance du niveau utilisateur vis-à-vis du noyau, sont fondamentales dans la façon dont les rootkits opèrent et se dissimulent. En particulier, qu'un rootkit opère sur une ring rend de fait les rings supérieures non fiables car susceptibles de fournir des résultats filtrés préalablement par le rootkit. c) Chaîne d’exécution d’un programme Import Address Table (IAT): au niveau utilisateur, chaque programme susceptible d'appeler des fonctions est rattaché à ces fonctions par un ensemble de pointeurs, dont la liste constitue l'IAT de l'exécutable. Interrupt Descriptor Table (IDT): le passage du niveau utilisateur au niveau noyau implique une « interruption » (entre le moment ou l'appel système est lancé, puis le moment où l'on recevra le résultat). La gestion de ces interruptions (entre la fonction appelante et le noyau), est gérée dans le kernel par l'IDT Syscall Table: enfin, d'une façon similaire à l'IAT, mais au niveau du noyau, une zone de la mémoire kernel est constituée de pointeurs vers des appels systèmes qui seront utilisés. Ainsi, derrière le déroulement d'un programme en ring 3, il existe un ensemble d'éléments qui relient le système de bas-niveau aux couches hautes. Les 3 tables présentées constituant par leurs pointeurs, les maillons fragiles de cette chaîne ou des redirections malveillantes peuvent être implémentées. 2) Le rootkit Le terme rootkit a été initialement introduit pour désigner un ensemble d’outils permettant l’acquisition de droits administrateurs système (root user) sous les OS UNIX. Parmi ces outils on pouvait trouver des applications de surveillance du système modifiées dans le but de cacher les actions d’un utilisateur non autorisé à accéder aux ressources du système en question. En agissant de cette façon, « l’assaillant » peut dissimuler ses traces sur le système cible en remplaçant les outils classiques de monitoring par des versions patchées, empêchant ainsi l’utilisateur lambda de détecter ses actions et les failles exploitées. Sous les systèmes Windows, le terme rootkit a pris une définition moins globale. Contrairement au virus et aux vers, le but d’un rootkit n’est pas de nuire aux systèmes attaqués en détruisant certains fichiers ou bibliothèques sensibles. Il s’agit plus tôt de changer le comportement du système attaqué afin de cacher l’existence de certains fichiers, des processus malicieux exécutés, des clés de registre Windows et des bibliothèques. Ainsi, un pirate peut dissimuler le comportement de programmes malveillants introduits à l’insu de la cible attaquée. Par comparaison aux systèmes UNIX, les rootkits Windows ne cherchent pas forcément à acquérir les droits privilégiés de ________________________________________________________________________________ 7 ________________________________________________________________________________ l’administrateur car par définition, ce type de programme nécessite des droits privilégiés pour pouvoir fonctionner et manipuler les fichiers système. Ceci requiert l’installation en amont du programme malicieux grâce à un accès physique à la machine cible ou en exploitant une faille de sécurité d’un autre logiciel. Les rootkits peuvent également installer des backdoors en remplaçant les mécanismes de login par un exécutable qui accepte une combinaison secrète permettant ainsi à l’assaillant d’accéder au système à distance sans que la cible ne s’en rende compte. Dans la suite, nous allons nous intéresser aux quatre grandes familles de rootkits agissant à quatre niveaux différents : le niveau applicatif, le niveau kernel, le niveau hyperviseur et enfin le niveau physique ou firmware. Chapitre II : Les trois familles de rootkits Le niveau de dissimulation distingue les rootkits des autres programmes malicieux. De plus, plus le rootkit agit à niveau bas plus il est difficile à détecter comme le montre le schéma ci-dessous : Fig : Structure en anneaux d’un système informatique (source www.rootkitanalytics.com) 1) a) L'user-mode rootkit Définition Comme son nom l’indique, l’user-mode rootkit opère dans l’espace applicatif où les programmes utilisent les droits associés à l’utilisateur en question pour effectuer leurs tâches. Le principe fondamental de ce type de rootkits est l’interception des appels systèmes des processus en cours d’exécution émis vers le noyau. Sous Windows, une pratique courante des user-mode rootkits est la modification de l’espace mémoire alloué aux bibliothèques .DLL des systèmes Windows. En effet, les programmes compilés pour ces systèmes utilisent les .DLL dans l’espace mémoire alloué permettant ainsi à ces logiciels de charger et d’exécuter le contenu de ces bibliothèques. A titre d’exemple, prenons le cas d’une application qui souhaite énumérer les clés de ________________________________________________________________________________ 8 ________________________________________________________________________________ registre Windows en utilisant la .DLL ADVAPI32.DLL dont le code est déjà exécuté dans l’espace mémoire du processus en question. Un user-mode rootkit peut donc intercepter le syscall lancé par l’application pour utiliser ADVAPI32.DLL et l’obliger à pointer vers le code malicieux du rootkit qui s’exécutera à la place de la bibliothèque Windows. Après avoir intercepté l’appel système et étant exécuté avec des droits élevés, le rootkit appellera lui-même ADVAPI32.DLL, obtient le résultat retourné par la .DLL pour le modifier et cacher sa propre clé de registre avant de le renvoyer à l’application initiale. En agissant de la sorte, le rootkit reste indétectable car l’utilisateur ignore son existence. Néanmoins ce mode de fonctionnement présente un défaut majeur compromettant la dissimulation du rootkit. Comme chaque processus tourne dans son propre espace mémoire qui lui est réservé par l’OS, le rootkit devra s’exécuter dans chacun de ces espaces mémoire pour pouvoir monitorer et intercepter les syscalls des processus tout en surveillant le système lui-même pour détecter tout lancement d’un nouveau processus pour le patcher à son tour. Cette surveillance continue et le patching constant impactera bien évidemment les performances du système à cause la consommation excessive des ressources mémoire de la machine attaquée. Un utilisateur pourra donc remarquer le ralentissement de son système et déceler par conséquence le rootkit. b) Exemple pratique (Hacker Defender) Le but de Hacker Defender est d’empêcher les logiciels antivirus et firewalls d’effectuer leur tâche fondamentale : détecter et éliminer tout code malicieux. En outre, l’assaillant peut dissimuler des fichiers, des processus, des services systèmes, des pilotes du système, des clés de registre, des ports secrètement ouverts and fausser la valeur de l’espace libre du disque dur. Ce programme s’installe en tant que service caché du système et peut également installer des pilotes cachés ainsi que des backdoors. Plus concrètement, ce rootkit surveille tous les ports ouverts par les processus et peut donc rediriger le trafic destiné au port 80/TCP (la cible est un serveur Web) ou encore utiliser ce port pour recevoir un trafic provenant de l’extérieur qui n’est pas nécessairement un flux HTTP, c’est le principe d’un backdoor. 2) a) Le kernel-mode rootkit Définition Le kernel-mode rootkit opère dans l’espace noyau du système qui possède des droits illimités. Cet espace est généralement interdit d’accès aux utilisateurs standards. Seul l’administrateur ayant les droits root peut intervenir à ce niveau 0, consulter et modifier l’espace mémoire du kernel. D’où l’intérêt pour un pirate d’installer un rootkit fonctionnant à ce niveau. Lors d’un syscall, il existe plusieurs points d’entrée au noyau dans le chemin de l’appel. Ainsi, le kernel-mode rootkit peut intercepter cet appel dans l’un ces points. En effet, il existe une passerelle entre le niveau applicatif et le noyau qui assure que les processus utilisateur n’aient pas un accès général au code du kernel afin de le protéger. De plus, cette passerelle identifie l’objectif de l’appel système entrant avant de l’exécuter dans le ________________________________________________________________________________ 9 ________________________________________________________________________________ code du noyau, puis elle retourne le résultat à l’application utilisateur qui a initié le syscall en premier lieu. Le kernel-mode rootkit donne la possibilité de contourner ce mécanisme analogue au proxy pour réorienter les syscalls vers le code malicieux au lieu du code du noyau. Un autre maillon fragile et exploitable est le Syscall Table (Voir la partie Fonctionnement des OS). En altérant cette table au niveau kernel, le rootkit peut orienter le noyau vers l’exécution de son propre code, en pointant vers son adresse mémoire, au lieu de l’appel système initial. Une technique assez similaire et plus difficile à détecter consiste en la réécriture des 7 premiers octets d’un syscall pour que l’appel pointe vers le code malveillant. Ainsi, la table des syscalls n’est pas altéré mais seulement une partie de l’appel. A noter que le rootkit garde les 7 octets originaux pour que les fonctions malicieuses puissent les réutiliser plus tard et fausser les résultats retournés pour se dissimuler. Plusieurs kernel-mode rootkits sont développés en tant que pilote hardware ou encore en tant que module qui se greffe au noyau (Principalement Linux). Par conséquent, ils possèdent le plus haut niveau de droits et esquivent facilement la surveillance effectuée par les logiciels antivirus qui opèrent au niveau applicatif. En revanche, il est difficile pour ce type de rootkit de cohabiter avec le reste des modules kernel proprement codés dans un ensemble homogène et cohérent. Généralement, les kernel-mode rootkits crachent lors de leur exécution engendrant le crash total du système compromettant ainsi son aspect fantôme. Ci-dessous un schéma récapitulatif des modes opératoires de kernel-mode rootkits : Source (www.rootkitanalytics.com) ________________________________________________________________________________ 10 ________________________________________________________________________________ b) Exemple pratique (FU rootkit) Il existe plusieurs rootkits opérant au niveau 0. FU est un programme malveillant non persistant. Cela veut dire qu’il ne s’installe en permanence dans le système attaqué, son code est plutôt chargé et exécuté dans le noyau et disparaît au redémarrage de la machine cible en ne laissant aucune trace. Ce rootkit se compose d’un exécutable FU.exe et d’un pilote hardware msdirectx.sys. Une fois le driver chargé, il n’y a plus besoin de privilège particulier nécessaire pour faire tourner l’exécutable. Ces deux composantes œuvrent ensemble : FU.exe envoie les paramètres à manipuler au driver qui de charge en tant que pilote système d’exécuter les instructions malveillantes. Ce rootkit peut effectuer plusieurs actions malveillantes : - Lister et/ou cacher les processus, les services et pilotes en cours d’exécution. - Lister les privilèges disponibles. - Changer le groupe d’un processus. Comme mentionné précédemment, le défaut principal de ce rootkit est volatilité. Il est nécessaire de recharger les deux composantes du programme après un redémarrage de la machine cible pour pouvoir la compromettre à nouveau. 3) a) Le virtual machine-mode rootkit Définition Durant les dernières années, les techniques de virtualisation se sont largement répondues. Elles permettent de simuler plusieurs machines virtuelles avec des OS différents, le tout sur une même plateforme physique. Le logiciel permettant la coexistance des OS et la gestion des accès aux ressources physiques est appelé hyperviseur. L’hyperviseur agit au niveau -1 en bas du kernel, donc il possède plus de privilèges. Ce principe a été détourné dans le but de créer des rootkits plus puissants. En effet, un tel rootkit est capable de modifier la séquence d’amorçage de la machine cible pour s’exécuter en tant qu’hyperviseur et faire tourner l’OS attaqué en tant qu’invité sur une machine virtuelle. Par conséquent, le rootkit est capable d’intercepter tous les appels système émis vers les ressources physiques. D’où un contrôle total sur la machine cible. Pour le moment, ce type de rootkit est toujours en phase d’expérimentation dans les laboratoires de recherche vu le niveau de complexité très élevé d’un tel programme. b) Exemple pratique (SubVirt rootkit) Ce virtual machine-mode rootkit a été développé conjointement par Microsoft et l’Université du Michigan. Le point fort de SubVirt est qu’il est indétectable car il opère au plus bas niveau et aucun logiciel existant ne peut déceler son existence. Si on considère un OS Windows émulé, aucun programme de sécurité ne peut accèder à l’hyperviseur SubVirt. En effet, les suites antivirales vérifient les clés e registre ainsi que ________________________________________________________________________________ 11 ________________________________________________________________________________ l’intégrité des API Windows. Dans le cas SubVirt, ces paramètres ne sont pas altérés. A noter qu’une version Linux de ce rootkit a été également développée en laboratoire. Si un tel rootkit infecte une machine physique, toutes les machines virtuelles sont donc compromises et les données sensibles sont facilement récupérables comme les mots de passe 4) a) Le bios-mode rootkit Définition Les composants physique de l'ordinateur comportent un code en dur exécuté à chaque démarrage, qu'on appelle "firmware". Le caractère non-volatile de ce code est particulièrement intéressant car il demeur malgré les changements d'OS, ce qui en fait une cible de choix pour les rootkits, qui, en se basant sur ce type de composants, sont assurés d'exister indépendamment du système d'exploitation. Il existe des BIOS sur la carte mère ou sur les composants PCI, dont certains sont « flashables », c'est à dire, modifiables de façon logicielle sans intervention physique. b) Exemple pratique (ACPI rootkit) Depuis quelques années, l'amdinistration de l'alimentation électrique des composants se fait via un ensemble de fonctions depuis le BIOS: l'Advanced Configuration and Power Interface (ACPI). Cet environnement permet, via quelques procédures, de placer un code malveillant dans la mémoire du noyau qui sera chargé juste aprés le démarrage (via la commande OperationRegions). Un rootkit utilisant ce type de procédés possède donc les attributs des rootkits opérant au niveau du kernel, tout en ayant en plus la capacité de rester dans le système malgré les ré-installations. Une équipe de chercheur(NGSSoftware) a démontré la faisabilité de tels rootkits en 2006 [annexe]. ________________________________________________________________________________ 12 ________________________________________________________________________________ Chapitre III : Les parades L'objectif principal des rootkits étant de demeurer invisibles, leur détection s'avère en soi difficile, puisqu'il s'agit précisemment de ce dont le rootkit a été conçu pour se prémunir. En particulier, les résultats des commandes lancées depuis un système dont on soupçonne qu'il est compromis, sont soumis à caution du fait de la présence potentielle d'interception ou de modifications de ce qui est retourné par le système. Toute investigation doit se faire par exemple via l'utilisation de CDs bootables, ou de machines distantes, pour opérer depuis un environnement qui ne soit pas suspect. Selon le niveau ou opère le rootkit (espace utilisateur, espace noyau, ou rootkit virtuel), un certain nombre de contre-mesures adapatées à chaque cas permet de mettre en évidence une possible infection; dans chacun de ces cas, divers outils souvent sous licence libre, permettent de mener ces tests. Les éditeurs commerciaux, conscient de la menace croissante, ont augmenté leurs solutions de sécurité de détecteurs de rootkits qui combinent les différentes stratégies décrites ci-dessous. 1) Surveillance du système Avant d'aborder les techniques de détection plus élaborées et automatisées par des outils existants, il est nécessaire de rappeler un certain nombre d'indicateurs à surveiller sur un système suspect. L'essentiel des rootkits laissent les traces d'une utilisation étrangère du système qu'on retrouve notamment en inspectant: - les « MAC times », qui sont les trois dates associées à un fichier (Modification, Access, Change), et qui trahissent toujours une activité suspecte (car seul l'administrateur peut remarquer l'incohérence de ces dates). La tâche étant sur le plan pratique difficilement réalisable, il existe des outils qui permettent de gérer cette surveillance dans le cas où des soupçons pèsent sur la machine concernée ( The Sleuth Kit, The Coroner's toolkit). ________________________________________________________________________________ 13 ________________________________________________________________________________ - les appels systèmes utilisés par les exécutables, via la commande strace. Surtout efficace contre les rootkits agissant au niveau utilisateur, il permet notamment de détecter l'utilisation anormalement élevée d'appels systèmes normalement peu utilisés. The Linux trac toolkit et Systrace réalisent cette surveillance. - les modules chargés par le noyau, pendant l'exécution en cours via la commande lsmod, ou au démarrage, en étudiant certains fichiers comme /etc/rc.d/rc.sysinit ou /lib/modules. L'activité anormale ou le chargement imprévu de modules apparaît également dans les logs et les messages de démarrages. 2) Détection des rootkits en "user-mode" a) Contrôle d’intégrité Les rootkits opérant dans l'espace utilisateur dissimulent leur activité en modifiant un ensemble d'éxecutables, de librairies, impliquées dans les processus qui permettent de révéler leur présence. L'étendue des modifications qu'il a ainsi opérées sur le système est considérable, et par là même, observable. Un moyen fiable de contrôler l'authenticité d'un fichier, est de se référer à ses empreintes, par vérification de l'intégrité via un certain nombre de fonction hash (MD5 par exemple). On ne peut être certain des résultats positifs retournés que lorsque cette opération est menée depuis un système dont on sait qu'il est sûr (par exemple depuis une machine distante). De façon empirique, cette opération est relativement simple à appliquer: il suffit de comparer les empreintes d'un certain nombre de fichiers sensibles à une empreinte qui aura été faite puis sauvegardée juste après l'installation. De cette manière, la moindre modification sera immédiatement détectable. Dans un environnement Linux, on surveillera traditionnellement un certain nombre d'exécutables sensibles, et de librairies. Sous environnement Windows, on s'intéressera aux API et DLLs, ainsi qu'à des entrées du registre. Sous Linux: - Executables: ps, ls, kill, top, du, find, netstat.... - Librairies: libproc.so, libc.so... Sous Windows: API FindFirstFile/FindNextFile, NtQueryDirectoryFile, chargées depuis kernel32.dll, NtQueryDirectoryFile chargée avec Advapi32.dll. L'essentiel des outils de détection de rootkits disponibles implémentent ce type de vérification: - -Rootkit Hunter[1] utilise les hash MD5 sur les fichiers sensibles des systèmes Linux et BSD, pour les comparer à ceux de référence stockés sur une base de données en ligne. ________________________________________________________________________________ 14 ________________________________________________________________________________ -Tripwire[2] permet l'administration d'un système dont les fichiers sont surveillés en permanence par un système de hash: en classifiant les fichiers selon leur seuil de criticité, et par un système d'alerte, cette solution permet la surveillance en continu et temps réel du système et des modifications qui lui sont apportées. Sous environnement Windows: -Rootkit Revealer[3] contrôle l'intégrité des applications Windows sans avoir recours aux hashs des exécutables. Il détecte la présence de modifications des API au niveau userspace en analysant l'arborescence de deux façons différentes: à l'aide de processus de haut-niveau, via des API qui énumérent les entrées de registres, les contenu des dossiers, etc...; puis via des processus de bas-niveau en reconstituant le contenu brut des volumes NTFS ou FAT. Une incohérence entre les deux peut être la trace d'une modification anormale des API Windows liées à l'arborescence. A titre préventif, et compte-tenu des modifications de certains exécutables, une bonne politique consiste à conserver en lieu sûr des copies saines de fichiers essentiels à toute investigation, dont voici une liste non-exhaustive: awk, cut, egrep, find, head, id, ls, netstat, ps, strings, sed, uname. Ils permettront de débusquer des rootkits fonctionnant dans l'espace utilisateurs. b) Recherche des signatures A la façon des antivirus, on peut détecter certains rootkits par des indices qui indiquent de façon certaine leur présence sur le système. La chaîne « /dev/ptyp » ou la présence de /usr/src/.puta indiquent par exemple la présence de 't0rnkit'. -Chkrootkits [4]dispose d'une base de données qui permet de reconnaître environ 60 rootkits parmi les plus répandus sur Linux, BSD, Solaris et Mac OS X. Ce type de recherche ne permet de se protéger que des rootkits connus dont le comportement sur le système est déjà documenté. -Samhain[5] opère dans le deux environnements et permet de centraliser les analyses de hash de fichiers de plusieurs machines, de façon centralisée sur un réseau. 3) Détection des rootkits en "kernel-mode" Les modifications apportées au système et susceptibles de trahir la présence d'un rootkit, ne se trouvent plus au niveau "user-space": les librairies, les exécutables, les API utilisées, sont parfaitement authentiques, mais font appel au niveau des couches inférieures, à des appels systèmes (ou syscalls) dont le contenu a été altéré. On ne peut donc détecter la trace d'anomalies qu'au niveau du noyau de l'OS, plus précisemment par l'analyse du comportements des appels système, de la mémoire du kernel et des tables d'adressages. a) Paramétrage du noyau (prévention) ________________________________________________________________________________ 15 ________________________________________________________________________________ - Restriction de l'accès à la mémoire du noyau: Sous environnement UNIX, /dev/kmem donne accès à la mémoire utilisée par l'exécution du noyau, et constitue une porte d'entrée qui permet d'y injecter du code. Un patch[6] diffusé dans le numéro 58 de Phrack doit être appliqué à n'importe quel noyau Linux. (http://doc.bughunter.net/rootkit-backdoor/kernel-patching.html). Cette mesure protège par exemple contre le rootkit "SucKIT". - Sécurisation des modules: Les "Loadable Kernel Modules" permettent de charger dynamiquement du code dans le noyau (ex: drivers), et constituent l'autre point d'entrée dans le "kernel-space". Statistiquement, la quasi-totalité des rootkits utilisent ce procédé pour s'introduire dans le noyau. Il convient donc de désactiver les fonctionnalités de chargement/déchargement dynamiques de LKM[7] pour avoir un noyau qui soit, à titre préventif, bien protégé, contre l'essentiel des rootkits: adore, knark, itf, heroin... Beaucoup de postes ne peuvent fonctionner de cette manière (avec un noyau monolithique n'acceptant plus les modules chargés dynamiquement). Des LKM permettent toutefois de continuer d'utiliser ce type de noyau en donnant une couche de sécurité qui correspond de fait à un Intrusion Detection System qui ne marcherait qu'au niveau noyau: St Jude (et l'extension St Michael) contrôlent l'intégrité du noyau au fur et à mesure que des LKM sont chargés et déchargés. Cette surveillance se fait en comparant les hash md5 de certaines zones mémoires non-volatiles du noyau, ou par les hash des tables d'adressages des syscalls. En cas de modification, cette suite permet de restorer un version précédente du noyau. b) Vérification de la mémoire (détection) - Adresses des syscalls. Sous environnement Linux, l'objectif consiste à discerner les adresses des appels systèmes qui ont été modifiées. Lors de sa compilation, le noyau génère une "carte" des adresses des appels systèmes utilisés (system.map). Un moyen utilisé par les rootkits consiste à remplacer les adresses par de nouvelles qui pointeront vers du code conçu par l'attaquant. Typiquement, les appels systèmes ciblés sont : sys_clone, sys_close, sys_execven sys_fork,... En comparant les adresses initiales avec celles utilisées par le noyau en cours d'exécution, qu'on obtient par exemple via la référence sys_call_table, il devient possible de vérifier les cohérences de l'ensemble des pointeurs vers les syscalls pour mettre en évidence des modifications malveillantes. -Kstat[8] permet de réaliser cette opération et de signaler les appels systèmes dont l'adresse en cours diffère de celle d'origine. hg:/home/tools/KSTAT24/2.4.16 # ./kstat -s 0 ________________________________________________________________________________ 16 ________________________________________________________________________________ sys_fork 0xf880c7a1 WARNING! should be at 0xc01058fa sys_write 0xf880ca31 WARNING! should be at 0xc013193b -Processus lancés. L'analyse détaillée des processus lancés fournit une aide précieuse quand il s'agit d'identifier d'éventuels rootkits. Task_struct contient au plus bas niveau du noyau, la généalogie de tous les threads en exécution; cette table sert par exemple aux outils ps ou pstree qui agissent au niveau utilisateur. -Carbonite[9] est un module noyau que l'on peut charger sur un système compromis, et qui agit grâce aux données de task_struct en gelant l'ensemble des processus en cours. La sortie texte qu'il fournit permet alors de rechercher les incohérences dans l'ensemble des processus (PID, propriétaires, etc...). - Temps d'exécution des syscalls. Les codes modifiés au niveau noyau induisent inévitablement un temps d'exécution différent du temps d'exécution originel. La mesure du temps d'écart entre ces deux exécutions permet de rester vigilant. Jan Rutkowki a implémenté une version d'un tel programme qui détecte une grande partie de modifications apportées au noyau: 4) Détection des rootkits en mode virtuel Les rootkits fonctionnant sur des OS virtuels (Subvirt, Blue-pill démontrent la faisabilité de cette technique) ont été présentés comme indétectables par le fait que l'OS s'exécutait ________________________________________________________________________________ 17 ________________________________________________________________________________ intégralement de façon émulée (le rootkit ayant donc plus de privilèges que le noyau luimême). Cependant, plusieurs laboratoires ont contesté cette assertion en déclarant même que ce type de rootkit « n'était pas un problème ». En effet, l'émulation du hardware génère inévitablement un certain nombre d'incohérences et anomalies dans les caractéristiques physiques d'utilisation des ressources (cycles CPU, utilisation de la mémoire, etc...). Pour cette catégorie de rootkits, le niveau de détection correspond donc à la précision qu'on peut atteindre dans l'analyse de ces incohérences pour établir de façon certaines que l'OS est émulé. A ce jour, il n'existe pas d'outils permettant au grand public de mener ce genre d'investigations qui ne sont menées qu'à titre expérimental. Mais tout indique que les machines virtuelles constitueront la prochaine étape de l'évolution des programmes malveillants, dont les rootkits. 5) Détection des rootkits en mode firmware Le déploiement de rootkits firmware nécessite d'avoir pu flasher le BIOS, ce qui nécessite pour une partie d'entre eux, un accès physique à la machine pour changer la position d'un "jumper" sur la carte mère. De façon préventive, la protection contre ce type de rootkits passe donc par deux décisions: -utiliser des BIOS qui demandent un accès physique pour être flashés. -désactiver les drivers ACPI. La détection d'un rootkit utilisant les fonctions ACPI du BIOS est fastidieuse: elle passe par l'analyse des logs enregistrés par le système au démarrage, accessibles sous Windows et Linux [annexe]. Un autre procédé consiste à décompiler la table chargée par le noyau[annaexe] et contenant la description physique du système (Differentiated System Description Table), pour étudier précisément le champ OperationRegion qui est la porte d'entrée pour charger du code dans le noyau lancé après la séquence de boot ________________________________________________________________________________ 18 ________________________________________________________________________________ Conclusion Comme le montre ce document, les rootkits suivent une évolution qui tend à les faire opérer au niveau des mécanismes de bas niveau, selon le principedu « chat et de la souris ». Chaque rootkit de nouvelles génération tend à opérer à un niveau plus privilégié que celui ou opérent les processus chargés de le détecter. Ainsi, les premiers rootkits du début des années 90 concernaient le monde UNIX, et se chargaient, à un niveau applicatif relativement élevé, de simplement remplacer les exécutables de base comme ls et ps. Le phénomène a continué son expansion au niveau applicatif en passant sous Windows: modification du registre, modification de DLLs; sous Linux: modification des librairies. Depuis plusieurs années, les rootkits opérent au niveau du kernel, et fonctionnent en détournant/réécrivant les appels systèmes. Ils constituent l'essentiel des rootkits agissant sur le réseau. Enfin, dernièrement, la démonstration de la faisabilité des rootkits virtualisant l'OS cible laisse présager que les rootkits virtuels (et de façon générale, l'utilisation malveillante de l'émulation pour dissimuler vers, chevaux de troies, ou autres) ________________________________________________________________________________ 19 ________________________________________________________________________________ constitueront la prochaine menace et créeront un nouveau besoin au niveau sécurité: la détection des machines virtuelles. La généralisation et la diffusion au grand public des solutions de sécurité ont pour conséquence l'utilisation de plus en plus fréquente de rootkits pour dissimuler les malwares dont le souci principale n'était pas de demeurer cacher. Mais l'avènement des botnets a changé la donne, et fait du rootkit un composant vital des logiciels malveillants, utilisé de façon exponentielle depuis quelques années: Nombre de malwares utilisant les rootkits pour se dissimuler. Comme l'a exposé la section IV de ce document, toute politique de sécurité se doit d'avoir une vision claire de la façon dont procède les rootkits; en particulier, prévenir n'est pas la même chose que détecter; également, toute solution déployée doit tenir compte des deux volets « user mode » et « kernel mode ». Enfin, la finalité du rootkit étant de modifier le système pour fausser certains indicateurs qui pourraient révéler sa présence, l'investigation doit considérer la machine comme compromise a priori, et donc se baser sur des tests fait depuis des machines distantes, ou depuis des images bootables par CD par exemple. Plus précisemment, les tests positifs faits depuis la machine indiquent la présence d'un rootkit, mais les tests négatifs ne prouvent rien tant qu'ils n'ont pas été comparés aux résultats obtenu depuis l'extérieur. ________________________________________________________________________________ 20 ________________________________________________________________________________ ________________________________________________________________________________ 21