Wednesday, August 3, 2011

Import Nessus nbe into Mysql

Discovered this post here from Michael Holstein:

There is needed modification to get it working from 2006, here is the whole deal. Tested against BT4 (I know I'm behind). To run the script:

cat [nessus nbe file] | ./nessusimport.pl

Now, to get things set up see below. I apologize for the current formatting:

1. Create MYSQL database and create these tables:
CREATE TABLE ipmain ( idmain int(10) unsigned NOT NULL auto_increment, mainip int(10) unsigned NOT NULL default '0', lastnmap datetime NOT NULL default '0000-00-00 00:00:00', lastnessus datetime NOT NULL default '0000-00-00 00:00:00', ipowner varchar(40) default NULL, PRIMARY KEY (idmain), KEY xip (mainip) ) TYPE=MyISAM;
CREATE TABLE nessusresults ( idnessus int(10) unsigned NOT NULL auto_increment, domain varchar(15) NOT NULL default '', nessushost int(10) unsigned NOT NULL default '0', service varchar(40) NOT NULL default '', scriptid int(10) unsigned NOT NULL default '0', risk tinyint(3) unsigned NOT NULL default '0', timestamp datetime NOT NULL default '0000-00-00 00:00:00', msg text, PRIMARY KEY (idnessus), KEY xidnessus (idnessus), KEY knessushost (nessushost), KEY knessushost2 (nessushost,service) ) TYPE=MyISAM;
CREATE TABLE nessusstats ( idstat int(10) unsigned NOT NULL auto_increment, domain varchar(15) NOT NULL default '', nessushost int(10) unsigned NOT NULL default '0', service varchar(40) NOT NULL default '', scriptid int(10) unsigned NOT NULL default '0', risk tinyint(3) unsigned NOT NULL default '0', timestamp datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (idstat), KEY xidstat (idstat), KEY kstat (nessushost), KEY kstst2 (nessushost,service) ) TYPE=MyISAM;
----------------------
2. Create the following perl script:
#!/usr/bin/perl
use Net::SMTP;
use Date::Manip;
our $TZ = 'US/Eastern';
use DBI();

#####DATABASE PARAMETERS#####

$DATABASE="DB GOES HERE";
$HOST="HOSTNAME GOES HERE";
$USERNAME="DB USERNAME GOES HERE";
$PASSWORD="DB PASSWORD GOES HERE";

#connect to the database server
#DBI->trace(1, "trace.log"); #uncomment to log all DBI stuff
$dbh = DBI->connect("DBI:mysql:database=$DATABASE;host=$HOST",
$USERNAME, $PASSWORD, {'RaiseError' => 1}) || die "Unable to connect:
$dbh->errstr\n";


######MAIN PROGRAM LOOP######

while ( )
{
@results = split '\||\|\|';
@results[6] =~ tr/;/\n/;
@results[6] =~ tr/"/'/;
@results[5] = "7";
#print @results[6];
# if(@results[6] =~ "Risk factor :\\\\n\\\\nCritical"){print @results[6];}
if(@results[6] =~ "Risk factor :\\\\n\\\\nCritical") {@results[5] = '1';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nSerious") {@results[5] = '1';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nHigh") {@results[5] = '1';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nMedium") {@results[5] = '2';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nMedium/Low") {@results[5] = '2';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nLow/Medium") { @results[5] = '3';}
if(@results[6] =~ "Risk factor :\\\\n\\\\nLow") { @results[5] = '3';}

# @results[5] = '1' if (@results[6] =~ "Risk factor : Critical");
# @results[5] = '1' if (@results[6] =~ "Risk factor : Serious");
# @results[5] = '1' if (@results[6] =~ "Risk factor : High");
# @results[5] = '2' if (@results[6] =~ "Risk factor : Medium");
# @results[5] = '2' if (@results[6] =~ "Risk factor : Medium/Low");
# @results[5] = '3' if (@results[6] =~ "Risk factor : Low/Medium");
# @results[5] = '3' if (@results[6] =~ "Risk factor : Low");
@results[6] =~ `Risk factor : Critical`;
@results[6] =~ `Risk factor : High`;
@results[6] =~ `Risk factor : Serious`;
@results[6] =~ `Risk factor : Medium`;
@results[6] =~ `Risk factor : Medium/Low`;
@results[6] =~ `Risk factor : Low/Medium`;
@results[6] =~ `Risk factor : Low`;
for (@results[0]) { s/^\s+//;s/\s+$//; }
for (@results[1]) { s/^\s+//;s/\s+$//; }
for (@results[2]) { s/^\s+//;s/\s+$//; }
for (@results[3]) { s/^\s+//;s/\s+$//; }
for (@results[4]) { s/\
for (@results[5]) { s/^\s+//;s/\s+$//; }
for (@results[6]) { s/^\s+//;s/\s+$//;s/\'/\\'/g;}
my $ip = &dot2dec(@results[2]);
next unless ($ip > 0);
$timestamp = UnixDate(@results[4], '%Y-%m-%d %H:%M:%S');
&findmainip($ip);
#condition 1 (entry is a timestamp for end of host scan)
if (@results[0] eq "timestamps" and @results[3] =~ 'host_end|host_start') {
&updatemainip($ip,$timestamp);
#print "Condition 1 Matched\n";
}
#condition 2 (entry is a result record)
#print "testing: " . @results[0] ." and results 5: ".@results[5] . "\n";
if (@results[0] eq "results" and @results[5] < 7) {
&findnessustimestamp($ip);
&updatenessus(@results[1],$ip, @results[3], @results[4], @results[5], @nessustime[1], @results[6]);
&updatestats(@results[1],$ip, @results[3], @results[4], @results[5], @nessustime[1]);
}
else {
next;
}
}

#####GLOBAL SUBROUTINES#####

#turn dotted quad into decimal
sub dot2dec {
my $address = @_[0];
($a, $b, $c, $d) = split '\.', $address;
$decimal = $d + ($c * 256) + ($b * 256**2) + ($a * 256**3);
return $decimal;
}

#turn decimal into dotted
sub dec2dot {
my $address = @_[0];
$d = $address % 256; $address -= $d; $address /= 256;
$c = $address % 256; $address -= $c; $address /= 256;
$b = $address % 256; $address -= $b; $address /= 256;
$a = $address;
$dotted="$a.$b.$c.$d";
return $dotted;
}

#find IP in master table
sub findmainip {
my $query = $dbh->prepare("select idmain,mainip from ipmain
where mainip = '@_[0]'");
$query->execute || die "Unable to locate IP in table ipmain:
$dbh->errstr\n";
@mainip = $query->fetchrow_array;
return @mainip;
}

#update/add IP&timestamp in master table
sub updatemainip {
my $query = $dbh->prepare("select * from ipmain where
mainip=@_[0]");
$query->execute || die "Unable to locate IP in table ipmain:
$dbh->errstr\n";
@mainip = $query->fetchrow_array;
if (@mainip[0]) {
$dbh->do("update ipmain set lastnessus='@_[1]' where
idmain='@mainip[0]'") || die "problem with updatemainip 1:$dbh->errstr\n";
# print "updated values lastnessus=@_[1] where idmain=@mainip[0]\n";
}
else {
$dbh->do("insert into ipmain (mainip,lastnessus) values
('@_[0]','@_[1]')") || die "problem with updatemainip 2:$dbh->errstr\n";
# print "inserted values mainip=@_[0], lastnessus=@_[1]\n";
}
return;
}

#find last nessus timestamp for some IP
sub findnessustimestamp {
my $query = $dbh->prepare("select idmain,lastnessus from ipmain
where mainip='@_[0]'") || die "problem with findnessustimestamp:
$dbh->errstr\n";
$query->execute || die "Unable to locate nessus timestamp in
table ipmain: $dbh->errsrt\n";
@nessustime = $query->fetchrow_array;
return @nessustime;
}

#update/add nessus results records in nessusresults table
sub updatenessus {
my $query = $dbh->prepare("select * from nessusresults where nessushost='@_[1]' and scriptid='@_[3]'") || die "problem with updatenessus 1:$dbh->errstr\n";
print "prepared";
$query->execute || die "Unable to locate record in NessusResults: $dbh->errstr\n";
print "executed";
@nessus = $query->fetchrow_array;
if (@nessus[0]) {
$dbh->do("update nessusresults set domain='@_[0]',
nessushost='@_[1]', service='@_[2]', scriptid='@_[3]', risk='@_[4]',
timestamp='@_[5]', msg='@_[6]' where idnessus='@nessus[0]'") || die
"problem with updatenessus 2: $dbh->errstr\n";
# print "updated values domain=@_[0], host=@_[1], service=@_[2], script=@_[3], risk=@_[4], time=@_[5], msg=@_[6]\n";
}
else {
$dbh->do("insert into nessusresults
(domain,nessushost,service,scriptid,risk,timestamp,msg) values
('@_[0]','@_[1]','@_[2]','@_[3]','@_[4]','@_[5]','@_[6]')") || die
"problem with updatenessus 3: $dbh->errstr\n";
# print "inserted values domain=@_[0], host=@_[1], service=@_[2], script=@_[3], risk=@_[4], time=@_[5], msg=@_[6]\n";
}
return;
}

sub updatestats {
$dbh->do("insert into nessusstats
(domain,nessushost,service,scriptid,risk,timestamp) values
('@_[0]','@_[1]','@_[2]','@_[3]','@_[4]','@_[5]')") || die "problem with
updatestats 1: $dbh->errsrt\n";
# print "inserted stats values domain=@_[0], host=@_[1], service=@_[2], script=@_[3], risk=@_[4], time=@_[5]\n";
return;
}