seemoo-lab / openhaystack

Build your own 'AirTags' 🏷 today! Framework for tracking personal Bluetooth devices via Apple's massive Find My network.
https://owlink.org
GNU Affero General Public License v3.0
8.44k stars 462 forks source link

Web server for accessing location data from a web gui #41

Open Bubba8291 opened 3 years ago

Bubba8291 commented 3 years ago

Since there can't be an iPhone app, could there be a web server option to access the data from a web gui, and not just the local device? It's a little frustrating that the Openhaystack app only works on the device that it's installed on. A web server could also open the opportunity to access the location of the lost item remotely. Let me know if y'all would consider this.

Edit: I just realized you can import/export configuration. But my goal isn't to access it on another computer, it's to be able to access it on my iPhone remotely. That's where the web gui would come in handy.

Sn0wfreezeDev commented 3 years ago

That is definitely an option to run a Swift server on macOS that would be able to fetch location reports and forward them to a requesting device, e.g. an iPhone. The main issue is that we would need a macOS server and those are quite expensive.

If you have some cheap / free options, I would be happy to have a look into it.

greatjack1 commented 3 years ago

I would be willing to put something together. Does apple rate limit location api requests?

Bubba8291 commented 3 years ago

The main issue is that we would need a macOS server and those are quite expensive.

Just to clarify, you mean a cloud macOS server not a physical macOS server that someone hosts? Because I was picturing each person that has openhaystack on their mac to have an option that would allow them to have a web server for openhaystack. But I'm opened to whatever. After all, y'all are the developers.

Sn0wfreezeDev commented 3 years ago

@greatjack1 as far as we know there is no rate limiting. I would recommend a new Apple account for this. @Bubba8291 Yes your suggestion would work, but it would expose your private Mac to the internet and to all sorts of attacks. That's why I suggested a cloud server with macOS.

I found some companies that sell them for 25$/month, which seems to be a reasonable price.

greatjack1 commented 3 years ago

@Sn0wfreezeDev Any chance you have an api spec I can use? Like a postman collection containing sample requests for obtaining location data from apples servers?

Bubba8291 commented 3 years ago

@Sn0wfreezeDev makes sense to have a cloud server over a local web server. How would you tell accounts apart from each other though? Sign in with Apple? Sign in with iCloud?

Sn0wfreezeDev commented 3 years ago

@greatjack1 Unfortunately we do not have a Postman collection, but that would be a nice addition. So at the moment the Apple API communication is implemented in Objective-C https://github.com/seemoo-lab/openhaystack/blob/acdae59b3985be18c054c2140d688582646d7fc7/OpenHaystack/OpenHaystack/ReportsFetcher/ReportsFetcher.m#L121 It should be portable to pure Swift running on Linux or even another programming language. The requests are quite simple, you basically send an array of ids and get an array encrypted location reports. The only problem is the authentication headers that are needed. Those can only be generated on Apple Hardware and can only be extracted using a Jailbreak or our Apple Mail Plug-In. So it would be possible to create a Mac server that runs on Swift which communicates with a running Apple Mail instance that has the plug-in installed.

@Bubba8291 You would not need any authentication. For this any iCloud account can download any location reports. Therefore, a simple clean account that is just connected to this one server Mac would be sufficient.

Sn0wfreezeDev commented 3 years ago

Okay I had some time today to go for an idea of a simple self hosted server combined with an iOS app.

You can start the server on your local Mac, expose it to the internet with ngrok and use the iOS App to show where your devices are.
The code is available here: https://github.com/Sn0wfreezeDev/openhaystack/tree/simple_server

Please see this as a first draft. I don't know if I have more time in the near future to shape it.

junleus commented 3 years ago

Awesome! working great.

there are little things that the IOS app only keeps the first imported plist files. change the icon or rename the accessory will not save after Closed the App. even deleted all accessory and imported another plist file.

Sn0wfreezeDev commented 3 years ago

Thanks for pointing it out. The iOS app is currently not part of our release and I have only very limited time to work on it. I'll try to address those issues in the future

da-stoi commented 3 years ago

Okay I had some time today to go for an idea of a simple self hosted server combined with an iOS app.

You can start the server on your local Mac, expose it to the internet with ngrok and use the iOS App to show where your devices are. The code is available here: https://github.com/Sn0wfreezeDev/openhaystack/tree/simple_server

Please see this as a first draft. I don't know if I have more time in the near future to shape it.

@Sn0wfreezeDev This is awesome! I was looking through what the endpoint returned and was a little confused by the payload. I looked through the iOS app you build to see how it was handling it. I think I found where it converts the payload into longitude and latitude, but with my extremely limited swift knowledge I have no clue how it's doing it.

I was looking to recreate the function in JS for a possible website view instead of an iOS app, but I'm not 100% sure on that final step of converting the payload. I was wondering if you could shed some light on it, or maybe link to a resource that could explain a little more in depth what is going on.

Any help would be greatly appreciated!

Sn0wfreezeDev commented 3 years ago

On the iOS app I receive the exact same payload as on the Mac app. Therefore, it also performs the same actions to handle the payload. For a JS web guy, you need to ensure that the actual private keys for decryption are stored locally (using web store or something similar). I'd not like that user uploads his/her private keys to some web hosted database.

The received data is handled like this: 1) The received data is converted to JSON 2) The payload is decrypted (see here) 2.1) For the decryption you need to perform ECDH. This is mostly implemented in the BoringSSL part of the apps 2.2) After decrypting you get a binary that has a specific data format. 3) Parse the decrypted data to receive lat / long. Check out the image I attached from our paper. It explains the data format used. image

hatomist commented 3 years ago

You can use Grafana dashboards to do that, more here: https://github.com/seemoo-lab/openhaystack/issues/63#issuecomment-869193289

Loic760 commented 3 years ago

@da-stoi Did you start something in JS or whatever you can use to make a gui ? It would be great if we could work together on that as I'm also pretty interested ;)