Cet article décrit l'ensemble des activités qu'il est possible d'enregistrer sur un système et sur un réseau, ainsi que la manière d'analyser efficacement l'information enregistrée.
Introduction
Les logs système et réseau sont un réel problème pour tout
administrateur. Chaque administrateur doit en effet disposer d'un
système de journalisation efficace afin d'être capable de détecter le
plus rapidement possible les attaques ou les tentatives d'attaques. Cet
article décrit l'ensemble des activités qu'il est possible d'enregistrer
sur un système et sur un réseau, ainsi que la manière d'analyser
efficacement l'information enregistrée.
Les logs système
Les logs gérés par le daemon syslogd
Le but des logs est d'enregistrer toute activité sur un système,
qu'elle soit licite ou non. Sur la plupart des systèmes Unix, ces logs
sont gérés par le daemon syslogd. Ce daemon permet,
à l'aide de son fichier de configuration /etc/syslog.conf,
de personnaliser la gestion des logs. Il est ainsi possible
d'enregistrer toutes les authentifications réalisées par le système,
de surveiller ce qui se passe au niveau de son noyau, de redigirer
absolument tous les logs vers un terminal, etc. Une pratique très
courante est d'enregistrer les fichiers de logs dans le répertoire
/var/log, mais également de tout envoyer sur un terminal
(par exemple /dev/tty12).
Les logs gérés par le système d'exploitation
En plus du daemon syslogd qui gère de manière
assez efficace l'activité d'un système, trois fichiers
supplémentaires fournissent de précieuses informations :
/var/log/wtmp, /var/log/lastlog et
/var/run/utmp. Ces fichiers sont maintenus par les
programmes init, login et getty.
Le premier, /var/log/wtmp, enregistre les connexions et
déconnexions au système, et peut être visualisé grâce à la commande
/usr/bin/last. Le second, /var/log/lastlog,
contient un historique des dernières connexions, et peut être visualisé
grâce à la commande /usr/bin/lastlog. Le dernier,
/var/run/utmp, permet de voir qui est connecté sur le
système, et peut être lu avec la commande /usr/bin/w.
La particularité de ces fichiers est qu'ils sont organisés
sous forme d'enregistrements d'une structure. Les fichiers
/var/log/wtmp et /var/run/utmp correspondent
à la structure utmp (détaillée dans le fichier
/usr/include/utmp.h) :
/* The structure describing an entry in the user accounting database. */
struct utmp
{
short int ut_type; /* Type of login. */
pid_t ut_pid; /* Process ID of login process. */
char ut_line[UT_LINESIZE]; /* Devicename. */
char ut_id[4]; /* Inittab ID. */
char ut_user[UT_NAMESIZE]; /* Username. */
char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */
struct exit_status ut_exit; /* Exit status of a process marked
as DEAD_PROCESS. */
long int ut_session; /* Session ID, used for windowing. */
struct timeval ut_tv; /* Time entry was made. */
int32_t ut_addr_v6[4]; /* Internet address of remote host. */
char __unused[20]; /* Reserved for future use. */
};
et le fichier /var/log/lastlog correspond à
la structure lastlog (détaillée dans le fichier
/usr/include/utmp.h) :
/* The structure describing an entry in the database of
previous logins. */
struct lastlog
{
__time_t ll_time;
char ll_line[UT_LINESIZE];
char ll_host[UT_HOSTSIZE];
};
L'utilisation d'une structure pour chacun de ces fichiers facilite
l'organisation de leur contenu. Même s'ils sont illisibles avec
un simple /bin/cat (ce sont des fichiers binaires),
il est assez aisé de développer des programmes pour les lire, les
modifier... à condition évidemment d'être root sur le système. Voici un
exemple :
$ /bin/cat utmp.c
#include
#include
#include
int main( int argc, char * argv[] )
{
char * user;
struct utmp * utn;
if ( argc != 2 ) {
fprintf( stderr, "Usage: %s user
", argv[0] );
return( -1 );
}
user = argv[ 1 ];
setutent();
while ( (utn = getutent()) != NULL ) {
if ( ! strcmp(utn->ut_user, user) ) {
utn->ut_type = DEAD_PROCESS;
memset( utn->ut_line, '
|