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

Initial wifi configuration without using phone #106

Closed
kumy opened this issue Jan 7, 2020 · 16 comments
Closed

Initial wifi configuration without using phone #106

kumy opened this issue Jan 7, 2020 · 16 comments

Comments

@kumy
Copy link

kumy commented Jan 7, 2020

I didn't found anywhere how to setup the initial wifi configuration without using the official app.

So I've tried to check by myself, looking inside the application. The TLS connections from the java code was easily intercepted, but the application core is compiled in an Android native-library, for which I don't have the necessary skills to dissect it. I failed to decipher the mqtts conversation provisioning the AP wifi parameters as I wasn't able to SSL unpin the native library.

Does anyone have insight on how to accomplish this?

@koalazak I saw in this post #10 (comment) that you successfully sniffed the traffic between the app and the robot. I only can get "alert certificate unknown" with sslsplit when it comes to the mqtts connexion. I'm on Android and tested with latest app version and v2.3.0 without success. Would you please share some pcap + key of the initial wifi setup?

@kumy
Copy link
Author

kumy commented Jan 8, 2020

The solution from @thoro at #10 (comment) unfortunately doesn't work for me. I've tested really old app versions. Those tagged 1.x does not support mqtt, and 2.0.0 to 4.4.2 have ssl pinning active in native library :/

@rwscott1961 you said in post #10 (comment) that you use android, did you finally get sslsplit working?

Anyone with a working sslsplit configuration (iOs users?) could share a pcap file please?

Attempt reuse dst SSL session
Connecting to [192.168.10.1]:8883
===> Original server certificate:
Subject DN: /C=US/ST=MA/L=Bedford/O=iRobot/CN=Roomba-80a7082091334770
Common Names: Roomba-80a7082091334770
Fingerprint: 10:DB:F9:94:C3:76:07:3E:8E:5BE0:6B:B9:2A:E5:F3:0D:A5:D1:05
Certificate cache: HIT
===> Forged server certificate:
Subject DN: /C=US/ST=MA/L=Bedford/O=iRobot/CN=Roomba-80a7082091334770
Common Names: Roomba-80a7082091334770
Fingerprint: 7C:2C:C9:79:DB:40:4A:35:4C:CD5B:FD:F8:F1:67:E6:A0:39:EA:13
SSL connected to [192.168.10.1]:8883 TLSv1.3 TLS_AES_256_GCM_SHA384
CLIENT_RANDOM 72517A9B0C7618C95ED4C2FBBF503BEA83D22D27255BA3BEFAD8E422219035A2 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Received privsep req type 01 sz 86 on srvsock 14
Error from src bufferevent: 0:- 336151574:1046:sslv3 alert certificate unknown:20:SSL routines:148:ssl3_read_bytes
SSL disconnected to [192.168.10.1]:8883
SSL disconnected from [10.42.0.225]:47580
SSL_free() in state 0000001a = 001a = SSLERR (error) [accept socket]
SSL_free() in state 00000001 = 0001 = SSLOK  (SSL negotiation finished successfully) [connect socket]

@rwscott1961
Copy link

rwscott1961 commented Jan 9, 2020 via email

@koalazak
Copy link
Owner

Hi @kumy,
I don't have pcap files of the initial password setup process :/
I do not remember the exaclty setup that I made to sniff the trafic, I tried a lot of things. I barely remember:
ARP spoofing to force the roobot to use one machine as gateway
sslsplit on that gateway
NAT forwarding on that gateway
CA with that robot BLID in the name.
iOS application

I notice your certificate with Subject DN: /C=US/ST=MA/L=Bedford/O=iRobot/CN=Roomba-80a7082091334770
Is your BLID edited with the a? or you misspell generating the cert?

@kumy
Copy link
Author

kumy commented Jan 12, 2020 via email

@kumy
Copy link
Author

kumy commented Jan 17, 2020

I finally got there! Please find prototype there https://github.com/kumy/Roomba980-Wifi/blob/master/initial-config.py @koalazak would you be kind to implement it in dorita980?

Steps to provision the robot

Push a password

  1. Reset to robot (press Home+Spot+Clean until all lights up)
  2. Start Soft AP (press Home+Spot) until sound + green wifi led blink - Eventually try again if the error bip sounds
  3. The password is pushed to the robot using an MQTT Authentication Exchange packet
    echo -n "f023efcc3b29003a313a313537393139353338363a386678376e597156744b67574a39744f" | xxd -r -p | openssl s_client -CAfile robot-ca.pem -connect 192.168.10.1 -quiet -noservername. This output the password back if set correctly.

packet format:

Value Description
0xf0 MQTT Authentication Exchange packet fixed header
0x23 The size of the remaining Bytes after this (35 in decimal)
0xefcc3b2900 Voodoo packet 😸
:1:1579195386:8fx7nYqVtKgWJ9tO Format: :1:timestamp:16 alpha-decimal chars

Note: I have not played using different password format, so use with caution.

Provision wifi settings

