Les kprobes
Kprobes est un mรฉcanisme dรฉveloppรฉ par les chercheurs d’IBM et a รฉtรฉ introduit ร la version du noyau Linux 2.6.9. Ce mรฉcanisme permet l’exรฉcution d’un gestionnaire du code arbitraire ร n’importe quel point, durant l’exรฉcution du noyau. Depuis que les gestionnaires des sondes sont รฉcrits dans les modules du noyau, le privilรจge root s’avรจre indisponible pour exploiter ce service. Ce mรฉcanisme est extrรชmement utile pour le dรฉbogage de certaines parties spรฉcifiques du noyau. De cette maniรจre, le dรฉbogage sera effectuรฉ sans avoir besoin de recompiler et de redรฉmarrer le systรจme. Ceci prรฉsente un gain considรฉrable de temps et du coรปt du dรฉveloppement. En plus, kprobes offre un meilleur support pour la traรงabilitรฉ du noyau et une meilleure รฉvaluation de ses performances (Ramaswamy, 2008). Kprobes faisait partie de lโoutil Dprobes qui est un outil de traรงage de haut niveau. Ce mรฉcanisme constitue une interface qui permet lโinsertion dynamique des points dโinstrumentation dans le noyau lors de son exรฉcution. Le principe de kprobes consiste ร associer un รฉvรฉnement ร une adresse dans le code du noyau.
Une fois lโexรฉcution atteint cette adresse, lโรฉvรฉnement sera dรฉclenchรฉ. Kprobes permet dโassocier une fonction ร un รฉvรฉnement. Cette fonction sโexรฉcute ร chaque dรฉclenchement de lโรฉvรฉnement qui lui est associรฉ. kprobes prรฉsente trois types de points de traรงage du noyau : les kprobes ordinaires, les kretprobes et les jprobes. Les kprobes ordinaires sโinsรจrent dans nโimporte quelle routine du noyau et elles peuvent associer deux fonctions pour chaque รฉvรจnement. La premiรจre fonction est exรฉcutรฉe avant lโinstruction, qui se situe ร lโadresse du point dโinstrumentation, elle est appelรฉe pre_handler. La deuxiรจme fonction est exรฉcutรฉe aprรจs cette instruction, cette fonction est appelรฉe post_handler. Quand les deux fonctions sont appelรฉes, une structure de type pt_regs, contenant une copie de lโรฉtat de tous les registres au moment oรน lโรฉvรฉnement est dรฉclenchรฉ, leur est passรฉe. Ce type de structure change de contenu quand lโarchitecture change. La spรฉcificitรฉ des kretprobes est que ce type de kprobes est enregistrรฉ aux points de retour des fonctions. Les jprobes, ร lโinverse des kretprobes, ont la possibilitรฉ de sโassocier aux points dโentrรฉe des fonctions du noyau. Ceci a pour but de collecter les arguments de ces fonctions. Plusieurs outils rรฉcents, de traรงage noyau, utilisent les kprobes tels que : Ftrace, LTTng et SystemTap (Fahem, 2012).
Cycle de vie d’un processus
Chaque processus a son propre cycle de vie tel que la crรฉation, l’exรฉcution, la terminaison et la suppression. Ces phases seront rรฉpรฉtรฉes des millions de fois tant que le systรจme est en cours d’exรฉcution. Le processus pรจre dรฉclenche un appel systรจme fork () pour crรฉer un processus fils. Quand un appel systรจme fork () est exรฉcutรฉ, il obtient un descripteur du processus fils crรฉe et dรฉtermine son id. Il copie les valeurs de descripteur du processus pรจre au processus fils. L’espace d’adresse du processus pรจre n’est pas entiรจrement copiรฉ. L’appel systรจme exec() copie le nouveau programme ร l’espace d’adresse du processus fils. Puisque les deux processus pรจre et fils partagent le mรชme espace d’adresse, une รฉcriture des donnรฉes du nouveau programme cause une exception de dรฉfaut de page. ร ce stade, le noyau attribue la nouvelle page physique au processus fils. Aprรจs la terminaison de l’exรฉcution du programme, le processus fils se termine avec un appel systรจme exit(). Cet appel systรจme libรจre la plupart des structures de donnรฉes du processus fils et notifie le processus pรจre de sa terminaison par un signal. Le processus ร cet รฉtat est appelรฉ processus zombie. Le processus fils ne sera pas complรจtement รฉliminรฉ jusqu’ร ce que le processus pรจre soit notifiรฉ de la terminaison de tous ses fils. Ceci est accompli ร l’aide de l’appel systรจme wait(). Une fois qu’il sera notifiรฉ de la terminaison de tous ses fils il supprime toute la structure de donnรฉes du processus fils et libรจre le descripteur de processus (Ciliendo et Kunimasa, 2007).
Le gestionnaire des interruptions
La gestion des interruptions est une des tรขches les plus prioritaires d’un systรจme d’exploitation. Les interruptions sont gรฉnรฉrรฉes par les pรฉriphรฉriques d’entrรฉes/sorties du systรจme. Le gestionnaire d’interruption informe le noyau Linux de l’interception d’un รฉvรฉnement comme la saisie au clavier, arrivรฉe de trame Ethernet et autres. Il indique au noyau d’interrompre l’exรฉcution des processus et d’effectuer la gestion des interruptions aussi rapidement que possible parce que certains dispositifs nรฉcessitent une rรฉactivitรฉ rapide. Cela est essentiel pour la stabilitรฉ du systรจme. Quand un signal d’interruption est interceptรฉ, par le noyau, ce dernier doit passer du processus en cours d’exรฉcution ร un nouveau processus pour gรฉrer cette interruption. Cela signifie que les interruptions provoquent le changement de contexte. Un grand nombre d’interruptions pourraient causer une dรฉgradation des performances du systรจme. Il existe deux types d’interruptions dans les implรฉmentations Linux. Le premier type est les interruptions matรฉrielles. Une interruption matรฉrielle est gรฉnรฉrรฉe pour les dispositifs qui exigent une rรฉactivitรฉ (E / S disque interruption, interruption de la carte rรฉseau, clavier interruption, interruption de la souris). Les informations des interruptions matรฉrielles sont localisรฉes sous /proc/interrupts. Le deuxiรจme type est les interruptions logicielles. Une interruption logicielle est utilisรฉe pour des tรขches dont le traitement peut รชtre diffรฉrรฉ (c.ร .d comme les opรฉrations TCP / IP, les opรฉrations du protocole SCSI, etc.). Dans un environnement multiprocesseur, les interruptions sont gรฉrรฉes par chaque processeur. Cette approche amรฉliore la performance du systรจme (Ciliendo et Kunimasa, 2007).
Les mรฉthodes dโinjection en espace noyau
Utilisation des modules noyaux Cette mรฉthode est utilisรฉe pour l’insertion des modules noyaux dans l’espace noyau. Elle nรฉcessite que le support LKM par le noyau soit activรฉ (Lacombe, Raynal et Nicomette, 2007). Ce support permet l’insertion et la suppression des modules noyaux en cours d’exรฉcution, ce qui permet aux utilisateurs de modifier les fonctionnalitรฉs du noyau sans avoir besoin de recompiler et de redรฉmarrer le systรจme. Au dรฉbut de sa crรฉation, cette technique avait pour but de faciliter la manipulation des pilotes de pรฉriphรฉriques, des pilotes du systรจme de fichier, les appels systรจmes, etc. Les modules noyaux sont insรฉrรฉs, en utilisant la commande insmod qui est un utilitaire qui insรจre les modules noyaux, peu importe sa localisation ou l’utilisation de la commande modprobe. Cette derniรจre nรฉcessite que les modules ร insรฉrer soient localisรฉs dans le rรฉpertoire / lib/modules. Les attaquants ont bรฉnรฉficiรฉ de cette simplicitรฉ d’utilisation du support LKM pour cacher leurs activitรฉs malicieuses, mais avant รงa ils doivent obtenir le privilรจge root. La nรฉcessitรฉ de localisation des modules noyaux dans le rรฉpertoire /lib/modules constitue le point faible de l’utilisation de l’utilitaire modprobe. Ces modules seront facilement dรฉtectรฉs. Pour cette raison, les attaquants prรฉfรจrent l’utilisation de l’utilitaire de lโinsmod.
Dโautres utilitaires du support LKM peuvent divulguer des informations importantes sur le systรจme. Lsmod liste les modules noyaux en cours d’exรฉcution sur un systรจme (Vandeven, 2014). Accรจs ร la mรฉmoire noyau via le pรฉriphรฉrique virtuel /dev/kmem et via dev/mem Cette mรฉthode consiste ร utiliser le fichier spรฉcial /dev/kmem pour l’injection des rootkits noyaux. Ce fichier pointe vers une image de l’espace mรฉmoire du kernel en cours d’exรฉcution. Un attaquant peut modifier en utilisant cette technique le noyau en cours d’exรฉcution une fois que le support /dev/kmem est activรฉ (Vandeven, 2014). Ce genre de technique ne persiste pas lors d’un redรฉmarrage du systรจme. Cette technique peut รชtre efficace dans des systรจmes oรน leurs redรฉmarrages sont peu frรฉquents comme les serveurs. Un des exemples de rootkits le plus connu, qui utilise cette technique, est le rootkit SuckIT (Super user control kit). Ce rootkit remplace la rรฉfรฉrence ร la table des appels systรจmes par une autre qui pointe vers une nouvelle table qui contient les appels systรจmes contenant le code malicieux. La table originale des appels systรจme reste chargรฉe en mรฉmoire sans subir aucune modification. Cette approche rend la dรฉtection de ce genre de rootkit trรจs difficile (Shah et Giffin, 2008). L’utilisation d’accรจs ร la mรฉmoire physique dev/mem, pour charger le rootkit, est similaire ร celui de /dev/kmem. Mais ce fichier spรฉcial reprรฉsente non seulement la mรฉmoire du noyau, mais il reprรฉsente aussi l’image entiรจre de la mรฉmoire physique (Lineberry, 2009; Vandeven, 2014).
|
Table des matiรจres
INTRODUCTION
1.1 Contexte
1.2 Dรฉfinition du problรจme
1.2.1 รtape 1
a) Quels sont les mรฉcanismes liรฉs au noyau, au rootkit et ร lโapprentissage automatique?
b) Quelles sont les mรฉthodes dโanalyse et les approches de dรฉtections des rootkits?
1.2.2 รtape 2 : Comment sรฉlectionner la mรฉthode dโanalyse et de dรฉtection de rootkits adรฉquate ร lโoutil LTTng ?
1.2.3 รtape 3 : Quel serait lโalgorithme dโapprentissage le plus efficace dans la dรฉtection des attaques spรฉcifiรฉes par les expรฉrimentations?
1.3 Questions de recherche
1.4 Mรฉthodologie de recherche
1.5 Organisation du rapport
CHAPITRE 1 LES ASPECTS FONDAMENTAUX LIรS ร LA DรTECTION DES ROOTKITS
1.1 Introduction
1.2 Le systรจme dโexploitation Linux
1.2.1 Le noyau Linux
1.2.2 Les modules du noyau Linux
1.2.3 Les appels systรจmes
1.2.4 Les kprobes
1.2.5 La gestion des processus sous Linux
1.2.6 Le gestionnaire des interruptions
1.2.7 Lโarchitecture mรฉmoire Linux
1.2.8 Les systรจmes de fichiers Linux
1.2.9 Les mesures de performances Linux
1.2.10 Le traรงage
1.3 Les rootkits
1.3.1 Cโest quoi un rootkit
1.3.2 La notion du ring
1.3.3 Le cycle de vie dโun rootkit
1.3.4 Les classes des rootkits
1.3.5 Les mรฉthodes dโinjection en espace noyau
1.3.6 Les mรฉthodes du dรฉtournement
1.3.7 Mรฉthodes de communication avec un rootkit
1.4 Les machines d’apprentissage
1.4.1 Les types d’apprentissages
1.4.2 L’apprentissage supervisรฉ
1.4.3 Les mesures d’รฉvaluation et de la classification
1.4.4 รvaluation des algorithmes d’apprentissages supervisรฉs
1.4.5 La sรฉlection des caractรฉristiques d’un vecteur d’entrรฉe
1.4.6 Les mรฉthodes de comparaison entre diffรฉrents algorithmes de classifications
1.5 Conclusion
CHAPITRE 2 REVUE DE LITTรRATURE SUR LES MรTHODES DโANALYSE ET DE DรTECTION DES ROOTKITS
2.1 Introduction
2.2 Mรฉthodes d’analyse
2.2.1 Analyse statique
2.2.2 Analyse dynamique
2.3 Mรฉthodes de dรฉtection
2.3.1 Dรฉtection basรฉe sur les signatures
2.3.2 Dรฉtection basรฉe sur le comportement
2.3.3 Dรฉtection basรฉe sur la vรฉrification dโintรฉgritรฉ
2.3.4 Dรฉtection basรฉe sur le crossview
2.3.5 Dรฉtection basรฉe sur la sรฉmantique
2.3.6 Dรฉtection basรฉe sur les heuristiques
2.4 Conclusion
CHAPITRE 3 APPROCHES DโANALYSE ET DE DรTECTION DES ROOTKITS BASรES SUR LTTNG
3.1 Introduction
3.2 Mรฉthode dโanalyse
3.3 Les approches de dรฉtection
3.3.1 Dรฉtection par algorithmes d’apprentissage automatique
3.3.2 Dรฉtection par extension du traceur LTTng
3.4 Champs dโapplication des approches de dรฉtection proposรฉes
3.5 Conclusion
CHAPITRE 4 EXPรRIMENTATION ET VALIDATION DE LโAPPROCHE BASรE SUR LโAPPRENTISSAGE AUTOMATIQUE
4.1 Introduction
4.2 Les choix techniques utilisรฉs dans les expรฉrimentations proposรฉes
4.2.1 Expรฉrimentation basรฉe sur lโattaque par la modification des appels systรจmes du Suterusu
4.2.2 Expรฉrimentation basรฉ sur lโattaque par le dรฉtournement des appels systรจmes du Kbeast
4.2.3 Expรฉrimentation basรฉe sur lโattaque par la dissimulation de processus du Suterusu
4.2.4 La validation du choix de lโalgorithme le plus adรฉquat sur les multiples ensembles de donnรฉes
4.3 Conclusion et perspectives
4.4 Limite de cette recherche
CONCLUSION GรNรRALE
BIBLIOGRAPHIE
Tรฉlรฉcharger le rapport complet