Full Disclosure mailing list archives
Re: Automated Vulnerability Scanners
From: Michael Holstein <michael.holstein () csuohio edu>
Date: Fri, 24 Feb 2006 16:13:10 -0500
Can anyone reccommend a perl based nessus wrapper that has the ability to dump results into a mysql database?
Here is what I use. I wrote this a while ago (before I got better at Perl) .. feel free to criticize -- or improve upon -- this. It's got some debugging stuff in there commented out that I never removed. Be nice.
(If this wraps and gets ugly -- feel free to email offlist and I'll send as attachment).
If you want the database schema, I can send that too. I also have reporting scripts that generate nifty departmental emails to various people once a week telling them what to fix (also in perl).
Anyway .. Here is how you run nessus, then involke this script :/usr/local/nessus/bin/nessus -x -c myrcfile.rc -T nbe -q nessus_host 1241 nessus_user nessus_passwd ipinputfile outputfile.nbe
cat outputfile.nbe | nice -n 20 ./nessusimport.plThis is pretty fast .. can process an entire test from a /16 and input the results into MySQL in about 5 minutes.
Cheers, Michael Holstein CISSP GCIA Cleveland State University --snip-- #!/usr/local/bin/perl use Net::SMTP; use Date::Manip; our $TZ = 'US/Eastern'; use DBI(); #####DATABASE PARAMETERS##### $DATABASE="--dbname--"; $HOST="--hostname--"; $USERNAME="--username--"; $PASSWORD="--password--"; #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 ( <STDIN> )
{
@results = split '\||\|\|';
@results[6] =~ tr/;/\n/;
@results[6] =~ tr/"/'/;
@results[5] = "7";
@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] =~ s`Risk factor : Critical``;
@results[6] =~ s`Risk factor : High``;
@results[6] =~ s`Risk factor : Serious``;
@results[6] =~ s`Risk factor : Medium``;
@results[6] =~ s`Risk factor : Medium/Low``;
@results[6] =~ s`Risk factor : Low/Medium``;
@results[6] =~ s`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/\<//g;s/^\s+//;s/\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)
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]);
# print "Condition 2 Matched\n";
}
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×tamp 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";
$query->execute || die "Unable to locate record in
NessusResults: $dbh->errstr\n";
@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;
}
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/
Current thread:
- Automated Vulnerability Scanners Q Beukes (Feb 22)
- Message not available
- Re: Automated Vulnerability Scanners Q Beukes (Feb 24)
- Re: Automated Vulnerability Scanners Gadi Evron (Feb 24)
- Re: Automated Vulnerability Scanners Simon Smith (Feb 24)
- Re: Automated Vulnerability Scanners Michael Holstein (Feb 24)
- Re: Automated Vulnerability Scanners Michael Holstein (Feb 24)
- Re: Automated Vulnerability Scanners Q Beukes (Feb 24)
- Re: Automated Vulnerability Scanners Dude VanWinkle (Feb 24)
- Message not available
- <Possible follow-ups>
- RE: Automated Vulnerability Scanners Krpata, Tyler (Feb 24)
