• Aucun résultat trouvé

5.4 Détection des activités illicites

5.4.2 Reconstruction des activités

L’objectif de la reconstruction est de générer des alertes lorsqu’une signature est reconnue, c’est-à-dire lorsque toutes les interactions composant cette signature ont été réalisées. La phase de recons-truction analyse donc l’ensemble des traces d’interactions afin d’y déceler d’éventuelles attaques. Lorsqu’une signature est reconnue, la fonction 5.4.1 est exécutée afin de générer une alerte. La géné-ration de l’alerte peut, par exemple, correspondre à l’écriture d’une alerte dans un fichier de traces, l’envoi d’un courriel à un administrateur, etc.

5.4. DÉTECTION DES ACTIVITÉS ILLICITES 141 Fonction 5.4.1 generer_alerte : BASE ×T est une fonction telle qu’étant donné une signa-ture de la base et une trace, cette fonction génère une alerte.

La phase de reconstruction utilise la représentation objet des observateurs et nous définissons deux méthodes différentes de reconstruction. Chaque méthode prend en paramètres une trace t ∈ T (géné-rée par le mécanisme de contrôle d’accès) et un sous ensemble de la base de signatures (B ⊂ BASE). Une alerte est alors levée lorsqu’une signature de cette base est reconnue.

Comme nous l’avons vu dans la sections 3.2 (page 60), une séquence est une fermeture transitive d’un ensemble d’opérations élémentaires causalement liées. Pour reconstruire une séquence, il faut que l’opération itj−1ait été observée avant l’interaction itj. Pour cela, nous tenons compte des dates d’apparition des interactions.

5.4.2.1 Influence des méthodes de reconstruction

Pour reconstruire correctement les séquences de transitions, nous sommes obligés de tenir compte de l’héritage des processus. En effet, dans le cas contraire, deux problèmes différents se posent. Nous proposons d’illustrer chaque problème par un exemple. Le premier problème concerne les fausses séquences, la figure 5.5 illustre ce problème. Cette figure représente deux processus P1 et P2

indé-FIG. 5.5 – Reconstruction de processus indépendants.

pendants, étiquetés par sc1et sc2, qui transitent tous les deux vers le contexte sc3. Ensuite, ces deux processus transitent vers les contextes sc4 et sc5. Si l’on ne tient pas compte des processus, la re-construction des séquences peut conduire à deux fausses séquences : sc1 −−−→ sctrans 3 −−−→ sctrans 5 et sc2 −−−→ sctrans 3 −−−→ sctrans 4. En effet, ces deux séquences de transitions correspondent alors à des chan-gements de contexte de sc1vers sc5et de sc2vers sc4qui n’ont pas eu lieu. On voit que ce problème est aisément éliminé si l’on tient compte des processus en plus des transitions.

Le second problème concerne les séquences qui peuvent manquer, avec le raisonnement précédent, si l’on ne tient pas compte de l’héritage des processus. La figure 5.6 illustre alors ce problème. Dans cette figure, un processus P1, étiqueté par sc1, transite vers un contexte sc2 puis crée un fils. Ce fils transite ensuite vers sc3. En appliquant le raisonnement précédent, les seules séquences recomposées seraient sc1 −−−→ sctrans 2et sc2 −−−→ sctrans 3. Or comme P2est un fils de P1, il y a bien une transition de sc1vers sc3. Ce problème est alors réglé en tenant compte de l’héritage des processus.

FIG. 5.6 – Héritage de processus

Ces deux problèmes sont traités par une méthode de reconstruction particulière, le reconstruc-teur arborescent, qui tient compte de l’héritage des processus. En ce qui concerne la reconstruction des autres types de séquences, nous n’avons pas à tenir compte de l’héritage puisqu’il faut juste-ment prendre en compte les interactions entre tous les processus du système. Pour les autres types de séquences, nous utilisons un reconstructeur système où les processus n’interviennent pas lors de la reconstruction. Ainsi nous proposons deux méthodes de reconstruction des activités :

Reconstructeur Système : permet de reconnaître une activité qui apparaît sur le système. Cette acti-vité ne différencie pas les processus mis-en-jeu ;

Reconstructeur Arborescent : permet de reconnaître une activité qui met en jeu une descendance de processus.

Nous allons maintenant détailler le fonctionnement de ces deux reconstructeurs.

5.4.2.2 Reconstructeur Système

La reconstruction système utilise les activités de la base de signatures et les traces pour calculer les activités en cours d’observation. Cette reconstruction nécessite donc la définition d’une liste d’ac-tivités en cours d’observation : Liste<Observateur> OBSsys. Une signature (activité) de la base est alors ajoutée à cette liste lorsque la première interaction de la signature correspond à la trace. Ainsi, dans ce reconstructeur, il n’y a qu’un seul ensemble d’observateurs (OBSsys), dit “global”, initialisé avant l’analyse des traces et partagé par l’ensemble des processus du système. La trace analysée per-met aussi de faire évoluer les activités en cours d’observation. Une alerte est alors générée lorsqu’une activité est totalement observée. Tous les processus du système participeront donc à l’évolution des activités de cet ensemble. Nous définissons ainsi la classeReconstructeur_Systemequi correspond à

