# Simple forking port scanner # By: magikh0e use strict; use warnings; use IO::Socket::INET; use Getopt::Std; my $opts = 'hvdt:p:s:e:'; my %opt; getopts( "$opts", \%opt ); sub help() { print < : Target IP or hostname -p : Protocol to scan on (default: tcp) -s : Starting port (default: 1) -e : End port (default: 65535) $0 -t 127.0.0.1 -p tcp -s 1 -e 80 EOF exit; } help() if $opt{h} || !%opt; $| = 1; my $host = $opt{t}; my $protocol = $opt{p}; my $port1 = $opt{s}; my $port2 = $opt{e}; my $parent = 0; my @kids = (); $protocol = 'tcp' unless $protocol; $port1 = 1 unless $port1; $port2 = 65535 unless $port2; if ($opt{t}) { print "Scanning: $host on ($protocol) Ports: [$port1-$port2]\n"; my $port; FORK: for ($port=$port1; $port<=$port2; $port++) { my $oldpid = $$; my $pid = fork; if (not defined $pid) { if ($! =~ /Resource temporarily unavailable/) { &DoKill; $port --; } else { die "Can't fork: $!\n"; } } elsif ($pid == 0) { $parent = $oldpid; @kids = (); last FORK; } else { push @kids, $pid; } } if ($parent) { my $socket; my $protocol; my $success = eval { $socket = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, Proto => $protocol) }; if ($success) { print "Port $port: Open\n"; shutdown($socket, 2); } exit 0; } else { &DoKill;} } sub DoKill { while (my $kid = shift @kids) { waitpid $kid, 0; } }