From Newsgroup: comp.sys.mac.advocacy
Marian wrote:
Apple's system is so different from everyone else's system that it was trivial for me, a nobody, to do it - using open source code out there.
One perfectly reasonable disagreement is that Chris repeatedly disputed
my personal ad hoc characterization that it is "trivial" to get the location
of up to 400 APs near any given AP in Apple's highly insecure but very public WPS database.
That's fine as adults can disagree on effort given differing skill sets.
a. Chris repeatedly claimed it was not trivial
b. I easily proved that it was excessively trivial
Too trivial, in fact.
Anyone can do it.
To prove that this is trivial, even as Chris clearly opined that he felt it wasn't trivial (where trivial is in the eyes of the beholder, I guess),
here is what I've modified just today to convert the raw integer values
Apple stores in its highly insecure but very public WPS database to the typical decimal values we plug into our GPS location devices.
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.
--- Synchronet 3.21a-Linux NewsLink 1.2