Connect using mqtt protocol v3.1.1 and send commands via json messages from the table bellow on the right topic and disconnect after. (I use only 6, 9, 10, 11, 12, it seems to be sufficient for a basic configuration). Having a little pause between commands seems to help the process a bit. Once sent, the SoftAP should turn off and the wifi led should turn fixed white.

  Topic payload Comment
1 delta { "state" : { "timezone" : "Europe/Paris" } } makes the robot bip once of two
2 wifictl { "state" : { "sdiscUrl" : "https://disc-prod.iot.irobotapi.com/v1/robot/discover?robot_id=0000000000000000&country_code=FR&sku=R966040" } } I did not checked what is this api…
3 wifictl { "state" : { "ntphosts" : "0.irobot.pool.ntp.org 1.irobot.pool.ntp.org 2.irobot.pool.ntp.org 3.irobot.pool.ntp.org" } }
4 delta { "state" : {"country" : "FR"} }
5 delta { "state" : { "cloudEnv" : "prod" } }
6 wifictl {"state": {"wlcfg": {"pass": "wifisecretpasssword", "sec": 7, "ssid": "575757"}}} pass as clear text, ssid as hex (mine is WWW here), sec???
7 wifictl { "state" : { "utctime" : 1579291795 } } timestamp
8 wifictl { "state" : { "localtimeoffset" : 60 } }
9 wifictl { "state" : { "chkssid" : true } }
10 wifictl { "state" : { "wactivate" : true } }
11 wifictl { "state" : { "get" : "netinfo" } }
12 wifictl { "state" : { "uap" : false } }

@rwscott1961
Copy link

rwscott1961 commented Jan 19, 2020 via email

@kumy
Copy link
Author

kumy commented Jan 19, 2020 via email

@Hypfer
Copy link

Hypfer commented May 2, 2021

Does this enable cloud-free operation or does it still need to connect to the vendor cloud and/or require other stuff such as creating an account etc?

If it's possible to avoid that altogether, it might be possible to add support to Valetudo

@kumy
Copy link
Author

kumy commented May 2, 2021

Does this enable cloud-free operation or does it still need to connect to the vendor cloud and/or require other stuff such as creating an account etc?

It doesn't require any account creation. Logically, the official app is no use then.

If it's possible to avoid that altogether, it might be possible to add support to Valetudo

I didn't knew about Valetudo, this sound great OSS app! Valetudo developers are free (and welcome) to implement the initial robot wifi configuration in their app - with proper credits ;) "Official' instruction are in repo https://github.com/kumy/Roomba980-Wifi

@kFYatek
Copy link

kFYatek commented Apr 24, 2022

Just to update on this topic: I managed to connect my Roomba i3 using the procedure from @kumy's script, but I had to hexlify both the SSID and the password, as opposed to just the SSID. It seems to use the V3 firmware API (it reports 'ver': '3' during discovery even though the version string reads 2.0.3), so probably that's where the difference comes from.

@v6ak
Copy link

v6ak commented Nov 9, 2022

I've tried to connect Roomba i7 this way. After some adjustments (primarily error handling + parameters), I realized that the MQTT server disconnects during the second connection. I was unable to get a reasonable error message from the library, so I have used Wireshark: (If you provide Wireshark TLS keylog file, it can decrypt the communication.)

First connection (after TLS handshake):

  1. The client sends Roomba a packet with password. (Protocol=MQTT Info=Authentication Exchange)
  2. The server responds something similar back. (Protocol=MQTT Info=Authentication Exchange)

Second connection (after TLS handshake):

  1. Client sends Connect Command with username=$BLID.
  2. Roomba responds with Connect Ack, which is a bit misnomer, because it contains Return Code: Connection Refused: identifier rejected (2).
  3. Client sends timezone publish packet. It seems the Paho library completely ignores that the server has rejected the connection.
  4. Roomba terminates the connection on TCP level by RST packet. (No TLS alert.)

Have you seen something similar?

@v6ak
Copy link

v6ak commented Dec 6, 2022

My fork of @kumy's Python script is there: https://github.com/v6ak/Roomba-Wifi-Initial-Provisioning

It should be easier to use (you can use a config file, without modifying the code and without manually encoding anything), but I haven't succeeded with my i7.

@kFYatek
Copy link

kFYatek commented Dec 6, 2022

@v6ak I forgot to post my version of the script here, it's in this PR for another project: NickWaterton/Roomba980-Python#108

Maybe you'll have more luck with that? It worked with my i3. Although I remember the process being somewhat finicky, I think I might have needed a full factory reset at some point to make it work.

@kumy
Copy link
Author

kumy commented Dec 6, 2022

My fork of @kumy's Python script is there: https://github.com/v6ak/Roomba-Wifi-Initial-Provisioning

@v6ak Please create a PR :)

@v6ak
Copy link

v6ak commented Dec 6, 2022

@kFYatek Thank you, I'll try that.

@kumy While I hopefully haven't broken anything that used to work, I hesitate creating a PR before having a success with the script.

@v6ak
Copy link

v6ak commented Dec 6, 2022

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

No branches or pull requests

6 participants