#!/usr/bin/perl use strict; use warnings; use Config::Simple; use Net::Pcap qw( :functions ); use NetPacket::Ethernet; use NetPacket::IP; use NetPacket::TCP; use NetPacket::ICMP; our (%config,$pcap,@all_packet_info,@open_ports,@udp_packets,@icmp_packets); &read_config_file; &read_offline_file; &list_unique_connections; &scan_statistics; &get_open_ports; &report(); sub read_config_file() { #Read PCAP Location tie %config, "Config::Simple",'config.txt'; } sub read_offline_file() { my ($dump,$err); #File to be opened $dump = $config{capture_file_location}; #Opening the Pcap file to read $pcap = pcap_open_offline($dump, \$err) or die "Can't read '$dump': $err\n"; process_packet(); #Closing after processing the Pcap file pcap_close($pcap); } sub process_packet { my($user_data, $header, $packet) = @_; my ($ether,$ip,$icmp,$trans,%header); open(PACKET , ">pktdump") or die "Cannot open file:$!"; #Grab only selected fields from each packet while ($packet = pcap_next( $pcap, \%header )) { $ether = NetPacket::Ethernet->decode($packet); $ip = NetPacket::IP->decode($ether->{'data'}); $icmp = NetPacket::ICMP->decode($ip->{'data'}); $trans = NetPacket::TCP->decode($ip->{'data'}); print PACKET "$ip->{src_ip}:$ether->{src_mac}:$ip->{dest_ip}:$ether->{dest_mac}:$ip->{proto}:$trans->{src_port}:$trans->{dest_port}:$trans->{flags}\n"; } close(PACKET); } sub list_unique_connections() { #Get a list of all unique connections between pairs of hosts my ($packet,@split_packet,@t1,$count,%t2,@t3); @t1=""; $count=0; open(PACKET , "; close(PACKET); open(LIST , ">list_of_connections") or die "Cannot open file:$!"; print LIST "Source IP\tSource MAC\tDestination IP\tDestination MAC\n"; print LIST "-" x 64 . "\n"; foreach $packet (@all_packet_info) { @split_packet = split(":" , $packet); $t1[$count] = "$split_packet[0]\t$split_packet[1]\t$split_packet[2]\t$split_packet[3]\n"; $count++; } %t2 = map { $_, 1 } @t1; @t3 = keys %t2; print LIST @t3; close(LIST); } sub scan_statistics(){ #Get all types of scans attempted to be made by each IP Address. my (@split_packet,$packet,%stats,$syn_count,$t1,$t2,$udp_count,$icmp_count); $syn_count=0; $udp_count=0;$icmp_count=0;$udp_count=0; open(PORTS , ">>all_ports") or die "Cannot open file:$!"; foreach $packet (@all_packet_info) { @split_packet = split(":" , $packet); #Check if open ports revealed in this packet. get_open_ports($packet); #Comparing value of the TCP Flags/Protocols and deciding type of scan. if ($split_packet[7] == 2) { $stats{$split_packet[0]}{syn} += 1; } elsif ($split_packet[4] == 17) { $stats{$split_packet[0]}{udp} +=1; $udp_packets[$udp_count] = $packet; $udp_count++; } elsif ($split_packet[4] == 1) { $icmp_packets[$icmp_count] = $packet; $icmp_count++; } elsif ($split_packet[7] == 41) { $stats{$split_packet[0]}{xmas} +=1; } elsif ($split_packet[7] == 16) { $stats{$split_packet[0]}{ack} +=1; } elsif ($split_packet[7] == 4) { $stats{$split_packet[0]}{rst} +=1; } } open(STATS , ">port_scan_stats") or die "Cannot open file:$!"; for my $k (keys %stats) { print STATS "============================IP\t$k:==========================\n"; if (defined $stats{$k}{syn}) { print STATS "SYN Scan Stats\t$stats{$k}{syn}\n"; } if (defined $stats{$k}{udp}) { print STATS "UDP Scan Stats\t$stats{$k}{udp}\n"; } if (defined $stats{$k}{xmas}) { print STATS "XMAS Scan Stats\t$stats{$k}{xmas}\n"; } if (defined $stats{$k}{ack}) { print STATS "ACK Scan Stats\t$stats{$k}{ack}\n"; } if (defined $stats{$k}{rst}) { print STATS "RST Scan Stats\t$stats{$k}{rst}\n"; } } close(PORTS); close(STATS); } sub get_open_ports() { #Check if the packet contains a SYN/ACK. This means the destination host definitely has this port open. my ($packet,@split_packet,$count); $packet = shift; if (defined $packet) { @split_packet = split(":" , $packet); if ($split_packet[7] == 18) { print PORTS "$split_packet[0]".':'."$split_packet[5]\n"; } } } sub report() { #Print out the results of Open Ports after stripping all duplicates. open(PORTS , "; close(PORTS); my %t2 = map { $_, 1 } @t1; my @t3 = keys %t2; open(PORTS , ">all_ports") or die "Cannot open file:$!"; print PORTS "==================Here is a list of open ports in the form IP:Port==================\n"; print PORTS @t3; close(PORTS); }