Saturday, February 14, 2009

Simple UDP port scanner in perl - ICMP unreachable

One way to scan the open UDP ports on a remote machine, Is to send an UDP packets to its ports and listen the ICMP "destination unreachable" responses, If we received that message, its mean that the port we have tried to send to is currently close.


In the following Perl code I will send an UDP packet to each port, and if I won't receive the ICMP destination unreachable packet I will assume the scanned port is open:


#!/usr/bin/perl

use Net::Ping;
use IO::Select;
use IO::Socket::INET;

# IP address to scan
my $ip = '10.0.0.1';

# First we will send a ping to make sure the scanned host is exist
my $p = Net::Ping->new( "icmp", 1, 64 );
if ( $p->ping($ip) ) {
print "$ip answered ping , Start scanning ....\n";
} else {
print "$ip did not answer ping\n";
exit 5;
}
# Time to wait for the "destination unreachable" package.
my $icmp_timeout=2;
# Create the icmp socket for the "destination unreachable" packages
$icmp_sock = new IO::Socket::INET(Proto=>"icmp");
$read_set = new IO::Select();
$read_set->add($icmp_sock);

# Buffer to send via UDP
my $buf="hello";

# Scan all the ports .....
for ( $i=1 ; $i <= 65535 ; $i++ ) { # Create UDP socket to the remote host and port
my $sock = new IO::Socket::INET(PeerAddr=>$ip,
PeerPort=>$i,
Proto=>"udp");
# Send the buffer and close the UDP socket.
$sock->send("$buf");
close($sock);

# Wait for incoming packets.
($new_readable) = IO::Select->select($read_set, undef, undef, $icmp_timeout);
# Set the arrival flag.
$icmp_arrived = 0;
# For every socket we had received packets (In our case only one - icmp_socket)
foreach $socket (@$new_readable)
{
# If we have captured an icmp packages, Its probably "destination unreachable"
if ($socket == $icmp_sock)
{
# Set the flag and clean the socket buffers
$icmp_arrived = 1;
$icmp_sock->recv($buffer,50,0);
}
}
if ( $icmp_arrived == 0 )
{
print "Open UDP port : $i\n";
}
}
# Close the icmp sock
close($icmp_sock);
print "End !!\n";


2 comments:

Unknown said...

hi,

i reviewed your code
and test result wasn't alike what you told..

this program always returns
UDP PORT open..

is there something wrong or anything else?

thank you for your answer in advance..

Ricardo V. Oliveira said...

That's because the checking is negative, i.e. it assumes the port is open if it does not receive a ICMP port unreachable, which may not happen if the packet crosses firewalls.