Hacking a Neato Robotics BotVac Connected
-
I have gotten stuck now on my venture -
Trying to figure out how the Authorization is calculated when it comes to the communication with the Neato. Found a place in the Java-code which mentions the Authorization part but can not figure out where it comes from
com/neatorobotics/android/activities/robot/C0645j.java:~142
private void m5619R() { if (!NeatoApplication.f2866a) { m5646a(); try { URI uri = new URI("ws://" + this.f3263d + ":" + this.f3264e + "/drive"); String b = C0764a.m5847b(); String str = this.f3262c.toLowerCase() + "\n" + b + "\n"; Mac instance = Mac.getInstance("HmacSha256"); instance.init(new SecretKeySpec(this.f3265f.getBytes(), "HmacSha256")); str = C0770g.m5880a(instance.doFinal(str.getBytes("UTF-8"))).toLowerCase(); Map hashMap = new HashMap(); hashMap.put("Date", b); hashMap.put("Authorization", "NEATOAPP " + str); this.al = new C0655t(this, uri, new C0017f(), hashMap, 5000); this.al.m41a(); new Thread(new C0661z(this)).start(); } catch (Exception e) { C0767d.m5867a("ManualCleaningFragment", "Exception", e); } }I have also found what String b is
com/neatorobotics/android/utils/C0764a.java:89: public static String m5847b() {public static String m5847b() { Calendar instance = Calendar.getInstance(); instance.add(12, (int) (((C0742a.m5809b(NeatoApplication.m5360a(), "SERVER_DEVICE_TIME_DELTA_MILLIS", 0) * -1) / 1000) / 60)); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); return simpleDateFormat.format(instance.getTime()); }So what we need to figure out is the following variables:
this.f3262c.toLowerCase()
this.f3265f.getBytes() < I am pretty sure this is secret_keywhen we crack these - we get closer to communicating with the central server
-
Maybe I can help because I figured something out. I can get my computer in between the App and the Neato Botvac.
I have a Asus motherboard with a Wifi adapter. With the software "Wifi Engine" from Asus I can make a Access point in my computer.
So what I have done is disabled my home Wifi Netwerk and configured the Wifi of my computer the same as the home network. Both my phone and the Neato Bot connect to the Wifi point with my computer in between now.
I have installed Wireshark so I could capture some date between the app and the Neato.
Unfortunately I can't make anything out of the data. It's not like the "Packet Capture" app I installed on my phone you can see in my earlier post.Someone any idea what I could do to help us out?
-
Already sniffed the Web Socket traffic - was the first thing I did. No sensible easy output - needs more analysing and so. Need to start on the end with reversing the control-part of the app to see what it does.
-
This is the code I found in the app. there is also a selfsigned certificate, which probably matches the robot.
So the reason why you can't make out anything useful in the traffic: It's SSL encrypted.HttpsURLConnection httpsURLConnection3 = (HttpsURLConnection) new URL(str2).openConnection(); try { if ("neatoProduction".contains("vorwerk")) { httpsURLConnection3.setSSLSocketFactory(C0751h.m5821a(0)); } httpsURLConnection3.setConnectTimeout(60000); httpsURLConnection3.setReadTimeout(60000); if (str.equals("GET") || str.equals("DELETE")) { httpsURLConnection3.setDoOutput(false); } else { httpsURLConnection3.setDoOutput(true); } httpsURLConnection3.setRequestMethod(str); String a = C0742a.m5803a(NeatoApplication.m5360a(), "ACCESS_TOKEN"); if (a != null) { httpsURLConnection3.setRequestProperty("Authorization", "Token token=" + a); } httpsURLConnection3.setRequestProperty("Accept", "application/vnd.neato.beehive.v1+json"); httpsURLConnection3.setRequestProperty("Content-type", "application/json"); httpsURLConnection3.setRequestProperty("X-Agent", C0765b.m5864f());``` -
This is the code I found in the app. there is also a selfsigned certificate, which probably matches the robot.
So the reason why you can't make out anything useful in the traffic: It's SSL encrypted.HttpsURLConnection httpsURLConnection3 = (HttpsURLConnection) new URL(str2).openConnection(); try { if ("neatoProduction".contains("vorwerk")) { httpsURLConnection3.setSSLSocketFactory(C0751h.m5821a(0)); } httpsURLConnection3.setConnectTimeout(60000); httpsURLConnection3.setReadTimeout(60000); if (str.equals("GET") || str.equals("DELETE")) { httpsURLConnection3.setDoOutput(false); } else { httpsURLConnection3.setDoOutput(true); } httpsURLConnection3.setRequestMethod(str); String a = C0742a.m5803a(NeatoApplication.m5360a(), "ACCESS_TOKEN"); if (a != null) { httpsURLConnection3.setRequestProperty("Authorization", "Token token=" + a); } httpsURLConnection3.setRequestProperty("Accept", "application/vnd.neato.beehive.v1+json"); httpsURLConnection3.setRequestProperty("Content-type", "application/json"); httpsURLConnection3.setRequestProperty("X-Agent", C0765b.m5864f());```@enlo That there isn't the problem - if you read my above post the problem is generating the HMAC correctly. I have already proxied the traffic from the app - since they don't used pinned certifications
-
There's good news guys. I finally figured out how the HMAC signature is calculated and now i'm able to control the neato without the mobile application, which offers all kinds of new integration options.
What can be found in
com/neatorobotics/android/activities/robot/C0645j.javais just half of the truth and i was looking at this part for way to long, i'm not sure where this part is used. maybe this would be the part where one can communicate with the neato without making use of the cloudservice. who knows ;)The actual fun starts in
com/neatorobotics/android/p040c/p042b/C0898b.javathe code reveals that there are 3 ingredients making up the HMAC signature- the robot's serial number
- the current date (as also found in the Date header)
- the http body
Together with the robot's secret key we're now able to properly sign the requests.
I've packaged this in a small ruby library https://github.com/kangguru/botvac which is
quite basic and just covers just a little more than i needed for my usecase
but i'm happy to extend this over time.Especially the part to obtain the secret key for the robot just be done via
trafic capturing, which is not the most convinent thing i can think of :)I hope this already helps some people to build new things around their robot. I've mixed the
stuff with ifttt.com and now can plan the cleaning schedule via a google calendar, which
makes it really convinent to skip single days in a given schedule, which ist kinda painful to
solve with the mobile app.happy hacking
-
There's good news guys. I finally figured out how the HMAC signature is calculated and now i'm able to control the neato without the mobile application, which offers all kinds of new integration options.
What can be found in
com/neatorobotics/android/activities/robot/C0645j.javais just half of the truth and i was looking at this part for way to long, i'm not sure where this part is used. maybe this would be the part where one can communicate with the neato without making use of the cloudservice. who knows ;)The actual fun starts in
com/neatorobotics/android/p040c/p042b/C0898b.javathe code reveals that there are 3 ingredients making up the HMAC signature- the robot's serial number
- the current date (as also found in the Date header)
- the http body
Together with the robot's secret key we're now able to properly sign the requests.
I've packaged this in a small ruby library https://github.com/kangguru/botvac which is
quite basic and just covers just a little more than i needed for my usecase
but i'm happy to extend this over time.Especially the part to obtain the secret key for the robot just be done via
trafic capturing, which is not the most convinent thing i can think of :)I hope this already helps some people to build new things around their robot. I've mixed the
stuff with ifttt.com and now can plan the cleaning schedule via a google calendar, which
makes it really convinent to skip single days in a given schedule, which ist kinda painful to
solve with the mobile app.happy hacking
I also figured it out some time ago. You get the robot secret key and serial number when you log in to beehive.neatocloud.com and request https://beehive.neatocloud.com/dashboard
I've written a powershell module where I exposed the entire api (as implemented in the android and iphone app), complete with login. I've yet to upload it to github but I can send it to you if you're unsure about the beehive part. -
As for replacing the cloud server, I don't think it's possible without rooting the robot. The first thing it does when it's connected to the internet is to start an HTTPS Comet session (long polling). The robot will kill the connection immediately if you try to MiTM it with a selfsigned certificate and there is no way to install new certificates on the robot. If anyone has opened the robot I'd be interested in pictures of the motherboard, especially of any pads labeled JTAG.
-
I also figured it out some time ago. You get the robot secret key and serial number when you log in to beehive.neatocloud.com and request https://beehive.neatocloud.com/dashboard
I've written a powershell module where I exposed the entire api (as implemented in the android and iphone app), complete with login. I've yet to upload it to github but I can send it to you if you're unsure about the beehive part.Also nice job! Hope to see a link soon to github so we can experiment with this to.
Thanks for the work.
-
@Ubiquitous yea, i just was too lazy about the login stuff :) but i added the stuff over the weekend, to make it more "end"-user friendly.
-
There's good news guys. I finally figured out how the HMAC signature is calculated and now i'm able to control the neato without the mobile application, which offers all kinds of new integration options.
What can be found in
com/neatorobotics/android/activities/robot/C0645j.javais just half of the truth and i was looking at this part for way to long, i'm not sure where this part is used. maybe this would be the part where one can communicate with the neato without making use of the cloudservice. who knows ;)The actual fun starts in
com/neatorobotics/android/p040c/p042b/C0898b.javathe code reveals that there are 3 ingredients making up the HMAC signature- the robot's serial number
- the current date (as also found in the Date header)
- the http body
Together with the robot's secret key we're now able to properly sign the requests.
I've packaged this in a small ruby library https://github.com/kangguru/botvac which is
quite basic and just covers just a little more than i needed for my usecase
but i'm happy to extend this over time.Especially the part to obtain the secret key for the robot just be done via
trafic capturing, which is not the most convinent thing i can think of :)I hope this already helps some people to build new things around their robot. I've mixed the
stuff with ifttt.com and now can plan the cleaning schedule via a google calendar, which
makes it really convinent to skip single days in a given schedule, which ist kinda painful to
solve with the mobile app.happy hacking
@kangguru I have not done any ruby before and I'm stuck trying to use the gem. I think I've managed to install Ruby, devkit and Git (and added git.exe to path which is needed to be able to 'bundle install'). I don't see any errors, but I am unable to find any binary named botvac to run. I've run "gem env" and none of the variables seems strange.
Any suggestions? I'm on Windows 10 btw.
BR / M
-
FYI, a friend of mine has created a PHP library for the Neato cloud service -> https://github.com/tomrosenback/botvac
It is based on the work @kangguru has done.
-
FYI, a friend of mine has created a PHP library for the Neato cloud service -> https://github.com/tomrosenback/botvac
It is based on the work @kangguru has done.
-
The PHP API Works great for me. I have two questions though.
- The [isCharging] value in the [details] array of the State JSON is always empty, even when it is clearly charging i.e. the [charge] value changes. Any Idea why?
- Whenever I call the pause cleaning, and then return to base, the robot will go back to its base, but it will not dock with it, is there any particular reason for this? and is there a way to have it return to the dock, and actually dock and charge with out just letting run through the entire cleaning cycle?
-
The PHP API Works great for me. I have two questions though.
- The [isCharging] value in the [details] array of the State JSON is always empty, even when it is clearly charging i.e. the [charge] value changes. Any Idea why?
- Whenever I call the pause cleaning, and then return to base, the robot will go back to its base, but it will not dock with it, is there any particular reason for this? and is there a way to have it return to the dock, and actually dock and charge with out just letting run through the entire cleaning cycle?
@Jonathan8301
You know, I've had that happen once or twice before I even found this page, but when I just tried it out, my botvac did dock properly.I just wish there were some way to get at the lower level sensor readings through this, I'd love to be able to see the 'map' that it builds when it cleans....
-
As for replacing the cloud server, I don't think it's possible without rooting the robot. The first thing it does when it's connected to the internet is to start an HTTPS Comet session (long polling). The robot will kill the connection immediately if you try to MiTM it with a selfsigned certificate and there is no way to install new certificates on the robot. If anyone has opened the robot I'd be interested in pictures of the motherboard, especially of any pads labeled JTAG.
@Ubiquitous
I have plans to open up my D80 the day that the warrantee is up, not sure if that will or won't help you any...