- Access to your Apple ID
- MacBook or Hackintosh
You don't need a MacBook for the actual search (any Linux with Bluetooth will do, or Windows should work too), but you need MacOS to perform step 1 in the steps below
/usr/bin/swift
installed- Python 3 installed with PIP
- VS Code or any other editor you prefer
- A little bit of technical skills
- Lost MacBook (or other Apple device) showing up in iCloud's Find My as offline, but location being updated from time to time via Offline Find
# open "terminal" by searching for "terminal" and clicking on it (cmd+space to open search)
# install homebrew (command copied from https://brew.sh)
# command will run for 5-10 minutes
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# set up environment to work with brew using this command or a similar one that brew prints at the end of its install script for you to run
(echo; echo 'eval "$(/usr/local/bin/brew shellenv)"') >> ~/.bash_profile
eval "$(/usr/local/bin/brew shellenv)"
# install python via brew
brew install python3
# install docker via brew
brew install --cask docker
# clone this repository and install python requirements
cd ~/Downloads
git clone https://github.com/robertsmd/OfflineFindRecovery.git
cd OfflineFindRecovery
python3 -m pip install -r ./src/python/requirements.txt --break-system-packages
# if the above command errors, you may need to remove `--break-system-packages` from the end of the command
# run the automated script
source script.sh
- Get
baUUID
s for which you want to graph historical data. Use 1. from #Manual Steps below - update
baUUIDarr
inscript.sh
to reflect thebaUUID
s obtained above - run
source script.sh
This will create a graph and open the graph in a web browser to show the historical data. NOTE: historical data will not go farther back than 7 days.
- If running into error `line XX, in fetch_reports; reports = await acc.fetch_last_reports(keys)`, run `rm account.json` and re-login to your Apple ID
First, you need to obtain the keypair which is being used to generate the broadcasting public key, along with a shared secret. This has to be done via acessing some files within MacOS. If you lost your MacBook, you can just sign-in to another one (your friend's for example) with your Apple ID and the files will sync there from iCloud. The files are encrypted, so you also need to access the decryption key from your Keychain.
Warning
Please note, that sharing this will allow the person holding your initial keypair to track your devices, even when you are offline, with a very good precision. Don't share the keys with anyone you don't trust.
- Start by signing into iCloud.com and accessing Find My from there.
- Open F12 Developer Tools, switch to Network tab, and find the request ending with
refreshClient
- Next view the response, and find the device you are going to search for, you are interested in
baUUID
, note it down, you will need it later. - Open Terminal on your MacBook, and execute the following command:
security find-generic-password -l "BeaconStore" -g
- From the output, copy the value of
gena
value (it starts with0x
, copy only the part before the quotes on the line, so from the example below the value is0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF
):hajekj@Jan-MacBook-Air bleak % security find-generic-password -l 'BeaconStore' -g keychain: "/Users/hajekj/Library/Keychains/login.keychain-db" version: 512 class: "genp" attributes: 0x00000007 <blob>="BeaconStore" 0x00000008 <blob>=<NULL> "acct"<blob>="BeaconStoreKey" "cdat"<timedate>=0x32303234303231383132313435365A00 "20240218121456Z\000" "crtr"<uint32>=<NULL> "cusi"<sint32>=<NULL> "desc"<blob>=<NULL> "gena"<blob>=0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF "<...>" "icmt"<blob>=<NULL> "invi"<sint32>=<NULL> "mdat"<timedate>=0x32303234303231383132313435365A00 "20240218121456Z\000" "nega"<sint32>=<NULL> "prot"<blob>=<NULL> "scrp"<sint32>=<NULL> "svce"<blob>="BeaconStore" "type"<uint32>=<NULL>
- Download the following script and put the obtained value from above into the variable called
hexKey
. Modify the path to the file infileURL
property to match your username and thebaUUID
(which you obtained earlier) of the device you want to track. - Enable the script to be executed via
chmod +x ./airtag_decryptor.swift
- Execute the script via
./airtag_decryptor.swift
- The result should be a file called
decrypted.plist
in the same folder as the script. Try to open the file with your editor, it should be an XML file.
Now you need the generate the keypairs which are being actually broadcasted by the device, this is important, so that you can find your device in all the devices around you. The keys are generated since the pairing date to up to 48 hours ahead. If you need keys for the future, you can modify the script, or just run it again.
Only
KeyType.PRIMARY
is relevant when searching for a MacBook.
- Download the script and place it in the same folder like
decrypted.plist
file. - In the same folder install FindMy.py via:
pip3 install findmy
- Run the script (it is going to run for couple of minutes and the result will be file called
discovery-keys.csv
)python3 findmy-keygeneration.py
The last thing to do is to take the keys and load them into the discovery tool, which will search for Bluetooth Low Energy beacons, calculate their key and compare it with the list of keys.
At the moment, it is necessary to manually modify FindMy.py's code until the PR is merged in order for the search to work on MacOS. (Update: PR has been merged, but no release has been made yet.)
- Download the script and place it in the same folder like
discovery-keys.csv
file. - Run the script
python3 findmy-discover.py
- Walk around with the device and observe the pings, the closer you get, the lower RSSI (distance displayed is not an indicator of an actual distance).
- The script will produce
discovery-output.csv
file containing all the discovered devices around, but the command-line will output only if the targeted device is found
Go to the last location of your device from Find My map. The sooner the better, the Bluetooth Low Energy broadcast works when your device is not connected to the internet, but it also drains battery. Start walking around slowly. From our tests, the beacon can be picked up every 2 seconds up to 5 minutes, depending on your distance and the surrounding area. Once you pick up the beacon's signal, try to find a bearing by walking around and comparing signal strength. The lower the RSSI, the closer you are. Remember that the signal can bounce around objects etc. The strength and reception varies - for example, I can pick up the signal one floor below, but not from the outside etc. It certainly takes time to locate the device.
You could also create a heatmap from the data with a little bit of effort and Excel spreadsheet from the CSV data outputted.
You can retrieve up to 7 days of location history via Offline Find. This is useful if you want to figure out where was the device moving. This is an advanced thing process, so do this only when you are confident with your technical skills.
This tutorial is dependent on running
findmy
library version with support for MFA
- Install Docker
- Run Anisette server image
docker run -d --restart always --name anisette-v3 -p 6969:6969 dadoum/anisette-v3-server
- Download this script
- Fill out
ACCOUNT_EMAIL
andACCOUNT_PASS
variables with your Apple IDYou can just use any Apple ID, since the Offline Find data is not tied to any specific ID (due to the privacy provided by public key and encryption)
- Filter out the
discovery-keys.csv
to include only keys for the time you want to retrieve the location history for - The script will produce
location_history.json
file, which can then be loaded to Excel (Data
>Get Data
>From File
>From JSON
) - Once you load the JSON to Excel, you will get following columns:
time
- the time the device was detected- Use the following formula to convert it to proper date time field (source):
=DATEVALUE(MID(A2,1,10))+TIMEVALUE(MID(A2,12,5))+(IF(MID(A2,17,1)="+",-1,1)*IFERROR(TIMEVALUE(MID(D2,18,5)),0))
- Use the following formula to convert it to proper date time field (source):
lat
,lon
- latitude and longitudepublished_at
- when the data was uploaded to Find My network, please note that the data is usually delayed by ~30 minutes, but it can be much longerconfidence
- no idea what this actually means, but probably based on RSSI, and seems like the higher the number, the closer the finder device waskey
- public key at the time of finding
- You can then create the 3D Map from the coordinates, confidence and time, to get an actual movement timeline
If this helped you, please consider donating some little money to this effort. We have some plans to make an actual application with UI, so these steps are easier, and will also share some of the funds with authors of the used code.
This project is released as free and open source. If you need any help, feel free to reach out privately, will do my best to help. You can use issues to submit bugs or discuss the future of this.
I would like to turn this code into an actual end-to-end application, so anyone can easily (except for pulling the beacon keys) search for their lost device.
None of this would be possible without the incredible work and effort of the following:
- OpenHaystack's research
- FindMy.py
- YeapGuy's decryptor
- Martin and Karel - for letting me borrow their MacBooks for testing
- Vlada - for giving me this idea by having his MacBook stolen
All of this code is released as open source under LICENSE. It is always a bad practice to run unknown code (especially this kind of code) on your machine, unless you know what you are doing (invite your technical friend to help you, or reach out). This project is not collecting any information or sharing it with anyone.
This project is not in any way associated with Apple Inc.