Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Finish API documentation #3

Open
FuzzyMistborn opened this issue Oct 29, 2019 · 101 comments
Open

Finish API documentation #3

FuzzyMistborn opened this issue Oct 29, 2019 · 101 comments
Assignees

Comments

@FuzzyMistborn
Copy link
Owner

We've got the basics regarding camera stream/images. Most important to me is the ability to control certain aspects of the cameras, like the schedule (ie disable motion sensor), and maybe even turn the chime on/off.

I've tried doing a MITM to try to uncover more but can't get it to work. Other ideas welcome.

@FuzzyMistborn FuzzyMistborn pinned this issue Oct 29, 2019
@bachya
Copy link
Collaborator

bachya commented Oct 30, 2019

I've tried a MITM proxy for these actions, too, with no luck.

I did see something interesting while setting the mode: while on the same network as the Eufy hub, I couldn't see any obvious API calls, but the mode was successfully set; while on a cellular network (and, again, with the proxy in the middle), the mode changes never succeeded. No clue what that means.

Any Android users out there who'd be willing to decompile the app and see what is going on?

@FuzzyMistborn
Copy link
Owner Author

The APK is available online on APK Mirror. https://www.apkmirror.com/apk/anker/eufy-security/

@bachya
Copy link
Collaborator

bachya commented Oct 31, 2019

I was able to decompile. On the hunt.

EDIT: Well, after several hours, I'm reminded how difficult Java is. 😆I don't see any particular API that gets called when the mode (Away/Home/etc.) buttons are tapped. Interestingly enough, I also see no reference to /api/v1/web/equipment/start_stream or /api/v1/web/equipment/stop_stream; this, combined with the fact that the mobile app's API calls start with https://security-app.eufylife.com/v1 and the web app's start with ``https://mysecurity.eufylife.com/api/v1`, makes me think we're dealing with different things.

Also worth noting that the web app doesn't appear to support modes currently.

@joepadmiraal
Copy link

I had a quick look at the APK and it seems to have some MQTT classes.
Maybe it's using MQTT instead of HTTP for the mode buttons.

@FuzzyMistborn
Copy link
Owner Author

That would be fascinating if true. Would also likely be true for some of the settings/configuration then too. Still would think the calls would show up in HTTP(S) traffic.

@bachya
Copy link
Collaborator

bachya commented Nov 13, 2019

Fascinating!

Most proxies aren't configured to handle raw TCP over TLS – they only look at HTTP traffic. Perhaps using a SOCKS proxy would be better, since that would redirect all traffic. Unfortunately, the Charles iOS app doesn't handle this yet.

@FuzzyMistborn
Copy link
Owner Author

If you know of an android option I'm happy to give it a go.

@bachya
Copy link
Collaborator

bachya commented Nov 13, 2019

@FuzzyMistborn
Copy link
Owner Author

Will give it a go tonight if I have time.

@FuzzyMistborn
Copy link
Owner Author

FuzzyMistborn commented Nov 14, 2019

Still digging but looks like @joepadmiraal is on to something. Seeing traffic going to "security-mqtt.eufylife.com:8789". Trying to get details.

Drony doesn't give out more details and I can't find a better working option that I can set up. Hit my limit for the evening, hope someone else can take the url at do some more sniffing.

@joepadmiraal
Copy link

Maybe Mallet or Mallory can do the trick?
I would love to do some tests myself but the doorbell is not available in the Netherlands yet.

@mjhram
Copy link

mjhram commented Nov 23, 2019

Hi
I am trying to use the API's. The login is successful, but the get device list returned no data!
{
"code": 0,
"msg": "Succeed."
}
what am I doing wrong?

@gingermike
Copy link

gingermike commented Dec 1, 2019

I was able to decompile. On the hunt.

EDIT: Well, after several hours, I'm reminded how difficult Java is. 😆I don't see any particular API that gets called when the mode (Away/Home/etc.) buttons are tapped. Interestingly enough, I also see no reference to /api/v1/web/equipment/start_stream or /api/v1/web/equipment/stop_stream; this, combined with the fact that the mobile app's API calls start with https://security-app.eufylife.com/v1 and the web app's start with ``https://mysecurity.eufylife.com/api/v1`, makes me think we're dealing with different things.

Also worth noting that the web app doesn't appear to support modes currently.

I had a quick look at the decompiled APK. I think that the mode changes are handled by the com.oceanwing.battery.cam.guard.logic.ModeManager class.

