Skip to content

Instantly share code, notes, and snippets.

@alecnunn
Created December 20, 2013 18:56
Show Gist options
  • Select an option

  • Save alecnunn/8059619 to your computer and use it in GitHub Desktop.

Select an option

Save alecnunn/8059619 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
#
# Copyright (C) 2005-2006 Joshua D. Abraham (jabra@ccs.neu.edu)
#
# This program is released under the terms of the GNU General Public License
# (GPL), which is distributed with this software in the file "COPYING".
# The GPL specifies the terms under which users may copy and use this software.
#
# PBNJ 2.0
# (P)orts (B)anners N' (J)unk
#
# Author: Joshua D. Abraham
# Date: March 15, 2006
# Updated: November 15, 2006
# Version: 2.04
#
# ScanPBNJ - a program for running Nmap scans and storing the results in
# a PBNJ 2.0 database.
#
# Modified by Alec Nunn
# Date: December 20, 2013
use strict;
use warnings;
use Shell;
use DBI;
use Nmap::Parser;
use Socket;
use Net::hostent;
use Sys::Hostname;
use Getopt::Long;
use FileHandle;
use YAML;
use File::Which;
use Term::ANSIColor qw(:constants);
use File::HomeDir;
use POSIX;
$Term::ANSIColor::AUTORESET = 1;
use vars qw( $PROG );
( $PROG = $0 ) =~ s/^.*[\/\\]//; # Truncate calling path from the prog name
my $AUTH = 'Joshua D. Abraham'; # author
my $VERSION = '2.04'; # version
my $np = new Nmap::Parser; # parser object
my $type = 'help'; # parse scan or file
my @ipRange; # ip Address or ip range to scan
my $iplist; # ip list file
my $xmlFile; # xml file to parse
my $Range = '1-1025'; # port range to scan
my $args = "-vv -O -P0 "; # scan args
my $scantype = "-sSV"; # default scantype
my $cargs = 'no'; # user changed args
my $outputdir = '.'; # output database directory
my $nmapPath = which('nmap'); # nmap path
my $interface = ""; # default interface to perform scan
my %options; # getopts hash
my $dbh; # database connection
my $dbconfig = 'config.yaml'; # database config
my $database; # database file
my $db; # db backend
my $hostname; # db host ip
my $port; # db port
my $user; # db username
my $passwd; # db password
my $datadb; # results from the config of the db
my $dir = "."; # dir of the config for the db
my $colors = 1; # print using colors
my $diff = 'version';
$options{test} = 0; # testing flag
$options{debug} = 0; # debug flag
my $configdir;
#chown() that reports errors
sub safe_chown {
my $uid = shift;
my $gid = shift;
my $file = shift;
if ( chown( $uid, $gid, $file ) != 1 ) {
error( 'Unable to change the owner of the file ' . $file . '.'
. "\n\n" );
}
}
if ( $^O eq 'MSWin32' || $^O =~ /cygwin/ ) {
$colors = 0;
require Win32;
import Win32;
Win32->import(qw(CSIDL_APPDATA));
my $dir = Win32::GetFolderPath( CSIDL_APPDATA() );
# 2.0
$configdir = $dir . "\\" . "pbnj-2.0";
if ( -e $configdir and -d $configdir ) {
if ( $options{test} > 2 ) {
print "$configdir exists\n";
}
}
else {
mkdir $configdir;
print "mkdir $configdir\n";
}
if ( !-e $dbconfig ) {
$dbconfig = "$configdir\\$dbconfig";
# check if the config exists in ~/.pbnj-2.0/config.yaml
if ( !-e $dbconfig ) {
open( CONFIG, ">$dbconfig" );
while (<DATA>) {
if ( defined($_) ) {
print CONFIG $_;
}
}
close(CONFIG);
print "$dbconfig generated\n";
}
}
}
else {
$configdir = File::HomeDir->my_home;
my $tmpuser = $configdir;
$configdir .= "/.pbnj-2.0";
$tmpuser =~ s/home//;
$tmpuser =~ s/\///g;
my $uid = getpwnam($tmpuser);
my $gid = id("-g $tmpuser");
if ( !defined($gid) ) {
error("gid not defined\n");
}
if ( !defined($uid) ) {
error("uid not defined\n");
}
if ( -e $configdir and -d $configdir ) {
if ( $options{test} > 2 ) {
print "$configdir exists\n";
}
}
else {
umask 077;
mkdir $configdir;
print "mkdir $configdir\n";
safe_chown( $uid, $gid, $configdir );
}
# check if config exists in the current directory
if ( !-e $dbconfig ) {
$dbconfig = "$configdir/$dbconfig";
# check if the config exists in ~/.pbnj-2.0/config.yaml
if ( !-e $dbconfig ) {
umask 077;
open( CONFIG, ">$dbconfig" );
while (<DATA>) {
if ( defined($_) ) {
print CONFIG $_;
}
}
close(CONFIG);
safe_chown( $uid, $gid, $dbconfig );
print "$dbconfig generated\n";
}
}
}
##############################################################################
#
# createMachinesTable: scalar -> scalar
# creates the table for machines in the database
# mid INTEGER PRIMARY KEY,
#
##############################################################################
sub createMachinesTable {
my $dbh = shift;
my $auto_increment = "AUTO_INCREMENT";
my $mid_type;
if ( $db eq "SQLite" ) {
$auto_increment = "AUTOINCREMENT";
$mid_type = "INTEGER PRIMARY KEY $auto_increment";
}
elsif ( $db eq "mysql" or $db eq "CSV" ) {
$mid_type = "INTEGER PRIMARY KEY AUTO_INCREMENT";
}
elsif ( $db eq "Pg" ) {
$mid_type = "SERIAL PRIMARY KEY";
}
else {
print "db not supported\n";
exit 1;
}
eval {
$dbh->do(
"CREATE TABLE machines (
mid $mid_type,
ip TEXT,
host TEXT,
localh INTEGER,
os TEXT,
machine_created TEXT,
created_on TEXT)"
);
};
if ($@) {
return 0;
}
return 1;
}
##############################################################################
#
# createService: scalar -> scalar
# creates the table for services in the database
#
##############################################################################
sub createServicesTable {
my $dbh = shift;
#sid INTEGER PRIMARY KEY,
eval {
$dbh->do(
"CREATE TABLE services (
mid INTEGER,
service TEXT,
state TEXT,
port INTEGER,
protocol TEXT,
version TEXT,
banner TEXT,
machine_updated TEXT,
updated_on TEXT)"
);
};
if ($@) {
return 0;
}
return 1;
}
sub createReportsTable {
my $dbh = shift;
eval {
$dbh->do(
"CREATE TABLE report (
mid INTEGER PRIMARY KEY AUTO_INCREMENT,
ip TEXT,
host TEXT,
os TEXT,
http INTEGER,
httpproxy INTEGER,
https INTEGER)"
);
if ($@) {
return 0;
}
return 1;
}
}
##############################################################################
#
# insertService: anoy hash -> scalar
# inserts information about a service into the database
#
##############################################################################
sub insertService {
my ($href) = @_;
die "insertService: mid not defined" unless defined $href->{mid};
die "insertService: service not defined" unless defined $href->{service};
die "insertService: state not defined" unless defined $href->{state};
die "insertService: port not defined" unless defined $href->{port};
die "insertService: proto not defined" unless defined $href->{proto};
die "insertService: ver not defined" unless defined $href->{ver};
die "insertService: banner not defined" unless defined $href->{banner};
die "insertService: updated not defined" unless defined $href->{updated};
die "insertService: machine_updated not defined"
unless defined $href->{machine_updated};
my $mid = $href->{mid};
my $service = $href->{service};
my $state = $href->{state};
my $port = $href->{port};
my $proto = $href->{proto};
my $ver = $href->{ver};
my $banner = $href->{banner};
my $updated = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $insert
= $dbh->prepare('INSERT INTO services VALUES (?,?,?,?,?,?,?,?,?)');
my $success = 1;
$success &&= $insert->execute(
$mid, $service, $state,
$port, $proto, $ver,
$banner, $machine_updated, $updated
);
return $success;
}
##############################################################################
#
# setLocal: anoy hash -> scalar
# set the localhost bit
#
##############################################################################
sub setLocal {
my ($href) = @_;
die "setLocal: ip not defined" unless defined $href->{ip};
die "setLocal: hostname not defined" unless defined $href->{hostname};
my $ip = $href->{ip};
my $hostname = $href->{hostname};
my $localh = 0;
if ( $hostname =~ m/localhost/ and $ip eq "127.0.0.1" ) {
if ( $options{test} > 0 or $options{debug} > 1 ) {
print "localhost scan\n";
}
$localh = 1;
}
return $localh;
}
##############################################################################
#
# insertMachine: anoy hash -> scalar
# inserts information about a machine into the database
#
##############################################################################
sub insertMachine {
my ($href) = @_;
die "insertMachine: ip not defined" unless defined $href->{ip};
die "insertMachine: host not defined" unless defined $href->{host};
die "insertMachine: localh not defined" unless defined $href->{localh};
die "insertMachine: os not defined" unless defined $href->{os};
die "insertMachine: created not defined" unless defined $href->{created};
die "insertMachine: machine_created not defined"
unless defined $href->{machine_created};
my $ip = $href->{ip};
my $host = $href->{host};
my $localh = $href->{localh};
my $os = $href->{os};
my $created = $href->{created};
my $machine_created = $href->{machine_created};
if ( $db eq "CSV" ) {
my $sth = $dbh->selectrow_hashref("select max('mid') from machines");
my $mid = $sth->{mid};
if ( !defined($mid) ) {
$mid = 1;
}
else {
$mid++;
}
my $insert = $dbh->prepare(
'INSERT INTO machines VALUES (?,?,?,?,?,?,?,?,?)');
my $success = 1;
$success &&= $insert->execute( $mid, $ip, $host, $localh, $os,
$machine_created, $created );
return $mid;
}
else {
$dbh->do(
"INSERT INTO machines (ip, host, localh, os,
machine_created, created_on) VALUES (
'$ip', '$host', '$localh', '$os',
'$machine_created', '$created' ) "
);
}
my $sth = $dbh->selectrow_hashref(
"SELECT mid from machines
WHERE ip='$ip' AND host='$host'
AND localh='$localh' AND os='$os' AND
machine_created='$machine_created' AND created_on='$created'"
);
return $sth->{'mid'};
}
sub insertReport {
my ($href) = @_;
my $ip = $href->{ip};
}
##############################################################################
#
# flushTables: ->
# flush the machines and services tables
#
##############################################################################
sub flushTables {
print "flushing tables\n";
$dbh->do("DROP TABLE machines");
$dbh->do("DROP TABLE services");
}
##############################################################################
#
# addHost: anoy hash -> scalar
# insert a host only if it is uniq
#
##############################################################################
sub addHost {
my ($href) = @_;
die "addHost: os not defined" unless defined $href->{os};
die "addHost: session not defined" unless defined $href->{session};
die "addHost: host not defined" unless defined $href->{host};
my $os = $href->{os};
my $session = $href->{session}; #a Nmap::Parser::Session object
my $host = $href->{host};
my $mid;
my $ip = $host->addr;
my $machine_created = $session->finish_time();
my $human_time = localtime($machine_created);
my $uniqhost = 0;
my $hostname = $host->hostname;
my $localh = setLocal( { ip => $ip, hostname => $host->hostname } );
my $uniq = $dbh->selectall_arrayref(
"select mid from
machines WHERE ip='$ip' AND os='$os' AND host='$hostname'
AND localh='$localh'"
);
if ( $options{test} > 1 ) {
print "uniq is $uniq\n";
}
foreach my $uniqtmp (@$uniq) {
my ($midtmp) = @$uniqtmp;
$uniqhost = 1;
$mid = $midtmp;
if ( $options{test} > 0 or $options{debug} > 1 ) {
print "non unique host\n";
print "mid shift is $mid\n";
}
}
if ( $uniqhost eq 0 ) {
if ( $colors eq 1 ) {
print BOLD GREEN "Inserting Machine\n";
}
else {
print "Inserting Machine\n";
}
$mid = insertMachine(
{ ip => $ip,
host => $hostname,
localh => $localh,
os => $os,
created => $human_time,
machine_created => $machine_created
}
);
if ( $options{test} > 0 or $options{debug} > 1 ) {
;
print "mid is $mid\n";
}
}
else {
print "Machine is already in the database\n";
print "Checking Current Services\n";
}
return ( $mid, $uniqhost );
}
##############################################################################
#
# insertServiceDB: anoy hash ->
# take information about a services from the database and insert it as
# as being down
#
##############################################################################
sub insertServiceDB {
my ($href) = @_;
die "insertServiceDB: mid not defined" unless defined $href->{mid};
die "insertServiceDB: port not defined" unless defined $href->{port};
die "insertServiceDB: state not defined" unless defined $href->{state};
die "insertServiceDB: proto not defined" unless defined $href->{proto};
die "insertSerciceDB: updated not defined"
unless defined $href->{updated};
die "insertSerciceDB: machine_updated not defined"
unless defined $href->{machine_updated};
my $mid = $href->{mid};
my $port = $href->{port};
my $state = $href->{state};
my $proto = $href->{proto};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $uniq_service = $dbh->selectall_arrayref(
"SELECT
service,version,protocol,banner
FROM services WHERE mid='$mid' AND port='$port'
AND protocol='$proto' AND state='up'
ORDER BY machine_updated DESC"
);
my ( $version, $service, $banner, $uniqservice );
foreach my $uniqtmp (@$uniq_service) {
( $service, $version, $proto, $banner ) = @$uniqtmp;
#print "service is $service\n";
}
if ( $colors eq 1 ) {
print BOLD RED "\t! Service $port:$proto $service is down\n";
}
else {
print "\t! Service $port:$proto $service is down\n";
}
insertService(
{ mid => $mid,
service => $service,
port => $port,
proto => $proto,
ver => $version,
state => $state,
banner => $banner,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
##############################################################################
#
# insertServiceScan: anoy hash ->
# take information about a services from the scan and insert it as
# as being up
#
##############################################################################
sub insertServiceScan {
my ($href) = @_;
die "insertServiceScan: host not defined" unless defined $href->{host};
die "insertServiceScan: mid not defined" unless defined $href->{mid};
die "insertServiceScan: port not defined" unless defined $href->{port};
die "insertServiceScan: state not defined" unless defined $href->{state};
die "insertServiceScan: proto not defined" unless defined $href->{proto};
die "insertServiceScan: change not defined"
unless defined $href->{change};
die "insertSerciceScan: updated not defined"
unless defined $href->{updated};
die "insertSerciceScan: machine_updated not defined"
unless defined $href->{machine_updated};
my $host = $href->{host};
my $mid = $href->{mid};
my $port = $href->{port};
my $state = $href->{state};
my $proto = $href->{proto};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $change = $href->{change};
my $service;
if ( $proto eq "tcp" ) {
$service = $host->tcp_service($port);
}
else {
$service = $host->udp_service($port);
}
my $name = "unknown name";
my $product = "unknown product";
my $version = "unknown version";
if ( defined( $service->name ) ) {
$name = $service->name;
}
if ( defined( $service->version ) ) {
$version = $service->version;
}
if ( defined( $service->product ) ) {
$product = $service->product;
}
if ( $change == 1 ) {
if ( $colors == 1 ) {
print BOLD GREEN "\tInserting Service on $port:$proto $name\n";
}
else {
print "\tInserting Service on $port:$proto $name\n";
}
}
insertService(
{ mid => $mid,
service => $name,
port => $port,
proto => $proto,
ver => $version,
state => $state,
banner => $product,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
##############################################################################
#
# cmpService: anoy hash -> scalar
# compare the service in the database and the service from the scan.
# Note:
# If the service is up the database & is not in the scan then the state is down.
# If the service is not in the database & is in the scan then the state is up.
#
##############################################################################
sub cmpService {
my ($href) = @_;
die "cmpService: host not defined" unless defined $href->{host};
die "cmpService: mid not defined" unless defined $href->{mid};
die "cmpService: port not defined" unless defined $href->{port};
die "cmpService: state not defined" unless defined $href->{state};
die "cmpService: proto not defined" unless defined $href->{proto};
die "cmpService: updated not defined" unless defined $href->{updated};
die "cmpService: machine_updated not defined"
unless defined $href->{machine_updated};
die "cmpService: db_updated not defined"
unless defined $href->{db_updated};
die "cmpService: db_machine_updated not defined"
unless defined $href->{db_machine_updated};
my $host = $href->{host};
my $mid = $href->{mid};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $state = $href->{state};
my $port = $href->{port};
my $proto = $href->{proto};
my $db_updated = $href->{db_updated};
my $db_machine_updated = $href->{db_machine_updated};
my $service;
if ( $proto eq "tcp" ) {
$service = $host->tcp_service($port);
}
elsif ( $proto eq "udp" ) {
$service = $host->udp_service($port);
}
else {
print "error in $proto\n";
exit 1;
}
my $banner_from_scan = "unknown product";
my $version_from_scan = "unknown version";
my $port_from_scan = $service->port;
my $service_name_from_scan = "unknown service";
if ( defined( $service->name ) ) {
$service_name_from_scan = $service->name;
}
if ( $options{test} eq 1 ) {
print "service name from scan is $service_name_from_scan\n";
}
if ( defined( $service->version ) ) {
$version_from_scan = $service->version;
if ( $options{test} > 2 ) {
print "version from scan is $version_from_scan\n";
}
}
if ( defined( $service->product ) ) {
$banner_from_scan = $service->product;
if ( $options{test} > 2 ) {
print "banner from scan is $banner_from_scan\n";
}
}
my ( $version_from_db, $service_name_from_db, $banner_from_db );
# note the version banner and service name are the only elements
# of the service that we can comparing
my $uniq_service = $dbh->selectall_arrayref(
"SELECT
service,version,banner FROM services
WHERE mid='$mid' AND
port='$port' AND state='$state'
AND protocol='$proto'
AND updated_on='$db_updated'
AND machine_updated='$db_machine_updated'"
);
foreach my $uniqtmp (@$uniq_service) {
my ( $nametmp, $vertmp, $bantmp ) = @$uniqtmp;
$service_name_from_db = $nametmp;
$version_from_db = $vertmp;
$banner_from_db = $bantmp;
}
if ( $options{test} > 1 ) {
print "state is $state\n";
print
"comparing service $service_name_from_db and $service_name_from_scan\n";
print "comparing version $version_from_db and $version_from_scan\n";
print "comparing banner $banner_from_db and $banner_from_scan\n";
}
if ( $diff eq "banner"
&& $version_from_db eq $version_from_scan
&& $banner_from_db eq $banner_from_scan
&& $service_name_from_db eq $service_name_from_scan )
{
print
"\t= $service_name_from_db:$port is ($version_from_db) $banner_from_db\n";
return 1;
}
elsif ($diff ne "banner"
&& $version_from_db eq $version_from_scan
&& $service_name_from_db eq $service_name_from_scan )
{
print
"\t= $service_name_from_db:$port is ($version_from_db) $banner_from_db\n";
return 1;
}
else {
if ( $colors == 1 ) {
print BOLD YELLOW
"\t! $service_name_from_db:$port is ($version_from_db) $banner_from_db\n";
}
else {
print
"\t! $service_name_from_db:$port is ($version_from_db) $banner_from_db\n";
}
if ( $service_name_from_db ne $service_name_from_scan ) {
if ( $colors == 1 ) {
print BOLD YELLOW
" Service Name was \"$service_name_from_db\" changed to \"$service_name_from_scan\"\n";
}
else {
print
" Service Name was \"$service_name_from_db\" changed to \"$service_name_from_scan\"\n";
}
}
elsif ( $version_from_db ne $version_from_scan ) {
if ( $colors == 1 ) {
print BOLD YELLOW
" Version was \"$version_from_db\" changed to \"$version_from_scan\"\n";
}
else {
print
" Version was \"$version_from_db\" changed to \"$version_from_scan\"\n";
}
}
elsif ( $diff eq 'banner' and $banner_from_db ne $banner_from_scan ) {
if ( $colors == 1 ) {
print BOLD YELLOW
" Banner was \"$banner_from_db\" changed to \"$banner_from_scan\"\n";
}
else {
print
" Banner was \"$banner_from_db\" changed to \"$banner_from_scan\"\n";
}
}
else {
print "version or banner difference\n";
}
# set time to earlier so insert works after old verison is down
$machine_updated = scalar($machine_updated);
$machine_updated -= 1;
insertService(
{ mid => $mid,
service => $service_name_from_db,
port => $port,
proto => $proto,
ver => $version_from_db,
state => 'down',
banner => $banner_from_db,
updated => $human_time,
machine_updated => $machine_updated,
}
);
return 0;
}
return 1;
}
##############################################################################
#
# setAndInsertService: anoy hash -> scalar
# store all the services in the scan into the database
#
##############################################################################
sub setAndInsertService {
my ($href) = @_;
die "setAndInsertService: mid not defined" unless defined $href->{mid};
die "setAndInsertService: proto not defined"
unless defined $href->{proto};
die "setAndInsertService: service not defined"
unless defined $href->{service};
die "setAndInsertService: updated not defined"
unless defined $href->{updated};
die "setAndInsertService: machine_updated not defined"
unless defined $href->{machine_updated};
my $mid = $href->{mid};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $service = $href->{service};
my $proto = $href->{proto};
my $state = 'up';
my $product_from_scan = "unknown product";
my $version_from_scan = "unknown version";
my $port_from_scan = $service->port;
my $name_from_scan = "unknown service";
if ( defined( $service->name ) ) {
$name_from_scan = $service->name;
}
if ( defined( $service->version ) ) {
$version_from_scan = $service->version;
}
if ( defined( $service->product ) ) {
$product_from_scan = $service->product;
}
print "Inserting Service on $port_from_scan:$proto $name_from_scan\n";
insertService(
{ mid => $mid,
service => $name_from_scan,
port => $port_from_scan,
proto => $proto,
ver => $version_from_scan,
state => $state,
banner => $product_from_scan,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
##############################################################################
#
# storeEverything: anoy hash -> scalar
# store all the services in the scan into the database
#
##############################################################################
sub storeEverything {
my ($href) = @_;
die "storeEverything: host not defined" unless defined $href->{host};
die "storeEverything: mid not defined" unless defined $href->{mid};
die "storeEverything: updated not defined"
unless defined $href->{updated};
die "storeEverything: machine_updated not defined"
unless defined $href->{machine_updated};
my $host = $href->{host};
my $mid = $href->{mid};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $state;
# $port is up in the database
# store all the services running on tcp ports
foreach ( $host->tcp_ports('open') ) {
my $state = $host->tcp_port_state($_);
if ( $options{test} eq 1 ) {
print "state is $state on port $_\n";
}
next if ( $state ne "open" );
my $service = $host->tcp_service($_);
next if ( !defined($service) );
#my $uniqservice = 1;
setAndInsertService(
{ proto => 'tcp',
service => $service,
mid => $mid,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
# store all the services running on tcp ports
foreach ( $host->udp_ports('open') ) {
my $state = $host->udp_port_state($_);
if ( $options{test} eq 1 ) {
print "in udp loop\n";
print "state is $state on port $_\n";
}
next if ( $state ne "open" );
my $service = $host->udp_service($_);
next if ( !defined($service) );
setAndInsertService(
{ proto => 'udp',
service => $service,
mid => $mid,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
return 0;
}
##############################################################################
#
# sortDB: anoy hash -> hash
# sort the database based on the time
#
##############################################################################
sub sortDB {
my ($href) = @_;
die "sortDB: mid not defined" unless defined $href->{mid};
die "sortDB: updated not defined" unless defined $href->{updated};
die "sortDB: machine_updated not defined"
unless defined $href->{machine_updated};
my $mid = $href->{mid};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my ( $port, $service, $banner, $state, $state_db );
# determines all ports that are in the database and not in the scan
# thus we assume these services went down
# may 30 added limit 1
my ( %port_db, %seen_ports, $scan_state, $scan_proto );
my $ports_db_ref = $dbh->selectall_arrayref(
"SELECT
port,state,protocol,machine_updated,updated_on FROM
services WHERE mid='$mid' ORDER BY machine_updated DESC "
);
foreach my $key (@$ports_db_ref) {
my ( $port, $state, $proto, $machine_updated, $updated ) = @$key;
if ( !$port_db{$port}{machine_updated} ) {
$port_db{$port}{machine_updated} = $machine_updated;
$port_db{$port}{updated} = $updated;
$port_db{$port}{port} = $port;
$port_db{$port}{state} = $state;
$port_db{$port}{proto} = $proto;
}
else {
#print "not less than and exists\n";
}
}
return %port_db;
}
##############################################################################
#
# setDown: anoy hash ->
# remove all services on a given protocol as the host has no ports on
# this protocol.
#
##############################################################################
sub setDown {
my ($href) = @_;
die "setDown: mid not defined" unless defined $href->{mid};
die "setDown: host not defined" unless defined $href->{host};
die "setDown: proto not defined" unless defined $href->{proto};
die "setDown: portdb not defined" unless defined $href->{portdb};
die "setDown: updated not defined" unless defined $href->{updated};
die "setDown: machine_updated not defined"
unless defined $href->{machine_updated};
my $host = $href->{host};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $mid = $href->{mid};
my $proto = $href->{proto};
my $db_ref = $href->{portdb};
my %portdb = %{$db_ref};
if ( $options{test} > 0 ) {
print "protocol is $proto\n";
}
my ( $scan_state, %seen_ports );
foreach my $port ( sort { $a cmp $b } keys %portdb ) {
#print "key is $port\n";
if ( $options{test} eq 1 ) {
print $portdb{$port}{state} . " and $port\n";
print "port db $port proto $proto\n";
}
$scan_state = "down";
if ( $options{test} eq 1 ) {
print "scan thinks the status of $port is $scan_state\n";
print "state is " . $portdb{$port}{state} . "\n";
}
if ( $scan_state eq "down"
&& $portdb{$port}{'state'} eq "up"
&& $portdb{$port}{proto}
&& $portdb{$port}{proto} eq $proto )
{
insertServiceDB(
{ mid => $mid,
port => $port,
state => $scan_state,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated
}
);
if ( $options{test} eq 1 ) {
print "pulling data about service from database\n";
}
}
}
}
##############################################################################
#
# cmpAndInsert: anoy hash ->
# add service changes to the database
#
##############################################################################
sub cmpAndInsert {
my ($href) = @_;
die "cmpAndInsert: mid not defined" unless defined $href->{mid};
die "cmpAndInsert: host not defined" unless defined $href->{host};
die "cmpAndInsert: proto not defined" unless defined $href->{proto};
die "cmpAndInsert: portdb not defined" unless defined $href->{portdb};
die "cmpAndInsert: updated not defined" unless defined $href->{updated};
die "cmpAndInsert: machine_updated not defined"
unless defined $href->{machine_updated};
my $host = $href->{host};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $mid = $href->{mid};
my $proto = $href->{proto};
my $db_ref = $href->{portdb};
my %portdb = %{$db_ref};
if ( $options{test} eq 1 or $options{debug} eq 1 ) {
print "protocol is $proto\n";
}
my ( $scan_state, %seen_ports );
foreach my $port ( sort { $a cmp $b } keys %portdb ) {
if ( $options{test} eq 1 ) {
print $portdb{$port}{state} . " and $port\n";
print "port db $port proto $proto\n";
}
my $tmp;
if ( $proto eq "tcp" ) {
$tmp = $host->tcp_port_state($port);
}
elsif ( $proto eq "udp" ) {
$tmp = $host->udp_port_state($port);
}
else {
next;
}
$seen_ports{$port} = "up";
if ($tmp) {
$scan_state = "up";
}
else {
$scan_state = "down";
}
if ( $options{test} eq 1 ) {
print "scan thinks the status of $port is $scan_state\n";
print "state is " . $portdb{$port}{state} . "\n";
}
if ( $portdb{$port}{state} eq "up"
&& $scan_state eq "up"
&& $portdb{$port}{proto}
&& $portdb{$port}{proto} eq $proto )
{
if ( $options{test} eq 1 ) {
print "states are both up\n";
print "checking versions and banners\n";
}
my $db_updated = $portdb{$port}{updated};
my $db_machine_updated = $portdb{$port}{machine_updated};
my $cmp = cmpService(
{ mid => $mid,
host => $host,
port => $port,
state => $scan_state,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated,
db_updated => $db_updated,
db_machine_updated => $db_machine_updated,
}
);
if ( $cmp eq 0 ) {
if ( $options{test} > 1 ) {
print "port is $port\n";
print "mark 1\n";
}
insertServiceScan(
{ mid => $mid,
host => $host,
port => $port,
state => $scan_state,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated,
change => $cmp,
}
);
}
else {
if ( $options{test} eq 1 ) {
print "no difference in name or version or banner\n";
}
}
}
else {
#print "scan state is $scan_state\n";
#print "database state is $port_db{$port}{'state'}\n";
if ( $scan_state eq "down"
&& $portdb{$port}{'state'} eq "up"
&& $portdb{$port}{proto}
&& $portdb{$port}{proto} eq $proto )
{
insertServiceDB(
{ mid => $mid,
port => $port,
state => $scan_state,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated
}
);
if ( $options{test} eq 1 ) {
print "pulling data about service from database\n";
}
}
elsif ($scan_state eq "up"
&& $portdb{$port}{'state'} eq "down"
&& $portdb{$port}{proto}
&& $portdb{$port}{proto} eq $proto )
{
if ( $options{test} > 1 ) {
print "port is $port\n";
print "mark 2\n";
}
insertServiceScan(
{ host => $host,
mid => $mid,
port => $port,
state => $scan_state,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated,
change => 1,
}
);
if ( $options{test} eq 1 ) {
print "pulling data about service from scan\n";
}
}
else {
if ( $portdb{$port}{proto}
&& $portdb{$port}{proto} eq $proto )
{
if ( $options{test} eq 1 ) {
print "states are both down\n";
}
}
else {
if ( $options{test} > 1 ) {
print "protocols are different\n";
}
}
}
}
chomp( $portdb{$port}{updated} );
#print "\n$port_db{$port}{port} keys is $port\n";
#print "\n$port_db{$port}{state} keys is $port\n";
#print "\n$port_db{$port}{updated} keys is $port\n";
}
# bug for seen ports on different protocols
if ( $proto eq "tcp" ) {
# handles ports that are open in the scan and don't exist in the database
foreach ( $host->tcp_ports('open') ) {
my $tmptest = $host->tcp_port_state($_);
if ( $options{test} eq 1 ) {
print "state is $tmptest\n";
}
next if ( $tmptest ne "open" );
my $port_tmp = $_;
my $state_tmp;
if ( $seen_ports{$port_tmp} && $seen_ports{$port_tmp} eq "up" ) {
if ( $options{test} eq 1 ) {
print "Port is already up\n";
}
}
else {
$state_tmp = "up";
if ( $options{test} > 1 ) {
print "inserting scan not in the database on $port_tmp\n";
print "mark 3\n";
}
insertServiceScan(
{ host => $host,
mid => $mid,
port => $port_tmp,
proto => $proto,
state => $state_tmp,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated,
change => 1,
}
);
}
}
}
else {
# handles ports that are open in the scan and don't exist in the database
foreach ( $host->udp_ports('open') ) {
my $tmptest = $host->udp_port_state($_);
if ( $options{test} eq 1 ) {
print "state is $tmptest\n";
}
next if ( $tmptest ne "open" );
my $port_tmp = $_;
my $state_tmp;
if ( $seen_ports{$port_tmp} && $seen_ports{$port_tmp} eq "up" ) {
if ( $options{test} eq 1 ) {
print "Port is already up\n";
}
}
else {
$state_tmp = "up";
if ( $options{test} > 1 ) {
print "inserting scan not in the database on $port_tmp\n";
print "mark 4\n";
}
insertServiceScan(
{ host => $host,
mid => $mid,
port => $port_tmp,
state => $state_tmp,
proto => $proto,
updated => $human_time,
machine_updated => $machine_updated,
change => 0,
}
);
}
}
}
}
##############################################################################
#
# addServices: anoy hash ->
# add service changes to the database
#
##############################################################################
sub addServices {
my ($href) = @_;
die "addServices: mid not defined" unless defined $href->{mid};
die "addServices: host not defined" unless defined $href->{host};
die "addServices: updated not defined" unless defined $href->{updated};
die "addServices: uniq not defined" unless defined $href->{uniq};
die "addServices: machine_updated not defined"
unless defined $href->{machine_updated};
my $host = $href->{host};
my $human_time = $href->{updated};
my $machine_updated = $href->{machine_updated};
my $mid = $href->{mid};
my $uniq = $href->{uniq};
my ( $port, $service, $banner, $state, $state_db );
my %port_db = sortDB(
{ host => $host,
mid => $mid,
updated => $human_time,
machine_updated => $machine_updated
}
);
# determines all ports that are in the database and not in the scan
# thus we assume these services went down
if ( $uniq eq 0 ) {
if ( $options{test} > 0 ) {
print "store everything from the scan\n";
}
storeEverything(
{ host => $host,
mid => $mid,
updated => $human_time,
machine_updated => $machine_updated
}
);
return 0;
}
my @tcp_ports = $host->tcp_open_ports();
my @udp_ports = $host->udp_open_ports();
if ( !defined( scalar(@tcp_ports) ) ) {
if ( $options{debug} > 0 or $options{test} eq 1 ) {
print "no TCP ports found\n";
}
setDown(
{ mid => $mid,
host => $host,
proto => "tcp",
portdb => \%port_db,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
else {
cmpAndInsert(
{ mid => $mid,
host => $host,
proto => "tcp",
portdb => \%port_db,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
if ( !defined( scalar(@udp_ports) ) ) {
if ( $options{debug} > 0 or $options{test} eq 1 ) {
print "no UDP ports found\n";
}
setDown(
{ mid => $mid,
host => $host,
proto => "udp",
portdb => \%port_db,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
else {
cmpAndInsert(
{ mid => $mid,
host => $host,
proto => "udp",
portdb => \%port_db,
updated => $human_time,
machine_updated => $machine_updated
}
);
}
}
##############################################################################
#
# storeData: scalar ->
# function to perform scans and insert hosts and services as needed
#
##############################################################################
sub storeData {
my $mTable = createMachinesTable($dbh);
if ( $mTable eq 0 ) {
print "creating Machines Table\n";
}
my $sTable = createServicesTable($dbh);
if ( $sTable eq 0 ) {
print "creating Services Table\n";
}
my $created_on = $np->get_session()->finish_time();
my $human_time = localtime($created_on);
for my $host ( $np->all_hosts() ) {
my $os = $host->os_sig();
my $os_scan;
if ( defined($os)
and defined( $os->osfamily )
and defined( $os->osgen ) )
{
$os_scan = $os->osfamily . " " . $os->osgen;
}
else {
$os_scan = "unknown os";
}
if ( !defined($os_scan) or $os_scan eq "" ) {
$os_scan = "unknown os";
}
print "\n--------------------------------------\n";
print "Starting Scan of " . $host->addr . "\n";
my ( $mid, $uniq ) = addHost(
{ os => $os_scan,
session => $np->get_session(),
host => $host,
created_on => $human_time,
machine_created => $created_on
}
);
addServices(
{ mid => $mid,
host => $host,
updated => $human_time,
machine_updated => $created_on,
uniq => $uniq,
}
);
print "Scan Complete for " . $host->addr . "\n";
print "--------------------------------------\n";
}
print "\n";
}
##############################################################################
#
# verify_windows: array ref ->
# verify that the windows machine isn't trying to scanning itself
# side effect: calls verify_scan and possibly quits
#
##############################################################################
sub verify_windows {
my $range = shift;
foreach (@$range) {
if ( $_ =~ m/127\.0\.0\.1/ ) {
print "Error: Win32 machines can't scan themselves.\n";
exit 1;
}
}
verify_scan();
}
##############################################################################
#
# verify_ip: anoy hash -> scalar
# determine if ip is in acceptable range
#
##############################################################################
sub verify_ip {
my ($href) = @_;
die "verify_ip: oct1 not defined" unless defined $href->{oct1};
die "verify_ip: oct2 not defined" unless defined $href->{oct2};
die "verify_ip: oct3 not defined" unless defined $href->{oct3};
die "verify_ip: oct4 not defined" unless defined $href->{oct4};
my $oct1 = $href->{oct1};
my $oct2 = $href->{oct2};
my $oct3 = $href->{oct3};
my $oct4 = $href->{oct4};
if ( $oct1 < 255 and $oct1 > 0 ) {
if ( ( $oct2 eq "*" or $oct2 eq "\* " )
or ( $oct2 == 0 )
or ( $oct2 < 256 and $oct2 > 0 ) )
{
if ( ( $oct3 eq "*" or $oct3 eq "\*" )
or ( $oct3 == 0 )
or ( $oct3 < 256 and $oct3 > 0 ) )
{
if ( ( $oct4 eq "*" or $oct4 eq "\*" )
or ( $oct4 =~ /0\/\d{1,2}/ )
or ( $oct4 < 256 and $oct4 > 0 ) )
{
return 1;
}
else {
print "fourth is $4\n" if ( $options{test} > 2 );
}
}
else {
print "third is $3\n" if ( $options{test} > 2 );
}
}
else {
print "second is $2\n" if ( $options{test} > 3 );
}
}
return 0;
}
##############################################################################
#
# verify_scan
# verifies that the nmap path is set
# side effect: quits if the nmap path is not set
#
##############################################################################
sub verify_scan {
if ( !defined($nmapPath) or $nmapPath eq "" ) {
print "Error: Nmap was not found in your path.\n";
print "Please download the latest version from\n";
print "http://www.insecure.org/nmap/download.html\n";
exit 1;
}
}
##############################################################################
#
# help ->
# display help information
# side effect: exits program
#
##############################################################################
sub help {
print "Usage: $PROG [Options] {target specification}
Target Specification:
Can pass hostnames, IP addresses, networks, etc.
Ex: microsoft.com, 192.168.0.1, 192.168.1.1/24, 10.0.0.1-254
-i --iplist <iplist> Scan using a list of IPs from a file
-x --xml <xml-file> Parse scan/info from Nmap XML file
Scan Options:
-a --args <args> Execute Nmap with args (needs quotes)
-e --extraargs <args> Add args to the default args (needs quotes)
--inter <interface> Perform Nmap Scan using non default interface
-m --moreports <ports> Add ports to scan ex: 8080 or 3306,5900
-n --nmap <path> Path to Nmap executable
-p --pingscan Ping Target then scan the host(s) that are alive
--udp Add UDP to the scan arguments
--rpc Add RPC to the scan arguments
-r --range <ports> Ports for scan [def 1-1025]
--diffbanner Parse changes of the banner
Config Options:
-d --dbconfig <config> Config for results database [def config.yaml]
--configdir <dir> Directory for the database config file
--data <file> SQLite Database override [def data.dbl]
--dir <dir> Directory for SQLite or CSV file [def . ]
General Options:
--nocolors Don't Print Colors
--test <level> Testing information
--debug <level> Debug information
-v --version Display version
-h --help Display this information
Send Comments to Joshua D. Abraham ( jabra\@ccs.neu.edu )\n";
exit;
}
##############################################################################
#
# print_version ->
# displays version
# side effect: exits program
#
##############################################################################
sub print_version {
print "$PROG version $VERSION by $AUTH\n";
exit;
}
##############################################################################
if ( @ARGV == 0 ) {
help;
exit;
}
GetOptions(
\%options,
'pingscan|p', 'scan|s', 'iplist|i=s', 'xml|x=s', 'range|r=s',
'moreports|m=s', 'nmap|n=s',
'dbconfig|d=s', 'dir=s', 'data=s', 'configdir=s', 'test=s',
'args|a=s', 'extraargs|e=s', 'udp', 'rpc', 'inter=s', 'diffbanner',
'help|h' => sub { help(); },
'version|v' => sub { print_version(); },
'nocolors' => sub { $colors = 0; },
'fruitycolors' => sub { $colors = 2; },
'debug=s',
)
or exit 1;
my $dephosts = "";
if ($options{'scan'}){
print "WARNING: --scan is deprecated\n";
print "Please use the following format: $PROG 127.0.0.1 \n";
$dephosts = $options{'scan'};
}
if ( ( $options{'iplist'} or $options{'pingscan'} )
and $options{'xml'} )
{
print "Invalid type of input\n";
exit 1;
}
if ( $options{'input'} and $options{'pingscan'} ) {
print "Conflicting type of Scan\n";
}
if ( $options{'dir'} ) {
$dir = $options{'dir'};
}
if ( $options{'configdir'} ) {
$configdir = $options{'configdir'};
}
if ( $options{'dbconfig'} ) {
my $tmpconfig;
if ( $^O eq 'MSWin32' || $^O =~ /cygwin/ ) {
$tmpconfig = $configdir . '\\' . $options{'dbconfig'};
}
else {
$tmpconfig = $configdir . "/" . $options{'dbconfig'};
}
if ( -e $tmpconfig && -r $tmpconfig ) {
$dbconfig = $tmpconfig;
}
}
chdir($dir) or die "Couldn't change to $dir directory\n";
if ( !defined($dbconfig)
or $dbconfig eq ""
or ( !-e $dbconfig or !-r $dbconfig ) )
{
print "Couldn't open $dbconfig for input\n";
exit;
}
if ( $options{'inter'} ) {
$interface = "-e " . $options{'inter'} . " ";
}
if ( $options{'nmap'} ) {
if ( -X $options{'nmap'} ) {
$nmapPath = $options{'nmap'};
}
else {
print $options{'nmap'} . " isn't executable using $nmapPath\n";
}
}
if ( $options{'iplist'} ) {
if ( -e $options{'iplist'} ) {
if ( -r $options{'iplist'} ) {
my $fh = new FileHandle("<$options{'iplist'}");
die "$options{'iplist'}:$!" unless defined $fh;
@ipRange = $fh->getlines();
chomp @ipRange;
$type = 'scan';
}
else {
print "File $options{'iplist'} isn't readable\n";
exit 1;
}
}
else {
print "File $options{'iplist'} doesn't exist\n";
exit 1;
}
}
if ( $options{'xml'} ) {
if ( -e $options{'xml'} ) {
if ( -r $options{'xml'} ) {
$xmlFile = $options{'xml'};
$type = 'file';
}
else {
print "Input File isn't readable\n";
exit 1;
}
}
else {
print "Input File doesn't exist\n";
exit 1;
}
}
if ( $options{'udp'} ) {
$scantype = $scantype . "U";
}
if ( $options{'rpc'} ) {
$scantype = $scantype . "R";
}
if ( $options{'args'} ) {
$args = "";
$scantype = "";
$args = $options{'args'};
$cargs = 'yes';
}
if ( $options{'extraargs'} ) {
$args = $args . $options{'extraargs'} . " ";
}
if ( $options{'dir'} ) {
$outputdir = $options{'dir'};
}
if ( $options{'range'} ) {
my (@ports) = split ',', $options{'range'};
foreach (@ports) {
chomp;
if ( $_ !~ /\d/ ) {
print "$_ not digit\n";
}
}
$Range = "";
for ( my $i = 0; $i < scalar(@ports); $i++ ) {
$Range .= $ports[$i];
if ( $i < scalar(@ports) - 1 ) {
$Range .= ",";
}
}
}
#@ports = @ports - 1;
if ( $options{'moreports'} ) {
my @morePorts = split ',', $options{'moreports'};
foreach (@morePorts) {
if (/(\d+)/) {
chomp;
if ( $_ =~ /\d/ ) {
$Range .= ",$_";
}
else {
print "MorePorts: Port $_ isn't between 1 and 65535\n";
exit 1;
}
}
else {
print "MorePorts: Port $_ isn't a number\n";
exit 1;
}
}
}
if ( $options{'diffbanner'} ) {
$diff = "banner";
}
my $tmp = scalar(@ARGV);
my @targets;
if ( $type ne 'file' ) {
foreach (@ARGV) {
s/\ //g;
my @args = split(',', $_);
foreach(@args){
push( @targets, $_ );
}
}
my @args = split(',', $dephosts);
foreach(@args){
push( @targets, $_ );
}
}
foreach my $host (@targets) {
if ($host) {
my $ipRange;
if ( $host =~ /[a-zA-Z]/ ) {
my $name = $host;
if ( $name eq 'localhost' ) {
$ipRange = '127.0.0.1';
}
else {
my ( $host, @addresses, $hent, $addr_ref );
if ( $hent = gethostbyname($name) ) {
$name = $hent->name(); # in case different
$addr_ref = $hent->addr_list();
@addresses = map { inet_ntoa($_) } @$addr_ref;
}
$ipRange = $addresses[0];
if ( !defined($ipRange) or $ipRange eq '' ) {
print "Invalid Ip Address being Resolved\n";
exit 1;
}
}
print "Resolved $host to $ipRange\n"
if ( $options{debug} > 3 );
$type = 'scan';
push( @ipRange, $ipRange );
}
elsif ( $host
=~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\-(\d{1,3}|\*|'*')/
)
{
my $max;
if ( $5 =~ m/\*/ ) {
$max = 255;
}
elsif ( $5 < 256 ) {
$max = $5;
}
else {
print "IP Address not in proper range\n";
exit 1;
}
if ( $4 < $5 ) {
for ( $4 .. $max ) {
if (verify_ip(
{ oct1 => $1,
oct2 => $2,
oct3 => $3,
oct4 => $_
}
) == 1
)
{
my $ip = join( ".", $1, $2, $3, $_ );
push( @ipRange, $ip );
$type = 'scan';
}
}
}
}
elsif ( $host
=~ /(\d{1,3})\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(0\/\d{1,2}|\d{1,3}|\*|'*')/
)
{
if ( $options{test} > 3 ) {
print "first is $1\n";
print "second is $2\n";
print "third is $3\n";
print "fourth is $4\n";
}
my $valid = verify_ip(
{ oct1 => $1,
oct2 => $2,
oct3 => $3,
oct4 => $4
}
);
if ( $valid == 1 ) {
$type = 'scan';
push( @ipRange, $host );
}
}
if ( !defined($host) ) {
print "IP Address not in proper range\n";
exit 1;
}
}
else {
print "Invalid IP Address\n";
exit 1;
print "scan is $host" if ( $options{debug} eq 1 );
}
}
if ( $options{'pingscan'} ) {
if ( $^O eq 'MSWin32' || $^O =~ /cygwin/ ) {
$nmapPath = "\"$nmapPath\"";
verify_windows( \@ipRange );
}
else {
verify_scan();
}
$np->parsescan( $nmapPath, "-R -sP", @ipRange );
my $livehosts = "";
for my $host ( $np->get_ips('up') ) {
if ( $livehosts eq "" ) {
$livehosts = $host;
}
else {
$livehosts = join( " ", $livehosts, $host );
}
}
if ( $livehosts eq "" ) {
print "Scanned @ipRange\n";
print "No Hosts Responding to Ping Scan\n";
exit;
}
else {
print "Live Hosts Found: $livehosts\n";
@ipRange = $livehosts;
}
}
# make sure something is passed
help() if ( $type ne 'file' and $type ne 'scan' );
if ( $type eq 'file' ) {
$np->parsefile($xmlFile);
}
elsif ( $type eq 'scan' ) {
$args = $args . $interface;
if ( $cargs eq 'no' ) {
$args = $args . $scantype . " -p $Range";
}
if ( $options{debug} > 2 or $options{test} > 0 ) {
print "nmap path is $nmapPath\n";
}
if ( $args =~ /-o(?:X|N|G)/ ) {
warn "$PROG Cannot pass option '-oX', '-oN' or '-oG'\n";
warn "Removing option\n";
$args =~ s/-o(?:X|N|G)//g;
print "args is now $args\n";
}
if ( $^O eq 'MSWin32' || $^O =~ /cygwin/ ) {
$nmapPath = "\"$nmapPath\"";
verify_windows( \@ipRange );
}
else {
verify_scan();
if ( $> ne 0 ) {
print "PBNJ Scans requires root privileges.\n";
exit 1;
}
}
if ( $options{debug} > 0 or $options{test} > 0 ) {
print "Scan Args are $args\n";
print "Scanning ";
foreach (@ipRange) { print "- $_ "; }
print "\n";
}
$np->parsescan( $nmapPath, $args, @ipRange );
}
else {
print "type error $type\n";
exit 1;
}
# only connect to the database when we need too.
if ( $type eq "scan" or $type eq "file" ) {
if ( $options{data} ) {
$db = "SQLite";
$database = $options{data};
}
else {
$datadb = YAML::LoadFile($dbconfig);
foreach my $tmp ( keys %$datadb ) {
$passwd = $$datadb{$tmp} if ( $tmp eq 'passwd' );
$user = $$datadb{$tmp} if ( $tmp eq 'user' );
$db = $$datadb{$tmp} if ( $tmp eq 'db' );
$database = $$datadb{$tmp} if ( $tmp eq 'database' );
$hostname = $$datadb{$tmp} if ( $tmp eq 'host' );
$port = $$datadb{$tmp} if ( $tmp eq 'port' );
}
}
# connection to database
if ( $db eq 'SQLite' or $db eq 'CSV' ) {
$dbh = DBI->connect(
"dbi:$db:$database",
$user, $passwd,
{ PrintError => 0,
RaiseError => 0,
AutoCommit => 1
}
)
|| die "Cannot connect: $DBI::errstr";
}
elsif ( $db eq 'mysql' ) {
my $dsn = "DBI:$db:database=$database;host=$hostname;port=$port";
$dbh = DBI->connect(
$dsn, $user, $passwd,
{ PrintError => 0,
RaiseError => 0,
AutoCommit => 1
}
)
|| die "Cannot connect: $DBI::errstr";
}
elsif ( $db eq 'Pg' ) {
my $dsn = "DBI:$db:database=$database;host=$hostname;port=$port";
$dbh = DBI->connect(
$dsn, $user, $passwd,
{ PrintError => 0,
RaiseError => 0,
AutoCommit => 1,
PrintWarn => 0
}
)
|| die "Cannot connect: $DBI::errstr";
}
else {
print "$db isn't supported\n";
}
}
storeData($dbh);
$dbh->disconnect;
__DATA__
# Config.yaml
#
# Copyright (C) 2005-2006 Joshua D. Abraham ( jabra@ccs.neu.edu )
#
# This config file is released under the terms of the GNU General
# Public License (GPL), which is distributed with this software in the
# file "COPYING". The GPL specifies the terms under which users
# may copy and use this software.
#
# PBNJ 2.0
# (P)orts (B)anners N' (J)unk
#
# Author: Joshua D. Abraham
# Date: March 15, 2006
# Updated: November 15, 2006
# Version: 2.04
#
# Configuration file for PBNJ 2.0
# YAML:1.0
#
# Config for connecting to a DBI database
# SQLite, mysql etc
db: SQLite
# for SQLite the name of the file. For mysql the name of the database
database: data.dbl
# Username for the database. For SQLite no username is needed.
user: ""
# Password for the database. For SQLite no password is needed.
passwd: ""
# Password for the database. For SQLite no host is needed.
host: ""
# Port for the database. For SQLite no port is needed.
port: ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment