Jun 242013

UDP scanning has always been slow. Slower than slow, slower than molasses, really fucking slow.

So when I started being interested in scanning for IPMI out in the wild, which runs on UDP 623, I first fired up trusty ol’ nmap… but bless it’s heart, it’s a cautious, robust scanner that is outrun by crippled snails on UDP scanning.

So I thought… well, most scans don’t really need a request-response-follow-up… so… well, I can just forge the requesting address… spread out collectors… then receive it in one location.  Then I thought… why am I writing a receiver?  I’ll just run tcpdump on the receiving end, and process that… and that also gives all the packets and data, not just what I think of parsing out at the time.

I wrote my “scanner” (not sure what to call it, more like a shotgun, it doesn’t really receive any data ;)) in perl, of course (below.)  I was playing with the speeds and delays – scanning a /8 or A CIDR block in 5-10 mins for a single UDP port A is pretty simple, but I never really know if I’m missing traffic – so many systems, so little time, are all the packets really working?

This might be an old technique or discredited or something… nothing is new under the sun, after all. But it worked for me. And it’s really, really simple, because it’s all the connection details and grabbing and parsing responses, and queuing up all the scans… that takes a fair bit of code – this is just a few for loops and bam.

And it sure beat the alternatives I knew about, at least, which is scanning for a year or so to do the same you can do in a day.  It’d be interesting to do a few nets simultaneously to see if any methods or speeds were better than others.  But for now….

#!/usr/bin/env perl

use Try::Tiny;
use Net::RawIP;

$src = $ARGV[0];
$dst = $ARGV[1];

die "Usage: $0 (faux?)source-IP (real)dest-class-A\n" unless $src != "" && $dst != "";

# take a breather for delay seconds
$NET_MOD = 90;
$DELAY   = 15;

$src_port = 623;
$dst_port = 623;

$torpackedo = "\x06\x00\xff\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x20\x18\xc8\x81\x00\x38\x8e\x04\xb5";

$new_socket = new Net::RawIP({udp =>{}});

# do an /8
for $two (0..255) {
   $dest = "$dst.$two";
   print "loading up the network torpedos for $dest\n";

   for $three (0..255) {
      $dest = "$dst.$two.$three";
      print "\tclearing torpedo tubes & decks for $dest\n";
      # do a /24
      for $four (0..255) {
         $dest = "$dst.$two.$three.$four";
         # print "\tpew pew => $dest\n";
            ip  => {saddr  => $src, daddr => $dest},
            udp => {source => $src_port, dest  => $dst_port, data => $torpackedo }
         try {
         } catch {
            # warn "couldn't send packet to $dest (Error: $_)\n";
#     if ($three > 0 && !($three % $NET_MOD)) {
#        print "\n...breathing for a few seconds...\n";
#        sleep($NET_MOD);
#     }
   print "\n...mopping the blood off the decks, hold on $DELAY seconds\n\n";

Sorry, the comment form is closed at this time.