-
Notifications
You must be signed in to change notification settings - Fork 60
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
Implement Samsung Smart Tag #65
Comments
I remember seeing that repo yes, but besides from the very impressive rom dump there is no more info there (as you already mentioned there). The paper on the other hand has a lot of info, and I did not see that one yet. I'll have a look soon. |
@KieronQuinn does your work on the Samsung tags also include creating fake tags, or is it focused on using official tags on non-samsung androids? |
Only official tags on non-Samsung. I'm not sure a similar setup to Open Haystack is even possible with Samsung's network, the Bluetooth communication is a lot more complex and would need replicating. |
Got a moment to spare so some more detail on the above:
Like I said on the linked ticket, I plan to include extensive API documentation with my app once it's released. The app won't require root, but will come in the form of a modified SmartThings APK and a companion app (with the option of using the official SmartThings build and Xposed for rooted users) |
I'm very much looking forward to the docs! My focus is on the BLE advertisement, I'll try to get that info from the paper linked a couple comments up. |
I do have a list of characteristic IDs and what they're for, as well as the output of an endpoint which gives a list of "commands" that can be made on them if that'd be useful to you. I think it includes which are encrypted too. |
Am I understanding correctly that the FD5A uuid in the advertisement is all a lost tag needs to transmit? |
As far as I've been able to find, the only difference between tags that are connected to a device (not lost) and not (potentially lost) is a single flag in the advertisement data on that service: the tag state. Here's two decoded service datas: Tag connected to phone:
Tag not connected to phone:
And here's the Kotlin code for decoding these items: val version = (serviceData[0].toInt() and 0xF0) shr 4
val tagStateAndAdvertisementType = serviceData[0].toInt() and 15
val tagState = tagStateAndAdvertisementType and 7
val advertisementType = tagStateAndAdvertisementType shr 3 and 1
val agingCounter = serviceData[1].toInt() and 0xFF or
((serviceData[2].toInt() and 0xFF) shl 8) or
((serviceData[3].toInt() and 0xFF) shl 16)
val privacyId = ByteArray(8).apply {
serviceData.copyInto(this, startIndex = 4, endIndex = 12)
}.toHexString()
val regionId = (serviceData[12].toInt() and 0xF0) shr 4
val flags = serviceData[12].toInt() and 15
val uwbFlag = flags shr 2 and 1
val encryptionFlag = flags shr 3 and 1
val batteryLevel = flags and 3
val motionDetection = 1 and ((serviceData[13].toInt() and 0xFF) shr 7)
val reserved = ByteArray(2).apply {
serviceData.copyInto(this, startIndex = 14, endIndex = 16)
}
val activityTrackingMode = (serviceData[15].toInt() and 1) != 0
val signature = ByteArray(4).apply {
serviceData.copyInto(this, startIndex = 16, endIndex = 20)
} I'm just checking now to see if there's an enum in the SmartThings APK for what the tag states correspond to, but obviously 5 is connected and 4 is disconnected. Edit: There doesn't seem to be one, it's always checking against just integers. Most likely it's been optimised out of the APK. |
Here's the full list of characteristics for a SmartTag2 from the https://client.smartthings.com/miniature/configure?profileId=*removed* endpoint: characteristics.json And my own table of them that was built before I found that endpoint, based on what they were used for in the APK: eedd5e73-6aa8-4673-8219-398a489da87c (Encryption/Auth Service)
0000fd5a-0000-1000-8000-00805f9b34f (Control Service)
a0e78d39-75b5-4182-8fdc-c4b7365c9062 (?)
|
Hi @KieronQuinn: amazing job. Can you tell me: this kotlin code is decoding the "5AFD" service data, or some GATT characteristic value? |
The service data. Characteristics are encrypted for the most part. |
Thank you! One more thing: in case having 2 SmartTags, is there any way based on this advertisement data to distinguish which one is my BLE scanner seeing, or in case of seeing 5AFD service data I just can be sure there is "A" SmartTag nearby (I can't even be sure it belongs to me)? I though either signature or privacyId is constant but it seems they are keep changing just as the mac. |
I was never able to figure out that bit. SmartThings seems to know which are owned by you, so I've been using that to filter the scan results. The API does send some privacy ID generation related code, so perhaps it's possible to work out which if you own it from that. |
Which API do you use for that? |
https://client.smartthings.com/devices with the right authentication, I'll post the full API documentation soon |
For me, this page is 401, maybe I need first login into somewhere before opening this link? |
Yes, like I said it needs the correct authentication. The auth system is complex so I won't explain it here now, but it's covered in my API documentation which will be posted soon. |
Just thought I'd link this component in case it's interesting: https://github.com/Vedeneb/HA-SmartThings-Find Even though you have to add the Samsung Smart Tags from a Samsung phone, you can use this integration to track the tags afterwards. Once in a while (every 2 weeks perhaps) you have to reauth, but that's basically logging in again on your Samsung account from a browser. |
Yes I saw that, but the web interface is very limited compared to the app |
One thing @KieronQuinn: I just realized, that even SmartThings Find doesn't work without network connection. It's easy to test with airplane mode. Simple it can't tell you wheather your SmartTag is nearby if it doesn't get internet. Pretty lame. Can you confirm / do you know this API works without internet? What I need is an Android app that exists on the same phone as SmartThings Find (if this matters), and able to identify my Tags via Bluetooth even when there is no internet coverage. |
You can parse the service data without internet, but obviously the API call requires internet. The response can be cached just fine though. |
So in case I have the Bluetooth LE Advertisement's Service Data, I can parse it without internet? This sounds great!
What does exactly the API call do? Are my "to-be" solution steps correct here? 1.) API call to initiate some key-exchange (Needs internet) If so - how frequent do we have to call the API, i.e. how long is the key/response valid for? Thank you! |
Do you mind sharing this? It might be not ready yet, but the auth part would help me continue my project. Thank you! |
All documentation is now at https://github.com/KieronQuinn/uTag/wiki |
@KieronQuinn: wow. That's a nice and comprehensive writeup. Would you mind putting me onto the correct track with my idea: Goal: identify my SmartTag (there can be many SmartTags around, and I need to know in my app that it's seeing mine). I can easily get the "BLE Service Data" on the Android phone in my app via Bluetooth (no server communication is needed for this). Q1: Is my intention correct, that I need to decode "Privacy ID" to identify this SmartTag? Important: I need to identify this SmartTag even during my phone is offline (no network coverage): you mentioned earlier here, that I can get the auth, then reuse it later. Q2: Do I have to do this Authentication, and it will let me use the tokens for 90 days? Q3: In case I have thies auth token bearer, is there any known way to decode the SmartTag's ID (again I only need to know if it's mine or not) without network coverage? Note: in case we don't have network coverage SmartThings can't run at all. |
If there is a way to use the privacy ID to know if the Tag belongs to you, I've not found it. In the response for the Device Info call (which needs that authentication token), there are fields in the metadata:
(I removed the content but they're both base64 encoded strings) These might be useful in working it out, and if they are you could store them offline for the check. The privacy ID changes often, so these values would only be part of the process. |
I see thank you! One more question:
Is this change managed by the SmartTag itself without any BT phone nearby or for this change there must be a phone in BT range which can facilitate the process? My scenario is that at first, my phone has network coverage, so it can get new token, new auth, etc, based on your Wiki. Then it will go offline for 1-2 days. During this 1-2 day I wish to monitor my SmartTag (battery and presence) with my phone. During this period there might or might not be other phones (and also SmartTags) around, which phones might or might not have network. I assume SmartTag on its own can't change it's privacy ID, but in case it finds a compatible "peer" phone having valid network, it can suddenly get its new privacy ID via that peer phone from the internet. Is this correct? |
The Tag changes its own privacy ID, it doesn't need another device nor a connection to the internet to do it. The inclusion of the IV and seed in the response from the server suggests the Tag holds the same value in its memory and uses them in combination with something reproducible (perhaps the timestamp to the minute or something) to generate an ID itself. If this is the case, it might be possible to replicate given we can get the IV and seed. The one exception to the "privacy ID changes often" rule is when it's in the "overmature offline" state, which happens between 12 and 24 hours after a disconnect. When this happens, the privacy ID stays the same until midnight, when it resets. If the owner doesn't connect again, it stays this way until the next midnight, and then changes again etc. This is how unknown tag scans work, it provides an ID that's unchanged for a long enough time to be detected, but only when the Tag isn't with the owner so it couldn't be used as a way of a third party to track the owner. |
Totally understandable.
So there are two cases: 1.) Tag is in "idle" state: tag had some network coverage to retrieve IV and seed, and it uses these to generate new ID for itself frequently. 2.) Overmature offline state: happens after disconnect, generation of new ID is scheduled for midnight. Is it a valid point to think that most tags are in overmature offline state in their life? I check mines regularly, but for sure not every single day. So 12-24hours always spent after disconnect (in case we mean "disconnect" when a user quits from SmartThings, or FindMy, etc, whichever establishes a directed BLE connection to the tag). Thank you! |
Nope, unless a tag is lost most will not enter overmature offline. The owner's phone makes sure to connect to the Tag often enough that the state is never entered. uTag does this too. |
Awesome, this is huge! I managed to scan through the whole thing but did not have enough time to dive in properly. Do you @KieronQuinn see a possibility to create "fake tags" like for the Apple (and very recently Google too!) networks? |
I've not looked at that part of the API, since SmartThings handles it for me. I'll see if I can find some time to have a look some time. |
Privacy ID documentation: https://github.com/KieronQuinn/uTag/wiki/BLE-Privacy-ID You can indeed use the response data from the device info call to re-generate the privacy IDs. You end up with 2000 of them, but once you have the pool it's as simple as checking if it contains the privacy ID of a nearby Tag to know if it belongs to you. This could also be used to identify the Tag without directly logging in, so long as you have the required data from the device info response (which could have been captured elsewhere). It would also work offline once the key, IV and seed have been obtained. It's also worth noting that the encryption key from the response also seems to be used for BLE communication, replacing "privacy" in the hash generation with |
In case tag is nearby to my phone, will it use these 2000 privacy IDs and once it finished it will request a generation of a new pool? 15mins * 2000 would mean more than 20days with same privacy pool. Or it will request a new pool in every 15mins? Thank you! |
The pool is always the same. There is no regeneration. |
Yupeee! So in case we can get the pool in our application, we can always identify our SmartTags!
This would mean, that after 21 days, SmartTags' IDs will be repeated from the same pool (until the SmartTag's owner "signes in into SmartThings on a new device"). We can now proceed with our design. Thank you so much @KieronQuinn. |
Hi everyone,
Have you seen this repo?
Samsung SmartTag Hack
Samsung holds a significant market share in the tracker space, and this could be interesting for anyone looking into.
The text was updated successfully, but these errors were encountered: