153024Sguido#!perl.exe 253024Sguido 353024Sguido# Author: Chris Grant 453024Sguido# Copyright 1999, Codetalker Communications, Inc. 553024Sguido# 653024Sguido# This script takes a firewall log and breaks it into several 753024Sguido# different files. Each file is named based on the service that 853024Sguido# runs on the port that was recognized in log line. After 953024Sguido# this script has run, you should end up with several files. 1053024Sguido# Of course you will have the original log file and then files 1153024Sguido# such as web.log, telnet.log, pop3.log, imap.log, backorifice.log, 1253024Sguido# netbus.log, and unknown.log. 1353024Sguido# 1453024Sguido# The number of entries in unknown.log should be minimal. The 1553024Sguido# mappings of the port numbers and file names are stored in the bottom 1653024Sguido# of this file in the data section. Simply look at the ports being hit, 1753024Sguido# find out what these ports do, and add them to the data section. 1853024Sguido# 1953024Sguido# You may be wondering why I haven't simply parsed RFC1700 to come up 2053024Sguido# with a list of port numbers and files. The reason is that I don't 2153024Sguido# believe reading firewall logs should be all that automated. You 2253024Sguido# should be familiar with what probes are hitting your system. By 2353024Sguido# manually adding entries to the data section this ensures that I 2453024Sguido# have at least educated myself about what this protocol is, what 2553024Sguido# the potential exposure is, and why you might be seeing this traffic. 2653024Sguido 2753024Sguido%icmp = (); 2853024Sguido%udp = (); 2953024Sguido%tcp = (); 3053024Sguido%openfiles = (); 3153024Sguido$TIDBITSFILE = "unknown.log"; 3253024Sguido 3353024Sguido# Read the ports data from the end of this file and build the three hashes 3453024Sguidowhile (<DATA>) { 3553024Sguido chomp; # trim the newline 3653024Sguido s/#.*//; # no comments 3753024Sguido s/^\s+//; # no leading white 3853024Sguido s/\s+$//; # no trailing white 3953024Sguido next unless length; # anything left? 4053024Sguido $_ = lc; # switch to lowercase 4153024Sguido ($proto, $identifier, $filename) = m/(\S+)\s+(\S+)\s+(\S+)/; 4253024Sguido SWITCH: { 4353024Sguido if ($proto =~ m/^icmp$/) { $icmp{$identifier} = $filename; last SWITCH; }; 4453024Sguido if ($proto =~ m/^udp$/) { $udp{$identifier} = $filename; last SWITCH; }; 4553024Sguido if ($proto =~ m/^tcp$/) { $tcp{$identifier} = $filename; last SWITCH; }; 4653024Sguido die "An unknown protocol listed in the proto defs\n$_\n"; 4753024Sguido } 4853024Sguido} 4953024Sguido 5053024Sguido$filename = shift; 5153024Sguidounless (defined($filename)) { die "Usage: logfilter.pl <log file>\n"; } 5253024Sguidoopen(LOGFILE, $filename) || die "Could not open the firewall log file.\n"; 5353024Sguido$openfiles{$filename} = "LOGFILE"; 5453024Sguido 5553024Sguido$linenum = 0; 5653024Sguidowhile($line = <LOGFILE>) { 5753024Sguido 5853024Sguido chomp($line); 5953024Sguido $linenum++; 6053024Sguido 6153024Sguido # determine the protocol - send to unknown.log if not found 6253024Sguido SWITCH: { 6353024Sguido 6453024Sguido ($line =~ m /\sicmp\s/) && do { 6553024Sguido 6653024Sguido # 6753024Sguido # ICMP Protocol 6853024Sguido # 6953024Sguido # Extract the icmp packet information specifying the type. 7053024Sguido # 7153024Sguido # Note: Must check for ICMP first because this may be an ICMP reply 7253024Sguido # to a TCP or UDP connection (eg Port Unreachable). 7353024Sguido 7453024Sguido ($icmptype) = $line =~ m/icmp (\d+)\/\d+/; 7553024Sguido 7653024Sguido $filename = $TIDBITSFILE; 7753024Sguido $filename = $icmp{$icmptype} if (defined($icmp{$icmptype})); 7853024Sguido 7953024Sguido last SWITCH; 8053024Sguido }; 8153024Sguido 8253024Sguido ($line =~ m /\stcp\s/) && do { 8353024Sguido 8453024Sguido # 8553024Sguido # TCP Protocol 8653024Sguido # 8753024Sguido # extract the source and destination ports and compare them to 8853024Sguido # known ports in the tcp hash. For the first match, place this 8953024Sguido # line in the file specified by the tcp hash. Ignore one of the 9053024Sguido # port matches if both ports happen to be known services. 9153024Sguido 9253024Sguido ($sport, $dport) = $line =~ m/\d+\.\d+\.\d+\.\d+,(\d+) -> \d+\.\d+\.\d+\.\d+,(\d+)/; 9353024Sguido #print "$line\n" unless (defined($sport) && defined($dport)); 9453024Sguido 9553024Sguido $filename = $TIDBITSFILE; 9653024Sguido $filename = $tcp{$sport} if (defined($tcp{$sport})); 9753024Sguido $filename = $tcp{$dport} if (defined($tcp{$dport})); 9853024Sguido 9953024Sguido last SWITCH; 10053024Sguido }; 10153024Sguido 10253024Sguido ($line =~ m /\sudp\s/) && do { 10353024Sguido 10453024Sguido # 10553024Sguido # UDP Protocol - same procedure as with TCP, different hash 10653024Sguido # 10753024Sguido 10853024Sguido ($sport, $dport) = $line =~ m/\d+\.\d+\.\d+\.\d+,(\d+) -> \d+\.\d+\.\d+\.\d+,(\d+)/; 10953024Sguido 11053024Sguido $filename = $TIDBITSFILE; 11153024Sguido $filename = $udp{$sport} if (defined($udp{$sport})); 11253024Sguido $filename = $udp{$dport} if (defined($udp{$dport})); 11353024Sguido 11453024Sguido last SWITCH; 11553024Sguido }; 11653024Sguido 11753024Sguido # 11853024Sguido # The default case is that the protocol was unknown 11953024Sguido # 12053024Sguido $filename = $TIDBITSFILE; 12153024Sguido } 12253024Sguido 12353024Sguido # 12453024Sguido # write the line to the appropriate file as determined above 12553024Sguido # 12653024Sguido # check for filename in the openfiles hash. if it exists then write 12753024Sguido # to the given handle. otherwise open a handle to the file and add 12853024Sguido # it to the hash of open files. 12953024Sguido 13053024Sguido if (defined($openfiles{$filename})) { 13153024Sguido $handle = $openfiles{$filename}; 13253024Sguido } else { 13353024Sguido $handle = "HANDLE" . keys %openfiles; 13453024Sguido open ($handle, ">>".$filename) || die "Couldn't open|create the file $filename"; 13553024Sguido $openfiles{$filename} = $handle; 13653024Sguido } 13753024Sguido print $handle "#$linenum\t $line\n"; 13853024Sguido 13953024Sguido} 14053024Sguido 14153024Sguido# close all open file handles 14253024Sguido 14353024Sguidoforeach $key (keys %openfiles) { 14453024Sguido close($openfiles{$key}); 14553024Sguido} 14653024Sguido 14753024Sguidoclose(LOGFILE); 14853024Sguido 14953024Sguido__DATA__ 15053024Sguidoicmp 3 destunreach.log 15153024Sguidoicmp 8 ping.log 15253024Sguidoicmp 9 router.log 15353024Sguidoicmp 10 router.log 15453024Sguidoicmp 11 ttl.log 15553024Sguidotcp 23 telnet.log 15653024Sguidotcp 25 smtp.log 15753024Sguidoudp 25 smtp.log 15853024Sguidoudp 53 dns.log 15953024Sguidotcp 80 http.log 16053024Sguidotcp 110 pop3.log 16153024Sguidotcp 111 rpc.log 16253024Sguidoudp 111 rpc.log 16353024Sguidotcp 137 netbios.log 16453024Sguidoudp 137 netbios.log 16553024Sguidotcp 143 imap.log 16653024Sguidoudp 161 snmp.log 16753024Sguidoudp 370 backweb.log 16853024Sguidoudp 371 backweb.log 16953024Sguidotcp 443 https.log 17053024Sguidoudp 443 https.log 17153024Sguidoudp 512 syslog.log 17253024Sguidotcp 635 nfs.log # NFS mount services 17353024Sguidoudp 635 nfs.log # NFS mount services 17453024Sguidotcp 1080 socks.log 17553024Sguidoudp 1080 socks.log 17653024Sguidotcp 6112 games.log # Battle net 17753024Sguidotcp 6667 irc.log 17853024Sguidotcp 7070 realaudio.log 17953024Sguidotcp 8080 http.log 18053024Sguidotcp 12345 netbus.log 181153877Sguidoudp 31337 backorifice.log