Hack 21. Broadcast Your GPS Position

Entertain yourself and passing wardrivers by abusing the beacon frame (and MAC address).

Have you ever wanted a lightweight protocol that would allow you to broadcast your current position? Many times you can see a wireless network, but you can't connect to it. In the NoCat community network (http://nocat.net) we would often do sight surveys that showed lots of networks, but we could not associate with them. Perhaps the access point has a more powerful network card, or a better antenna, and is able to blast a signal out, but you are not able to get your signal back to the access point.

What to do? With a complete abuse of the 802.11 beacon frame you can share your position with anyone around you!

802.11 wireless networks in both Ad Hoc and Infrastructure mode [Appendix A] send periodic beacon frames. These are about 50 bytes long and contain information that a client needs in order to associate with a wireless network. The beacon frame includes the Service Set Identifier (SSID), which is the name of the network.

Wireless discovery programs such as NetStumbler [Hack #24], iStumbler [Hack #27], and Kismet [Hack #29] get all of their information from sniffing for these beacon frames. So what happens if we change the SSID on the access point? What happens if we change it whenever we get a new GPS fix?

For our purposes the SSID, at 32 bytes, provides enough room to encode the latitude and longitude of our current position to 5 digits of precision (about 1 meter). We can also separate the coordinates with readable delimiters and still have 11 characters for a unique station ID.

To run this hack, you need to have a DIY Linux access point [Hack #63]. Then, set up the GPSd daemon and connect a GPS [Hack #20].

Once you have your access point and GPSd functional, use the Perl script in Example 1-2 to broadcast your current position by using the beacon frame.

Example 1-2. Broadcasting your position through GPSd using beacon_abuse.pl

#!/usr/bin/perl # /usr/local/sbin/gpsd -p /dev/ttyS0 use 5.6.1; use IO::Socket; use Term::ReadKey; use strict; BEGIN { $|++ }; # autoflush STDOUT. my $station_id = shift( @ARGV ) || 'myid'; my $GPSD = shift( @ARGV ) || "localhost:2947"; my $delay = 3; # number of seconds to sleep my $ssid = 'gpsd not initialized';; # Connect to gpsd. warn "connecting to gpsd "; my $gps = IO::Socket::INET->new($GPSD) or die "Can't connect to gpsd at $GPSD: $! "; while (1) { # Tell gpsd we want position, altitude, date, and status. $gps->print("pads "); # Parse out the response. If the date is blank, gpsd needs # a second to catch up. my $location = <$gps>; my ($lat, $long, $alt, $date, $status) = ($location =~ /P=(.+?) (.+?),A=(.+?),D=(.+?),S=(.+?)/gos); # create new SSID $lat = sprintf("%9.5f", $lat); $long = sprintf("%10.5f", $long); $ssid = "$station_id:$lat:$long"; print "$ssid "; `iwconfig wlan0 essid "$ssid" mode "Master" channel 1 rate "Auto"`; sleep( $delay ); }

Copy the code into a file called beacon_abuse.pl and run it from the command line:

$ ./beacon_abuse.pl myid

In this example, myid is the unique station ID that will preface the latitude and longitude in the SSID generated by the code. The code enters a loop where it connects to GPSd to get the current position, then changes the SSID of the network card and prints out the new SSID. You will know it is working if you get a series of new SSID's that consist of your station ID and the latitude and longitude; for example:

myid: 38.40254:-122.182889

Depending on your platform you can use MacStumbler, NetStumbler, or Kismet to watch the SSID change, as shown in Figure 1-57.

If your machine isn't moving too quickly, or you stop beacon_abuse.pl, you can connect to the machine as a normal access point, as shown in Figure 1-58.

Figure 1-57. Watching the moving SSID in MacStumbler

Figure 1-58. A geolocated access point

One disadvantage of the script in Example 1-2 is that your Stumbler program probably shows only the most recent SSID. This is because the programs use the MAC address of the wireless card to uniquely identify the access point. By design, this is the right thing to do, because MAC addresses are not supposed to change. Unless we want them to change.

This code flips the MAC address, and sets the SSID as well:

#!/usr/bin/perl $cnt=0; while (1) { `ifconfig wlan0 hw ether 0000000000$cnt`; `iwconfig wlan0 essid "foo:$cnt" mode "Master" channel 1 rate "Auto"`; print "new essid foo:$cnt "; sleep 1; $cnt++; }

Copy the code into a file called bad_plan.pl and run it from the command line:

$ ./bad_plan.pl

This is almost certainly a Bad Idea, but it does let you create amusing Stumbler logs like Figure 1-59 for passing wardrivers.

Figure 1-59. How to confuse a wardriver

Changing your SSID on a whim is almost certainly a bad idea, but imagine an event such as Burning Man (http://www.burningman.com), where the action happens in a wireless-friendly flat plane. You could add a wireless card to the computer to serve MP3s in your art car and broadcast your position with GPS. Since the beacon frame drops down to 1MB and is sent relatively infrequently, you could have quite a few location-aware vehicles sharing a single Wi-Fi radio channel.

This hack lets you communicate your position (or anything else you can convey 32-bytes at a time) to a client and there is no way for the server, or anyone listening in, to identify which clients are getting the position information. This technique has lots of disadvantages, not least of which is that it destroys all normal use of the link, but that's what makes it a hack.

1.22.1. See Also

Rich Gibson

Категории