5.4. DÉTECTION DES ACTIVITÉS ILLICITES 143 ce type de reconstructeur.

Classe Reconstructeur_Systeme etend Reconstructeur

reconstruire(TRACE t, ACT⊂ BASE) début pour chaque act ∈ ACT faire

si t.it == act.get(1) alors OBSsys.ajouter(act); fin

fin

pour chaque act ∈ OBSsysfaire act.analyse(t); si act.observe() alors generer_alerte(act, t); fin fin fin

Cette classe possède une seule méthode reconstruire qui prend en paramètres une trace et un ensemble de signatures (les activités nécessitant une reconstruction système). Tout d’abord, cette mé-thode ajoute les nouveaux observateurs. La trace t est ensuite analysée par chaque activité présente dans la liste OBSsys. Lorsqu’une activité est observée, c’est-à-dire complètement réalisée, une alerte est alors générée.

5.4.2.3 Reconstructeur Arborescent

Afin de prendre en compte la descendance des processus, nous définissons un second reconstruc-teur que nous appellerons reconstrucreconstruc-teur Arborescent. Lors de l’analyse des traces, ce reconstrucreconstruc-teur construit un arbre “généalogique” des processus du système :Arbre arbre_proc. L’arbre de processus est alors initialisé (via l’appel à la méthodeinit_arbre()) qui crée un nouvel arbre ayant comme nœud racine le processus initial du système. Par exemple, sous GNU/Linux le processus initial correspond à init et son PID vaut 1.

La construction de cet arbre nécessite de prendre en compte les opérations élémentaires de créa-tion et de destruccréa-tion de processus. Chaque nœud de cet arbre correspond ainsi à un processus du système identifié par son PID et il est relié à son père identifié par le numéro PPID. De plus, chaque nœud de l’arbre stocke sa propre liste d’observateurs OBSarb, dite “locale” au nœud. Les observa-teurs d’un nœud n’évoluent que si la trace correspond au processus du nœud. Lors de l’ajout d’un nouveau nœud, correspondant à l’apparition d’un nouveau processus, le nœud fils hérite d’une copie des observateurs OBSarbde son père. L’ajout d’un nouveau nœud dans l’arbre est alors réalisé par la procédure suivante :

ajouter_proc(arbre, t) début

arbre.ajouter_noeud(t.ppid, t.pid);

arbre.get(t.pid).OBSarb:= P ROC_T REE.get(t.ppid).OBSarb.copy(); fin

Cette procédure ajoute le nouveau nœud correspondant au processus fils de la trace, puis elle initialise l’ensemble OBSarbdu nouveau nœud avec une copie de celui du processus père.

La reconstruction des activités est alors réalisée par la méthode reconstruire de la classe

Reconstructeur_Arborescent. Cette méthode prend en paramètres une trace et une base de signatures. Si la trace correspond à un nouveau processus, ce processus est alors ajouté à l’arbre des processus et hérite d’une copie des activités en cours de son père. L’appel àOBSarb := arbre_proc.get(t.pid)renvoie alors les observateurs locaux du processus courant (le processus ayant réalisé l’interaction). Ensuite,

les nouvelles activités sont ajoutées à cet ensemble d’observateurs. Finalement, seuls les observateurs de cet ensemble évoluent. Une alerte est alors générée pour chaque activité totalement observée.

Classe Reconstructeur_Arborescent etend Reconstructeur

global arbre_proc;

reconstruire(TRACE t, ACT ⊂ BASE) début si t.p 6∈ arbre_proc alors

ajouter_proc(arbre_proc, t.ppid, t.p); fin

OBSarb:= arbre_proc.get(t.pid); pour chaque act ∈ ACT faire

si t.it == act.get(1) alors OBSarb.ajouter(act); fin

fin

pour chaque act ∈ OBSarbfaire act.analyse(t); si act.observe() alors generer_alerte(act, t); fin fin fin

Notons que l’algorithme présentée ici est une version simplifiée de l’algorithme réel de reconstruction. Notamment, cette version ne prend pas en compte la destruction des processus.

Nous pouvons finalement remarquer que les séquences que le reconstructeur arborescent peut re-construire peuvent aussi être reconstruites par le reconstructeur système. En effet, le reconstructeur système calcule toutes les séquences alors que le reconstructeur arborescent calcule uniquement les séquences d’une descendance de processus. Bien que le reconstructeur système est suffisant pour reconstruire n’importe quel type de séquence, nous avons vu dans la section 5.4.2.1 que le recons-tructeur arborescent permet d’éliminer les fausses séquences de transitions. C’est pourquoi c’est ce reconstructeur qui est utilisé pour reconstruire les séquences de transitions.