I have written a perl script that churns through tcpdump files and generates reports on the data. When I do a security audit, one thing I do is a 24 hour packet capture, where I plug my Linux box into the core switch and mirror all traffic on the core to my linux box where I run: tcpdump -n -q >capture.file Then I run dumpscan.pl capture.file I gather 24 hours of data, which sometimes is several hundred gigs of data, then I run it through my perl script which generates my reports. I take these raw traffic reports and plug them into excel where I generate these charts and graphs. (See Attached) I also tossed these files up to my site - http://www.appiant.net/audit so anyone can download them. If you use it, and you like it, drop me a note. Joel ----- Original Message ----- From: Aaron Gray To: Full Disclosure Sent: Sunday, June 18, 2006 5:01 PM Subject: [Full-disclosure] tcpdump logfile viewer Are there any viewers for tcpdump log files ? 1) a) On Linux b) on Windows c) as an HTML server 2) a) text dump file b) binary dump file Aaron ------------------------------------------------------------------------------ _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/
Attachment:
Traffic-Types.gif
Description: GIF image
# Go back and right click and "SAVE AS" - Save the dumpscan.txt as DUMPSCAN.PL # # dumpscan.pl: input tcpdump file (must be of form -n -q OR -nn -q) and extract # relevant data. Creates 4 tables in .txt format: # 1) # packets by IP # 2) # of unique proto, src, dst, port combinations # 3) # packets per $timeblock in minutes # 4) packet type as % and # of total packets # # joel@xxxxxxxxxxxx 9/21/05 (http://www.appiant.net) # # by Appiant, Inc (http://www.appiant.net/) # die "dumpscan.pl [tcpdump -n -q file]\n" unless @ARGV > 0; #variables $infile=$ARGV[0]; #input tcpdump file (executed with -n -q) die " ... $infile does not exist ...\n" unless (-f $infile); $timeblock = 5; #number of minutes in a block of the output histogram $percenttraffic = 0; # percent of total traffic a protocol must make up to be listed #outfiles $outfileips=$infile."_ips.txt"; $outfiletable=$infile."_table.txt"; $outfiletime=$infile."_time.txt"; $outfiletraf=$infile."_traffic.txt"; #initialize blank variables $hour=0; $eventdata=""; $service=0; $time=0; open(INFILE,"$infile"); while (<INFILE>) { $line=$_; chop($line); if ($line=~ /^(\d+)\:(\d+)\:(\d+)\.\d+\s+(.*)/) { $newhour=$1; $min=$2; $sec=$3; $rest=$4; # check time; if hour goes DOWN, must be a new day if ($hour > $newhour) { $newhour=$newhour+24; } $hour=$newhour; if ($time eq 0) { $inittime = 60*$hour+$min; } $time=int((60*$hour+$min)/$timeblock); #new event # look for IP addresses if ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\.(\S+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\.(\S+)\:\s+(\S+)\s+(\S+)/) { $srcip=$1; $srcport=$2; $dstip=$3; $dstport=$4; $proto=$5; # find replies if ($con{"$proto,$dstip,$srcip,$srcport"} > 0) { if (($dstport =~ /^\d+$/) && ($dstport > 1023)) { if (($srcport =~ /\D/) || ($dstport < 1150)) { # is probably reply packet; switch src & dst #print "$srcport, $dstport\n" unless ($srcport =~ /netbios/); $temp=$srcport; $srcport=$dstport; $dstport=$temp; $temp=$srcip; $srcip=$dstip; $dstip=$temp; } } } #cleaning up formatting if ($proto =~ "UDP,") { $proto=UDP; } if ($proto =~ "tcp") { $proto=TCP; } $con{"$proto,$srcip,$dstip,$dstport"}++; $type{"$proto\/$dstport"}++; # ICMP } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+icmp\s+(\S+):\s+(.*)/) { $srcip=$1; $dstip=$2; $icmptype=$3; $proto="ICMP"; $con{"$proto,$srcip,$dstip,$icmptype"}++; $type{"ICMP"}++; # ICMP(Alternative) } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+icmp/) { $srcip=$1; $dstip=$2; $proto="ICMP"; $con{"$proto,$srcip,$dstip"}++; $type{"ICMP"}++; # OSPFv2 (JRH) "IP 10.79.209.3 > 224.0.0.5: OSPFv2, Hello (1), length: 48" } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+OSPFv2,\s+(.*)/) { $srcip=$1; $dstip=$2; $proto="OSPFv2"; $con{"OSPFv2,$srcip,$dstip"}++; $type{"OSPFv2"}++; # IP Proto 224 (JRH) "IP 156.99.62.249 > 156.99.62.255: ip-proto-224 60" } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+.*ip-proto-224\s+(.*)/) { $srcip=$1; $dstip=$2; $con{"IP224,$srcip,$dstip"}++; $type{"IP PROTO 224"}++; # arp requests "arp who-has 156.99.62.170 tell 156.99.62.240" } elsif ($rest =~ /^arp\s+who-has\s+(\d+\.\d+\.\d+\.\d+)\s+.*tell\s+(\d+\.\d+\.\d+\.\d+)/) { $srcip=$1; $dstip=$2; $con{"ARP,$srcip,$dstip,request"}++; $type{"ARP"}++; # arp reply "arp reply 156.99.62.197 is-at 00:b0:d0:fc:ba:52" } elsif ($rest =~ /^arp\s+reply\s+(\d+\.\d+\.\d+\.\d+)\s+is-at\s+(\S+)/) { $srcip=$1; $dstmac=$2; $con{"ARP,$srcip,$dstip,reply"}++; $type{"ARP Reply"}++; # SAP } elsif ($rest =~ /^(\S+)\s+>\s+(\S+)\s+sap/) { $srcmac=$1; $dstmac=$2; $con{"SAP,$srcip,$dstip"}++; $type{"SAP"}++; # MAC bridging "802.1d config 0032.00:0e:d6:3b:8b:80.2101 root 0032.00:0e:d6:3b:8b:80 pathcost 0 age 0 max 20 hello 2 fdelay 15" } elsif ($rest =~ /^802\.1d\s+(.*)/) { $con{"MAC Bridging packets"}++; $type{"MAC Bridging"}++; # CDPv2 (cisco discovery protocol) } elsif ($rest =~ /^CDPv2,\s+/) { $con{"CDP"}++; $type{"CDP"}++; # CDPv1 (JRH) "CDPv1, ttl: 180s, Device-ID 'MSRSIPCC.ipcc.local'[|cdp]" } elsif ($rest =~ /^CDPv1,\s+/) { $con{"CDP"}++; $type{"CDP"}++; # IGMP } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+igmp/) { $srcip=$1; $dstip=$2; $con{"IGMP,$srcip,$dstip"}++; $type{"IGMP"}++; #fragmented packets } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+\(frag\s+/) { $srcip=$1; $dstip=$2; $con{"FRAG,$srcip,$dstip"}++; $type{"FRAG"}++; # # Appletalk Routing Table Maintenance Protocol (RTMP) # Sample "255.0.220.1 > 0.0.1: at-rtmpReq 25" } elsif ($rest =~ /(\S+)\s+>\s+(\S+)\:\s+at-rtmpReq\s+(.*)/) { $srcip=$1; $proto="AT-RTMP"; $con{"AT-RTMP,$srcip"}++; $type{"AT-RTMP"}++; # # Point-to-Point over Ethernet PADI (PPPoE Active Discovery Initiation) # Sample: "PPPoE PADI [Service-Name] [Host-Uniq "ATWPPPOE"] [TAG-0xa5a5" } elsif ($rest =~ /^PPPoE\s+PADI\s+(.*)/) { $con{"PPPoE"}++; $type{"PPPoE PADI"}++; # # Unknown UDP (JRH) "IP 172.16.2.2 > 156.99.144.235: udp" } elsif ($rest =~ /^IP\s+(\d+\.\d+\.\d+\.\d+)\s+\>\s+(\d+\.\d+\.\d+\.\d+)\:\s+udp/) { $srcip=$1; $dstip=$2; $con{"Unknown_UDP,$srcip,$dstip"}++; $type{"Unknown UDP"}++; # #IPX (NOVELL) Traffic types # # Loopback (JRH) "00:0f:f7:40:3e:7e > 00:0f:f7:40:3e:7e, Loopback, length 60:" } elsif ($rest =~ /(\S+)\s+>\s+(\S+)\,\s+Loopback,\s+(.*)/) { $srcmac=$1; $dstmac=$2; $con{"Loopback,$srcmac,$dstmac"}++; $type{"Loopback Frame"}++; # NULL (JRH) "00:04:00:48:2c:40 > 00:04:00:48:2c:40 null I (s=0,r=0,C) len=42" } elsif ($rest =~ /(\S+)\s+>\s+(\S+)\s+null\s+(.*)/) { $srcmac=$1; $dstmac=$2; $con{"Loopback,$srcmac,$dstmac"}++; $type{"Loopback Frame"}++; # SNAP (JRH) " 00:0f:34:ab:88:83 > 01:00:0c:cc:cc:cd snap ui/C len=39" } elsif ($rest =~ /(\S+)\s+>\s+(\S+)\s+snap\s+(.*)/) { $srcmac=$1; $dstmac=$2; $con{"SNAP,$srcmac,$dstmac"}++; $type{"SNAP Frame"}++; # Novell (JRH) "(NOV-802.2) 00000000.00:c0:f2:00:9e:04.4008 > 00000000.ff:ff:ff:ff:ff:ff.0452:ipx-sap-resp[|ipx 64]" } elsif ($rest =~ /^\(NOV-802\.2\)\s+(.*)/) { $con{"Novell 802.2"}++; $type{"Novell 802.2"}++; # Novell (JRH) "(NOV-802.3) 00000000.00:04:00:d7:94:b7.83c2 > 00000000.ff:ff:ff:ff:ff:ff.0452:ipx-sap-resp[|ipx 64]" } elsif ($rest =~ /^\(NOV-802\.3\)\s+(.*)/) { $con{"Novell 802.3"}++; $type{"Novell 802.3"}++; # Novell (JRH) "(NOV-ETHII) 00000000.00:04:00:d7:94:b7.83c2 > 00000000.ff:ff:ff:ff:ff:ff.0452:ipx-sap-resp[|ipx 64]" } elsif ($rest =~ /^\(NOV-ETHII\)\s+(.*)/) { $con{"Novell ETHII"}++; $type{"Novell ETHII"}++; # Novell (JRH) "00:11:21:ce:df:4f > 01:40:96:ff:ff:00, Unknown Ethertype (0x872d), length 60:" } elsif ($rest =~ /(\S+)\s+>\s+(\S+)\s+Unknown\s+Ethertype\s+(.*)/) { $con{"Novell Unknown Ethertype"}++; $type{"Novell Unknown Ethertype"}++; # NetBeui (JRH) "NetBeui Packet" } elsif ($rest =~ /^NetBeui\s+/) { $con{"NetBeui Packet"}++; $type{"NetBeui Packet"}++; #Unknown } else { print "unknown line: $_"; $time{$time}--; $ip{$srcip}--; $ip{$dstip}--; } $time{$time}++; $ip{$srcip}++; $ip{$dstip}++; } else { #extraneous line, record for posterity } } close(INFILE); open(OUTFILE,"> $outfiletable"); # dump data foreach $key (sort keys %con) { print OUTFILE "$con{$key},$key\n"; } close(OUTFILE); open(OUTFILE2,"> $outfileips"); print OUTFILE2 "Unique IP,Packets In & Out\n"; # packets to or from unique IPs foreach $ip (sort keys %ip) { printf OUTFILE2 ("%20.18s,%10d\n",$ip,$ip{$ip}); } close(OUTFILE2); open(OUTFILE3,"> $outfiletime"); # dump time graph print OUTFILE3 "Minutes,Packets\n"; foreach $time (sort keys %time) { $displaytime=$time*$timeblock-$inittime; print OUTFILE3 "$displaytime,$time{$time}\n"; } close(OUTFILE3); open(OUTFILE4,"> $outfiletraf"); # traffic breakdown foreach $type (sort keys %type) { $total=$total+$type{$type}; } $threshold=$percenttraffic*$total/100; print OUTFILE4 "Traffic_Type,Total_Packets,Percent\n"; foreach $type (sort keys %type) { #print "$type{$type},$threshold\n"; $percent=int($type{$type}/$total*10000)/100; if ($type{$type} > $threshold) { # printf OUTFILE4 ("%20s,%15d,%5.2f\n",$type,$type{$type},$percent); } else { $othertotal=$othertotal+$type{$type}; } } $otherpercent=int($othertotal/$total*10000)/100; print OUTFILE4 "Other_traffic,$othertotal,$otherpercent\n"; print OUTFILE4 "Total,$total,100.00\n"; close(OUTFILE4); exit 1;
Attachment:
Time.gif
Description: GIF image
Attachment:
Top-Talkers.gif
Description: GIF image
Attachment:
Top-TCP-Talkers.gif
Description: GIF image
Attachment:
Top-UDP-Talkers.gif
Description: GIF image
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/