#!/usr/bin/perl ########################################################################################################## # # Kismet Log Viewer 0.9.7 - By Brian Foy Jr. - 4/13/2003 # # Outputs html interface to Kismet .xml log files. # # Requires: # The XML::LibXML perl module # At leaast one Kismet .xml logfile. # # Optional: # Snort (http://www.snort.org/) # The .dump logfile that matches the .xml logfile. # # To Use: # Either make sure that the 3 included files: # logo.png, ap_manuf, and client_manuf are in the same dir as the log you are going to use or, # if you prefer, drop them into a set dir (like /etc/klv) and update the lines below to reflect # their new location. # # Note: ap_manuf and client_manf are the files that come with Kismet. It may be a good idea # to just point those two lines to the Kismet files so that when Kismet updates them, # klv will use the new files by default. # # Example: $logo_location = "../obrazky/logo.png"; $ap_manuf_location = "/etc/kismet/ap_manuf"; $client_manuf_location = "/etc/kismet/client_manuf"; #$logo_location = "logo.png"; #$ap_manuf_location = "ap_manuf"; #$client_manuf_location = "client_manuf"; # Optionaly: # At this point you can combine some log files using the included klc.pl script. See klc.pl for more options. # # Example: # ./klc.pl *.xml # # Then: # ./klv.pl (logfile).xml # # Optionaly: # If you have Snort and the .dump file from the same run, you can use -snort to # generate a page for the Snort output for each specific bssid that has data avilable. # # Example: # ./klv.pl (logfile).xml -snort # # And Finaly: # Open the (logfile).xml-kismet-log-view.html in your fav browser. # # Other Options: # # Set the alignment of the bssid's, center by default. Standard HTML # aligments apply, left, right, etc. $ssid_align = "center"; # Set the character to be used in the clients column when there are 0 clients. # This default's to - but can be 0 or any other character you choose. $no_clients_char = "-"; # # Enjoy! # The help and about links point to: # http://www.mindflip.org/klv/help.html and http://www.mindflip.org/klv/about.html respectivly # you can see those for more info. # # Please send bugs, feature requests, questions, suggestions to: klv@mindflip.org # Watch http://www.mindflip.org/klv for updates. # ########################################################################################################## use XML::LibXML; unless ( @ARGV > 0 ) { print "Usage: $0 [-snort]\n"; exit; } $file = $ARGV[0]; $help_location = "http://www.mindflip.org/klv/help.html"; $about_location = "http://www.mindflip.org/klv/about.html"; $net_stats_link = "$file" . "-kismet-log-view-" . "stats.html"; if ( "$ARGV[1]" eq "-snort" ) { print "\nKLV: Running Snort...\n"; &do_snort; $snort_ok = 1; } print "KLV: Loading AP Manuf Data...\n"; open( AP_FILE, "$ap_manuf_location" ); @ap_manf = ; close(AP_FILE); print "KLV: Loading Client Manuf Data...\n"; open( CLIENT_FILE, "$client_manuf_location" ); @client_manf = ; close(CLIENT_FILE); print "KLV: Loading Logfile...\n"; $parser = XML::LibXML->new(); $parser->expand_entities(0); $tree = $parser->parse_file($file); $root = $tree->getDocumentElement; $kismet_ver = $root->getAttribute('kismet-version'); $kismet_start_time = $root->getAttribute('start-time'); $kismet_end_time = $root->getAttribute('end-time'); print "KLV: Generating main HTML File...\n"; $html_out_file = "$file" . "-kismet-log-view.html"; open( HTML_OUT, ">$html_out_file" ); print HTML_OUT < Kismet Log Viewer 1.0 - By Brian Foy Jr.


help - about - stats
EOM $total_networks = @networks = $root->getElementsByTagName('wireless-network'); $total_factory_defaults = 0; $total_wep = 0; $total_cloaked = 0; foreach $this_network (@networks) { $total_clients_this_net = @net_clients = $this_network->getElementsByTagName('wireless-client'); $total_clients += $total_clients_this_net; $net_number = $this_network->getAttribute('number'); $net_type = $this_network->getAttribute('type'); $net_wep = $this_network->getAttribute('wep'); $net_cloaked = $this_network->getAttribute('cloaked'); undef $net_device_cloaked; if ("$net_cloaked" eq "true") { $net_device_cloaked = 1; $total_cloaked++; } $net_carrier = $this_network->getAttribute('carrier'); $net_first = $this_network->getAttribute('first-time'); $net_last = $this_network->getAttribute('last-time'); if ( $temp = $this_network->getElementsByTagName('SSID')->[0] ) { $net_ssid = $this_network->getElementsByTagName('SSID') ->[0]->getFirstChild->getData; } elsif ( $temp = $this_network->getElementsByTagName('info')->[0] ) { $net_ssid = $this_network->getElementsByTagName('info') ->[0]->getFirstChild->getData; } else { $net_ssid = "NA"; } $net_bssid = $this_network->getElementsByTagName('BSSID')->[0]->getFirstChild->getData; $net_channel = $this_network->getElementsByTagName('channel') ->[0]->getFirstChild->getData; $net_quality = $this_network->getElementsByTagName('quality') ->[0]->getFirstChild->getData; $net_signal = $this_network->getElementsByTagName('signal') ->[0]->getFirstChild->getData; $net_noise = $this_network->getElementsByTagName('noise') ->[0]->getFirstChild->getData; $net_maxrate = $this_network->getElementsByTagName('maxrate') ->[0]->getFirstChild->getData; $net_packets_LLC = $this_network->getElementsByTagName('LLC')->[0]->getFirstChild->getData; $net_packets_data = $this_network->getElementsByTagName('data')->[0]->getFirstChild->getData; $net_packets_crypt = $this_network->getElementsByTagName('crypt')->[0]->getFirstChild->getData; $net_packets_weak = $this_network->getElementsByTagName('weak')->[0]->getFirstChild->getData; $net_packets_total = $this_network->getElementsByTagName('total')->[0]->getFirstChild->getData; $total_packets += $net_packets_total; if ( $temp = $this_network->getElementsByTagName('datasize')->[0] ) { $net_datasize = $this_network->getElementsByTagName('datasize') ->[0]->getFirstChild->getData; } else { $net_datasize = "NA"; } if ( $temp = $this_network->getElementsByTagName('min-lat')->[0] ) { $net_gps_min_lat = $this_network->getElementsByTagName('min-lat') ->[0]->getFirstChild->getData; $net_gps_min_lon = $this_network->getElementsByTagName('min-lon') ->[0]->getFirstChild->getData; $net_gps_min_alt = $this_network->getElementsByTagName('min-alt') ->[0]->getFirstChild->getData; $net_gps_min_spd = $this_network->getElementsByTagName('min-spd') ->[0]->getFirstChild->getData; $net_gps_max_lat = $this_network->getElementsByTagName('max-lat') ->[0]->getFirstChild->getData; $net_gps_max_lon = $this_network->getElementsByTagName('max-lon') ->[0]->getFirstChild->getData; $net_gps_max_alt = $this_network->getElementsByTagName('max-alt') ->[0]->getFirstChild->getData; $net_gps_max_spd = $this_network->getElementsByTagName('max-spd') ->[0]->getFirstChild->getData; $net_gps_med_lon = ( ( $net_gps_min_lon + $net_gps_max_lon ) / 2 ); $net_gps_med_lat = ( ( $net_gps_min_lat + $net_gps_max_lat ) / 2 ); $net_gps_aprox_map1 = "http://tiger.census.gov/cgi-bin/mapper/map.gif?&lat=$net_gps_med_lat&lon=$net_gps_med_lon&ht=0.004&wid=0.011&&tlevel=-&tvar=-&tmeth=i&mlat=$net_gps_med_lat&mlon=$net_gps_med_lon&msym=cross&mlabel=N$net_number&murl=&conf=mapnew.con&iht=359&iwd=422"; $net_gps_aprox_map2 = "http://tiger.census.gov/cgi-bin/mapper/map.gif?&lat=$net_gps_med_lat&lon=$net_gps_med_lon&ht=0.009&wid=0.022&&tlevel=-&tvar=-&tmeth=i&mlat=$net_gps_med_lat&mlon=$net_gps_med_lon&msym=cross&mlabel=N$net_number&murl=&conf=mapnew.con&iht=359&iwd=422"; $net_gps_aprox_map3 = "http://tiger.census.gov/cgi-bin/mapper/map.gif?&lat=$net_gps_med_lat&lon=$net_gps_med_lon&ht=0.018&wid=0.044&&tlevel=-&tvar=-&tmeth=i&mlat=$net_gps_med_lat&mlon=$net_gps_med_lon&msym=cross&mlabel=N$net_number&murl=&conf=mapnew.con&iht=359&iwd=422"; $net_gps_aprox_map4 = "http://tiger.census.gov/cgi-bin/mapper/map.gif?&lat=$net_gps_med_lat&lon=$net_gps_med_lon&ht=0.036&wid=0.088&&tlevel=-&tvar=-&tmeth=i&mlat=$net_gps_med_lat&mlon=$net_gps_med_lon&msym=cross&mlabel=N$net_number&murl=&conf=mapnew.con&iht=359&iwd=422"; $net_gps_aprox_map5 = "http://tiger.census.gov/cgi-bin/mapper/map.gif?&lat=$net_gps_med_lat&lon=$net_gps_med_lon&ht=0.064&wid=0.192&&tlevel=-&tvar=-&tmeth=i&mlat=$net_gps_med_lat&mlon=$net_gps_med_lon&msym=cross&mlabel=N$net_number&murl=&conf=mapnew.con&iht=359&iwd=422"; $net_gps_aprox_map_avilable = "(+) 12345 (-)"; } else { $net_gps_min_lat = "NA"; $net_gps_min_lon = "NA"; $net_gps_min_alt = "NA"; $net_gps_min_spd = "NA"; $net_gps_max_lat = "NA"; $net_gps_max_lon = "NA"; $net_gps_max_alt = "NA"; $net_gps_max_spd = "NA"; $net_gps_aprox_map = "NA"; $net_gps_aprox_map_avilable = "NA"; } if ( $temp = $this_network->getElementsByTagName('ip-range')->[0] ) { $net_ip_range = $this_network->getElementsByTagName('ip-range') ->[0]->getFirstChild->getData; @net_ip_parts = $this_network->getElementsByTagName('ip-address'); foreach $this_ip (@net_ip_parts) { $net_ip_type = $this_ip->getAttribute('type'); } } else { $net_ip_range = "NA"; $net_ip_type = "NA"; } $net_link = "$file" . "-kismet-log-view-" . "$net_number" . "-info.html"; $net_clients_total = @net_clients; if ("$net_clients_total" eq "0") { $net_clients_total = "$no_clients_char"; } $net_clients_link = "$file" . "-kismet-log-view-" . "$net_number" . "-clients.html"; $net_type = substr( $net_type, 0, 2 ); if ( "$net_type" eq "in" ) { $net_type = "AP"; } if ( "$net_wep" eq "true" ) { $net_wep = "Y"; $total_wep++; } else { $net_wep = "N"; } if ( "$net_cloaked" eq "true" ) { $net_cloaked = "Y"; } else { $net_cloaked = "N"; } $net_first =~ s/ / /g; $net_last =~ s/ / /g; @first_parts = split ( / /, $net_first ); @last_parts = split ( / /, $net_last ); $net_device_name = "NA"; undef $net_device_def; foreach $ap_manuf_line (@ap_manf) { chomp $ap_manuf_line; @ap_manuf_line_parts = split ( /\t/, $ap_manuf_line ); if ( $net_bssid =~ /$ap_manuf_line_parts[0]/ ) { $net_device_name = "$ap_manuf_line_parts[1] $ap_manuf_line_parts[2]"; if ("$net_channel" eq "$ap_manuf_line_parts[4]") { if ("$net_ssid" eq "$ap_manuf_line_parts[3]") { $net_device_def = 1; } if ("$net_ip_range" eq "NA") { $net_ip_range .= " ($ap_manuf_line_parts[5])"; } else { $net_ip_range = "$net_ip_range ($ap_manuf_line_parts[5])"; } } } } if ( $net_number % 2 == 0 ) { print HTML_OUT ""; } else { print HTML_OUT ""; } if ($snort_ok) { undef $this_net_snort; $mod_bssid = $net_bssid; $mod_bssid =~ s/://g; if ( $network_packets{"$mod_bssid"} ) { print "KLV: Extracting Snort Data for $net_ssid ...\n"; &gen_snort($mod_bssid); $this_net_snort = 1; } } undef $flags; if ($net_device_cloaked) { $flags .= "C"; $total_factory_defaults++; } if ($net_device_def) { $flags .= "F"; $total_factory_defaults++; } if ($this_net_snort) { $flags .= "D"; } $net_total_unwep = eval($total_networks - $total_wep); $net_percent_wep = eval($total_wep / $total_networks) * 100; $net_percent_wep = substr($net_percent_wep,0,4); $net_percent_factory_default = eval($total_factory_defaults / $total_networks) * 100; $net_percent_factory_default = substr($net_percent_factory_default,0,4); $net_percent_cloaked = eval($total_cloaked / $total_networks) * 100; $net_percent_cloaked = substr($net_percent_cloaked,0,4); print HTML_OUT <
$net_number$flags
EOM if ($net_clients_total > 0) { print HTML_OUT < EOM } else { print HTML_OUT <
$net_clients_total
EOM } print HTML_OUT <
$first_parts[0] $first_parts[1] $first_parts[2]
$first_parts[3]
EOM print "KLV: Generating details for network #$net_number ($net_ssid) ...\n"; open( HTML_NET_OUT, ">$net_link" ); print HTML_NET_OUT < Kismet Log Viewer 1.0 - By Brian Foy Jr.
Net
Name (SSID)
Type
Wep
Ch
Quality
Signal
Noise
Packets
Type/BSSID
Clients
First Seen
Last Seen
$net_type
$net_wep
$net_channel
$net_quality
$net_signal
$net_noise
$net_packets_total
$net_device_name
$net_bssid
$last_parts[0] $last_parts[1] $last_parts[2]
$last_parts[3]


help - about - stats
EOM if ($net_clients_total > 0) { print HTML_NET_OUT < EOM } else { print HTML_NET_OUT < EOM } print HTML_NET_OUT < EOM if ($this_net_snort) { print HTML_NET_OUT < EOM } print HTML_NET_OUT <



EOM close HTML_NET_OUT; if (@net_clients) { open( HTML_CLIENT_OUT, ">$net_clients_link" ); print HTML_CLIENT_OUT < Kismet Log Viewer 1.0 - By Brian Foy Jr.
$net_ssid
Type: $net_device_name ($net_bssid)
Net
$net_number
Type
$net_type
Wep
$net_wep
Cloaked
$net_cloaked
Carrier
$net_carrier
First Seen
$net_first
Last Seen
$net_last
Channel
$net_channel
Maxrate
$net_maxrate
Packets (LLC)
$net_packets_LLC
Packets (data)
$net_packets_data
Packets (crypt)
$net_packets_crypt
Packets (weak)
$net_packets_weak
Packets (total)
$net_packets_total
Datasize
$net_datasize
Clients
Clients
$net_clients_total
GPS Min Lat
$net_gps_min_lat
GPS Min Lon
$net_gps_min_lon
GPS Min Alt
$net_gps_min_alt
GPS Min Spd
$net_gps_min_spd
GPS Max Lat
$net_gps_max_lat
GPS Max Lon
$net_gps_max_lon
GPS Max Alt
$net_gps_max_alt
GPS Max Spd
$net_gps_max_spd
IP Range
$net_ip_range
IP Type
$net_ip_type
Map Approx. Location:
$net_gps_aprox_map_avilable
Snort Output:


help - about - stats
EOM foreach $this_client (@net_clients) { $client_number = $this_client->getAttribute('number'); $client_type = $this_client->getAttribute('type'); $client_wep = $this_client->getAttribute('wep'); $client_first = $this_client->getAttribute('first-time'); $client_last = $this_client->getAttribute('last-time'); $client_mac = $this_client->getElementsByTagName('client-mac') ->[0]->getFirstChild->getData; $client_packets_data = $this_client->getElementsByTagName('client-data') ->[0]->getFirstChild->getData; $client_packets_crypt = $this_client->getElementsByTagName('client-crypt') ->[0]->getFirstChild->getData; $client_packets_weak = $this_client->getElementsByTagName('client-weak') ->[0]->getFirstChild->getData; $client_datasize = $this_client->getElementsByTagName('client-datasize') ->[0]->getFirstChild->getData; $client_maxrate = $this_client->getElementsByTagName('client-maxrate') ->[0]->getFirstChild->getData; if ( $temp = $this_client->getElementsByTagName('client-min-lat')->[0] ) { $client_gps_min_lat = $this_client->getElementsByTagName('client-min-lat') ->[0]->getFirstChild->getData; $client_gps_min_lon = $this_client->getElementsByTagName('client-min-lon') ->[0]->getFirstChild->getData; $client_gps_min_alt = $this_client->getElementsByTagName('client-min-alt') ->[0]->getFirstChild->getData; $client_gps_min_spd = $this_client->getElementsByTagName('client-min-spd') ->[0]->getFirstChild->getData; $client_gps_max_lat = $this_client->getElementsByTagName('client-max-lat') ->[0]->getFirstChild->getData; $client_gps_max_lon = $this_client->getElementsByTagName('client-max-lon') ->[0]->getFirstChild->getData; $client_gps_max_alt = $this_client->getElementsByTagName('client-max-alt') ->[0]->getFirstChild->getData; $client_gps_max_spd = $this_client->getElementsByTagName('client-max-spd') ->[0]->getFirstChild->getData; } else { $client_gps_min_lat = "NA"; $client_gps_min_lon = "NA"; $client_gps_min_alt = "NA"; $client_gps_min_spd = "NA"; $client_gps_max_lat = "NA"; $client_gps_max_lon = "NA"; $client_gps_max_alt = "NA"; $client_gps_max_spd = "NA"; } if ( $temp = $this_client->getElementsByTagName('client-ip-address')->[0] ) { $client_ip_address = $this_client->getElementsByTagName('client-ip-address') ->[0]->getFirstChild->getData; @client_ip_parts = $this_client->getElementsByTagName('client-ip-address'); foreach $this_client_ip (@client_ip_parts) { $client_ip_type = $this_client_ip->getAttribute('type'); } } else { $client_ip_address = "NA"; $client_ip_type = "NA"; } if ( "$client_wep" eq "true" ) { $client_wep = "Y"; } else { $client_wep = "N"; } $client_device_name = "Type: NA"; foreach $client_manuf_line (@client_manf) { chomp $client_manuf_line; @client_manuf_line_parts = split ( /\t/, $client_manuf_line ); if ( $client_mac =~ /$client_manuf_line_parts[0]/ ) { $client_device_name = "Type: $client_manuf_line_parts[1] $client_manuf_line_parts[2]"; } } print "KLV: Generating details for network #$net_number ($net_ssid) client #$client_number ...\n"; print HTML_CLIENT_OUT <
Client #$client_number
$client_device_name ($net_ssid)
Type
$client_type
Wep
$client_wep
First Seen
$client_first
Last Seen
$client_last
Mac
$client_mac
Packets (data)
$client_packets_data
Packets (crypt)
$client_packets_crypt
Packets (weak)
$client_packets_weak
Packets (total)
$net_packets_total
Datasize
$client_datasize
Maxrate
$client_maxrate
GPS Min Lat
$client_gps_min_lat
GPS Min Lon
$client_gps_min_lon
GPS Min Alt
$client_gps_min_alt
GPS Min Spd
$client_gps_min_spd
GPS Max Lat
$client_gps_max_lat
GPS Max Lon
$client_gps_max_lon
GPS Max Alt
$client_gps_max_alt
GPS Max Spd
$client_gps_max_spd
IP Address
$client_ip_address
IP Type
$client_ip_type

EOM } # end foreach client print HTML_CLIENT_OUT <



EOM close HTML_CLIENT_OUT; } # end of @net_clients } # end foreach @networks print HTML_OUT <

Started: $kismet_start_time - Ended: $kismet_end_time
Log File: $file






































EOM close HTML_OUT; print "KLV: Generating Stats...\n"; open( HTML_STATS_OUT, ">$net_stats_link" ); print HTML_STATS_OUT < Kismet Log Viewer 1.0 - By Brian Foy Jr.


help - about - stats
Stats:
$file
Started
$kismet_start_time
Ended
$kismet_end_time
Kismet Server Ver
$kismet_ver
Total Networks
$total_networks
Total Networks with WEP
$total_wep
Total Networks without WEP
$net_total_unwep
% Networks with WEP
$net_percent_wep%
Total Networks Factory Default
$total_factory_defaults
% Networks Factory Default
$net_percent_factory_default%
Total Cloaked Networks
$total_cloaked
% Networks Cloaked
$net_percent_cloaked%
Total Clients
$total_clients
Total Packets
$total_packets



EOM print "KLV: Done!\n"; exit; sub do_snort { $snort_file = $file; $snort_file =~ s/\.xml/\.dump/g; system("snort -vdeCr $snort_file > snort_temp.txt"); open( SNORTFILE, "snort_temp.txt" ); @all_snort_lines = ; close SNORTFILE; unlink("snort_temp.txt"); foreach $this_line (@all_snort_lines) { $all_lines_comb .= "$this_line"; } @all_snort_line_parts = split ( /\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+\=\+/, $all_lines_comb ); foreach $this_line (@all_snort_line_parts) { undef $this_packets_lines; undef $bssid; @this_packet_lines = split ( /\n/, $this_line ); foreach $this_packet_line (@this_packet_lines) { if ( $this_packet_line =~ /Run time for packet processing was/ ) { break; } if ( $this_packet_line =~ /bssid/ ) { @this_bssid_parts = split ( / /, $this_packet_line ); $bssid = "$this_bssid_parts[1]"; } $this_packet_line =~ s/\r/\/g; if ( $this_packet_line =~ /No run mode specified, defaulting to verbose mode/g ) { $this_packet_line = "
"; } $this_packets_lines .= "$this_packet_line
"; } if ($bssid) { @bssid_parts = split ( /\:/, $bssid ); undef $this_full_bssid; foreach $this_bssid_parts (@bssid_parts) { if ( length($this_bssid_parts) < 2 ) { $this_bssid_parts = "0" . "$this_bssid_parts"; } $this_full_bssid .= "$this_bssid_parts"; } $network_packets{"$this_full_bssid"} .= "$this_packets_lines"; } } } # end sub do_snort sub gen_snort($mod_bssid) { $net_snort_link = "$file" . "-kismet-log-view-" . "$mod_bssid" . "-snort.html"; open( HTML_SNORT_OUT, ">$net_snort_link" ); print HTML_SNORT_OUT < Kismet Log Viewer 1.0 - By Brian Foy Jr.


help - about - stats
Snort output for: $net_ssid ($net_bssid)
EOM print HTML_SNORT_OUT $network_packets{"$mod_bssid"}; print HTML_SNORT_OUT <





EOM close HTML_SNORT_OUT; } #end sub gen_snort