Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use with device already in the network? #48

Open
YeapGuy opened this issue Jan 28, 2024 · 21 comments
Open

Use with device already in the network? #48

YeapGuy opened this issue Jan 28, 2024 · 21 comments

Comments

@YeapGuy
Copy link

YeapGuy commented Jan 28, 2024

Hi,
How technically feasible is it to modify this project to work with official AirTags or other Find My devices? Already working AirTag clones are being sold for $2-4 a piece on Aliexpress, so I don't see a point in spending a lot of time messing with flashing, firmwares and all of that stuff, when I can just buy a working "AirTag" for so cheap.
The only issue for me is that I have an Android phone (I was able to set the tags up using a friend's iPhone), so I need to get something similar to this project working.

@Systm21
Copy link

Systm21 commented Jan 28, 2024

How technically feasible is it to modify this project to work with official AirTags or other Find My devices?

Its impossible, you need the private key and you won't get it from official devices.

Already working AirTag clones are being sold for $2-4 a piece on Aliexpress, so I don't see a point in spending a lot of time messing with flashing, firmwares and all of that stuff, when I can just buy a working "AirTag" for so cheap.

These Tags working with the official Findmy SDK, "our" Tags are working with reverse engineering, nothing official. The China ones are also only working with Apple Hardware, "our" Tags are not working official with ios (but with a workaround).

@YeapGuy
Copy link
Author

YeapGuy commented Jan 28, 2024

I think I can retrieve the private key from the macOS application. Is that all I need?

@biemster
Copy link
Owner

The private key is all you need indeed, but that's stored in the Secure Enclave as far as I know. To my knowledge nobody knows how to get that, but if you have ideas please have a crack at it! (and report back here if you succeed)

@YeapGuy
Copy link
Author

YeapGuy commented Jan 29, 2024

I successfully retrieved the keys from the macOS Find My application.
Screenshot 2024-01-29 at 08 38 41
What's next?

@biemster
Copy link
Owner

the generate_keys.py script generates a random key here:

priv = random.getrandbits(224)

If you change that line and put there the private key you found for your device, then the script generates a .keys file for it. Let me know if that works, and also how you retrieved the key please!

@biemster
Copy link
Owner

On top of that, in case you did find the correct key but you still get zero reports back, it's possible that your fake tag also implemented the key rolling as per spec so you should check if the advertised key from the tag is the same as the advertised key you generated.

@biemster
Copy link
Owner

@YeapGuy any luck on this? I just stumbled by accident on your swift gist https://gist.github.com/YeapGuy/f473de53c2a4e8978bc63217359ca1e4, did you by any chance use this?

@YeapGuy
Copy link
Author

YeapGuy commented Feb 12, 2024

Yep, I used that to get the keys out of the macOS Find My app.
See here for what I (or rather, Malmeloo) managed to do with this: malmeloo/FindMy.py#4 Honestly, I'm quite lost in all of this Find My-related stuff, so I can't give a concise explanation. Best to read the linked issue for yourself, you'll probably understand better what's going on 😄

@biemster
Copy link
Owner

No you can't, trust me. The Code is rolling every 10 Minutes.

He can!

@shiprec
Copy link

shiprec commented Feb 22, 2024

@YeapGuy Is it possible to pull the reports of a device on the network that is not tied to your apple ID?

@humpataa
Copy link

I successfully retrieved the keys from the macOS Find My application.

Do you mind sharing how you did that?

@biemster
Copy link
Owner

Not abandoned :) actually the iOS17 issue (#40) seems to be just resolved, so I'm going to put a bit more time into this again.

Awesome that you managed to decrypt the .record files, I'm planning on adding a script for that here (although @malmeloo in https://github.com/malmeloo/FindMy.py seems to have picked up the ball and did wonderful things on this already)

Your comment is very hard to read, does the public key sent out by your tag in lost mode match the one in the request from request_reports.py?

@samtombson
Copy link

samtombson commented Mar 24, 2024

Hi @biemster, I hope you're well and haven't abandoned this project yet.
I decrypted the .record file of an air tag that's already been added to icloud, got a decrypted.plist which contain:

	<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
	<dict>
		<key>batteryLevel</key>
		<integer>1</integer>
		<key>cloudKitMetadata</key>
		<data>
		%MASKED%
		</data>
		<key>identifier</key>
		<string>%MASKED%</string>
		<key>isZeus</key>
		<false/>
		<key>model</key>
		<string></string>
		<key>pairingDate</key>
		<date>2024-03-24T11:28:16Z</date>
		<key>privateKey</key>
		<dict>
			<key>key</key>
			<dict>
				<key>data</key>
				<data>
				%MASKED%
				</data>
			</dict>
		</dict>
		<key>productId</key>
		<integer>21760</integer>
		<key>publicKey</key>
		<dict>
			<key>key</key>
			<dict>
				<key>data</key>
				<data>
				%MASKED%
				</data>
			</dict>
		</dict>
		<key>secondarySharedSecret</key>
		<dict>
			<key>key</key>
			<dict>
				<key>data</key>
				<data>
				%MASKED%
				</data>
			</dict>
		</dict>
		<key>sharedSecret</key>
		<dict>
			<key>key</key>
			<dict>
				<key>data</key>
				<data>
				%MASKED%
				</data>
			</dict>
		</dict>
		<key>stableIdentifier</key>
		<array>
			<string>%MASKED%</string>
		</array>
		<key>systemVersion</key>
		<string>2.0.61</string>
		<key>vendorId</key>
		<integer>76</integer>
	</dict>
	</plist>

I've bit changed generation in the generate_keys.py file like this

5a6
> from math import ceil
25c26
<     priv = random.getrandbits(224)
---
>     priv = int.from_bytes(base64.b64decode('%MASKED%'))
28,29c29,33
<     priv_bytes = int.to_bytes(priv, 28, 'big')
<     adv_bytes = int.to_bytes(adv, 28, 'big')
---
>     priv_length = ceil(priv.bit_length() / 8)
>     adv_length = ceil(adv.bit_length() / 8)
> 
>     priv_bytes = int.to_bytes(priv, priv_length, 'big')
>     adv_bytes = int.to_bytes(adv, adv_length, 'big')

generate a valid .keys file with a matching private key, but still can't get the location after executing request_reports.py.
What am I doing wrong?

@biemster
Copy link
Owner

generate a valid .keys file with a matching private key, but still can't get the location after executing request_reports.py. What am I doing wrong?

did you confirm with something like nRF connect that your tag is broadcasting the same key as in the .keys file?

@samtombson
Copy link

Your comment is very hard to read

Sorry about that, was posting a comment from my phone and the layout broke, I fixed the post

does the public key sent out by your tag in lost mode match the one in the request from request_reports.py?

Unfortunately, no

@biemster
Copy link
Owner

biemster commented Mar 24, 2024

It doesn't match or you didn't test? Sorry I did not read my own question well enough

@samtombson
Copy link

samtombson commented Mar 24, 2024

did you confirm with something like nRF connect that your tag is broadcasting the same key as in the .keys file?

In my case it's not possible, the tag is already far away from me and I can't just sniff signal

@samtombson
Copy link

samtombson commented Mar 24, 2024

It doesn't match or you didn't test?

The public key from the decrypted.plist does not match the public key I got from .keys file running generate_keys.py, that's what I meant

@biemster
Copy link
Owner

It doesn't match or you didn't test?

The public key from the decrypted.plist does not match the public key I got from .keys file running generate_keys.py, that's what I meant

Ok, are you able to craft a request with the public key from the decrypted plist? That should return reports.
I think there is a bit of logic involved to generate derived public keys from the root private key you got from the .record. I did not work with that yet, but @malmeloo did so you'll probably find an answer if you ask in his repository.

@samtombson
Copy link

Ok, are you able to craft a request with the public key from the decrypted plist? That should return reports.

Yes. I'll give it try and let you know

@malmeloo
Copy link

You will not be able to directly retrieve reports using that key. The "shared secret" values in the plist you have are used as a seed which can be used to generate a sequence of keys for the AirTag; it then rotates through these keys on a timed interval to prevent other people from tracking you.

My library has a feature to find possible private keys for a given time period; you can check out an example here. You'll probably need to request location reports for all of the keys it generates in order to get an accurate location history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants