#!/usr/bin/perl -w # # Copyright (C) 2006 Joshua D. Abraham (jabra@spl0it.org) # # 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 2 of the License, or # 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 # MERCHANTABILITY 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 # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # scan.pl - simple port scanner # # use strict; use Socket; use Net::hostent; use IO::Socket::SSL; use IO::Socket; use Getopt::Long; use FileHandle; use vars qw( $PROG ); ( $PROG = $0 ) =~ s/^.*[\/\\]//; # Truncate calling path from the prog name my $AUTH = 'Joshua D. Abraham'; # author my $VERSION = '1.0'; # version my %options; my $raw = 0; my @targets; # list of all targets my $target; # current target my @ports; # list of all ports to scan my $open_ports = 0; my $scan_ports = 0; $options{verbose} = 1; $options{debug} = 0; $options{banner} = 0; ############################################################################## # # help -> # display help information # side effect: exits program # ############################################################################## sub help { print "Usage: $PROG [Options] Options: -s --scan Scan Target ex: 10.0.0.100 or Hostname -i --input Ip List of Adresses to scan -p --port TCP ports to scan (ex 22,25,80-139) -b --banner Perform banner grabbing on open ports -V --verbose Verbose information -v --version Display version -h --help Display this information Send Comments to Joshua D. Abraham ( jabra\@spl0it.org )\n"; } ############################################################################## # # print_version -> # displays version # side effect: exits program # ############################################################################## sub print_version { print "$PROG version $VERSION by $AUTH\n"; exit; } sub scan { if ( !defined($target) ) { print "no target\n"; exit; } foreach (@ports) { if ( $_ eq 443 ) { my $sslconnect = IO::Socket::SSL->new("$target:https"); if ( defined($sslconnect) ) { print "Open port $_/tcp\n" if ( $options{verbose} > 0 ); $open_ports += 1; if ( $options{banner} > 0 ) { print $sslconnect "GET / HTTP/1.0\r\n\r\n"; print <$sslconnect>; } close $sslconnect; } } else { my $connect = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $target, PeerPort => $_, Timeout => .60, Type => SOCK_STREAM, ); if ( defined($connect) ) { print "Open port $_/tcp\n" if ( $options{verbose} > 0 ); $open_ports += 1; if ( $options{banner} > 0 ) { $connect->send("GET \r\n\r\n"); print <$connect>; close $connect; } } } } } if ( @ARGV == 0 ) { help; exit; } GetOptions( \%options, 'scan|s=s', 'ports|p=s', 'iplist|i=s', 'banner|b' => sub { $options{banner} = 1; }, 'help|h' => sub { help(); }, 'version|v' => sub { print_version(); }, 'verbose|V' => sub { $options{verbose} = 1; }, ) or exit 1; if ( $options{'scan'} and $options{'iplist'} ) { help; exit; } if ( $options{'iplist'} ) { if ( -e $options{'iplist'} ) { if ( -r $options{'iplist'} ) { my $fh = new FileHandle("<$options{'iplist'}"); die "$options{'iplist'}:$!" unless defined $fh; @targets = $fh->getlines(); chomp @targets; } else { print "File $options{'iplist'} isn't readable\n"; exit 1; } } else { print "File $options{'iplist'} doesn't exist\n"; exit 1; } } if ( $options{'scan'} ) { my $ipRange; if ( $options{'scan'} =~ /[a-zA-Z]/ ) { my $name = $options{'scan'}; 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 '' ) { die "Invalid Ip Address being Resolved\n"; } print "resolved host is $ipRange\n" if ( $options{debug} > 0 ); push( @targets, $ipRange ); } else { if ( $options{'scan'} =~ m/(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)/ ) { if ( $5 eq 24 ) { for ( 1 .. 255 ) { my $tmp = "$1.$2.$3.$_"; push( @targets, $tmp ); } } } elsif ( $options{'scan'} =~ m/(\d+)\.(\d+)\.(\d+)\.\*/ ) { for ( 1 .. 255 ) { my $tmp = "$1.$2.$3.$_"; push( @targets, $tmp ); } } else { my $tmp = $options{'scan'}; push( @targets, $tmp ); } } } if ( $options{'ports'} ) { my @tmp = split( ',', $options{'ports'} ); foreach (@tmp) { if ( $_ =~ m/(\d+)\-(\d+)/ ) { for ( $1 .. $2 ) { push( @ports, $_ ); $scan_ports += 1; } } else { push( @ports, $_ ); $scan_ports += 1; } } } foreach (@targets) { $target = $_; $open_ports = 0; print "Target is $target\n"; if ( $options{debug} > 0 ) { print "ports are:\n"; foreach (@ports) { print "$_\n"; } } scan; if ( $open_ports eq 0 ) { print "Found $open_ports open ports while scanning $scan_ports\n"; } print "-------------------------------------------\n"; } exit;