#!/usr/bin/perl # Tool for processing log files produced by clamscanLogParse.pl, fprotLogParse.pl # and bdLogParser.pl and inserting the relevant data into a MySQL database. # Currently only linux supported. PEiD works fine with wine. The only manual process # is saving the PEiD log file and making it Unice friendly. # ## mwInventory.pl - 1.0 ## By:magikh0e # ### README #### # When starting a new collection to be managed by these utilities, follow the best practices # below for the most accurate results. ############### ## Starting a malware collection ## ## Step 1 - copy all of your binaries into 1 directory. ## Step 2 - run mwInventory.pl -P from that directory. ## Step 3 - run F-Prot, ClamAV and BitDefender scans on the files saving a log file. ## See below for examples. ### #### # BitDefender - bdscan --action=ignore --log=bdscan.log --log-overwrite # ClamAV - clamscan --infected --log=clamscan.log # F-Prot - fpscan --report -o fpscan.log ## NOTE: Make sure to tell the AV scanner to only report and/or ignore. They will sabotage your collection =) ## You have been warned... #### ## ## Step 4 - Process the av log files. mwInventory.pl -b, -c, -f ## The order of av log processing has no bearing, though keep in mind 1 at a time. Multiple log processing is un-tested. ## ## Step 5 - Last but not least, scan the entire directory of your collection with PEiD. PEiD.exe -hardcore path/* ## The log file must be then converted to unix format. There is also a spot in filenames that has a /\, which will ## also need to be removed... The last thing is to remove the Drive letter, as I run it on wine. ## perl -pi -e 's/\\//g' PEiD.log and perl -pi -e 's/Z://g' PEiD.log # BEGIN SQL CONFIG $platform = "mysql"; $database = "vxDB"; $host = "localhost"; $port = "3306"; $tablename = "vx"; $user = "SET-A-USER"; $pw = "SET-A-Password"; $dsn = "dbi:$platform:$database:$host:$port"; $connect = DBI->connect($dsn, $user, $pw); # END SQL CONFIG use Digest::MD5; use DBI; use DBD::mysql; use POSIX 'strftime'; use Getopt::Std; %opts=(); getopts('fvdhpPcb', \%opts); usage() if $opts{h}; CLAM_proc() if $opts{c}; BD_proc() if $opts{b}; FProt_proc() if $opts{f}; procFiles() if $opts{P}; procPackers() if $opts{p}; $debugging = 0 unless $debugging = $opt{d}; $verbose = 0 unless $verbose = $opts{v}; $enable_report = 0 unless $enable_report = $opts{r}; $process_files = 0 unless $process_files = $opts{P}; $process_bitdefender = 0 unless $process_bitdefender = $opts{b}; $process_clamav = 0 unless $process_clamav = $opts{c}; $process_fprot = 0 unless $process_fprot = $opts{f}; $process_packers = 0 unless $process_packers = $opts{p}; sub usage { print <) { chomp; if ($line =~ m/:/) { ($file, $packer) = split /:/, $line;} $md5 = md5sum($file); print $md5 . $packer; $query = "SELECT id from $database WHERE MD5='$md5'"; $qh = $connect->prepare($query); $qh->execute(); $qh->bind_columns(\$id); while($qh->fetch()) { $query2 = 'UPDATE $database SET packer="' . $packer . '" WHERE id="' . $id . '"'; $qh2 = $connect->prepare($query2); $qh2->execute(); } } } close LOG; sub procFiles { $cnt=0; $today = strftime('%Y-%m-%d', localtime); @files = qx('ls'); foreach $file (@files) { chomp; $cnt++; $md5 = md5sum($file); $fileType = qx"file -b $file"; chomp; ($arch, $info) = split ' ', $fileType; print "$cnt - $date - Hash: $md5 Arch: $arch \n" if $opt{v} || $opt{d}; $query = "INSERT INTO $database (date_added, fileName, fileType, architecture, MD5) VALUES ('$today', '$file', '$fileType', '$arch', '$md5')"; $query_handle = $connect->prepare($query); $query_handle->execute(); } } sub BD_proc { $cnt=0; $today = strftime('%Y-%m-%d', localtime); open BDLOG, 'bdscan.log' or warn "unable to open file: $!"; foreach $line () { $cnt++; if ($line =~ m/infected/) { ($fileName, $status, $vx_name) = split(' ', $line); ($fileName, $gbg) = split(/=>/, $fileName) if ($fileName =~ m/=>/); @BVX = $vx_name; foreach $BX (@BVX) { $cnt{$BX}++; } $md5 = md5sum($fileName); sqlAddInv('bitdefender', $md5, $vx_name); print $cnt if $opt{d}; } }close BDLOG; } sub FProt_proc { print "I made it\n"; open FPS, 'fpscan.log' or warn "unable to open file: $!"; $fcount=0; foreach $line () { if ($line =~ m/\[Found ([^.]+)\] <(.+?)>\s{1,32}(.+?\.[a-zA-Z0-9]{1,6})/) { $fcount++; $category = $1; $fileName = $3; @category = $category; if ($2 =~ m/([^ ]+)\/([^ ]+)/) { $arch = $1; $vx_name = $2; } else { $arch = ""; $vx_name =$2; } @vx = $vx; } print "$vx_name\n"; foreach $vx (@vx) { $cnt{$vx}++; } $md5 = md5sum($fileName); sqlAddInv('fprot', $md5, $vx_name); print $cnt if $opt{d}; } } close FPS; sub CLAM_proc { $cnt=0; $today = strftime('%Y-%m-%d', localtime); open FPS, 'clamscan.log'; foreach $line () { $cnt++; ($fileName, $info) = split(/:/, $line); if ($info =~ m/FOUND/) { ($vx_name, $status) = split(" ", $info); ($file, $ext) = split(/\./, $fileName); @CVX = $vx_name; foreach $CX (@CVX) { $cnt{$CX}++; } foreach $vx ($vx_name) { $md5 = md5sum($fileName); sqlAddInv('clamav', $md5, $vx_name); print $cnt if $opt{d}; } } } close FPS; } sub sqlAddInv { $today = strftime('%Y-%m-%d', localtime); my ($DB, $md5, $vx_name) = @_; print "Adding Entry: $DB $md5 $vx_name\n" if $opt{d} || $opt{v}; $FK = 'FK_bid' if ($DB =~ "bitdefender"); $FK = 'FK_fid' if ($DB =~ "clamav"); $FK = 'FK_fid' if ($DB =~ "fprot"); $query = "SELECT id from $database WHERE MD5='$md5'"; $qh = $connect->prepare($query); $qh->execute(); $qh->bind_columns(\$id); while($qh->fetch()) { $query2 = "INSERT INTO $DB (result,last_scan,$FK) VALUES ('$vx_name', '$today', '$id')"; $qh2 = $connect->prepare($query2); $qh2->execute(); } } sub md5sum{ my $file = shift; my $digest = ""; eval{ open(FILE, $file) or die "Can't find file $file\n"; my $ctx = Digest::MD5->new; $ctx->addfile(*FILE); $digest = $ctx->hexdigest; close(FILE); }; if($@){ print $@; return ""; } return $digest; }