chklastlog.c v1.3 checks lastlog and wtmp for signs of tampering. It will detect most log wiping programs, such as z2 and zap.
5c70a4d3d2f9a170c0fb3ab5fec5a3ac1e7f46bf1c40d812bf7e23dea65d5910
/*
Copyright (c) DFN-CERT, Univ. of Hamburg 1994
Univ. Hamburg, Dept. of Computer Science
DFN-CERT
Vogt-Koelln-Strasse 30
22527 Hamburg
Germany
02/20/97 - Minimal changes for Linux/FreeBSD port.
02/25/97 - Another little bit change
12/26/98 - New Red Hat compatibility
Nelson Murilo, nelson@pangeia.com.br
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <utmp.h>
#if (HAVE_LASTLOG_H)
#include <lastlog.h>
#endif
#include <sys/file.h>
#ifdef __FreeBSD__
#define WTMP_FILENAME "/var/log/wtmp"
#else
#ifndef WTMP_FILENAME
#define WTMP_FILENAME "/var/adm/wtmp"
#endif
#endif
#ifdef __FreeBSD__
#define LASTLOG_FILENAME "/var/log/lastlog"
#else
#ifndef LASTLOG_FILENAME
#define LASTLOG_FILENAME "/var/adm/lastlog"
#endif
#endif
#define TRUE 1
#define FALSE 0
int main() {
int fh_wtmp;
int fh_lastlog;
struct lastlog lastlog_ent;
struct utmp utmp_ent;
struct passwd *pw_ent;
int userid[65535];
int i;
int status = 0;
for (i=0; i<65535; i++)
userid[i]=FALSE;
if ((fh_lastlog=open(LASTLOG_FILENAME,O_RDONLY)) < 0) {
fprintf(stderr, "unable to open lastlog-file %s\n", LASTLOG_FILENAME);
return(1);
}
if ((fh_wtmp=open(WTMP_FILENAME,O_RDONLY)) < 0) {
fprintf(stderr, "unable to open wtmp-file %s\n", WTMP_FILENAME);
close(fh_lastlog);
return(2);
}
while (read (fh_wtmp, &utmp_ent, sizeof (struct utmp)) > 0)
if ( !nonuser(utmp_ent) && strncmp(utmp_ent.ut_line, "ftp", 3) &&
(pw_ent=getpwnam(utmp_ent.ut_name)) != NULL )
if ( userid[pw_ent->pw_uid] == FALSE ) {
lseek(fh_lastlog, (long)pw_ent->pw_uid * sizeof (struct lastlog), 0);
if (read(fh_lastlog, &lastlog_ent, sizeof (struct lastlog)) > 0)
if (lastlog_ent.ll_time == 0)
{
printf("user %s deleted or never loged from lastlog!\n", pw_ent->pw_name);
++status;
}
userid[pw_ent->pw_uid]=TRUE;
}
close(fh_wtmp);
close(fh_lastlog);
return(status);
}
/* minimal funcionality of nonuser() */
nonuser(struct utmp utmp_ent)
{
return (!memcmp(utmp_ent.ut_name, "shutdown", sizeof ("shutdown")));
}