#!/usr/bin/perl
# =====
# Author: Karl-Heinz Fischbach
# Date: 16.05.2022
# Content: Massscan of IP-Addresses and Ports available
#
# Copyright (C) 2022 Karl-Heinz Fischbach
# This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or (a
+t your option) any later version.
# This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTAB
+ILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
# You should have received a copy of the GNU General Public License al
+ong with this program; if not, see <http://www.gnu.org/licenses/>.
#
# Changelog:
#
# Ports: 80, 443, 25, 587, 993, 5060, 5080, 7, 9, 21, 22, 23, 37, 49,
+53, 69, 79, 88, 107, 115, 119, 137, 138, 139, 143, 161, 162, 194, 199
+, 445, 464, 465, 500, 513, 514, 520, 547, 554,
# =====
use strict;
use warnings;
use utf8;
use English;
use Net::Domain qw(hostname hostfqdn hostdomain domainname);
use Net::Ping;
use Masscan::Scanner;
use Getopt::Long;
use autodie; # die if problem reading or writing a file
use Sys::Hostname;
use DateTime;
use DateTime::Format::Strptime;
use DateTime::TimeZone;
use File::Spec;
use File::Basename;
use File::Copy;
use File::Touch;
use File::ReadBackwards;
use IO::All;
use Config::IniFiles;
use Log::Log4perl qw(get_logger);
use Log::Log4perl::Config;
use Log::Log4perl::Level;
use Log::Dispatch;
# _ __ _ _ _
# \ / / (_) | | | |
# \ \ / /_ _ _ __ _ __ _| |__ | | ___
# \ \/ / _` | '__| |/ _` | '_ \| |/ _ \
# \ / (_| | | | | (_| | |_) | | __/
# \/ \__,_|_| |_|\__,_|_.__/|_|\___|
#
#
### variables block
our $av_std_ARG=1;
my $av_std_BASENAME=basename($0,".pl");
my $av_std_BIN='/usr/local/share/averlon';
my $av_std_DIRNAME=dirname($0); # gibt dann u.U. nur "." wieder
my $av_std_EXIT=0;
my $av_std_FORCE=0;
my $av_std_POSPAR;
my $av_std_RETVAL;
my $av_std_USER;
my $av_std_TMP='/tmp';
my $av_std_VERBOSE=3;
# Loglevel = 0; no logging
# Loglevel = 1; fatal
# Loglevel = 2; error
# Loglevel = 3; warn
# Loglevel = 4; info
# Loglevel = 5; debug
# Loglevel = 6; trace
our $av_std_CONFIG;
our $av_std_LOGFILE='/var/log/' . hostname() . '.log';
our $av_std_LOGGING=0;
our $av_std_STORAGE='/mytmp/';
our $av_std_TEST=0;
my $av_loc_TESTDATE;
my $av_loc_TODAY;
my $av_loc_TESTHOUR;
our $av_loc_PARAMFILE='';
my $av_loc_NAS="/mytmp";
my $av_loc_mail_CONTENT='';
my $av_loc_STORAGE;
my $av_loc_IP;
my @av_arr_PORTS;
###
### predefined objects
###
my $av_obj_DT=DateTime->today();
my $av_obj_LOGGER=undef;
my $av_obj_TMP=undef;
my $av_obj_FILE=undef;
my $av_obj_INIFILE=undef;
my $av_obj_MAIL=undef;
my @av_obj_PARTS=undef;
my $av_obj_PING=undef;
my $av_obj_XMLF=undef;
my $av_obj_MAS=undef;
my $av_obj_SCANRESULT=undef;
my $av_obj_RESULT=undef;
my $av_tmp_STRING;
my $av_tmp_FN;
my $av_tmp_FILE;
my $av_tmp_SCAN;
my $av_tmp_SCANRESULT;
my %av_hash_SCANRESULT;
my @av_arr_SCANRESULT;
my @av_arr_RESULTPORTS;
# ______ _ _
# ____| | | (_)
# |__ _ _ _ __ ___| |_ _ ___ _ __ ___
# __| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
# | | |_| | | | | (__| |_| | (_) | | | \__ \
# _| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
#
#
### functions commands block
sub av_help
{
print "Benutzung:\n";
print "xxx.pl [-h, --help] [-t, --test] [-v [0-6], --verbose [0-6]
+] [-V, --version]\n";
print "Bedeutung der Optionen:\n";
print " -h, --help := diese Information\n";
print " -l, --logging := log all output to file in /var/userlog/\
+n";
print "\tfile is stored in /var/userlog and will have job_ as pref
+ix and .log as suffix\n";
print " -v [0-6], --verbose [0-6] := verbose logging, Loglevel is
+ set to 4\n";
print " -V, --version := Version wird ausgegeben\n";
}
# _____ _ _
# __ \ | | (_)
# |__) | __ ___ _ __ __ _ _ __ __ _| |_ _ ___ _ __
# ___/ '__/ _ \ '_ \ / _` | '__/ _` | __| |/ _ \| '_ \
# | | | | __/ |_) | (_| | | | (_| | |_| | (_) | | | |
# _| |_| \___| .__/ \__,_|_| \__,_|\__|_|\___/|_| |_|
# | |
# |_|
### preparation commands block
print "alle optionen: @ARGV\n";
GetOptions (
"i|ip=s" => \$av_loc_IP, # IP-Address
"p|ports=s" => \@av_arr_PORTS, # Ports
"h|help" => \&av_help, # help
"l|logging" => \$av_std_LOGGING, # logging
"t|test" => \$av_std_TEST, # test
"v|verbose:4" => \$av_std_VERBOSE, # verbose + loglevel
)
or print ("Error in command line arguments: @ARGV");
print "hostname: ", hostname() . "\n";
( $av_std_VERBOSE > 0 ) && print "debug \$av_std_LOGGING: $av_std_LOGG
+ING\n";
( $av_std_VERBOSE > 0 ) && print "debug \$av_std_VERBOSE: $av_std_VERB
+OSE\n";
( $av_std_VERBOSE > 0 ) && print "debug \$av_std_LOGFILE: $av_std_LOGF
+ILE\n";
#
# GetOptions Parameter verarbeiten
#
if ($av_std_LOGGING)
{
$av_std_LOGFILE="/var/userlog/job_" . basename($0,".pl") . ".log";
$av_obj_FILE = File::Touch->new()->touch("$av_std_LOGFILE");
}
if ( not @av_arr_PORTS )
{
print "PORTS not defined\n";
@av_arr_PORTS = ('1-1000');
}
if ( scalar @av_arr_PORTS == 0 )
{
print "no ports given: @av_arr_PORTS\n";
exit (1);
}
###
### log4perl
### vorher muss $av_std_LOGFILE gesetzt sein
###
my $conf = q(
log4perl.rootLogger=TRACE, av_FILE, av_SCREEN
log4perl.appender.av_FILE=Log::Log4perl::Appender::File
log4perl.appender.av_FILE.filename=sub { return $main::av_std_LOGFIL
+E; }
log4perl.appender.av_FILE.mode=append
log4j.PatternLayout.cspec.U = sub { $ENV{USER} }
log4perl.appender.av_FILE.layout=PatternLayout
log4perl.appender.av_FILE.layout.ConversionPattern=%-3d{MMM} %d{d} %
+d{HH:mm:ss} %-8H %F{1}[%P]: %p %U %m%n
log4perl.appender.av_SCREEN=Log::Log4perl::Appender::Screen
log4perl.appender.av_SCREEN.stderr=0
log4perl.appender.av_SCREEN.layout=Log::Log4perl::Layout::SimpleLayo
+ut
log4perl.appender.av_SCREEN.layout.ConversionPattern = %d %m %n
);
$_=$conf;
if ( $av_std_VERBOSE == 0 ) {
s/TRACE/FATAL/;
} elsif ( $av_std_VERBOSE == 1 ) {
s/TRACE/FATAL/;
} elsif ( $av_std_VERBOSE == 2 ) {
s/TRACE/ERROR/;
} elsif ( $av_std_VERBOSE == 3 ) {
s/TRACE/WARN/;
} elsif ( $av_std_VERBOSE == 4 ) {
s/TRACE/INFO/;
} elsif ( $av_std_VERBOSE == 5 ) {
s/TRACE/DEBUG/;
} elsif ( $av_std_VERBOSE == 6 ) {
s/TRACE/TRACE/;
}
#print $_;
#$conf=$_;
Log::Log4perl::Config->utf8( 1 );
#Log::Log4perl->init("/usr/local/share/averlon/av_log4perl.conf");
Log::Log4perl->init( \$conf );
$av_obj_LOGGER = get_logger();
#
####
#### prepare variables
####
##
#$av_obj_LOGGER->trace("..."); # Log a trace message
#$av_obj_LOGGER->debug("..."); # Log a debug message
#$av_obj_LOGGER->info("..."); # Log a info message
#$av_obj_LOGGER->warn("..."); # Log a warn message
#$av_obj_LOGGER->error("..."); # Log a error message
#$av_obj_LOGGER->fatal("..."); # Log a fatal message
# __ __ _ _____
# \/ | (_) | __ \
# \ / | __ _ _ _ __ | |__) | __ ___ ___
# |\/| |/ _` | | '_ \ | ___/ '__/ _ \ / __|
# | | | (_| | | | | | | | | | | (_) | (__ _
# _| |_|\__,_|_|_| |_| |_| |_| \___/ \___(_)
#
#
$av_obj_MAS = Masscan::Scanner->new();
# host given by the command line option
$av_obj_MAS->add_host($av_loc_IP);
# set the ports given by the command line options
$av_obj_MAS->ports(\@av_arr_PORTS);
$av_obj_MAS->sudo(1);
$av_obj_MAS->verbose(1);
# now scan
$av_tmp_SCAN = $av_obj_MAS->scan;
# if result is available
if ($av_tmp_SCAN)
{
# get result from module - this then seems to be an object
$av_obj_SCANRESULT = $av_obj_MAS->scan_results;
#
# # now I need to fetch the part of scan_results from this object
# $av_obj_RESULT = %$av_obj_SCANRESULT{scan_results};
# since the scan_result is an array of values, I need to put it in
+to an array
@av_arr_SCANRESULT = @{%$av_obj_SCANRESULT{scan_results}};
# now to process this array of results
# this should contain the e.g. the ip-address of the computer scan
+ned and an array of ports found in what status ever
foreach $av_tmp_STRING ( @av_arr_SCANRESULT )
{
# print simply the ip-address
print %$av_tmp_STRING{ip} . "\n";
# now I need to put the array of ports scanned and reported as
+ an result into an array
@av_arr_RESULTPORTS = @{%$av_tmp_STRING{ports}};
# this array may have several entries for each port scanned
# now to process the array and print the results
foreach $av_tmp_STRING ( @av_arr_RESULTPORTS )
{
print "Port: " . %$av_tmp_STRING{port} . "\n";
print "Status: " . %$av_tmp_STRING{status} . "\n";
}
}
}
else {
print "scan not successful \n";
}
# ______ _ _____
# | ____| | | | __ \
# | |__ _ __ __| | | |__) | __ ___ ___
# | __| | '_ \ / _` | | ___/ '__/ _ \ / __|
# | |____| | | | (_| | | | | | | (_) | (__ _
# |______|_| |_|\__,_| |_| |_| \___/ \___(_)
#
#
### end procedure
exit (0);
anyhow, since I use a standard template for all my scripts there might be some elemtens in not at all used in the script. I will clean up later.
so far it works - but I need to add some messages if arrays are empty - means - no ports found ....when I have time - it is just for fun
|