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

Documents pareils