Advertisement
opexxx

hoover.pl

Jul 7th, 2014
443
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.41 KB | None | 0 0
  1. #!/usr/bin/perl
  2. #
  3. # hoover.pl - Wi-Fi probe requests sniffer
  4. #
  5. # Original idea by David Nelissen (twitter.com/davidnelissen)
  6. # Thank to him for allowing me to reuse the idea!
  7. #
  8. # This script scans for wireless probe requests and prints them out.
  9. # Hereby you can see for which SSID's devices nearby are searching.
  10. #
  11. # Copyright (c) 2012 David Nelissen & Xavier Mertens
  12. # All rights reserved.
  13. #
  14. # Redistribution and use in source and binary forms, with or without
  15. # modification, are permitted provided that the following conditions
  16. # are met:
  17. # 1. Redistributions of source code must retain the above copyright
  18. #    notice, this list of conditions and the following disclaimer.
  19. # 2. Redistributions in binary form must reproduce the above copyright
  20. #    notice, this list of conditions and the following disclaimer in the
  21. #    documentation and/or other materials provided with the distribution.
  22. # 3. Neither the name of copyright holders nor the names of its
  23. #    contributors may be used to endorse or promote products derived
  24. #    from this software without specific prior written permission.
  25. #
  26. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  28. # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  29. # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
  30. # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. # POSSIBILITY OF SUCH DAMAGE.
  37. #
  38. # History
  39. # -------
  40. # 2012/01/11    Created
  41. #
  42.  
  43. use strict;
  44. use Getopt::Long;
  45.  
  46. $SIG{USR1}  = \&dumpNetworks; # Catch SIGINT to dump the detected networks
  47. $SIG{INT}   = \&cleanKill;
  48. $SIG{KILL}  = \&cleanKill;
  49. $SIG{TERM}  = \&cleanKill;
  50.  
  51. my $uniqueSSID = 0;     #uniq ssid counter
  52. my %detectedSSID;   # Detected network will be stored in a hash table
  53.             # SSID, Seen packets, Last timestamp
  54. my $pid;
  55. my $help;
  56. my $verbose;
  57. my $interface;
  58. my $dumpFile;
  59. my $ifconfigPath = "/sbin/ifconfig";
  60. my $iwconfigPath = "/sbin/iwconfig";
  61. my $tsharkPath   = "/usr/local/bin/tshark";
  62. my $options = GetOptions(
  63.     "verbose"       => \$verbose,
  64.     "help"          => \$help,
  65.     "interface=s"       => \$interface,
  66.     "ifconfig-path=s"   => \$ifconfigPath,
  67.     "iwconfig-path=s"   => \$iwconfigPath,
  68.     "tsharkPath=s"      => \$tsharkPath,
  69.     "dumpfile=s"        => \$dumpFile,
  70. );
  71.  
  72. if ($help) {
  73.     print <<_HELP_;
  74. Usage: $0 --interface=wlan0 [--help] [--verbose] [--iwconfig-path=/sbin/iwconfig] [--ipconfig-path=/sbin/ifconfig]
  75.         [--dumpfile=result.txt]
  76. Where:
  77. --interface     : Specify the wireless interface to use
  78. --help          : This help
  79. --verbose       : Verbose output to STDOUT
  80. --ifconfig-path     : Path to your ifconfig binary
  81. --iwconfig-path     : Path to your iwconfig binary
  82. --tshark-path       : Path to your tshark binary
  83. --dumpfile      : Save found SSID's/MAC addresses in a flat file (SIGUSR1)
  84. _HELP_
  85.     exit 0;
  86. }
  87.  
  88. # We must be run by root
  89. (getlogin() ne "root") && die "$0 must be run by root!\n";
  90.  
  91. # We must have an interface to listen to
  92. (!$interface) && die "No wireless interface speficied!\n";
  93.  
  94. # Check ifconfig availability
  95. ( ! -x $ifconfigPath) && die "ifconfig tool not found!\n";
  96.  
  97. # Check iwconfig availability
  98. ( ! -x $iwconfigPath) && die "iwconfig tool not found!\n";
  99.  
  100. # Check tshark availability
  101. ( ! -x $tsharkPath) && die "tshark tool not available!\n";
  102.  
  103. # Configure wireless interface
  104. (system("$ifconfigPath $interface up")) && "Cannot initialize interface $interface!\n";
  105.  
  106. # Set interface in monitor mode
  107. (system("$iwconfigPath $interface mode monitor")) && die "Cannot set interface $interface in monitoring mode!\n";
  108.  
  109. # Create the child process to change wireless channels
  110. (!defined($pid = fork)) && die "Cannot fork child process!\n";
  111.  
  112. if ($pid) {
  113.     # ---------------------------------
  114.     # Parent process: run the main loop
  115.     # ---------------------------------
  116.     ($verbose) && print "!! Running with PID: $$ (child: $pid)\n";
  117.     open(TSHARK, "$tsharkPath -i $interface -n -l subtype probereq |") || die "Cannot spawn tshark process!\n";
  118.     while (<TSHARK>) {
  119.         chomp;
  120.         my $line = $_;
  121.         chomp($line = $_);
  122.         # Everything exept backslash (some probes contains the ssid in ascii, not usable)
  123.         #if($line = m/\d+\.\d+ ([a-zA-Z0-9:]+).+SSID=([a-zA-ZΓ€-ΓΏ0-9"\s\!\@\$\%\^\&\*\(\)\_\-\+\=\[\]\{\}\,\.\?\>\<]+)/) {
  124.         if($line = m/\d+\.\d+ ([a-zA-Z0-9:_]+).+SSID=([a-zA-ZΓ€-ΓΏ0-9"\s\!\@\$\%\^\&\*\(\)\_\-\+\=\[\]\{\}\,\.\?\>\<]+)/) {
  125.             if($2 ne "Broadcast") { # Ignore broadcasts
  126.                 my $macAddress = $1;
  127.                 my $newKey = $2;
  128.                 print DEBUG "$macAddress : $newKey\n";
  129.                 if (! $detectedSSID{$newKey})
  130.                 {
  131.                     # New network found!
  132.                     my @newSSID = ( $newKey,        # SSID
  133.                             1,          # First packet
  134.                             $macAddress,        # MAC Address
  135.                             time());        # Seen now
  136.                     $detectedSSID{$newKey} = [ @newSSID ];
  137.                     $uniqueSSID++;
  138.                     print "++ New probe request from $macAddress with SSID: $newKey [$uniqueSSID]\n";
  139.                 }
  140.                 else
  141.                 {
  142.                     # Existing SSID found!
  143.                     $detectedSSID{$newKey}[1]++;            # Increase packets counter
  144.                     $detectedSSID{$newKey}[2] = $macAddress;    # MAC Address
  145.                     $detectedSSID{$newKey}[3] = time();     # Now
  146.                     ($verbose) && print "-- Probe seen before: $newKey [$uniqueSSID]\n";
  147.                 }
  148.             }
  149.         }  
  150.     }
  151. }
  152. else {
  153.     # --------------------------------------------------
  154.     # Child process: Switch channels at regular interval
  155.     # --------------------------------------------------
  156.     ($verbose) && print STDOUT "!! Switching wireless channel every 5\".\n";
  157.     while (1) {
  158.         for (my $channel = 1; $channel <= 12; $channel++) {
  159.             (system("$iwconfigPath $interface channel $channel")) &&
  160.                 die "Cannot set interface channel.\n";
  161.             sleep(5);
  162.         }
  163.     }
  164.    
  165. }
  166.  
  167. sub dumpNetworks {
  168.     my $i;
  169.     my $key;
  170.     print STDOUT "!! Dumping detected networks:\n";
  171.     print STDOUT "!! MAC Address          SSID                           Count      Last Seen\n";
  172.     print STDOUT "!! -------------------- ------------------------------ ---------- -------------------\n";
  173.     if ($dumpFile) {
  174.         open(DUMP, ">$dumpFile") || die "Cannot write to $dumpFile (Error: $?)";
  175.         print DUMP "MAC Address          SSID                           Count      Last Seen\n";
  176.         print DUMP "-------------------- ------------------------------ ---------- -------------------\n";
  177.     }
  178.     for $key ( keys %detectedSSID)
  179.     {
  180.         my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($detectedSSID{$key}[2]);
  181.         my $lastSeen = sprintf("%04d/%02d/%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
  182.         print STDOUT sprintf("!! %-20s %-30s %10s %-20s\n", $detectedSSID{$key}[2],
  183.                          $detectedSSID{$key}[0], $detectedSSID{$key}[1], $lastSeen);
  184.         ($dumpFile) && print DUMP sprintf("%-20s %-30s %10s %-20s\n",
  185.                          $detectedSSID{$key}[2], $detectedSSID{$key}[0],
  186.                          $detectedSSID{$key}[1], $lastSeen);
  187.     }
  188.     print STDOUT "!! Total unique SSID: $uniqueSSID\n";
  189.     ($dumpFile) && print DUMP "Total unique SSID: $uniqueSSID\n";
  190.     close(DUMP);
  191.     return;
  192. }
  193.  
  194. sub cleanKill {
  195.     if ($pid) {
  196.         # Parent process: display information
  197.         print "!! Received kill signal!\n";
  198.         kill 1, $pid;
  199.         dumpNetworks;
  200.     }
  201.     exit 0;
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement