playing with ruby

i started playing around with ruby recently.
one of the first things i figured i’d do is muck about with sockets.
it turns out that’s brain dead easy with ruby, which i was happy to discover.
here’s a quick and dirty whois client i whipped up as a way to learn the syntax etc.

require "socket"

rr = Array.new
whoisrv = "whois.arin.net"
port = "43"
qry = "208.105.198.137"

s = TCPSocket.open(whoisrv, port)
s.puts(qry)
while rr = s.gets
   puts rr
end
s.close

Packet Flooder Script

I considered for a while whether or not to post this here.
Ultimately I decided to go ahead and do it for a couple of reasons:

1. This isn’t anything special, there are myriad similar (or better) tools out there that do the same thing.
2. It is actually useful for testing IP stacks on various devices.

And so, here it is, a perl based packet flood script.
It’s got a few things that make it interesting:

1. Ports are chosen randomly for TCP and UDP.
2. ICMP type codes are chosen randomly.
3. TCP flags are chosen randomly.
4. The fragment bit is un/set randomly.

#!/usr/bin/perl -w
# =================================================
# simple network flooder script
# takes type of flood (icmp, tcp, udp) as param
# optionally takes dest ip and packet count
# =================================================
my $VERSION = 0.5;
# =================================================
use strict;
use Net::RawIP;

my $flood = shift or &usage();
my $dstip = shift || '127.0.0.1';
my $pktct = shift || 100;

&icmpflood($dstip, $pktct) if $flood =~ 'icmp';
&tcpflood($dstip, $pktct) if $flood =~ 'tcp';
&udpflood($dstip, $pktct) if $flood =~ 'udp';

sub icmpflood() {
   my($dstip, $pktct, $code, $type, $frag);
   $dstip = shift;
   $pktct = shift;

   print "nstarting flood to $dstipn";
   for(my $i=0; $i <= $pktct; $i++) {

      $code = int(rand(255));
      $type = int(rand(255));
      $frag = int(rand(2));

      my $packet = new Net::RawIP({
         ip => {
            daddr => $dstip,
            frag_off => $frag,
         },
         icmp => {
            code => $code,
            type => $type,
         }
      });

      $packet->send;
      print "sent icmp $type->$code, frag: $fragn";
   }
   print "nflood completenn";
}

sub tcpflood() {
   my($dstip, $pktct, $sport, $dport, $frag, $urg, $psh, $rst, $fin,
$syn, $ack);
   $dstip = shift;
   $pktct = shift;
   print "nstarting flood to $dstipn";
   for(my $i=0; $i <= $pktct; $i++) {

      $sport = int(rand(65535));
      $dport = int(rand(65535));
      $frag = int(rand(2));
      $urg = int(rand(2));
      $psh = int(rand(2));
      $rst = int(rand(2));
      $fin = int(rand(2));
      $syn = int(rand(2));
      $ack = int(rand(2));

      my $packet = new Net::RawIP({
         ip => {
            daddr => $dstip,
            frag_off => $frag,
         },
         tcp => {
            source => $sport,
            dest => $dport,
            urg => $urg,
            psh => $psh,
            rst => $rst,
            fin => $fin,
            syn => $syn,
            ack => $ack,
         }
      });

      $packet->send;
      print "sent tcp packet from $sport to $dport, frag: $frag, psh:
$psh, rst: $rst, fin: $fin, syn: $syn, ack: $ackn";
   }
   print "nflood completenn";
}

sub udpflood() {
   my($dstip, $pktct, $sport, $dport, $frag);
   $dstip = shift;
   $pktct = shift;

   print "nstarting flood to $dstipn";
   for(my $i=0; $i <= $pktct; $i++) {

      $sport = int(rand(255));
      $dport = int(rand(255));
      $frag = int(rand(2));

      my $packet = new Net::RawIP({
         ip => {
            daddr => $dstip,
            frag_off => $frag,
         },
         udp => {
            source => $sport,
            dest => $dport,
         }
      });

      $packet->send;
      print "sent udp packet from $sport to $dport, frag: $fragn";
   }
   print "nflood completenn";
}

sub usage() {
   print "
need to set a valid flood type (one of icmp, tcp, udp)
optionally set dest ip and packetcount

example:

   $0 [tcp udp icmp]  nn";
   exit 0;
}

Handy Python Snippets

Obtaining the local IP address (getip.py)

#!/usr/bin/env python

def getip():
 from socket import gethostbyaddr, gethostname
 theip = gethostbyaddr(gethostname())[2][0]
 return theip

Obtaining the local MAC address (getmac.py)

#!/usr/bin/env python

def getmac():
 import sys, os
 if sys.platform == 'win32':
  for line in os.popen("ipconfig /all"):
   if line.lstrip().startswith('Physical Address'):
    mac = line.split(':')[1].strip().replace('-',':')
    break
 else:
  for line in os.popen("/sbin/ifconfig"):
   if line.find('Ether') > -1:
    mac = line.split()[4]
    break
 return mac

Putting these together (test.py)

#!/usr/bin/env python
import getmac, getip

myip = getip.getip()
mymac = getmac.getmac()

print mymac + " has address: " + myip