#!/usr/bin/perl ### # Parse text-based log files of Snort scan reports, and save them # to a file in Berkley DB format. ### # Load necessary libraries. require "init.pl"; ### # Initialize output scan database. if (-e $SCANDB) { die "Output scan database $SCANDB already exists. Exiting.\n"; } if (! tie(%SCANDB, "DB_File", $SCANDB)) { die "Could not initialize output scan database $SCANDB:\n$!\n"; } ### # Process every line on STDIN or in files passed on command line. $counter = 0; $dbdelim = "|"; while (<>) { # Display a message every time a new file is being processed. if ($VERBOSE) { if ($ARGV eq "-") { $infile = "STDIN"; } else { $infile = $ARGV; } if (! $PROCESSED_FILES{$infile}) { warn "Processing $infile...\n"; $PROCESSED_FILES{$infile} = 1; sleep(1); } } # Skip empty lines, lines with nothing but stars, and title lines. # Also skip lines that don't start with a date, but warn about that. next if ((/^\s*\**\s*$/) || (/^\s*Snort Scan Report/)); if (! /^(May|Jun) [\d ]\d /) { warn "No leading date: $_"; next; } # Separate the line into meaningful fields. chop; /^(\w\w\w [\d ]\d \d\d:\d\d:\d\d) (.*) \-\> ([^ ]*) (.*)$/; $timestamp = $1; $src = $2; $dst = $3; $details = $4; $details =~ s/\s+$//; if ($timestamp =~ /^\s*$/) { warn "Timestamp empty ([**] $name [**] $details)\n"; next; } $timestamp =~ s/^May /05\//; $timestamp =~ s/^Jun /06\//; $timestamp =~ s/\/([\d ]\d) /\/$1\-/; $timestamp .= ".000000"; if ($src =~ /^\s*$/) { warn "Source empty ($timestamp)\n"; next; } if ($dst =~ /^\s*$/) { warn "Destination empty ($timestamp)\n"; next; } ($srchost, $srcport) = split(/:/, $src); ($dsthost, $dstport) = split(/:/, $dst); if (($srchost =~ /^\s*$/) || ($dsthost =~ /^\s*$/)) { # Hosts cannot be empty, but ports are in some alerts. warn "Source or destination host corrupted ($timestamp)\n"; next; } # Write alert to the database. $SCANDB{$counter++} = $timestamp . $dbdelim . $details . $dbdelim . $srchost . $dbdelim . $srcport . $dbdelim . $dsthost . $dbdelim . $dstport; } ### # Clean up and exit. untie(%SCANDB);