Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

syscheck: check system files for changes

by cianoz (Friar)
on Sep 11, 2000 at 02:05 UTC ( [id://31818]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info Claudio Della Ciana cianoz
Description: this program checks files and directories in your system reporting if they were modified (by checking an md5 sum) created or deleted since last time you initialized it.

I use it to check my /etc /sbin /lib /bin /usr/bin and /usr/sbin for changes i didn't made (backdoors?)

you can run it from a cron job or manually (it is safe to store a copy of the checksum database outside the system) it takes about 2 minutes to scan all rilevant files on my systems.

although it seems to work for me it is just a quick hack, i would appreciate some hints to make it better.

#!/usr/bin/perl -w

use strict;
use vars qw(%opt %DB $VERSION $NAME $DEFRC $DEFDB);

$VERSION = '0.9';
$NAME = 'syscheck';
$DEFDB = '/var/lib/syscheck/sum.db';
$DEFRC = '/etc/syscheck.rc';
use File::Find;
use Digest::MD5;
use Getopt::Std;
use DB_File;
getopts('hvif:c:', \%opt);

if($opt{h}) {
  print(<<EOF);

$NAME $VERSION

USAGE: $NAME [-hvi] [-f checksum_file] [-c config_file]

DESCRIPTION:

this program checks files and directories in your system 
reporting if they were modified (by checking an md5 sum) 
created or deleted since last time you initialized it.

I use it to check my /etc /sbin /lib /bin /usr/bin and /usr/sbin
for changes i didn't made (backdoors?)

you can run it from a cron job or manually 
(it is safe to store a copy of the checksum database outside the syste
+m)
it takes about 2 minutes to scan all rilevant files on my systems.

although it works for me it is all but perfect: 
i would appreciate some hints to make it better.

Options:
-h this (poor) help

-i create (initialize) a new checksum database 

-f <checksum_file> use another checksum file instead of 
   $DEFDB 

-c <config_file> use another config file instead of 
   $DEFRC ( - for STDIN)

-v verbose output (not yet implemented :)

EOF

  exit 0;
}

my $rcfile = $opt{c} || $DEFRC;
my $dbfile = $opt{f} || $DEFDB;



open(FIND, "<$rcfile")|| die "cannot open $rcfile: $!\n";
if($opt{i}) {
   unlink($dbfile) || die "cannot unlink $dbfile: $!\n";
}
tie %DB, 'DB_File', $dbfile || die "cannot tie $dbfile\n";
my @list;
while(<FIND>) {
  chomp;
  next if( $_ =~ /^\s*#/);
  next if( $_ =~ /^\s*$/);
  push @list, $_;
}

close FIND;

chdir('/');
print "$NAME V. $VERSION\n";
print "begin date: ", scalar(localtime(time())), "\n";
print "\n---- BEGIN REPORT ---\n";
print "init db $dbfile" if($opt{i});

find(\&checkfile, @list);
unless($opt{i}) {
  print "\nDeleted files:\n";
  foreach my $key (keys %DB) {
    unless($DB{$key} =~ s/:CHECKED$//) {
      print "$key\n";
      delete $DB{$key};
    }
  }
}

print "\n----  END REPORT  ---\n";
print "end date: ", scalar(localtime(time())), "\n";
untie %DB;

sub checkfile {
  if(-f $_) {
     my $fname = $File::Find::name;
     if(open(FILE, $_)){

    my $md5 = new Digest::MD5;
    my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
       $atime,$mtime,$ctime,$blksize,$blocks) = stat(FILE);
    $md5->addfile(*FILE);
    my $digest = $md5->hexdigest;
    if($opt{i}) {
      #add it
      $DB{$fname} = "$digest:$mode:$uid:$gid:$mtime";
    }
    else {
      #verify
      my $finfo = $DB{$fname} || 0;
      $DB{$fname} = $finfo .  ':CHECKED';
      if($finfo) {
        my ($odigest,$omode,$ouid,$ogid,$omtime) =
        split(':', $finfo);
        unless($digest eq $odigest) {
        print "FILE $fname - digest changed: \n\t old: $odigest \n\t n
+ew: $digest\n"; 
        }
        unless($mode eq $omode) { 
        print "FILE $fname - mode changed: \n\t old: $omode \n\t new: 
+$mode)\n";
        }
        unless($uid eq $ouid) { 
        print "FILE $fname - uid changed: \n\t old: $ouid \n\t new: $u
+id\n";
        }
        unless($gid eq $ogid) { 
        print "FILE $fname - gid changed: \n\t old: $ogid \n\t new: $g
+id\n";
        }
        unless($mtime eq $omtime) { 
        $mtime = scalar(localtime($mtime));
        $omtime =  scalar(localtime($omtime));
        print "FILE $fname - mtime changed: \n\t old: $omtime \n\t new
+: $mtime\n";
        
        }
      }
      else {
        print "- new file: $fname\n";
        delete $DB{$fname};
      }
      close FILE;    
    }
     }
     else {
      warn "cannot open file $fname: $!";
     }    
  }    
}
Replies are listed 'Best First'.
Re: syscheck: check system files for changes
by starbolin (Hermit) on Apr 16, 2008 at 19:02 UTC

    I borrowed your code and have been using it to keep track of my BSD system. Unfortunately, it fell down behind the book-rack where the dog got it and ripped it into little tiny shreds. I got it put back together again with plenty of tape and glue but it's not the same program it once was. All the data access got rolled up into their own loops, well.. most of them, and some time when I wasn't looking the CHECKED field totally wandered off but I did find a hash key to take it's place. I did manage to push most of the flow control out of the loops and push the data access inside of the subroutines so it should be more suited to converting to OO; something I would like to tackle when the round-toit I requisitioned is finally delivered.


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
      Thanks for the leg up on this. i need it as a based point for a more general monitoring tool. Once i have made improvements will share the src
Re: syscheck: check system files for changes
by Anonymous Monk on Aug 18, 2009 at 09:59 UTC
    Any suggestions on what to do if you have to also check binary files? The scipt will choke if the line: if( -f $_ ) { # Only process plain files is changed is skipped. Cheers -Tom

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://31818]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-03-29 04:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found