#!/bin/perl #tcpdump script which detects network activity #Courtesy of Programmaton, Gestion et Consultation, Informatique, INC. #http://www.pgci.ca #Copyright (C) 1998 gilbert@pgci.ca #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; either version 2 #of the License, or (at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use Socket; use Sys::Syslog; # modify these for your particular network @ex = (53,80,113); $net = "207.253.13.5"; $line=""; $dup="127.0.0.1"; while (@ex) { $port = shift @ex; # ignore packets to defined ports and tack on the line $line="$line and not port $port"; } # all icmp packets: icmp # all udp packets: udp # TCP packets with no ACK: tcp[13]&16!=16 # fragmented IP packets: ip[6:2]&16383!=0 # IP packets with options: ip[0]!=69 # packets with X.X.X.255 destination: ip[19]=255 # packets with X.X.X.0 destination: ip[19]=255 $tcpdump="tcpdump -n -q -l icmp or udp or 'tcp[13]&16!=16' or 'ip[6:2]&16383!=0' or 'ip[0]!=69' or 'ip[19]=255' or 'ip[19]=0' and src net not $net $line"; open (TCPDUMP, "$tcpdump |") || die "couldn't execute tcpdump: $!\n"; while ($dumpline = ) { ($time, $src, $junk, $dest, $proto, $junk, $junk, $flag) = split (/ /, $dumpline); ($gmt,$micro) = split(/\./,$time); $proto =~ s/://g; if($proto eq "icmp") { ($a, $b, $c, $d) = split (/\./, $src); } if(($proto eq "tcp") || ($proto eq "udp")) { ($a, $b, $c, $d, $srcport) = split (/\./, $src); } @ip_src = ($a,$b,$c,$d); $hostname = pack("C4",@ip_src); $srcname = gethostbyaddr($hostname, &AF_INET); $ipsrc = join '.',$a,$b,$c,$d; if ($srcname eq "") { $srcname = $ipsrc; } $dest =~ s/://g; if($proto eq "icmp") { ($e, $f, $g, $h) = split (/\./, $dest); } if(($proto eq "tcp") || ($proto eq "udp")) { ($e, $f, $g, $h, $dstport) = split (/\./, $dest); } @ip_dst = ($e,$f,$g,$h); $destname = pack("C4",@ip_dst); $dstname = gethostbyaddr($destname, &AF_INET); $destip = join '.',$e,$f,$g,$h; if ($dstname eq "") { $dstname = $destip; } #we are using 1 second flood buffers $current = join '.',$gmt,$srcname,$dstname,$dstport; #we are logging to local0.notice, so don't forget to add it to syslog.conf #local0.notice /var/adm/synlog #if the packet is for our $net, and has not been seen in the past second with the same src,dst and port. if ((index($destip, $net,0) >= 0) && (index($current,$dup)<0)){ if(($proto eq "tcp") || ($proto eq "udp")) { #remove the cons keyword if you do not want it logged to the console openlog("syn.pl", "cons,pid","local0"); syslog("notice","%s:%s to %s:%s, %s\n", $srcname,$srcport,$dstname,$dstport,$proto); closelog(); } if($proto eq "icmp") { openlog("syn.pl", "cons,pid","local0"); syslog("notice","%s to %s, %s\n", $srcname,$dstname,$proto); closelog(); $dstport = 0; } $old_srcname = $srcname; $old_dstname = $dstname; $old_dstport = $dstport; $dup = join '.',$gmt,$old_srcname,$old_dstname,$old_dstport; } }