The setMode method calls through to the ZMediaCom class, which appears to use some classes labelled as using P2P connectivity. This connection is then handled through a native interface - so no idea how it's initiated or where it's going to! I need to fiddle with the REST API - I think some clues might exist there...?

Also, in regards to MQTT it looks like Anker has hardcoded the passwords to their broker 🤦‍♂. Looks like there are thousands of topics, one per mobile device. Messages being sent over the wire appear to be connect/disconnect notifications with IP addresses embedded.

@nonsleepr
Copy link
Contributor

I've looked into decompiled Android app and my understanding is that the doorbell communicates with the cloud via MQTT while the phone gets notifications via FCM with the directions on how to connect to cloud's MQTT broker. Static analysis wouldn't help here. I will try to MITM the app some time later.

@nonsleepr nonsleepr mentioned this issue Dec 11, 2019
@keshavdv
Copy link

While I only have the Eufy Floodlight and not the doorbell to test with, I've been able to identify enough parts of the UDP-based P2P protocol to be able to successfully toggle the light outside of the app. The approach seems to use the same control plane that I think the app uses to talk to the Eufy HomeBase, but I don't have one to confirm. So far, the floodlight seems entirely independent of the MQTT pipeline that seems to exist for the doorbell only.

@nonsleepr
Copy link
Contributor

@keshavdv This is great, do you have any snippets of code you can share, a gist would be enough.

@keshavdv
Copy link

I’ll put something up in a bit, but it’s mostly based on a custom version of https://github.com/fbertone/lib32100 for the initial handshake and custom data packets. Interestingly, I tried the HTTP API you exposed in the other PR to set device params and while the property does seem to exist for the manual light state (1400) and is reported, flipping it only caused the app UI state to update but didn’t actually turn the light on or off.

@nonsleepr
Copy link
Contributor

Have you checked what (other things) changes in the params when you flip the switch in the app?

@nonsleepr
Copy link
Contributor

I was able to capture the contents of the app chatter with https://security-app.eufylife.com. It's pretty much the same is of the WebApp. It obtains a private key for the p2p communication and registers FCM token though. It then talks to the doorbell directly using 32100 protocol (thanks @keshavdv for pointing to it), it uses UDP port 10125 though (maybe just in my case).

The app also talks with security-mqtt.eufylife.com:8789, I wasn't able to decrypt that yet though.

@nonsleepr
Copy link
Contributor

Alright! I have everything I need to start working on p2p part. Just added an endpoint here used to obtain private keys for p2p communication.

@nonsleepr
Copy link
Contributor

@keshavdv What were you able to achieve so far? It seems that p2p communication after the handshake is different from the protocol implemented be the library.

@keshavdv
Copy link

After the initial handshake, the protocol is indeed different, but replaying packet payloads that were generated from the app seems to work pretty reliably to do certain things (change light/detection settings).

I've made progress on reversing the actual protocol itself and I think with the packet types I've decoded so far, we can change most of the boolean/string based parameters that are available in the app. So far, and a bit worryingly, it seems like most control actions are not encrypted/authenticated apart from the actual video stream itself (I think this is where the key returned by the endpoint you linked comes into play).

@nonsleepr
Copy link
Contributor

nonsleepr commented Dec 15, 2019

Oh, you're right! I thought the settings are set via the API, but there's a P2P communication.

Tried to disable the motion detection and that's what I got:

