I wrote my first perl code today. I know its not something to be proud but hey it works!
It runs perfectly in Linux, about windows I am not sure (let me know any feedbacks)
I had written something similar with VBS but Perl does a much much better job interacting directly with the Socket is nice! here is the VBS code.
I will still Improve this code, Ideas are welcome.
#!/usr/bin/perl
# IP scanning, Randomize, Grab Banner
# Author: Felipe Ferreira
# Date 19/08/2008
# Version: 0.6
#Imporve:
#1 scan entier subnets (OK, could also do X.X.+1.+1)
#2 call plugin scripts for each port ,21,25,80,139
use IO::Socket;
use Fcntl;
use POSIX;
use Net::Ping;
$pingok = “1”;
#EDIT HERE
$output = “openPorts.txt”;
if (!defined(@ARGV[0]) || !defined(@ARGV[1]) || !defined(@ARGV[2]))
{
print “nUsage : $0 <victim address> <port start> <port end>n”;
print “Example: $0 127.0.0.1 1 1023n”;
print “nAuthor: Felipe Ferreira nn”;
exit 1;
}
$IP = @ARGV[0];
chomp($IP);
$PS = @ARGV[1];
chomp($PS);
$PE = @ARGV[2];
chomp($PE);
my @ports = ($PS .. $PE);
#my @ports = (21,22,25,80,139);
#Shuffle the port order
shufflea( @ports );
print “Scanning IP: “, $IP, ” Port “, $PS, ” to “, $PE, “n”;
open (LIST, “>>$output”);
#Parse IPs to scan entire Range
$countIP = 1;
for my $countIP (1..254)
{
parseIP();
print $IP, “n”;
#Pinging first
ping();
if ($pingok eq “0”) {
foreach $port(@ports){
$sock = new IO::Socket::INET (PeerAddr => $IP,
PeerPort => $port,
Proto => ‘tcp’,
Timeout => 0.2);
#print “Scanning IP: $IP Port: $port n”;
if ($sock){
print “$IP $port -openn”;
print LIST “$IP | $port | openn”;
# will try to get banner
# Set socket to nonblocking.
&nonblock($sock);
print $sock “HEAD / HTTP/1.0nn”;
# Read socket.
$sock->recv($data, POSIX::BUFSIZ, 0);
# Data was read.
if (length($data))
{
$rx = 1;
$banner .= $data;
}
elsif (!length($data) && $rx == 1)
{
# Not Getting any more data.
last;
}
# Sleep for 200ms before trying a read again.
select undef, undef, undef, 0.20;
close $sock;
#Show only if banner has some value
if (defined $banner)
{
print “Banner grabbed for ip $IP port $port:n”;
print “-“x77 . “n”;
print $banner;
print “-“x77 . “nn”;
print LIST “$IP | $port | $banner”;
}
#INCREMENT
$portopen++;
$port++;
}
#CONNECTION REFUSED
else{
#print “$port -closedn”;
$portclosed++;
$port++;
}
}# end Port Loop
} # end If ping OK loop (only scan if host alive)
} # end IP loop
print “nTotal Open: “, $portopen,”n”;
print “Total Closed: “, $portclosed,”n”;
print “Total Scanned: “, scalar(@ports), “n”;
close(LIST);
### ————— SUBS —————— ###
sub shufflea {
my $deck = shift; # $deck is a reference to an array
my $i = @$deck;
while (–$i) {
my $j = int rand ($i+1);
@$deck[$i,$j] = @$deck[$j,$i];
}
}
## Sets a socket in to nonblocking operation.
sub nonblock()
{
# Define local variables.
my $sock = shift;
# Get the current descriptor flags.
my $flags = fcntl($sock, F_GETFL, 0)
or die “Can’t get flags for socket: $!n”;
# Add the O_NONBLOCK flag to the socket.
fcntl($sock, F_SETFL, $flags | O_NONBLOCK)
or die “Can’t make socket nonblocking: $!n”;
}
sub ping {
$p = Net::Ping->new(“icmp”);
if ($p->ping($IP, 2) eq 0)
{
print “Host is NOT reachablen”;
sleep(1);
$p->close();
$pingok = “1”;
#exit(0);
}
else
{
print “Host is reachablen”;
sleep(1);
$pingok = “0”;
$p->close();
}
}
#Adds one IP each time it is called and returns it
sub parseIP
{
next if $IP !~ /d+.d+.d+.d+$/; #validate
my ($o1,$o2,$o3,$o4) = split /./,$IP; #puts in Array
$IP = $o1 . “.” . $o2 . “.” . $o3 . “.” . $countIP;
$countIP++;
}