Re: Tutorial: Query the Apple database with Python for your access point BSSID
Marian <[email protected]>
| Newsgroups | alt.comp.os.windows-10,alt.internet.wireless,alt.comp.microsoft.windows |
|---|---|
| Organization | BWH Usenet Archive (https://usenet.blueworldhosting.com) |
| Message-ID | <[email protected]> |
Marian wrote: > Chris wrote: >> Jeff Liebermann <[email protected]> wrote: >>> >>> I can't determine if either company has a reason to have a longer >>> Lat/Long. However, notice the number of digits in the Lat, which are >>> mostly zeros, except for the last digit: >>> Latitude: 32.459438320000004 >>> I don't know what they're doing, but it looks like they're using the >>> Latitude to store some kind of data or ID. There are several other >>> entries in the data that show a similar pattern of 8 places to the >>> right of the decimal point for useful data followed by 6 zeros and 1 >>> numeric digit. >> >> These are from loss of precision in the storing of floating-point numbers >> in python. They aren't real. The source data will not include all the >> zeros. > > The precision is a red herring, in my opinion, since the fact that you > can't get out of the Apple WPS database even though you followed all of > Apple's legally binding published policies is the main privacy issue. > > Apple's decision is legally, morally & ethically reprehensible, so I will > start working on getting Apple to change their decision any way that I can. > > However, to the point of the raw precision in the Apple WPS database, I've > modified the open source Apple bssid locator tools to report raw integer > values in addition to conversion to the human-readable GPS coordinates. > > Here are raw/converted values for the bssid lookup on the access point > located near 4302 Josey Cir, Shreveport, LA 71109 (as a random AP lookup). > > 00:18:f8:c1:4a:65 3245990371 -9381384277 32.459904 -93.813843 > 02:aa:a0:e3:5f:38 3245890808 -9381494903 32.458908 -93.814949 > 44:1c:12:99:23:58 3245909881 -9381492614 32.459099 -93.814926 > 44:1c:12:99:23:5b 3245910644 -9381491088 32.459106 -93.814911 None of us knew how Apple saved the location of our APs until recently. 02:aa:a0:e3:5f:38 3245891571 -9381494140 32.45891571 -93.81494140 00:18:f8:c1:4a:65 3245990371 -9381384277 32.45990371 -93.81384277 44:1c:12:99:23:58 3245911026 -9381490325 32.45911026 -93.81490325 44:1c:12:99:23:5b 3245911026 -9381489562 32.45911026 -93.81489562 44:1c:12:99:23:5d 3245911407 -9381490325 32.45911407 -93.81490325 44:1c:12:99:23:5e 3245912170 -9381490325 32.45912170 -93.81490325 06:aa:a0:e3:5f:38 3245893096 -9381491088 32.45893096 -93.81491088 72:13:01:01:99:9a 3245925521 -9381433868 32.45925521 -93.81433868 72:13:01:01:99:9d 3245924758 -9381433868 32.45924758 -93.81433868 etc. After digging deeper (see other posts), I've confirmed Apple is simply storing our personal data to 8 decimal places, but without the decimal point. So all the conversion of Apple's raw values to GPS are off a bit. That is, Apple's wide-open yet highly insecure WPS database stores latitude and longitude as integers representing the real coordinate multiplied by 100,000,000 (i.e., multiply by one hundred million). I think mainly, since we're using Windows tools to get Apple privacy data, that we simply needed to UNDERSTAND better what it is that Apple is allowing everyone on the planet, no matter who they are, to access. I agree with everyone who says the precision for the decimal location in Apple's highly insecure but all-too-public easily accessed WPS database is likely far higher than it needs to be for simply locating an access point. 9a:0f:6f:18:7c:00 3246034622 -9381387329 32.460346 -93.813873 a2:0f:6f:18:7c:00 3246035003 -9381387329 32.460350 -93.813873 a6:0f:6f:18:7c:00 3246034622 -9381386566 32.460346 -93.813866 2a:ad:18:fc:8b:1f 3246102142 -9381381988 32.461021 -93.813820 where all four of those in Shreveport, LA map to the same 100-meter area. 0.0008deg latitude ~ 89 meters 0.0010deg longitude at that latitude ~ 92 meters Apple's WPS (Wi-Fi Positioning System) database appears to be storing our personal BSSID locations using fixed-point integer encoding where Latitude is apparently stored as an integer ~ lat * 1e8 Longitude is stored as an integer ~ lon * 1e8 Hence Apple's WPS database stores coordinates with 8 decimal places: 1e-8 degrees of latitude ~ 1.1 millimeters But the real-world accuracy of Wi-Fi geolocation is nowhere near that. So the location of each individual BSSID is probably within ~10 meters. When you look up your own AP in Apple's database, if you get the raw numbers, all you need to do to convert Apple's stored value back into a normal GPS coordinate, you just divide by 100,000,000. Here's the modified python script that just divides by 100 million the raw data that Apple stores about us in its highly insecure public WPS database. #!/usr/bin/env -S uv run --script # -*- coding: utf-8 -*- # C:\app\os\python\apple_bssid_locator\apple_bssid_locator.py # Queries Apple WPS database for GPS:BSSID location pairs # Implementation based on https://github.com/hubert3/iSniff-GPS # # Usage: apple_bssid_locator.py 11:22:33:AA:BB:CC # Usage: apple_bssid_locator.py 11:22:33:AA:BB:CC --all # Usage: apple_bssid_locator.py 11:22:33:AA:BB:CC --map # # Changelog: # v1p0 20251205 - Initial version # v1p1 20251214 - Added logging to results.txt # v1p2 20251215 - Timestamped results.txt to avoid overwrites # v1p3 20251219 - Limited output to 6 decimal places # v1p4 20251219 - Added raw integer output alongside converted decimals # v1p5 20251222 - Fixed raw to decimal conversion (divide by 100 Million) import argparse import requests import webbrowser import AppleWLoc_pb2 def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument("bssid", type=str, help="display the location of the bssid") parser.add_argument("-m", "--map", help="shows the location on google maps", action='store_true') parser.add_argument("-a", "--all", help="shows all results returned, not just the requested one", action='store_true') args = parser.parse_args() return args def format_bssid(bssid): return ':'.join(e.rjust(2, '0') for e in bssid.split(':')) def query_bssid(bssid, output_file="results.txt"): apple_wloc = AppleWLoc_pb2.AppleWLoc() wifi_device = apple_wloc.wifi_devices.add() wifi_device.bssid = bssid apple_wloc.unknown_value1 = 0 apple_wloc.return_single_result = 0 # request ALL results serialized_apple_wloc = apple_wloc.SerializeToString() length_serialized_apple_wloc = len(serialized_apple_wloc) headers = {'User-Agent':'locationd/1753.17 CFNetwork/889.9 Darwin/17.2.0'} data = b"\x00\x01\x00\x05"+b"en_US"+b"\x00\x13"+b"com.apple.locationd"+b"\x00\x0a"+b"8.1.12B411"+b"\x00\x00\x00\x01\x00\x00\x00" + bytes((length_serialized_apple_wloc,)) + serialized_apple_wloc r = requests.post('https://gs-loc.apple.com/clls/wloc', headers=headers, data=data) apple_wloc = AppleWLoc_pb2.AppleWLoc() apple_wloc.ParseFromString(r.content[10:]) # Build dictionary of results results = {} with open(output_file, "w") as f: for wifi_device in apple_wloc.wifi_devices: if wifi_device.HasField('location'): raw_lat = wifi_device.location.latitude raw_lon = wifi_device.location.longitude lat = raw_lat * 1e-8 lon = raw_lon * 1e-8 mac = format_bssid(wifi_device.bssid) results[mac] = (lat, lon, raw_lat, raw_lon) # Write both raw integers and converted decimals (8 decimal places) f.write(f"{mac}\t{raw_lat}\t{raw_lon}\t{lat:.8f}\t{lon:.8f}\n") print(f"Saved {len(results)} entries to {output_file}") return results def main(): args = parse_arguments() print("Searching for location of bssid: %s" % args.bssid) results = query_bssid(args.bssid) # Determine which BSSIDs to process bssids_to_process = results.keys() if args.all else [args.bssid.lower()] found = False for bssid in bssids_to_process: if bssid in results: lat, lon, raw_lat, raw_lon = results[bssid] if lat == -180.0 and lon == -180.0: continue # Skip entries that were not found if found: print() print(f"BSSID: {bssid}") print(f"Raw latitude integer: {raw_lat}") print(f"Raw longitude integer: {raw_lon}") print(f"Latitude (degrees): {lat:.8f}") print(f"Longitude (degrees): {lon:.8f}") if args.map: url = f"http://www.google.com/maps/place/{lat:.8f},{lon:.8f}" webbrowser.open(url) found = True if not found: print("The bssid was not found.") if __name__ == '__main__': main() # end of C:\app\os\python\apple_bssid_locator\apple_bssid_locator.py -- We need to work together to help Apple understand that it is morally, ethically & legally reprehensible to not allow us to opt out of WPS.