0000  f1 d0 00 3c d1 00 00 01 58 5a 59 48 a4 06 28 00   ...<....XZYH..(.
0010  00 00 01 00 ff 00 00 00 7b 22 63 6f 6d 6d 61 6e   ........{"comman
0020  64 54 79 70 65 22 3a 31 30 31 36 2c 22 64 61 74   dType":1016,"dat
0030  61 22 3a 7b 22 65 6e 61 62 6c 65 22 3a 30 7d 7d   a":{"enable":0}}

Do you also see those XZYH all over the place?

Not encrypting the data above is indeed concerning.

@nonsleepr
Copy link
Contributor

I saw the option to open telnet in the app disassembly. It is probably meant for the base station though. Anyway, would be cool to get telnet access.

@keshavdv
Copy link

Sweet, thanks for sharing! Since I only have one device, I couldn't tell what was user/device specific versus a constant, but it looks like the preamble (XYZH) is the same. Nice find on telnet! I'll see if I can enable it on my device since I think the doorbell and floodlights also act as independent "hubs/stations".

@nonsleepr
Copy link
Contributor

The telnet command is 1247. I tried it via API but that didn't work. I think the API's params endpoint is just for the app and the actual command is sent via p2p. That explains why you weren't available to switch the floodlight.

I'll implement the p2p option setting in the next few days.

@fullphat
Copy link

fullphat commented Aug 7, 2020

Any update on when floodlight cam Homebridge integration might be possible? Even if I could only turn the security lights on and off via HomeKit, that would be fantastic! 👍

@JanLoebel
Copy link

Hi everyone! Thanks for the amazing project and the things you all have already discovered. I've implemented a small client in node/typescript to be able to look further. If anyone is interested in helping to find out more about the protocol / structure and so on, feel free to contact me!

https://github.com/JanLoebel/eufy-node-client

Has anyone tried to access firebase to receive notifications? MQTT seems not to be supported anymore.

@JanLoebel
Copy link

I've created a frida script to disable ssl pinning, intercept and log a some of the traffic (HTTPS / P2P) and a wireshark dissector to get more information already in wireshark.

I've also tried to connect to FCM/GCM to receive push notifications but without any luck. I've tried to create a new "client" and register that with the register-push-token api-endpoint and open another session directly with the already registered push token from the running android app.

Does anyone know how the encryption for the P2P packages work that will send or received from the cloud services? The packages are completely different after the "standard" discovery method..

@nonsleepr
Copy link
Contributor

@JanLoebel Mind sharing what you've got as a gist?

As for P2P exchange, there's another PR that handles that.

@JanLoebel
Copy link

JanLoebel commented Sep 21, 2020

@nonsleepr Thanks, I've posted already before all what I have (wirshark, frida, node-client, ...), in my repository: https://github.com/JanLoebel/eufy-node-client

The P2P exchange locally is handled by the PR I know, but for the Cloud P2P Part is only the discovery working. Sadly I can't easily post the requests because of the authentication/secrets etc.. I will check if I can easily hide/remove that from the logs and then upload also the communication.

Update: I got the push notifications working, checkout the repo.

@bachoo786
Copy link

It seems the protocol is still relatively unchanged apart from the initial discovery mechanism, so while it's at least considerably more difficult for an attacker to find an exposed device, it is still possible. With that said, I think it'd be good to start getting some stuff out in the open to make more progress on the P2P protocol analysis and hopefully get closer to being HA/homebridge compatible.

Screen Shot 2020-05-29 at 12 10 41 AM

Hi @keshavdv

To run an RTSP stream from the eufy doorbell, the link that you have used is that the standard link? or would I have to find a different port in my case?

thanks.

@martinorob
Copy link

Hello, i discover this thread that make me happy :) thank you all for the job.

I would like to automate the security mode from my domoticz (if possible using dzvents).

I already set up the connect sequence to get my token : OK
I already setup the dev_devs_list to get the list of devices : OK
-> I have in the return a lot of information like that (here is a partial extrat of my return
"station_conn": {
"station_sn": "manually removed",
"station_name": "manually removed",
"station_model": "T8002",
"main_sw_version": "2.1.0.5h",
"main_hw_version": "P1",
"p2p_did": "manually removed",
"push_did": "manually removed",
"ndt_did": "manually removed",
"p2p_conn": "manually removed",
"app_conn": "manually removed",
"binded": false,
"setup_code": "",
"setup_id": "",
"wifi_mac": "8C:85:manually removed"
},
"family_num": 0,
"member": {
"family_id": 19171,
"station_sn": "manually removed",
"admin_user_id": "manually removed",
"member_user_id": "manually removed",
"short_user_id": "0000",
"member_type": 2,
"permissions": 0,
"member_nick": "",
"action_user_id": "manually removed",
"fence_state": 0,
"extra": "",
"member_avatar": "",
"create_time": 1566489076,
"update_time": 1566489076,
"status": 1,
"email": "manually removed",
"nick_name": "manually removed",
"avatar": "https://d10z7gzu6c6vo4.cloudfront.net/users/*manually removed*",
"action_user_email": "manually removed",
"action_user_name": "manually removed"
},

Now I try to get the json response to the API all: https://security-app-eu.eufylife.com/v1/app/equipment/get_dsk_keys
in order to establish P2P connexion later

I use reqbin to test it and i put correctly the header with my token and then content with my station_sn

When I call the API I get a 200 return code (meaning url AND token are OK) but json contain no other information than that :
{
"code": 10000,
"msg": "Failed to request."
}

Can you help me ?

I got my token using this url : https://mysecurity.eufylife.com/apieu/v1/passport/login

thank you

I have the same problem, did you solve this?

@MaxWinterstein
Copy link

As I would love to have more features ending up in my HomeAssistant I digged trough other projects and found this one (which seems not to be mentioned here before):

https://github.com/bropat/ioBroker.eufy-security

Aside from battery status, which is cool, it seems like it is able to change at least the mode of the base station, which I would love!

@amosyuen
Copy link

amosyuen commented Jan 9, 2021

I also ran into the login 10000 error code specifically in hubitat. Using curl it worked fine. I got it to work in hubitat by setting 'Content-Type: application/json' header. Interestingly curl worked without that header.

@89jd
Copy link

89jd commented Apr 5, 2021

Was hoping to download videos from the base station, and wondered if anyone has advice on where to go?

Did some decompiling before finding this thread, and can see it uses the P2P connection to connect to base station, and that is where I should be able to download from the SDCard. Wondered if anyone has managed to do it yet?

I tried calling get_history_records_all on api, and that returns empty (assumedly this is from cloud storage). Is there an equivalent on P2P?

@keshavdv: have you made any progress since the PR? Would be happy to contribute / help out if I can

@JanLoebel
Copy link

@89jd I know that @bropat was working on it, but I don't know if he has finished that feature. Checkout https://github.com/bropat/ioBroker.eufy-security

@89jd
Copy link

89jd commented Apr 6, 2021

@89jd I know that @bropat was working on it, but I don't know if he has finished that feature. Checkout https://github.com/bropat/ioBroker.eufy-security

Cheers for reply. Doesn't look like it does, but looks close. Will dig deeper in to that code, thanks :)

@bropat
Copy link

bropat commented Apr 6, 2021

@JanLoebel, @89jd

This feature is already implemented in the client library eufy-security-client (see here).
The ioBroker adapter already uses this library and also the download of a video (see here).
However, there is currently no documentation other than the "practical example" ioBroker.eufy-security.

@89jd
Copy link

89jd commented Apr 6, 2021

@bropat Amazing. I have just been following the thread on the home assistant forum (that is what I am planning on integrating it into). So great work :). I did stumble upon the client library. Can you run the client directly as a micro-service? Just so I can interface directly?

@bropat
Copy link

bropat commented Apr 6, 2021

@89jd

Can you run the client directly as a micro-service? Just so I can interface directly?

Unfortunately not, but there is here this project by @matijse, which provides an interface as a microservice via MQTT.
Unfortunately, however, the conversion to the new client library is still in progress here.

PS: @matijse, if you need help, let me know.

@JanLoebel
Copy link

@bropat I deprecated my project and referred yours :) Great work!

@bropat
Copy link

bropat commented Apr 6, 2021

@JanLoebel ok, thanks :) if you want to contribute you are welcome ;) (or anybody else)

@89jd
Copy link

89jd commented Apr 6, 2021

@bropat I am happy putting this as a question on your page, but just wanted to check, Is there a way to list all events on sdcard, and bulk download (like the MacOS app does)?

Thanks

@bropat
Copy link

bropat commented Apr 8, 2021

@89jd Yes, but only if you use the client library and program it yourself. ;)

@89jd
Copy link

89jd commented Apr 8, 2021

@89jd Yes, but only if you use the client library and program it yourself. ;)

That's fine! Any pointers to where the command to list the files is?

@bropat
Copy link

bropat commented Apr 8, 2021

Any pointers to where the command to list the files is?

Good question, I checked now and saw that I haven't implemented that part (http api call) yet :P
With a little patience I will catch up in the next days.

@89jd
Copy link

89jd commented Apr 8, 2021

Nice one, no huge rush, happy to help with the dev, if you have the api it should be hitting!

Out of interest, to get the file list, do you have to go via the eufy servers? Rather than through p2p directly?

@bropat
Copy link

bropat commented Apr 9, 2021

Out of interest, to get the file list, do you have to go via the eufy servers? Rather than through p2p directly?

Yes, unfortunately it is.

@bropat
Copy link

bropat commented Apr 10, 2021

@89jd

I have released the new version (0.7.2) which now includes the necessary HTTP Api calls.
The method you need is getVideoEvents or getAllVideoEvents.

Basically, here's what you need to do now:

  1. get the following values from all videos using the HTTPApi method getAllVideoEvents:
    • station_sn
    • device_sn
    • storage_path
    • cipher_id
  2. Open a P2P connection to the relativ station
  3. use the Station method startDownload to download all videos one by one by using the parameters you got in the 1st call
  4. you get the data of the respective video now over the event start_download
  5. Process the data and save to file

@89jd
Copy link

89jd commented Apr 10, 2021

Brilliant. Much appreciated!

That was a quick turn around :)

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

No branches or pull requests