Utiliser auditd sur Mac OS X et FreeBSD – 3

Cet article est la suite de Utiliser auditd sur Mac OS X et FreeBSD - 2

Exploiter les résultats de l'audit

Dans le premier article j'ai mentionné très succinctement une commande qui permet de lire les logs d'audit en temps réel. Et finalement la consultation de ces logs est sans doute la chose la plus intéressante. Personne n'a envie d'activer l'audit sur une machine pour le simple plaisir de remplir son disque dur. Tout ceci doit avoir une raison d'être : pouvoir ensuite (ou en temps réel) exploiter les logs d'auditd.
Comme précisé par défaut dans le fichier audit_control, la taille maximale d'un fichier de log d'audit est 2Mo, et les anciens fichiers sont supprimés pour que le volume total ne dépasse pas 10 Mo :

filesz:2M
expire-after:10M

Il existe plusieurs options intéressantes pour expire-after que je vous laisse découvrir dans le man audit_control. Sachez seulement qu'en fonction de ce que vous choisirez de surveiller, vous allez devoir modifier ces paramètres. Sur une machine assez sollicitée, 10 Mo de log peuvent représenter moins d'une heure d'audit. Si vous avez besoin d'enquêter sur un événement de la veille, il vous sera alors impossible d'en retrouver la trace.

Il y a deux moyens immédiats d'exploiter les logs d'audit. Vous pouvez soit les suivre en direct comme je l'ai montré dans le premier article via la commande praudit /dev/auditpipe, soit les étudier a posteriori. C'est sans doute cette option qui sera le plus souvent utilisée. Vous pouvez ainsi utiliser praudit pour lire les fichiers de logs enregistrés dans /var/audit/.
Comme les logs d'audit peuvent grossir très vite, et qu'on cherche souvent l'aiguille dans la meule de foin, il est bon de pouvoir réduire les logs à ce que l'on cherche avant de les afficher. C'est le rôle de la commande auditreduce. Cette commande permet de filtrer les logs selon une série de critères tels que la date, le ou les flags d'évènement (fc, ex, ...), l'UID, le ou les évènements précis (tels qu'ils sont répertoriés dans le fichier audit_event), et d'autres encore.
auditreduce s'utilise sous la forme générale suivante :

auditreduce paramètres fichiers_de_log | praudit

Comme les logs sont binaires, il est impératif de les traduire via praudit.
Sur Mac OS X, voici un exemple de ce que l'on peut obtenir avec la configuration par défaut d'auditd. Je cherche ici tous les événements pour l'UID réelle patpro ayant eu lieu après le 5 juin 2011 à 12h. Je fais cette recherche dans le fichier de log ouvert par auditd.

# auditreduce -a 2011060512 -r patpro /var/audit/current | praudit
header,68,11,logout - local,0,Sun Jun  5 15:47:35 2011, + 877 msec
subject,patpro,root,patpro,patpro,patpro,10485,10485,0,0.0.0.0
return,success,0
trailer,68
header,68,11,logout - local,0,Sun Jun  5 15:57:05 2011, + 718 msec
subject,patpro,root,patpro,patpro,patpro,10948,10948,0,0.0.0.0
return,success,0
trailer,68

Ces deux évènements correspondent à la fermeture d'une fenêtre de terminal. On voit que chacun d'eux commence par "header" et termine par "trailer". Je ne vais pas couvrir l'intégralité des champs d'un enregistrement de log d'audit, il y a beaucoup trop de possibilités. Reportez-vous au man audit.log pour le détail. Ceux qui ont un intérêt sinon universel, au moins relativement général, sont subject qui décrit le sujet qui a généré les évènements, path qui décrit le chemin du fichier concerné, et return qui indique si l'opération a réussi ou non.
Le champ subject contient les UID et GID (audit UID, effective UID et GID, real UID et GID), le PID, et le port et l'IP de la machine connectée.
Le champ path donne par exemple le chemin d'un exécutable lancé, ou le chemin d'un fichier créé/modifié/détruit.
Le champ return indique success ou failure.

Voici un second exemple, pour un serveur Apache sur Mac OS X, lancé via l'utilitaire setaudit :

