Re: [Full-disclosure] Automated Vulnerability Scanners



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.pl

This 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&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";
$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/



Relevant Pages

  • Re: What is the name of the Language we are using & recommend book
    ... Can I have 2 sub forms in a form that are not sub forms of the other sub ... As for my process I am trying to create my Access Database in shells like ... QSL or Microsoft SQL Server Data Engine or what. ... language of queries, and the query design grid is just a tool to construct ...
    (microsoft.public.access.formscoding)
  • Re: Custom Login Screen
    ... Private Sub cmdLogin_Click ... On Error GoTo ErrorHandler ... You will need to enter your full path to the database file and MDW file in the appropriate places. ... Now make an MDE file from this MDB. ...
    (microsoft.public.access.security)
  • Re: Jeff C
    ... properly secure an Access database. ... Private Sub Form_Open ... Resume ExitPoint ... Dim db As DAO.Database ...
    (microsoft.public.access.formscoding)
  • Re: How to use a logon screen to log into a secured Database?
    ... > that appears with a secured database. ... >>On Error GoTo ErrorHandler ... >> Exit Sub ... Now make an MDE file ...
    (microsoft.public.access.security)
  • Re: linking databases
    ... Doug Steele, Microsoft Access MVP ... Sub chrCountry_AfterUpdatestring highlighted in yellow.The code as I ... I using the text box's [Event Procedure] After Update property on the ... The name of the column in the table in the 2nd database I want to ...
    (microsoft.public.access.externaldata)