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

help finding SP3 "nightlight" payload #158

Closed
Nightreaver opened this issue Mar 11, 2018 · 6 comments
Closed

help finding SP3 "nightlight" payload #158

Nightreaver opened this issue Mar 11, 2018 · 6 comments

Comments

@Nightreaver
Copy link
Contributor

Nightreaver commented Mar 11, 2018

Hello

As i have both now, SP3S anbd SP3, i'm trying to find the the proper payload für turning on/off the nightlight of the SP3.

As these are wifi switches I've setup a wifi-ethernat bridge with raspberry to tcpdump the package comunication between AWS and the SP3.

I found out, that there a general "status" request from AWS every 3 seconds.
So i've been capturing and after some delay i turned the nightlight on and off, same for power .. on and off.

Because of the 3sec ping with is pretty exact every 3 seconds.

So I think I figured out which are the corresponding command packages

image

So thepackage with 72byte of data is the control package coming from AWS to turn on/off the device answered by a 560byte response from the device. (compared to 72 -> 568 for regular status)
So further i'm only looking into the packages coming from AWS, not going to, as I guess they dont help me with turning on/off yet.

So in the end I got exactly 4 packages of 72 byte from AWS (which is matching with turning on/off two times)

the data looks like (this is supposed to be night light on)

5aa5aa555aa5aa551b002200714438061b002200000000000d711ae600400000eed5000033276a00a182b7a6f534ea3401000000acc0000081f7721d06ebf9cea409f66bc6b94292

technically after removing the first 56 bytes im left with the payloads

b87bf6605768540fa3aa06564237a781 - nl on
81f7721d06ebf9cea409f66bc6b94292 - nl off
8a47dfd8e413a59dadb07fe6a869d411 - power on
81f7721d06ebf9cea409f66bc6b94292 - power off

i did several dumps, on turning on/off seem to be always same

my problem now is decrypting and reading what is actually going on.
i'm using this

    _response = bytearray.fromhex('8a47dfd8e413a59dadb07fe6a869d411')
    payload = self.decrypt(bytes(_response))

but it doesnt seem right to ... i think i'm missing something
maybe someone can help with that

I was thinking that when I decode the payload, i'll get back a payload like from python-broadlink which is like bytearray(b'\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') but its totally different

making 4 commands in total

nl on, power off
b87bf6605768540fa3aa06564237a781 ->  '2a0f785ce35d0f52643c5d05a002fe70'

nl on, power on
ecbb6ab226a5df9187d93146aad684f8 ->  'efae991be149840e2d90be75f49556d6'

nl off, power off
81f7721d06ebf9cea409f66bc6b94292 ->  '9c61f3959ce3f36a0290eee7e3467b20'

nl off, power on
8a47dfd8e413a59dadb07fe6a869d411 ->  '0db372cbd3cc0e4efed81a607c71fbca'

so they use different encryption or something?

@a1aw
Copy link
Contributor

a1aw commented Mar 12, 2018

Broadlink devices authenticates at the beginning and they will have another key and iv for that session. Have you got those key and iv for decryption? The packet of authentication should be at the beginning of the communication.

@Nightreaver
Copy link
Contributor Author

Oh, I think that is the part I've been missing!
I will check the authentication and report back

@Nightreaver
Copy link
Contributor Author

Nightreaver commented Mar 12, 2018

I've been looking into the dump but couldnt really find any hint of and authentication package, not in the described way.
All I can see is packages that look like
000000000000000000000000000000001b00220000000000000000000000000095c80000000003000000b7a6f534ea34010000000d711ae6004000007928930c004000000d711ae6004000000d716804140700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 which might not tell me anything for now.

But I found out, that the decrypt key, once the device is "setup" stay the same for time being, or at least as long the network isnt changed anymore... means it doesnt matter if I change the device from where I am sending the packets (like from the lib or from AWS)... the key stays same, which will be helpful to decode later.

I also noticed that the key changes whenever you "reset" the device... ie move it to another wifi or similar.
This means I cannot decrypt packages from other sessions, I have to get the key and the package-dump together in order to decrypt the packages properly.

@Nightreaver
Copy link
Contributor Author

Nightreaver commented Mar 13, 2018

So, my guess was right. When you move the device to antoher wifi network, the "key" will reset, otherwise it will stay the same. So I am thinking that the "initliaze" procedure will always alter the key.

What i did now is brought the python-broadlink on my raspi which i use to capture the packages. First i'Ve been running the manual "power on/power off" procedure, printing out the "key". Verifying its changing away from `0976...'

I did this by adding this early in the send_packet method

    print("-----")
    if type(self.key) == str:
        b = bytearray()
        b.extend(self.key)
        print(''.join(format(s, '02x') for s in b[::1]))
    else:
        print(''.join(format(s, '02x') for s in self.key[::1]))
    print("-----")

I cant tell why self.key turns into str on my raspberry i doesnt do that on my windows machine though - but doesnt matter.

Then I used tcpdump to capture packages going from and to the SP3 (as described above).

On my pc I've then created a new device and changed self.id and self.key.
Then used the snippet (from above) to get the payload. And it worked - finally!!

This is what I got

'132bc0fd34c886c435bd97e75578393f' -> '020000000000fcff0000000000000000' - all off
'573566294daf701625f26108ae96ff83' -> '020000000100fcff0000000000000000' - power on
'43469db5a8c0a199841c2e6c552e65e2' -> '020000000200fcff0000000000000000' - nl on
'654b63765ce9f76b6523d4255d2ddec4' -> '020000000300fcff0000000000000000' - nl on, power on

So there are 4 states in total :) - someone might just have guessed that!

This is also reflects directly in the return state of the check_power method

010000000000fcff... - off
010000000100fcff... -  power on
010000000200fcff... - nl on
010000000300fcff... - all on 

@MayeulC
Copy link
Contributor

MayeulC commented Apr 30, 2018

@Nightreaver, @mjg59 I think that this issue can be closed, together with #73

Thanks a lot @Nightreaver !

@felipediel
Copy link
Collaborator

Fixed with #159. Thank you!

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

4 participants