network scanner with perl + Tk

perl Tk ip scanner application
perl Tk ip scanner application

I enhanced my command line ip scanner by adding a Tk gui and adding a few more features.  Above, I am scanning a range of contiguous addresses on my home network.

It can also accept a list of hosts from a csv file.

list of hosts in csv format
list of hosts in csv format

Here are the results from the scan of the above list.

perl Tk ip scanner results using csv file input
perl Tk ip scanner results using csv file input

I am forced against my will to use Windows 10 on my PC at work.  I also lack admin privileges, so I cannot install a free ip scanner application.  I do, however, have ActivePerl installed on my box, and it has tons of modules so I can write my own utilities.

I have several classes of ip devices (routers, switches, battery chargers, etc.) that I want to monitor and have created individual csv files for each.  This simple script is highly effective at discovering devices on a subnet, or to give a quick glance at what devices on a list are online.

 
     1	#!/usr/bin/perl -w
     2	use strict;
     3	use Tkx;
     4	use Tkx::Scrolled;
     5	use Net::Ping;
     6	use Time::HiRes qw(gettimeofday);
       
     7	#main window
     8	my $mw = Tkx::widget->new(".");
     9	$mw->g_wm_title("nnmap network scanner");
    10	$mw->g_wm_geometry("800x600");
       
    11	#global vars
    12	my $ip_range = '';
    13	my $tdelay = 250; 
       
    14	#create ping object
    15	my $p = Net::Ping->new('icmp');
    16	#hi res time
    17	$p->hires();
       
    18	#a single ip address
    19	my $host;
       
    20	#up / down devices
    21	my @online_devices; 
    22	my @offline_devices; 
       
       
    23	#main content frame
    24	my $mfrm = $mw->new_ttk__frame(-padding => "5 10");
    25	$mfrm->g_grid(-column => 1, -row => 0, -sticky => "news");
    26	$mfrm->new_ttk__label(-text => "ip range")->g_grid(-column => 1, -row => 1, -sticky => "nw", -padx => 3, -pady => 1);
    27	$mfrm->new_ttk__entry(-textvariable => \$ip_range, -width => 24)->g_grid(-column => 1, -row => 2, -sticky => "nw", -padx => 3, -pady => 1);
    28	$mfrm->new_ttk__label(-text => "delay msec")->g_grid(-column => 1, -row => 3, -sticky => "nw", -padx => 3, -pady => 1);
    29	$mfrm->new_ttk__spinbox(-from => 1, -to => 900, -width => 5, -textvariable => \$tdelay)->g_grid(-column => 1, -row => 4, -sticky => "nw", -padx => 1, -pady => 2);
    30	$mfrm->new_ttk__button(-text => "scan", -command => sub {scan_net($ip_range);})->g_grid(-column => 1, -row => 5, -sticky => "nw", -padx => 1, -pady => 2);
       
    31	my $ta = $mfrm->new_tkx_Scrolled(
    32	    'text',
    33	    -scrollbars => "e",
    34	    -width => 70,
    35	    -height => 33,
    36	    -state => "normal"
    37	);
    38	$ta->g_grid(-column => 2, -row => 1, -sticky => "e", -padx => 5, -pady => 5, -rowspan => 50);
       
    39	#colors
    40	$ta->tag_configure("success", -foreground=>"white", -background=>"green");
    41	$ta->tag_configure("failure", -foreground=>"white", -background=>"red");
    42	#fonts
    43	$ta->tag_configure("lgtxt", -font =>"r18", -relief=>"raised", -underline=>1);
       
    44	sub scan_net{
    45		my $func_name = (caller(0))[3];
    46		print "Called $func_name on line ". __LINE__."\n";
    47		
    48		print "ip range: $ip_range\n";
       
    49		#parse ip range
    50		#only for class c or smaller subnets
    51		#?'s in regex account for a single ip address to scan
    52		$ip_range =~ /(\d+\.\d+\.\d+)\.(\d+)-?(\d+)?/;
    53		my $network = $1;
    54		my $start_ip = $2;
    55		my $end_ip = $3;
    56		
    57		print "end_ip: $end_ip\tstart ip: $start_ip\n";
       
    58		#account for just one ip to scan
    59		if($end_ip eq ""){
    60			$end_ip = $start_ip; 
    61		}#end if
       
    62		#convert time delay
    63		my $ping_delay = $tdelay * 0.001;
       
    64		#empty text area
    65		$ta->delete("1.0", "end");
       
    66		#get t0 for benchmark
    67		my $t0 = gettimeofday();
       
    68		#line counter
    69		my $line_n = 1; 
       
    70		for(my $i=$start_ip;$i<=$end_ip;$i++) { 71 $host = "$network.$i"; 72 print "scanning host: $host\n"; 73 #list context, returns duration 74 my ($ret, $dur, $ip) = $p->ping($host, $ping_delay);
    75			
    76			#format time
    77			$dur = sprintf("%.6f", $dur); 	
       
    78			#results
    79			if($ret){
    80				#print WHITE ON_GREEN "$host is up  latency: $dur seconds", RESET;
    81				#form response string
    82				my $response = "$host is up  $dur seconds";
    83				my $res_len = length($response); 
    84				if($res_len < 70){#fill up ta rows with color
    85					my $n_sp = 70 - $res_len; 
    86					for(my $x=0;$x<$n_sp;$x++){ 87 $response = $response." "; 88 }#end for add sp 89 }#end if 90 $response = $response."\n"; 91 #print "res_len: $res_len\n"; 92 #print "\n"; 93 $ta->insert("$line_n.0", $response);
    94				$ta->tag_add("success", "$line_n.0", "$line_n.0 lineend");
    95				push @online_devices, $host;
    96			}#end if
    97			else{
    98				my $response = "$host down";
    99				my $res_len = length($response); 
   100				if($res_len < 70){
   101					my $n_sp = 70 - $res_len; 
   102					for(my $x=0;$x<$n_sp;$x++){ 103 $response = $response." "; 104 }#end for add sp 105 }#end if 106 $response = $response."\n"; 107 #print "res_len: $res_len\n"; 108 #print WHITE ON_RED "$host down", RESET; 109 #print "\n"; 110 $ta->insert("$line_n.0", $response);
   111				$ta->tag_add("failure", "$line_n.0", "$line_n.0 lineend");
   112				push @offline_devices, $host;
   113			}#end else		
       
   114			#increment line number
   115			$line_n++;
   116		
   117		}#end for
       
   118		#results
   119		#benchmarking results
   120		my $t1 = gettimeofday();
   121		my $elapsed = $t1 - $t0; 
   122		$elapsed = sprintf("%6f", $elapsed);
   123		print "\ntime elapsed: $elapsed....\n";
   124		my $up_sz = @online_devices;
   125		my $down_sz = @offline_devices;
   126		print "$up_sz devices online\n$down_sz devices offline\n";
       
   127		#form results
   128		my $results = "Results\ntime elapsed: $elapsed\n\n$up_sz devices online\n$down_sz devices offline\n";
   129		
   130		#insert results
   131		$ta->insert("$line_n.0", $results);
   132		$ta->tag_add("lgtxt", "$line_n.0", "$line_n.0 lineend");
   133	}#end scan_net
       
   134	sub openCSV{
   135		my $func_name = (caller(0))[3];
   136		print "Called $func_name on line ". __LINE__."\n";
       
   137		my $fn = Tkx::tk___getOpenFile();
   138		print "FILE: $fn\n";
       
   139		#open csv file
   140		open HF, $fn, or die $!;
       
   141		#empty text area
   142		$ta->delete("1.0", "end");
       
   143		#ping delay
   144		my $ping_delay = $tdelay*0.001;
       
   145		#get t0 for benchmark
   146		my $t0 = gettimeofday();
       
   147		#line number counter
   148		my $line_n = 1;
       
   149		while(){
   150			my $ipdevice = $_;
   151			my @ipdev = split(',', $ipdevice); 
   152			my $description = $ipdev[1]; 
   153			$host = $ipdev[2]; 		
   154			$host =~ s/\s+//;
   155			$description =~ s/\n//;
   156			
   157			#list context, returns duration
   158			my ($ret, $dur, $ip) = $p->ping($host, $ping_delay);
       
   159			print "scanning host: $host\n";
   160			
   161			#format time
   162			$dur = sprintf("%.6f", $dur); 	
   163			
   164			my $host_desc = $host."\t\t".$description;
   165			
   166			#results
   167			if($ret){
   168				#print WHITE ON_GREEN "$host $description is up  latency: $dur seconds", RESET;
   169				#print "\n";
   170				my $response = "$host $description is up  $dur sec";
   171				my $res_len = length($response); 
   172				if($res_len < 70){#fill up ta rows with color
   173					my $n_sp = 70 - $res_len; 
   174					for(my $x=0;$x<$n_sp;$x++){ 175 $response = $response." "; 176 }#end for add sp 177 }#end if 178 $response = $response."\n"; 179 $ta->insert("$line_n.0", $response);
   180				$ta->tag_add("success", "$line_n.0", "$line_n.0 lineend");
   181				push @online_devices, $host_desc;
   182			}#end if
   183			else{
   184				#print WHITE ON_RED "$host $description down", RESET;
   185				#print "\n";
   186				push @offline_devices, $host_desc;
   187				my $response = "$host $description down";
   188				my $res_len = length($response); 
   189				if($res_len < 70){#fill up ta rows with color
   190					my $n_sp = 70 - $res_len; 
   191					for(my $x=0;$x<$n_sp;$x++){ 192 $response = $response." "; 193 }#end for add sp 194 }#end if 195 $response = $response."\n"; 196 $ta->insert("$line_n.0", $response);
   197				$ta->tag_add("failure", "$line_n.0", "$line_n.0 lineend");
   198			}#end else
       
   199			$line_n++;
   200		}#end while
   201		
   202		close HF; 
       
   203		#results
   204		#benchmarking results
   205		my $t1 = gettimeofday();
   206		my $elapsed = $t1 - $t0; 
   207		$elapsed = sprintf("%6f", $elapsed);
   208		print "\ntime elapsed: $elapsed....\n";
   209		my $up_sz = @online_devices;
   210		my $down_sz = @offline_devices;
   211		print "$up_sz devices online\n$down_sz devices offline\n";
       
   212		#form results
   213		my $results = "Results\ntime elapsed: $elapsed\n\n$up_sz devices online\n$down_sz devices offline\n";
   214		
   215		#insert results
   216		$ta->insert("$line_n.0", $results);
   217		$ta->tag_add("lgtxt", "$line_n.0", "$line_n.0 lineend");
   218	}#end openCSV
       
   219	#menu
   220	Tkx::option_add("*tearOff", 0);
   221	$mw->configure(-menu => mk_menu($mw));
   222	sub mk_menu{
   223		my $mw = shift;
   224		my $menu = $mw->new_menu();
   225		my $file = $menu->new_menu( -tearoff => 0);
   226		$menu->add_cascade(
   227			-label => "File", 
   228			-underline => 0, 
   229			-menu => $file
   230		);
   231		$file->add_command(
   232			-label => "Open CSV File", 
   233			-underline => 0, 
   234			-command => sub {openCSV();}
   235		);
   236	          $file->add_command(
   237	              -label   => "Exit",
   238	              -underline => 1,
   239	              -command => [\&Tkx::destroy, $mw],
   240	          );
   241		return $menu;
   242	}#end mk_menu
       
   243	Tkx::MainLoop();

This is one of those utilities of mine that will probably continue to grow in complexity.

internet access to a raspberry pi zero through usb

In my previous post, I set up the ability to ssh into a pi zero (not pi zero w) via usb.  Since I got that far,  I was pretty sure it was possible to give internet access to my pi zero through my laptop.  Turns out it is not that difficult.  First I set up a default route on the pi to send all packets not on the local subnet to my laptop:

sudo route add default gw 169.254.75.231

Now here is my routing table on the pi:

NAT router to give pi zero internet access
NAT router to give pi zero internet access

Next, I set up my laptop to essentially be a NAT router for the pi zero.  This is how to share my laptop’s internet connection with my pi:

modprobe iptable_nat
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE
iptables -A FORWARD -i enps0s18f2u1 -j ACCEPT

Now my pi zero has internet access.  I tested by pinging my favorite dns server 8.8.8.8.  However, when I try to ping my beloved employer’s domain, I get nowhere.  After I added a dns server to /etc/resolv.conf,  I am good to go:

pi zero internet access via usb
pi zero internet access via usb

perl + curl hyperlink parser

I go through seasons where I struggle to find ideas for projects that I am interested in.  Now is not one of those times.  I am finding it hard to make time to work on my ideas.  I like that.  I wanted to see how hard it would be to implement my own web crawler.  At the core of this idea is the ability to find all the hyperlinks in a given web page.  After some trial and error (not googling)  I have a pretty decent hyperlink finder.  My script involves getting the content using curl.  It then redirects the output of curl to a text file.  I use perl to parse the text file and a regular expression to locate the hyperlinks.  At first I was using anchor tags to find links.  It was somewhat effective, unless there were multiple links on a single  line of text.  I scrapped this approach because I used the ‘.+’ method of getting the inner contents of the anchor. It had the undesirable (but predictable) effect of mushing multiple links in a single line together.   I had more luck looking for the inner text of the href=”” attributes of the anchor tags.

Here is a hyperlink finder script.

 
#/usr/bin/perl -w
use strict;

my $url = $ARGV[0];

print "looking up $url...\n";

`curl $url > pl.txt`;

print "analyzing $url...\n";

my $wc = `wc  pl.txt`;

print $wc;

open XL, "pl.txt" or die $!;
my $nlink = 0;
while(){
	while($_ =~ /\shref="(\S+)"/g){
		$nlink++;
		print "$nlink\t$1\n";
	}#end if	
}#end while

print "num links on page: $nlink\n";

close XL;

Here is a sample output using my homepage.

hyperlink parser using cURL and perl regular expressions
hyperlink parser using cURL and perl regular expressions

oui mac address identifier utility with perl

wireshark has a good online oui lookup utility that will tell you the manufacturer of a particular network interface card based on the first six bytes of the mac address referred to as the oui (organizationally unique identifier).  nmap, at least the version on my ubuntu machine, has this feature but I am dissatisfied with it’s accuracy or lack thereof.  Being fond of perl,  I searched cpan.org before I attempted to reinvent the wheel.  I found the Net::MAC::Vendor module.  I found it to be slow, and relied on querying an online database (which didn’t work well).

I decided to write my own to augment the functionality of my own network scanner.  I downloaded a local copy of the text file provided by wireshark and wrote the following script to scan my local arp cache and tell me the manufacturer of  each device on the network.

#!/usr/bin/perl -w
use strict;

#update arp table
`arp > arp.txt`;

open(AF, '<', 'arp.txt') or die $!;

while(){
	if($_ =~ /(\d+\.\d+\.\d+\.\d+).+(..:..:..)(:..:..:..)/){
		my $match_flag = 0; 
		my $ip = $1;
		my $oui = $2;
		print "$ip\t$oui$3\t";
		reset;
		open(OU, '<', 'oui_mac.txt') or die $!; 
			#open oui file and search
			my $i=0;
			while(){
				#print "$oui \n";
				if($_  =~ /$oui/i){
					print "$_";
					$match_flag = 1;
					last;
				}#end if
				$i++;
			}#end while
		close OU;
		if($match_flag == 0){
			print "NO OUI MATCH!\n";
		}#end if
	}#end if
}#end while

close AF;

Simple and effective.

mac oui lookup tool written in perl
mac oui lookup tool written in perl

protect against wordpress xmlrpc.php exploit

goaccess has already paid off for me.  I have been checking it daily since I installed it and noticed that my most requested page was xmlrpc.php.  Tons of data was being POSTed to it.  After a quick search, I came across a tutorial for a brute-force attack to login to a wordpress site.

wordpress xmlrpc.php attack detection with goaccess
wordpress xmlrpc.php attack detection with goaccess

I immediately logged into my VPS and renamed my xmlrpc.php file, and the attacks stopped.  Thanks, goaccess.

goaccess web access log analyzer

Back when I was a freelance web designer,  I hosted most of my sites via a reseller account I had with Hostgator.  I was really pleased with the service.  They used cPanel, which in my opinion is very feature rich and easy to use.  It is the next best thing to a VPS.  Hostgator also provided the all-important awstats traffic analyzer.  I still think awstats is an extremely good access log analyzer,  parsing the log in every conceivable way and producing easy to understand graphs.

example of awstats
example of awstats

Setting up awstats on a server can be a pain, especially if you have several virtual hosts.  I just wanted something simple to check the traffic for this blog.  After contemplating writing my own analyzer, I decided to go with goaccess.  I followed this tutorial on digitalocean, and I am very pleased so far.

goaccess web access log analyzer
goaccess web access log analyzer

I manually went through parts of the access log, and obviously I have some bots from an ip address in hong kong trying to post bogus data to scripts that dont exist.  They didn’t get anything.

ip in hong kong POSTing bogus data to my webserver
ip in hong kong POSTing bogus data to my webserver

goaccess does just about everything I am interested in:  top pages, bandwidth, OS, browser, and referrers.  I highly recommend it.

pine64 as a terminal server via UART

Still working on the maker space and expanding my networking lab.  I added a cisco 1721 router with a 10-base T wan interface card and a serial 1T WIC in addition to the built-in fast ethernet interface.  I also added an old cisco 2514 with two built-in AUI (ethernet) interfaces and two serial interfaces.

Cisco 1721 and 2514 routers
Cisco 1721 and 2514 routers

The computer at my work bench doesn’t have a serial interface that I can connect to the routers’ console interfaces, and I was too lazy to go get my usb to serial converter out of my van; especially when I had my pine64 nearby with an rs-232 to TTL converter.  I fired up my pine64 and connected the rs-232 to TTL converter to the UART pins on the pi-2-bus.  The converter and the console port of the routers are both DTE devices, so a null-modem (serial crossover) cable / adapter are necessary.  I hooked it all up like so:

Pine64 as a simple terminal server
Pine64 as a simple terminal server

Here you can see I have my pine64 connected to a cisco console cable via a null modem adapter and a gender changer.  First I had to ssh into the pine.   Now to install screen on my pine64.


sudo apt-get install screen
sudo screen /dev/ttyS2 9600

The second command tells screen to use ttyS2, which is the serial interface that is on the pi-2 bus and use 8-N-1 and 9600 baud. Now I’m in.

cisco router IOS command line interface
cisco router IOS command line interface

getting started with snort

 snort IPS
snort IPS

Wireshark is great.  Personally, I prefer tcpdump from the command line with my own scripts to extract specific results I am looking for.  If you want to become dangerous with tcpdump, you should check out Daniel Miessler’s tutorial on the subject and start experimenting.  That being said, my ideas of how to see what is actually going on in networks that I manage are constrained to my limited knowledge base, experience and imagination, and I am sure it is not terribly hard to outsmart me:

  • is my LAMP server getting hit with  SQL injection attacks?
  • is there some (unknown to me) vulnerability to a package on my system that I am not aware of yet?
  • is a device on my network compromised by some type of malware?
  • is the NSA all up in my biz?
  • am I getting port-scanned?  If so, by whom? What are they looking for?
  • is someone trying really hard with nmap scripts or other penetration tools to hack me?
  • some kinds of attacks I can’t even fathom?

I’m pretty sure at this point, the answer to all of these questions is YES!  Well, I want to know what the heck is going on, and even with decent tcpdump skills, I am not sure how to tell if, for instance, I am being hit with an OS detection scan or something like that.  Snort is the perfect tool for problems like this.

Snort sniffer mode

Snort’s sniffer mode is pretty cool.

sudo snort -i enp1s0 -dev

This command will basically show every frame on the wire whether IPv4, IPv6, et. al,  with the hex and ascii output to the console.  Here is the output from this command:

snort sniffer mode
snort sniffer mode

If I just want to see frames moving on my LAN in this manner, snort is definitely not my tool of choice; tcpdump is.  However, in sniffer mode, I can capture and log network traffic in binary  (which is incredibly fast) and analyze it later.  But, I want to be alerted about intrusions…..

Snort Network Intrusion Detection Mode

This is what I think makes snort special.  I installed snort as an NIDS on a few machines in my lab by following this awesome turorial. I intend to attack my snort machines and post the results soon.

ethical uses of nmap: scanning your home network

I routinely monitor the devices on my home network for many reasons:

  • did the kids really turn off their phones / tablets at night when I told them to?
  • has someone hacked my wifi?
  • are my routers / switches up and running?
  • are my home servers up?
  • what IP address did the device I just plugged in get from the my ISP’s router?

While there are many tools at my disposal for any of these issues, nmap is usually where I start.  While one could easily use nmap for nefarious purposes,  I focus on penetration testing networks / devices that belong to me like my home network, VPS’s that I lease, and my networking lab.  My ISP actually forbids port scanning in my terms of service, so I steer clear of doing any port scanning from home

I just plugged in my new pine64 running debian into my home network, and wanted to know the IP address so I could ssh into it.  To discover this, I did a ‘before’ scan of my network to see what was online.

nmap -T5 192.168.0.2-51

This tells nmap to scan the specified address range, and to make it quick.  Here are the results.

Starting Nmap 7.01 ( https://nmap.org ) at 2018-11-21 22:20 CST
Warning: 192.168.0.13 giving up on port because retransmission cap hit (2).
Warning: 192.168.0.8 giving up on port because retransmission cap hit (2).
Warning: 192.168.0.10 giving up on port because retransmission cap hit (2).
Warning: 192.168.0.9 giving up on port because retransmission cap hit (2).
Warning: 192.168.0.12 giving up on port because retransmission cap hit (2).
Warning: 192.168.0.2 giving up on port because retransmission cap hit (2).
Nmap scan report for 192.168.0.2
Host is up (0.0037s latency).
Not shown: 733 closed ports, 266 filtered ports
PORT STATE SERVICE
62078/tcp open iphone-sync

Nmap scan report for 192.168.0.5
Host is up (0.00031s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh

Nmap scan report for 192.168.0.7
Host is up (0.00018s latency).
Not shown: 991 closed ports
PORT STATE SERVICE
21/tcp open ftp
25/tcp open smtp
80/tcp open http
110/tcp open pop3
139/tcp open netbios-ssn
445/tcp open microsoft-ds
995/tcp open pop3s
3128/tcp open squid-http
3306/tcp open mysql

Nmap scan report for 192.168.0.8
Host is up (0.0039s latency).
Not shown: 694 closed ports, 304 filtered ports
PORT STATE SERVICE
49153/tcp open unknown
62078/tcp open iphone-sync

Nmap scan report for 192.168.0.9
Host is up (0.018s latency).
Not shown: 646 closed ports, 351 filtered ports
PORT STATE SERVICE
49152/tcp open unknown
49154/tcp open unknown
62078/tcp open iphone-sync

Nmap scan report for 192.168.0.10
Host is up (0.00027s latency).
Not shown: 790 closed ports, 203 filtered ports
PORT STATE SERVICE
21/tcp open ftp
23/tcp open telnet
80/tcp open http
515/tcp open printer
631/tcp open ipp
7443/tcp open oracleas-https
9100/tcp open jetdirect

Nmap scan report for 192.168.0.11
Host is up (0.011s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh

Nmap scan report for 192.168.0.12
Host is up (0.0020s latency).
Not shown: 671 closed ports, 328 filtered ports
PORT STATE SERVICE
62078/tcp open iphone-sync

Nmap scan report for 192.168.0.13
Host is up (0.0028s latency).
Not shown: 569 filtered ports, 430 closed ports
PORT STATE SERVICE
62078/tcp open iphone-sync

Nmap done: 50 IP addresses (9 hosts up) scanned in 32.16 seconds

Here I can see that my LAMP server is up, a few iPhones, my printer, and a few PC’s.  Now, I turn on the pine64 and rescan.

BOOYizzAH!  A new device at 192.168.0.16 with port 22 ssh open.

Nmap scan report for 192.168.0.16
Host is up (0.00032s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
22/tcp open ssh

using namp for OS detection

The OS detection feature is pretty awesome.  Here, I scan  a cisco 2940 ethernet switch.


nmap -vv -T5 -A 192.168.0.200

Below is a portion of the output of this command.  It correctly guesses a cisco device (easily ascertained by the OUI section of the MAC address), specifically a 2900 series switch running IOS 12.x.

PORT STATE SERVICE REASON VERSION
23/tcp open telnet syn-ack ttl 255 Cisco router telnetd
80/tcp open http syn-ack ttl 255 Cisco IOS http config
| http-auth:
| HTTP/1.0 401 Unauthorized
|_ Basic realm=level 15 access
| http-methods:
|_ Supported Methods: GET POST
|_http-title: Authorization Required
MAC Address: 00:14:XX:XX:XX:XX (Cisco Systems)
Device type: switch
Running: Cisco IOS 12.X
OS CPE: cpe:/o:cisco:ios:12.1
OS details: Cisco 2900-series or 3700-series switch (IOS 12.1)
TCP/IP fingerprint:
OS:SCAN(V=7.01%E=4%D=11/21%OT=23%CT=1%CU=41341%PV=Y%DS=1%DC=D%G=N%M=00141C%
OS:TM=5BF63311%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%CI=I%TS=
OS:U)OPS(O1=M5B4%O2=M578%O3=M280%O4=M218%O5=M218%O6=M109)WIN(W1=1020%W2=102
OS:0%W3=1020%W4=1020%W5=1020%W6=1020)ECN(R=Y%DF=N%T=FF%W=1020%O=M5B4%CC=N%Q
OS:=)T1(R=Y%DF=N%T=FF%S=O%A=S+%F=AS%RD=0%Q=)T2(R=Y%DF=N%T=FF%W=0%S=A%A=S%F=
OS:AR%O=%RD=0%Q=)T3(R=Y%DF=N%T=FF%W=1020%S=O%A=S+%F=AS%O=M5B4%RD=0%Q=)T4(R=
OS:Y%DF=N%T=FF%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=N%T=FF%W=0%S=A%A=S+%F=A
OS:R%O=%RD=0%Q=)T6(R=Y%DF=N%T=FF%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=N%T=F
OS:F%W=0%S=A%A=S%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=FF%IPL=38%UN=0%RIPL=G%RID=G%
OS:RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=S%T=FF%CD=S)

Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: IOS; Devices: router, switch; CPE: cpe:/o:cisco:ios

decoding ripv2 packets with Packetor

I regularly read Daniel Miessler’s blog and his unsupervised learning newsletter.  He recently mentioned a website called Packetor which is a free online packet analyzer.

I captured some ripv2 packets on my lab network using tcpdump, and filtered for destination address 224.0.0.9, which is the multicast IP address for ripv2 routers.  Ripv2 routers blast their entire routing table to this multicast address periodically (usually every 30 seconds).  I captured the packets like so:

sudo tcpdump -i eno1 dst 224.0.0.9 -# -XX | tee ripd.txt

This command captures ripv2 packets, numbers them, displays them in hex and ascii, and pipes the output to a text file.  Here is some of the tcpdump output.

 3 21:31:38.536458 IP 192.168.0.5 > rip2-routers.mcast.net: igmp v2 report rip2-routers.mcast.net
0x0000: 0100 5e00 0009 e411 5b40 6fa8 0800 46c0 ..^.....[@o...F.
0x0010: 0020 0000 4000 0102 4361 c0a8 0005 e000 ....@...Ca......
0x0020: 0009 9404 0000 1600 09f6 e000 0009 ..............
4 21:31:44.808348 IP 192.168.0.5 > rip2-routers.mcast.net: igmp v2 report rip2-routers.mcast.net
0x0000: 0100 5e00 0009 e411 5b40 6fa8 0800 46c0 ..^.....[@o...F.
0x0010: 0020 0000 4000 0102 4361 c0a8 0005 e000 ....@...Ca......
0x0020: 0009 9404 0000 1600 09f6 e000 0009 ..............
5 21:31:55.606022 IP 192.168.0.201.route > rip2-routers.mcast.net.route: RIPv2, Response, length: 64
0x0000: 0100 5e00 0009 0014 1c61 b1b4 0800 45c0 ..^......a....E.
0x0010: 005c 0000 0000 0211 1657 c0a8 00c9 e000 .\.......W......
0x0020: 0009 0208 0208 0048 ea3d 0202 0000 0002 .......H.=......
0x0030: 0000 0a0a 0a32 ffff ffff 0000 0000 0000 .....2..........
0x0040: 0001 0002 0000 0a14 1400 ffff ff00 0000 ................
0x0050: 0000 0000 0001 0002 0000 0a32 3206 ffff ...........22...
0x0060: ffff 0000 0000 0000 0002 ..........
6 21:32:21.206294 IP 192.168.0.201.route > rip2-routers.mcast.net.route: RIPv2, Response, length: 64
0x0000: 0100 5e00 0009 0014 1c61 b1b4 0800 45c0 ..^......a....E.
0x0010: 005c 0000 0000 0211 1657 c0a8 00c9 e000 .\.......W......
0x0020: 0009 0208 0208 0048 ea3d 0202 0000 0002 .......H.=......
0x0030: 0000 0a0a 0a32 ffff ffff 0000 0000 0000 .....2..........
0x0040: 0001 0002 0000 0a14 1400 ffff ff00 0000 ................
0x0050: 0000 0000 0001 0002 0000 0a32 3206 ffff ...........22...
0x0060: ffff 0000 0000 0000 0002 ..........

This is great and all, but I wanted to see like some human-readable routing table information or something. That is where packetor came in.

I pasted the hex output of a frame from the router at 192.168.0.201 and got much more detailed information about the routing table ->

I’m impressed.   Definitely going into ctrl+d.