header,127,11,execve(2),0,Wed Jun  1 14:50:44 2011, + 667 msec
exec arg,ls
path,/bin/ls
path,/bin/ls
attribute,100555,root,wheel,234881026,24767,0
subject,_www,_www,_www,_www,_www,26696,100031,0,0.0.0.0
return,success,0
trailer,127
header,131,11,open(2) - write,creat,trunc,0,Wed Jun  1 14:50:44 2011, + 735 msec
argument,3,0x1a4,mode
argument,2,0x601,flags
path,/Users/patpro/Sites/testFile.txt
subject,_www,_www,_www,_www,_www,26694,100031,0,0.0.0.0
return,failure : Permission denied,4294967295
trailer,131

La requête http s'est faite sur la machine locale (http://localhost/...) vers un fichier PHP dont le code exécute la commande system("ls"); puis tente d'écrire un fichier testFile.txt.
Le premier évènement enregistré montre le lancement de la commande ls, avec succès. Le second évènement montre la tentative d'écriture du fichier testFile.txt qui échoue.
Cet exemple montre donc clairement comment les logs d'audit peuvent permettre, par exemple, de remonter la trace d'une compromission d'un serveur web. Notez que si j'avais lancé le serveur web normalement, sans utiliser setaudit, la ligne subject aurait indiqué subject,patpro,_www,_www,_www,_www..., patpro étant l'UID suivi par auditd. Il aurait donc fallu que le fichier audit_user indique les flags ex et fc pour le login patpro, sans quoi les évènements pour le serveur web n'auraient pas été enregistrés.

auditreduce permet de filtrer les évènements selon un critère beaucoup plus fin que le simple flag (fc, fd, ex, ...). Il vous autorise à différencier chaque évènement avec la granularité du fichier audit_event. Si vous avez eu la curiosité d'ouvrir ce fichier, vous savez qu'il contient plus de 600 lignes de ce genre :

0:AUE_NULL:indir system call:no
1:AUE_EXIT:exit(2):pc
2:AUE_FORK:fork(2):pc
3:AUE_OPEN:open(2) - attr only:fa
4:AUE_CREAT:creat(2):fc
5:AUE_LINK:link(2):fc
6:AUE_UNLINK:unlink(2):fd
7:AUE_EXEC:exec(2):pc,ex
8:AUE_CHDIR:chdir(2):pc
9:AUE_MKNOD:mknod(2):fc

La nomenclature est simple. Chaque colonne est séparée des autres par ":". La première donne le numéro de référence d'un événement, la seconde donne son nom, la troisième le nom de la fonction correspondante, avec éventuellement un complément d'information, et la dernière indique le ou les flags correspondants.
Sur les 10 lignes citées au dessus, vous notez qu'il y a déjà 4 évènements correspondants au flag pc, et 3 au flag fc. Donc si on se contente de faire un filtrage sur pc ou fc, on peut remontrer beaucoup trop d'évènements par rapport à ce que l'on cherche vraiment. Par ailleurs, dans certains cas, un même évènement peut correspondre à plusieurs flags contradictoires. Par exemple :

75:AUE_OPEN_RTC:open(2) - read,creat,trunc:fc,fd,fr,fa,fm

Cet évènement peut être détecté si on souhaite suivre les flags fc, fd, fr, fa ou fm !
C'est ici qu'intervient le contenu de la ligne header des logs d'audit. En effet, l'entête indique clairement l'évènement qui est capturé. Par exemple open(2) - write,creat,trunc. Il suffit alors de chercher son nom dans le fichier audit_event pour pouvoir s'en servir de clé de filtrage :

grep 'open(2) - write,creat,trunc' /etc/security/audit_event
79:AUE_OPEN_WTC:open(2) - write,creat,trunc:fc,fd,fw,fa,fm

Il est alors possible d'utiliser AUE_OPEN_WTC comme ceci pour obtenir en sortie une sélection parfaite des évènements qu'on recherche :

auditreduce -m AUE_OPEN_WTC -r www -o file=".*/bd/.*" /var/audit/current | praudit

Cette commande permet de trouver tous les évènements AUE_OPEN_WTC pour l'utilisateur www qui ont eu pour cible des fichiers dont le chemin contient la chaîne "/bd/" dans le fichier de log d'audit courant.
Il ne vous reste plus qu'à essayer par vous même !

Bibliographie sommaire

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/audit-config.html
https://ssl.apple.com/support/security/commoncriteria/CommonCriteriaAdminGuide.pdf
man auditreduce
man auditd
man audit_user
man audit_control
man audit_event
man audit.log
http://forums.freebsd.org/showthread.php?t=23716

À lire aussi :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *