nayaverdier / halohome

A python library to control Eaton HALO Home Smart Lights
MIT License
1 stars 1 forks source link

Not working for large deployment #5

Open oyvindkinsey opened 12 months ago

oyvindkinsey commented 12 months ago

My understanding is that Avi-on's protocol changes based on the deployment being large or small (you can see the Location entity has 'size' field), and the current library only supports small I think.

With my deployment now being large, there's two things that happens: 1) adding 0x80 + device_id to get the first byte overflows; I suspect that the device_id has to be split across the two bytes (offset by 0x80) now? 2) connecting to the mesh and sending a packet to a low value device id succeeds, but is not acted upon by the mesh. No reaction by the device.

What can I do to help debug this?

nayaverdier commented 12 months ago

I no longer have these lights so am not able to debug much myself, but the way I originally reverse engineered it was by decoding the Bluetooth data while using the halo home app, have you been able to inspect that at all?

oyvindkinsey commented 12 months ago

I've managed to capture the two characteristics being written - will see if I can figure out how to go from there. Any pointers?

-cheers

On Sun, Jul 23, 2023, 2:17 PM nayaverdier @.***> wrote:

I no longer have these lights so am not able to debug much myself, but the way I originally reverse engineered it was by decoding the Bluetooth data while using the halo home app, have you been able to inspect that at all?

— Reply to this email directly, view it on GitHub https://github.com/nayaverdier/halohome/issues/5#issuecomment-1646961499, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2MAVRQNROXI4LONCWZN3XRWIH5ANCNFSM6AAAAAA2UWXL6A . You are receiving this because you authored the thread.Message ID: @.***>

oyvindkinsey commented 12 months ago

OK, I'm making progress - here are the three writes that I saw when I changed the brightness of a group from the app:

import csrmesh 
from binascii import unhexlify, hexlify

combined = ['b4d9f8008086e45a79b77d25ab96876ff7f65f84' + 'df5cc1e7e04937', 'b5d9f800804d72f1e2dc6c9708c45df713294280' + '9374aeb90ccb37', 'b6d9f80080a6f928a65cd5cdbf134c9f482f2c63' + 'c20f87f4704f37']

passphrase = '*****
key = csrmesh.crypto.generate_key(passphrase.encode("ascii") + b"\x00\x4d\x43\x50")

for s in combined:
    print('decoding ' + s)
    res = csrmesh.crypto.decrypt_packet(key, unhexlify(s))
    print (res)

Not at all sure if I'm combining the low/high fragments correctly here though, I don't do much python...

decoding b4d9f8008086e45a79b77d25ab96876ff7f65f84df5cc1e7e04937
{'seq': 16308660, 'source': 32768, 'encpayload': b'\x86\xe4Zy\xb7}%\xab\x96\x87o\xf7\xf6', 'decpayload': b'\x00\x00s\x00\x15\x00\x00\x00\x17\x07\x17\x00\x00', 'hmac_computed': b'_\x84\xdf\\\xc1\xe7\xe0I', 'hmac_packet': b'_\x84\xdf\\\xc1\xe7\xe0I', 'eof': b'7'}
decoding b5d9f800804d72f1e2dc6c9708c45df7132942809374aeb90ccb37
{'seq': 16308661, 'source': 32768, 'encpayload': b'Mr\xf1\xe2\xdcl\x97\x08\xc4]\xf7\x13)', 'decpayload': b'\x00\x00s\x00\x16\x00\x00\x00\x15\x1c!\x00\x00', 'hmac_computed': b'B\x80\x93t\xae\xb9\x0c\xcb', 'hmac_packet': b'B\x80\x93t\xae\xb9\x0c\xcb', 'eof': b'7'}
decoding b6d9f80080a6f928a65cd5cdbf134c9f482f2c63c20f87f4704f37
{'seq': 16308662, 'source': 32768, 'encpayload': b'\xa6\xf9(\xa6\\\xd5\xcd\xbf\x13L\x9fH/', 'decpayload': b'\x00\x00s\x02\x06\x00\x00\x00\x07\x06\x06\x14\x1a', 'hmac_computed': b',c\xc2\x0f\x87\xf4pO', 'hmac_packet': b',c\xc2\x0f\x87\xf4pO', 'eof': b'7'}
nayaverdier commented 11 months ago

Looks like it's correctly decoded. decpayload is the important bit, try to capture a bunch of writes of different attributes (brightness, on/off, whatever you can) and go through different lights/groups for each one. That should make it easier to see the pattern of where the device id is being encoded and where the other data is being encoded, if you haven't done that already.

If you're able to tag each decrypted payload with what action you did that resulted in it, I can help compare to the current implementation here.

oyvindkinsey commented 11 months ago

Thanks @nayaverdier ,

Yeah, that's what I'll try - need to renew my adb/wireshark foo though, as it right now takes a lot of work to capture and identify the right packets.

nayaverdier commented 11 months ago

@oyvindkinsey I used this approach to filter down to the relevant packets, might be easier if wireshark is being difficult: https://github.com/nayaverdier/halohome/issues/2#issuecomment-1021921213

IIRC it basically only logs the packets that are useful for debugging like this using that setup.

oyvindkinsey commented 11 months ago

Ah, right - that makes it so much easier! Thanks again!

On Mon, Jul 24, 2023, 4:53 PM nayaverdier @.***> wrote:

@oyvindkinsey https://github.com/oyvindkinsey I used this approach to filter down to the relevant packets, might be easier if wireshark is being difficult: #2 (comment) https://github.com/nayaverdier/halohome/issues/2#issuecomment-1021921213

IIRC it basically only logs the packets that are useful for debugging like this using that setup.

— Reply to this email directly, view it on GitHub https://github.com/nayaverdier/halohome/issues/5#issuecomment-1648773027, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2MATL2EJT6JMH3YWVCWTXR4DIZANCNFSM6AAAAAA2UWXL6A . You are receiving this because you were mentioned.Message ID: @.***>

oyvindkinsey commented 11 months ago

Using https://jsfiddle.net/okinsey/dx8hm1vz/18/ to parse the log file:

b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 00 73 01 0a 00 00 00 00 00 00 00 00'
b'00 80 73 01 0a 00 6a'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 0c'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 01'
b'00 80 73 01 0a 00 01'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 08'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 ff'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 01'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 3c'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 01'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 97'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'e8 50 df ad fe 90 be 8a b8 5d b3 57 a6'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'e8 50 df ad fe 90 be 8a b8 5d b3 57 a5'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 00'
b'00 80 73 01 0a 00 6a'
b'00 80 73 01 0a 00 ff'
b'e8 50 df ad fe 90 be 8a b8 5d b3 57 a4'
b'00 80 73 01 0a 00 ff'
b'e8 50 df ad fe 90 be 8a b8 5d b3 57 ab'

I feel like not all the packets are being captured, but I'm more and more convinced that the e8 50 df ad fe 90 be 8a b8 5d b3 57 ** package is simply the target address.

oyvindkinsey commented 11 months ago

Yeah; the last token is the device_id. Now I just need to figure out how to make such a packet. Getting closer :)

I wonder if it wouldn't be easier simply to try to extract the firmware from one of the bridge devices :D

oyvindkinsey commented 11 months ago

i'm not able to reconcile the logs I get with my actions; it seems like the logs are incomplete.

Is it correct to say that the nRF logs only show the notifications for these two characteristics updating (as sent from the mesh), and not what the phone actually sent? I wonder if the addressing is being done via one of the other characteristics provided by the server, there's an 8005 and 8006 showing up for me as well, but those do not support notifications.

nayaverdier commented 11 months ago

I think you're right, the logs do not show what the phone actually sent. I wonder if it's related to your deployment being large now, I don't remember missing any data on my lights. I guess back to wireshark...

oyvindkinsey commented 11 months ago

Got an nRF52840 dongle to sniff, but can't get any GATT traffic to show up (super weird). Ended up decompiling the Avi-on app instead; lot's of clues there, and various ideas for how to reverse engineer this completely (the app is way too abstracted to simply pull the specific format). When using the bridge via web, I think it simply relays the raw commands (the app basically posts the raw packet), so a simply MITM should allow me to inspect this (I doubt the app is using cert pinning...).