Net::Nessus::ScanLite - This module uses NTP 1.2 fast over SSL to perform nessus attacks on given host(s).


Net-Nessus-ScanLite documentation Contained in the Net-Nessus-ScanLite distribution.

Index


Code Index:

NAME

Top

Net::Nessus::ScanLite - This module uses NTP 1.2 fast over SSL to perform nessus attacks on given host(s).

SYNOPSIS

Top

   use Net::Nessus::ScanLite;
   my $nessus = Net::Nessus::ScanLite->new(
                                host            => "some.host.net"
                                port            => 1234,
				ssl		=> 1,
				);

   $nessus->preferences( { host_expansion => 'none', safe_checks => 'yes', checks_read_timeout => 1 });
   $nessus->plugin_set("10835;10861;11808;11921;11790");

  my $addr = "10.0.0.1";
  if( $nessus->login() )
        {
        $nessus->attack($addr);
        printf("Total info's = %d\n",$nessus->total_info);
        foreach( $nessus->info_list )
                {
                my $info = $_;
                printf("Info:\nID: %s\nPort: %s\nDessc: %s\n",
                        $info->ScanID,
                        $info->Port,
                        $info->Description);
                }
        printf("Total hole's = %d\n",$nessus->total_holes);
        foreach( $nessus->hole_list )
                {
                my $info = $_;
                printf("Info:\nID: %s\nPort: %s\nDessc: %s\n",
                        $info->ScanID,
                        $info->Port,
                        $info->Description);
                }

        }
   else
        {
        die("Nessus login failed %d: %s\n",$nessus->code,$nessus->error);
        }







DESCRIPTION

Top

This module is primarily designed to run single host nessus attacks over a secure ssl connection. Because is uses the nessus NTP 1.2 protocol's "fast_login" option, it can be used in real time applications such as NetReg.

CONSTRUCTOR

Top

new ( [ OPTIONS ] )

Creates a new Net::Nessus::ScanLite object. OPTIONS are a list of key-value pairs, valid options are :

host

Host running nessusd daemon.

port

Port that the nessusd daemon is listning to.

ssl

Turn on/off using ssl to connect to nessusd. (Default: 1)

user

Admin user setup using nessus rules.

password

Password for the admin account.

ntp_proto

NTP protocol version to use when connecting. (Default: 1.2)

preferences

A hash ref of valid nessus preferences such as those in nessusd.conf. Example: preferences => { plugin_set => "10835", safe_checks => 'no' }

timeout

Timeout passed to IO::Socket when connecting the remote server. (Default: 3)

cfg ( PATH | REF )

This can be a path to an ini config file or a Config::IniFiles object.

Example: new( Cfg => "/path/to/inifile" );

Example: my $ini = Config::IniFiles->new( -file => "/path/to/inifile" ); new( Cfg => $ini );

METHODS

Top

login( [ USER, PASSWORD ] )

Performs a nessus fast login using a given or preset user/password pair. Resurns 1 upon success, sets code and error methods.

attack( IP, [,IP] )

Performs a nessus attack on a given hostname or ip address. Sets code and error methods.

plugin_set( SCALAR )

Sets the plugin set for the attack method to use. Example: $nessus->plugin_set("10835;10861;11808;11921;11790");

preferences( HASH )

Sets the preferences sent to the nessesd daemon. Useful to override defaults. Example: $nessus->preferences( { host_expansion => 'none', safe_checks => 'yes', checks_read_timeout => 1 });

ssl( [ BOOLEAN ] )

Tells the class to use ssl or not. 0 = off, 1 = on. (Default: 1) Only tested using TLSV1 see ssl_version to change this.

host ( [ HOSTNAME | IP ] )

Points the class at the server running the nessus daemon.

port ( [ PORT ] )

Points the class at the port the nessus daemon is listning to. (Default: 1241 )

user ( [ NAME ] )

Name of the account you set up using nessus-adduser

password ( [ PWD ] )

Password assigned to the account above.

ntp_version ( [ VER ] )

NTP version sent at login time. This can change results so use with care. (Default: 1.2)

ssl_version ( [ VER ] )

Version of ssl nessusd is using. I've not done much with this passed directly to IO::Socket::SSL::SSL_version

socket ( [ GLOB ] )

Returns or sets the current IO::Socket handle.

timeout ( [ VALUE ] )

Timeout sent to IO::Socket; (Default: 3)

total_holes

Returns the number of HOLES found in the scan.

total_info

Returns the number of INFO found in the scan.

holes

Returns a reference to an array of Net::Nessus::Message::HOLE objects.

info

Sane as hole but holds info.

hole_list

Returns an array of Net::Nessus::Message::HOLE objects.

info_list

Returns an array of Net::Nessus::Message::INFO objects.

holes2tmpl

Returns an array hash results suitable for use with an HTML::Template object.

The following keys are seeded for each Net::Nessus::Message objects;

port host description service proto scanid

infos2tmpl

Sane as holes2tmpl but holds info.

code

Returns the error code from last operation, non zero means error.

error

Returns an error message.

hostport

Returns the "host:port" of the server your connected to.

cfg

The path or handle of the Config::IniFiles configuration file if used.

section ( [ SECT ] )

Sets or gets the section in the ini file to get the nessus host/login infomation. (Default: nessus)

pref_section ( [ SECT ] )

Sets or gets the section in the ini file to get the nessus preferences. (Default: preferences)

ini_default ( [ SECT ] )

Sets or gets the section in the ini file to use as default in case it can't find something. (Default: defaults)

PREREQUISITES

Top

Note that this module has been tested using nessusd (Nessus) 2.0.9 for SunOS.

TODO

Top

Perhaps configuration from a .nessusrc. Could be gnarly.

ACKNOWLEDGEMENTS

Top

This class relies heavily on work done by Jochen Wiedmann's Net::Nessus bundle.

SEE ALSO

Top

IO::Socket::SSL Config::IniFiles Net::Nessus::Client Net::Nessus::Message

AUTHOR

Top

John Ballem, <jpb@brown.edu>

COPYRIGHT AND LICENSE

Top


Net-Nessus-ScanLite documentation Contained in the Net-Nessus-ScanLite distribution.

package Net::Nessus::ScanLite;

use 5.008;
use strict;
use warnings;

use IO::Socket::SSL;
use Config::IniFiles;
use Net::Nessus::Client;
use Net::Nessus::Message;


require Exporter;

our @ISA = qw(Exporter IO::Socket::SSL Net::Nessus::Client Net::Nessus::Message );

our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw( );

our $VERSION = '0.01';

sub new
        {
        my $class = shift;
	$class = ref($class) || $class;
        my %args = @_;
        my $self = bless {
                _code           => 0,
                _error          => "",
                ntp_version     => '1.2',
                host            => undef,
                port            => 1241,
                user            => undef,
                password        => undef,
                ssl_version     => 'TLSv1',
                timeout         => 1,
		ssl		=> 1,
		debug		=> 1,
                _cfg            => undef,
                _section        => 'nessus',
		_duration	=> 0,
                _prefsect	=> 'preferences',
		_defsection	=> 'defaults',
                _holes          => [],
                _info           => [],
                preferences     => {},

        },$class;
	# Handle ini config handle or path
	if( $args{Cfg} )
		{
		$self->cfg($args{Cfg});
		if( ref($self->cfg) )
                        { $self->init_cfg; }  # assume handle
                else
                        { $self->init_cfg_path; }
                }
	@{$self}{keys %args} = values %args;
        return($self);
        }

#----------------------------------------------------#
# IniFiles methods
#----------------------------------------------------#
sub init_cfg_path
        {
        my $this = shift;
        my $file = $this->cfg;
        my $cfg = new Config::IniFiles( -file => $file, -default => $this->ini_default );
        return($this->set_error(100,"Config file error for $file ($!)")) unless($cfg);
        $this->cfg($cfg);
        $this->ok("Config file $file is ok.");
        $this->init_cfg;
        }
sub init_cfg
        {
        my $this = shift;
        my $cfg = $this->cfg;
	# Get host/login defaults from nessus section override keys in main class.
        init_section($cfg,$this,$this->section);
	# Get preferences from preferences section put them under preferences. 
        init_section($cfg,$this->{preferences},$this->pref_section);
        }
sub init_section
        {
        my ($cfg,$hash,$section) = @_;
        if( $cfg->SectionExists( $section ) )
                {
                foreach( $cfg->Parameters($section)  )
                        {
                        $hash->{$_} = $cfg->val($section,$_);
                        }
                }
        }
sub pref_section
        {
        my $this = shift;
        my $key = '_prefsect';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub ini_default
        {
        my $this = shift;
        my $key = '_defsection';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }


#----------------------------------------------------#
# Nessus methods
#----------------------------------------------------#
sub plugin_set
        {
        my $this = shift;
        my $class = 'preferences';
        my $key = 'plugin_set';
        $this->preference($key,shift) if( @_ );
        return($this->preference($key));
        }
sub preferences
        {
        my $this = shift;
        my $class = 'preferences';
        $this->{$class} = shift if( @_ );
        return($this->{$class});
        }

sub preference
        {
        my ($this,$key,$value) = @_;
        my $class = 'preferences';
        return(undef) unless($key);
        $this->{$class}->{$key} = $value if($value);
        return(undef) unless($this->{$class}->{$key});
        return($this->{$class}->{$key});
        }
sub login
        {
        my $this = shift;
        my $i = 0;
        $this->user(shift) if( @_ );
        $this->password(shift) if( @_ );
        $this->__connect;
        return(0) if( $this->code );
        my $ssl = $this->socket;
        $ssl->autoflush();
        $ssl->print($this->ntp_fast);
         my $r = join(' ',$ssl->getline);
        chomp($r);
        if( $r ne $this->ntp_proto )
                {
                $this->set_error(1,"Protocol error $r");
                return(0);
                }
        $ssl->print( $this->user . "\n");
        $ssl->print( $this->password . "\n");
        $ssl->print( "CLIENT <|> NESSUS_VERSION  <|> CLIENT\n");
        $r = join(' ',$ssl->getline);
        chomp($r);
        if( $r =~ /Bad login/gis )
                {
                $this->set_error(1,"Bad login ".  $this->user);
                return(0);
                }
        return(1);
        }
sub setprefs
        {
        my $this = shift;
        my $p = "CLIENT <|> PREFERENCES <|>\n";
        $this->socket->flush;
        my $h = $this->preferences;
        foreach( sort keys %$h )
                { $p .= sprintf("%s <|> %s\n",$_,$h->{$_}); }
        $p .= " <|> CLIENT\n";
        $this->socket->print($p);
        my $msg = Net::Nessus::Message->new('socket' => $this->socket,
                                           'sender' => 'SERVER',
                                           'type' => 'PREFERENCES_ERRORS');
        }

sub __connect
        {
        my $this = shift;
	my $sock = undef;
	if( $this->ssl )
		{
        	# $IO::Socket::SSL::DEBUG = $this->{debug};
        	$sock = IO::Socket::SSL->new(
                        PeerAddr        => $this->host,
                        PeerPort        => $this->port,
                        SSL_version     => $this->ssl_version,
                        Timeout         => $this->timeout
                        )
		or $this->set_error(1,sprintf("Connect to %s failed. (%s)",$this->hostport,&IO::Socket::SSL::errstr()));	
		}
	else
		{
		$sock = IO::Socket::INET->new(
                        PeerAddr        => $this->host,
                        PeerPort        => $this->port,
                        Timeout         => $this->timeout
                        )
                or $this->set_error(2,sprintf("Connect to %s failed. ($!)",$this->hostport));      
                }
        $this->socket($sock) if($sock);
        return($this->code);
        }

sub ShowHOLE
        {
        my ($this,$msg) = @_;
        my $key = '_holes';
        push(@{$this->{$key}},$msg);
        }
sub ShowINFO
        {
        my ($this,$msg) = @_;
        my $key = '_info';
        push(@{$this->{$key}},$msg);
        }

sub total_holes
        {
        my $this = shift;
        my $key = '_holes';
        my $a = $this->{$key};
        return( scalar @$a);
        }
sub total_info
        {
        my $this = shift;
        my $key = '_info';
        my $a = $this->{$key};
        return(scalar @$a);
        }
sub holes
        {
        my $this = shift;
        my $key = '_holes';
        my $a = $this->{$key};
        return($a);
        }
sub info
        {
        my $this = shift;
        my $key = '_info';
        my $a = $this->{$key};
        return($a);
        }
sub info_list
        {
        my $this = shift;
        return(@{$this->info});
        }
sub hole_list
        {
        my $this = shift;
        return(@{$this->holes});
        }
sub holes2tmpl
        {
        my $this = shift;
        return(nessus2tmpl($this->holes));
        }
sub infos2tmpl
        {
        my $this = shift;
        return(nessus2tmpl($this->info));
        }

sub nessus2tmpl
        {
        my $list = shift;
        my $array = [];
        foreach( @$list )
                {
                my $msg = $_;
                push(@$array,
                        {
                        port            => $msg->Port,
                        host            => $msg->Host,
                        description     => $msg->Description,
                        service         => $msg->Service(),
                        proto           => $msg->Proto,
                        scanid          => $msg->ScanID,
                        });
                }
        return($array);
        }

sub ntp_fast
        {
        my $this = shift;
        return(sprintf("%s< fast_login >\n",$this->ntp_proto));
        }
sub ntp_version
        {
        my $this = shift;
        my $key = 'ntp_version';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

sub ntp_proto
        {
        my $this = shift;
        return(sprintf("< NTP/%s >",$this->ntp_version));
        }



sub attack
        {
        my ($this,$host) = @_;
	my $start = time;
        $this->setprefs;
        my @hosts = ( $host );
        my $status = $this->Attack(@hosts);
	$this->duration(time - $start);
        }
sub user
        {
        my $this = shift;
        my $key = 'user';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub password
        {
        my $this = shift;
        my $key = 'password';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub hostport
	{
	my $this = shift;
	return($this->host . ':' . $this->port);
	}
sub host
        {
        my $this = shift;
        my $key = 'host';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub port
        {
        my $this = shift;
        my $key = 'port';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

sub ssl
        {
        my $this = shift;
        my $key = 'ssl';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

# Note: Net::Nessus::Message is expecting $this->{socket} to be there
sub socket
        {
        my $this = shift;
        my $key = 'socket';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

sub ssl_version
        {
        my $this = shift;
        my $key = 'ssl_version';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub timeout
                {
        my $this = shift;
        my $key = 'timeout';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub cfg
        {
        my $this = shift;
        my $key = '_cfg';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub section
        {
        my $this = shift;
        my $key = '_section';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

sub duration
        {
        my $this = shift;
	my $key = '_duration';
	$this->{$key} = shift if( @_ );
        return($this->{$key});
        }



sub ok
        {
        my $this = shift;
        $this->error(shift) if( @_ );
        return($this->code(0));
        }

sub set_error
        {
        my ($this,$code,$msg) = @_;
        $this->error($msg);
        return($this->code($code));
        }


sub code
        {
        my $this = shift;
        my $key = '_code';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }
sub error
        {
        my $this = shift;
        my $key = '_error';
        $this->{$key} = shift if( @_ );
        return($this->{$key});
        }

# Fixes the GLOB reference when SSL.pm shuts down, recent?
sub DESTROY { $_[0]->socket->close if( $_[0]->socket ); }











	

		




# Preloaded methods go here.

1;
__END__
# Below is stub documentation for your module. You'd better edit it!