98.3. Systém skriptů HBIDS

Host Based Intrusion Detection System

Dalším vylepšením je obalení předchozí varianty sadou skriptů která umožní nejen udržování historie, ale také uložení této na zabezpečeném počítači a s automatickým udržováním kdy nemusíme myslet na ukládání souboru do systému správy verzí. Takovýto systém je pak použitelný i jako primitivní Systém detekce průniků (Intrusion Detection System)

Abstrakt

Kontrola a udržování konfigurací počítačů (hostů) na dálku s detekcí změn. Napsáno podle „Verifying Filesystem Integrity with CVS“ v Linux Journal č. 40 February 2002

Pro sledování použijeme vyhrazený bezpečný stroj. Na tomto stroji pod uživatelem, například hbids budeme spouštět skripty. Přesněji necháme démona cron spouštět v pravidelných intervalech, například 15 minut, skript 98.4 – „cvschecker.pl.

Systém“ sledování konfiguračních a jiných souborů sestává ze dvou skriptů. První collector.pl provádí sběr dat z jednotlivých sledovaných strojů (hostů).

Příklad 98.3. collector.pl

#!/usr/bin/perl -w
# $Id: collector.pl,v 1.1.1.1 2009-01-24 15:42:52 radek Exp $

use Net::SSH::Perl;
use strict;

my %Cmds;
my $host = qw(10.16.66.19);
my $user = "root";

my @md5files = qw(/bin/login
		  /usr/bin/passwd
		  /bin/ps
		  );

my @configfiles = qw(/etc/passwd
		     /etc/shadow
		     /etc/inetd.conf
		     /etc/services
		     );

$Cmds{'md5sigs'}     = "md5sum @md5files";
$Cmds{'configs.tar'} = "tar cf - @configfiles";
$Cmds{'suidfiles'}   = "find / -type f -perm +6000 | xargs ls -l";


### main loop ###
for my $file (keys %Cmds) {
    my $cmd = $Cmds{$file};

    # run each command on $host and print the output to $file
    &run_command($cmd, $file, $host);
}
exit 0;

sub run_command() {
    my ($cmd, $file, $host) = @_;

    # turn on compression across the ssh session
    my $ssh = Net::SSH::Perl->new($host, compression=>1);
    $ssh->login($user);
    my ($stdout, $stderr, $exit) = $ssh->cmd($cmd);

    open F, "> $file";
    print F $stdout;
    close F;
    return;
}

Příklad 98.4. cvschecker.pl

#!/usr/bin/perl                                            (1)
# $Id: cvschecker.pl,v 1.1.1.1 2009-01-24 15:42:52 radek Exp $

use File::Find;
use strict;
use vars qw(@Files);

my $email = 'root@localhost';
my $host = "192.168.10.5";
my $cvsroot = "/usr/local/hbids_cvs";
my $collectorCmd = "/usr/local/bin/collector.pl";

system "cvs -d $cvsroot checkout -ko $host";
chdir $host;
system "$collectorCmd";		# get the files from $host

find(\&findfiles, "/home/mbr/${host}");

# check to see if any file has been changes
for my $file (@files) {
    if (`cvs -d $cvsroot commit -m . $file`) {
	my $cvsfile = $file;
	$cvsfile =~ s|^\S+?$host|$host|;
	$cvsfile = $cvsroot ."/" . $cvsfile .",v";
	my $prerev = "";

	# use rlog to get the previous revision
	open RLOG, "rlog $cvsfile|";
	my $found = 0;
	while (<RLOG>) {
	    if (/^revision\s(\S+)/) {
		$prerev = $1;
		$found++;
	    }
	    last if ($found == 2);
	}
	close RLOG;

	# get the changes using 'cvs diff'
	my $diff = `cvs -d $cvsroot diff -r $prerev $file`;
	open TMP, "> /tmp/change";
	print TMP $diff;
	close TMP;
	$file =~ s|^\S+?$host||g;

	# send an mail that contains the changes
	`mail -s "Changed file on $host: $file" $email \
                 < /tmp/change`;
    }
}
exit 0;

# find all files in the local directory structure,
# but ignore directories and CVS files
sub findfiles() {
    my $file = $File::Find::name;
    unless (-d $file || $file =~ /CVS/) {
	push @Files, $file;
    }
    return;
}
1Tento skript je napsán v Perlu.