koalazak / dorita980

Unofficial iRobot Roomba and Braava (i7/i7+, 980, 960, 900, e5, 690, 675, m6, etc) node.js library (SDK) to control your robot
MIT License
942 stars 149 forks source link

roomba 980 firmware 2.0.0-34 ready? #10

Closed koalazak closed 7 years ago

koalazak commented 7 years ago

What about this new firmware update? Does anyone here upgrade their roomba? I heard that the new firmware no longer listens on port 443. For now I recommend deny internet access to your roomba to keep v1.6.6 and enjoy dorita980.

j-vanetten commented 7 years ago

Mine stopped working, and yup, It's firmware 2.0.0-34. :(

xibriz commented 7 years ago

Does the roomba upgrade automaticly?

koalazak commented 7 years ago

yes @xibriz. but 2.0.0-34 seems to be a beta version only for few users. on 2.0.0. will be update for everyone.

koalazak commented 7 years ago

Hi @TheMasterBaron thanks for reply!

please, can you run this code and share the output?

test.js

const dgram = require('dgram');

const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  server.close();
  console.log(err);
});

server.on('message', (msg) => {
  try {
    var parsedMsg = JSON.parse(msg);
    console.log(parsedMsg);
    process.exit();
  } catch (e) {}
});

server.on('listening', () => {
  console.log('Looking for robots...');
});

server.bind(5678, function () {
  const message = new Buffer('irobotmcs');
  server.setBroadcast(true);
  server.send(message, 0, message.length, 5678, '255.255.255.255');
});

Is something like this:

$ node test.js
Looking for robots...
{ ver: '2',
  hostname: 'Roomba-xxxxxxxxxxxxxx',
  robotname: 'Dorita',
  ip: '192.168.1.104',
  mac: 'xx:xx:xx:xx:xx:xx',
  sw: 'v1.6.6',
  sku: 'R98----',
  nc: 0,
  proto: 'http' }

thanks!

KleemannT commented 7 years ago

Output from test.js:

{ ver: '2', hostname: 'Roomba-xxxxxxxxxxxx', robotname: 'Heike', ip: '192.168.1.15', mac: 'xx:xx:xx:xx:xx:xx', sw: 'v2.0.0-34', sku: 'R98----', nc: 0, proto: 'mqtt' }

koalazak commented 7 years ago

proto: 'mqtt' oh crap...

koalazak commented 7 years ago

@KleemannT thanks! can you test one more thing please?

cou can try deny the internet connection (not lan) to your roomba from the router (parent control or something), soft restart the roomba and try to send commands using dorita980 to look if its listen on port 443 or 80? (maybe if new firmware detect no internet connection to the cloud, then open local API, i dont know.)

thanks!

KleemannT commented 7 years ago

internet access locked for Robot soft reset no connection with dorita980 portscan against robot from 1-65535 open port on TCP:8883

koalazak commented 7 years ago

thank you @KleemannT ! sounds like the new firmware is no longer using http/s portocol and now use mqtt protocol on port 8883. MQTT is more apropiated for IoT things, btw. When my roomba updates her firmware I'm going to have a lot of work to do in dorita980 ¬¬

thanks!

CLARENNE-Q commented 7 years ago

Hi everybody,

First of all, thanks for this good documentation/code it's really appreciated !

I have the same issue:

@
node index.js 
Looking for robots...
{ ver: '2',
  hostname: 'Roomba-30F88508216136XX',
  robotname: 'Terminator',
  ip: '192.168.2.22',
  mac: '80:A5:89:AA:DB:XXX',
  sw: 'v2.0.0-34',
  sku: 'R98----',
  nc: 0,
  proto: 'mqtt' }

I try to found a TCP port open but nothing:

nmap -sU -p 137,5353 --script nbstat,dns-service-discovery 192.168.2.22
Starting Nmap 7.40 ( https://nmap.org ) at 2017-01-24 22:59 EST
Nmap scan report for 192.168.2.22
Host is up (0.047s latency).
PORT     STATE  SERVICE
137/udp  closed netbios-ns
5353/udp closed zeroconf
MAC Address: 80:A5:89:AA:DB:XX (AzureWave Technology)

nmap -p 1883 --script mqtt-subscribe 192.168.2.22
Starting Nmap 7.40 ( https://nmap.org ) at 2017-01-24 23:20 EST
Nmap scan report for 192.168.2.22
Host is up (0.013s latency).
PORT     STATE  SERVICE
1883/tcp closed mqtt

sudo nmap -sTU 192.168.2.22
Starting Nmap 7.40 ( https://nmap.org ) at 2017-01-24 23:21 EST
Nmap scan report for 192.168.2.22
Host is up (0.0056s latency).
All 2000 scanned ports on 192.168.2.22 are closed
MAC Address: 80:A5:89:AA:DB:XX (AzureWave Technology)
Nmap done: 1 IP address (1 host up) scanned in 57.50 seconds

Is it possible to make a downgrade ?

koalazak commented 7 years ago

Hi @CLARENNE-Q, sounds like you have a firewell or something (and port is 8883 not default 1883). Try knoking with netcat command:

nc -vz 192.168.2.22 8883

I dont know if its possible to make a downgrade. If you found a way for that, please come back and share how to :)

regards,

IngmarStein commented 7 years ago

@koalazak, has your Roomba updated to 2.0.0-34 already?

Here's the netcat output for an updated robot:

$ nc -vz <ip> 8883
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif en0
    src 192.168.178.20 port 51423
    dst 192.168.178.22 port 8883
    rank info not available
    TCP aux info available

Connection to <ip> port 8883 [tcp/*] succeeded!
CLARENNE-Q commented 7 years ago

Hi all,

Sorry, I'am late:

$ nc -vz 192.168.2.22 8883 found 0 associations found 1 connections: 1: flags=82<CONNECTED,PREFERRED> outif en0 src 192.168.2.14 port 51580 dst 192.168.2.22 port 8883 rank info not available TCP aux info available

Connection to 192.168.2.22 port 8883 [tcp/*] succeeded!

koalazak commented 7 years ago

Hi guys,

@IngmarStein no yet ;/ @CLARENNE-Q you firewall detects tehe nmap, but you can connect with nc to port 8883.

im in conditions to confirm that the new firmware is no longer using http/s protocol and now use mqtt protocol on port 8883. dorita980 needs changes to work with 2.0 firmware.

Im waiting the update in my robot...

sputt commented 7 years ago

I have the 2.0.0-34 firmware as of 1/29/2017. Let me know if there's anything you want me to try

iosdeveloper commented 7 years ago

Does this change only affect local or also cloud API?

LordLiverpool2 commented 7 years ago

I am the latest victim of this unwanted update.

If you need me to do any tests, let me know.

normanth commented 7 years ago

Hi,

I have the same problem.

With "local" access I get "Internal server error".

With "cloud" access I get infos - but Roomba doesn't act.

http://ds:3000/api/cloud/info/status {"status":"OK","method":"getStatus","sku":"R980040","country":"",........

http://ds:3000/api/cloud/action/start {"status":"OK","method":"multipleFieldSet"}

Thanks for the api - very good solution!

Norman

koalazak commented 7 years ago

thanks guys! my roomba is updated now. Im reverse engineering the new api. Will keep you informed!

sheppy99 commented 7 years ago

Mine has updated and stopped talking to the API. Really wish iRobot would stop stuffing about and release a supported API. Not everyone wants several bloated apps on their phone to work stuff when one can do all!!!

Happy to help in any way I can to get this thing working again

jb-home commented 7 years ago

I did some sniffing and 2.0.0-34 is for example now connecting to https://sl7awxqj03.execute-api.us-east-1.amazonaws.com/dev/v1/30F8431482042630/missionhistory?app_id=IOS-12345678-1234-1234-1234-123456789012 And the whole authentication and header stuff looks more tricky. At least not like the previous headers that could be decoded on first sight.

So seems it is really some beta test. I do not know whether it makes sense to decode everything now.

@normanth: I suppose that with the 2.0.0-34 firmware that roomba registers to the beta cloud service. So the original cloud service still has the records of the roomba but does no longer have authorisation on the roomba. That is why the roomba is no longer listening to the original cloud service. Hope after the beta test the cloud service will return to the original, that only the local connection has to be updated to mqtt.

sheppy99 commented 7 years ago

@JensBonse did you see the app taking to that address and then that address talking to the Robot? I've been using the Wireshark built into my Router to try and see what is happening. I see a connection to the server, but nothing to the robot despite it starting and stopping from the App. I wonder whether on WiFi the connection is going direct from ios app to robot, maybe via broadcast and the app reports the status to the server. I am new to Wireshark so could of course be wrong!

jb-home commented 7 years ago

@sheppy99 I saw the App communicating with that address. I did not sniff the the connection of the cloud service with the robot. I just used a man in the middle attack with a proxy. The proxy prevents the direct connection of the phone to the robot. In general there are two ways to communicate with the robot.

  1. Using the cloud as described.
  2. Direct connection of the APP to the robot. (I did not sniff this)
sheppy99 commented 7 years ago

This has given me an idea. Tomorrow I will put my iPhone on 5Ghz and the Robot will be on 2.4GHz. I will see if I can capture any app to robot traffic. The router will have to pass it between the 2 radio bands, so maybe I can log it

koalazak commented 7 years ago

Hi guys, im focusing on the local mqtt api, but talking about cloud i see this flow: 1) Discovery

GET /v1/robot/discover/MY_ROBOT_ID HTTP/1.1
Host: disc-prod.iot.irobotapi.com
User-Agent: aspen/1.9.1.184.1 CFNetwork/808.2.16 Darwin/16.3.0

response:

HTTP/1.1 200 OK
Content-Type: application/json
x-amzn-RequestId: 2c537002-eb08-11e6-aa52-a1421888806e
X-Amzn-Trace-Id: Root=1-58961e0d-00fcdf8067e8fb1f1588e6a5
X-Amz-Cf-Id: f_base64string
{
    "awsRegion": "us-east-1",
    "discoveryTTL": 86400,
    "httpBase": "https://d1nokieziam3wp.cloudfront.net",
    "httpBaseAuth": "https://bcgqn5awqe.execute-api.us-east-1.amazonaws.com/dev",
    "iotTopics": "$aws",
    "irbtTopics": "v005-irbthbu",
    "mqtt": "a2uowfjvhio0fa.iot.us-east-1.amazonaws.com",
    "svcDeplId": "v005"
}

this tells where is the cloud api and mqtt cloud servers (there are two mqqt brokers one inside roomba and other in the cloud)

2) login:

POST /v1/login HTTP/1.1
Host: d1nokieziam3wp.cloudfront.net get this from discovery
Content-Type: application/json

{"associations":{"0":{"robot_id":"MY_ROBOT_ID","deleted":false,"password":":1:1486234474:ONE_PASSOWRD"}},"app_id":"IOS-UUID"}

response:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 38
Connection: keep-alive
Date: Sat, 04 Feb 2017 19:07:58 GMT
X-Cache: Miss from cloudfront
X-Amz-Cf-Id: base64string

{"associations": {"0": "ErrorTooNew"}}

aparently the password change all the time, maybe is generated using a timestamp (the first numers in password field are a timestampt)

(I dont know what is the correct response for that login. i always get errorTooNew)

Talking about Local API, I use arpspoof to tells to the mobile app that my computer is the roomba, so the trafics pass throw me and then I redirect the trafic with ip forwarding to the roomba.

arpspoof -i at0 -t mobile_id roomba_ip

thanks for the help!

sheppy99 commented 7 years ago

By putting the phone and Roomba on separate channels I've just managed to sniff the traffic using my Fritzbox. I can see SSL 8883 traffic direct between my iPhone and Roomba. So it seems Roomba and the app talk directly when on the local LAN. Can't see a lot else but thought this may help.

koalazak commented 7 years ago

Are you using sslsplit to see the trafic content? i see some mqtt packages but I dont found the correct configurations to connect with the local broker. That is what i have for now but i cant connect and listen for topics :/

const mqtt = require('mqtt');

const robotID = 'myROBOTID';
const robotIP = 'myROBORIP';
const myROBOTPASS = 'robotpass';

const url = 'mqtts:/' + robotIP; // what protocol? mqtts? tls? tcp?

var options = {
  port: 8883,
  clientId: robotID, // use robot id? or random generated?
  rejectUnauthorized: false,
  protocolId: 'MQTT', // MQTT or MQIsdp?
  protocolVersion: 4, //4 or 3?
  clean: true, // true or false?
  keepalive: 0,
  will: { retain: true,
     qos: 3,
     topic: robotID, //sure?
     payload: ':1:1486234474:' + myROBOTPASS
  }
};

var client = mqtt.connect(url, options);

client.on('error', function (e) {
  console.log('eeeeerrr', e);
});

client.on('close', function () {
  console.log('on close');
});

client.on('disconnect', function () {
  console.log('on disconnect');
});

client.on('reconnect', function () {
  console.log('on reconnect');
});

client.on('offline', function () {
  console.log('on offline');
});

client.on('packetreceive', function (packet) {
  console.log('packet', packet);
});

client.on('connect', function () { // When connected

  console.log('connectado!');
  // the topic is the robot ID? or other?
  client.subscribe(robotID, function () {
    client.on('message', function (topic, message, packet) {
      console.log("Received '" + message + "' on '" + topic + "'");
    });
  });

  // publish a message to a topic
  // client.publish('hello/world', 'my message', function() {
  //  console.log("Message is published");
  //   client.end(); // Close the connection when published
  // });
});
akpotter commented 7 years ago

@koalazak I got successfully login:

request:(password looks like does not change every time)

POST /v1/login HTTP/1.1
Host: d1nokieziam3wp.cloudfront.net get this from discovery
Content-Type: application/json

{"associations":{"0":{"robot_id":"MY_ROBOT_ID","deleted":false,"password":":1:1486234474:ONE_PASSOWRD"}},"app_id":"IOS-UUID"}

response: (every key changes every time)

{"associations": {"0": "Success"}, "credentials": {"SecretKey": "GIVED_40bits_KEYS", "SessionToken": "GIVED_1248bits_KEYS", "Expiration": "2017-02-09T04:06:23+00:00", "CognitoId": "us-east-1:a8999d99-f295-4532-990d-d8f06d263138", "AccessKeyId": "GIVED_40bits_KEYS"}}{
}
iosdeveloper commented 7 years ago

Would donating a few $ help the effort to update this library? Really bummed by the update and need an API again.

koalazak commented 7 years ago

nice @akpotter! i can too. Maybe is better put the focus on cloud api now and continue with the local mqtt api later. Im stuck.

@iosdeveloper donations are welcome but honestly they dont burst the process. botcoin address for donations: 189JxfTBWXMDZomGbmdQ1KVwvhJNGD8jFJ

im working on this, be patient:) thanks!

turbochip commented 7 years ago

{"associations":{"0":{"robot_id":"MY_ROBOT_ID","deleted":false,"password":":1:1486234474:ONE_PASSOWRD"}},"app_id":"IOS-UUID"}

Where do you get MY_ROBOT_ID from?

rwscott1961 commented 7 years ago

During the discover, about comment 5 above, it is the x's after the Roomba-.

I'm stuck on the IOS-UUID. All my attempts at looking at any of the communication streams end an SSL alert, certificate unknown.

The local MQTT connection I have got past the connect error of 0x01, to a connect error of 0x05. I haven't been able to determine what the app sends for the username and password :(

thoro commented 7 years ago

Sooo, for everyone a breakthrough ;)

The iPhone app communicates locally via mqtt (obviously) - it only connects to servers that uses a certificate with the right name (e.g. ROBOTID), maybe you even need a CA, I made my server so that is uses the 1:1 naming like the robot.

Now for the connect packet, it needs to contain the Username and Password Flags, uses the robot id as Identifier and as Username and the password we all got as the password, after sending this to the port at 8883 (via nodejs) you get already pumped with notifications from the robot ;)

1040
00044d515454
04
c0
0000
0010 (length hex encoded)
ROBOT_ID (16 bytes)
0010 (length hex encoded)
ROBOT_ID (16 bytes)
0010
PASSWORD (16 bytes)

After we got that, now there's a new problem to tackle: the remaining length field sent from the robot is simply wrong:

5 ' -- ' <Buffer 30 ef bf bd 01> '30efbfbd01' '0�\u0001'
2 ' -- ' <Buffer 00 08> '0008' '\u0000\b'
8 ' -- ' <Buffer 77 69 66 69 73 74 61 74> '7769666973746174' 'wifistat'
172 ' -- ' <Buffer 7b 22 73 74 61 74 65 22 3a 7b 22 72 65 70 6f 72 74 65 64 22 3a 7b 22 6e 65 74 69 6e 66 6f 22 3a 7b 22 64 68 63 70 22 3a 74 72 75 65 2c 22 61 64 64 72 ... > '7b227374617465223a7b227265706f72746564223a7b226e6574696e666f223a7b2264686370223a747275652c2261646472223a333233323233353732302c226d61736b223a343239343936373034302c226777223a333233323233353532312c22646e7331223a333237333831393431332c22646e7332223a333536393031333532352c226273736964223a2238303a32613a61383a63613a62393a3333222c22736563223a347d7d7d7d' '{"state":{"reported":{"netinfo":{"dhcp":true,"addr":3232235720,"mask":4294967040,"gw":3232235521,"dns1":3273819413,"dns2":3569013525,"bssid":"80:2a:a8:ca:b9:33","sec":4}}}}'

That's the Publish (0x30) message sent from the robot, but the length field does not match with the following data, (2 + 8 + 172 = 184), based on the variable length encoding, the robot tells us it's about 3 MB in size, which is not the case. All publish messages <= 127 bytes work fine.

Sadly the remaining length field makes no sense at all:

30 ef bf bd 01 -> 184 bytes 30 ef bf bd 01 -> 165 bytes 30 ef bf bd 02 -> 288 bytes 30 ef bf bd 01 -> 246 bytes

If anyone can make sense of that, would be great!

rwscott1961 commented 7 years ago

I still get 20 02 00 05 for the CONNACK

You mention that "it only connects to servers that uses a certificate with the right name". But I am trying to connect to the robot as a client. So how did you create the client key and certificate to get a 20 02 00 00 CONNACK when connecting to the robot??

I am also interested in how you made the key and cert to allow the IOS app to connect. Using the "right name" with anything dealing with PKI is ambiguous, at least to me.

thoro commented 7 years ago

1) regarding the CONNACK, you are sending something wrong in the CONNECT message. According to here http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html it means wrong authorization, so I guess username, identifier or password are wrong

2) just a self signed ca + certificate with the same settings for country, state, commonName etc:

id-at-commonName=Roomba-{MY_ROBOT_ID},id-at-stateOrProvinceName=MA,id-at-localityName=Bedford,id-at-organizationName=iRobot,id-at-countryName=US

Got that info from Wireshark.

3) Not really easy to make you app connect to your PC, I needed a second notebook, configured as Wireless AP, and then rewriting the MAC and the IP address from the iphone to the robot to my local pc - Would not recommend, took me a total of 14 hours (with figuring out, that it won't work on osx :) ) - 0.5 hours if you have the materials and know what your are doing ^^

Edit:

4) also got the parsing working, my approach: add each byte of the payload, and then try to parse it as json (since everything is json), when it succeeds once, the packet is done

5) for commands to the robot:

Message Type: Publish Topic: cmd Payload: { command: 'stop', time: 1486933961, initiator: 'localApp' };

or: { command: 'dock', time: 1486933961, initiator: 'localApp' }; or: { command: 'start', time: 1486933961, initiator: 'localApp' };

In hex that would look like here:

30410003636d647b22636f6d6d616e64223a227374617274222c2274696d65223a313438363933353238312c22696e69746961746f72223a226c6f63616c417070227d
koalazak commented 7 years ago

Hi @Thoro i have the same setup as you (2nd notebook as AP), cert with asset id and y can see all the trafic mobile<->roomba. But i cant emulate the mobile to connect to the roomba. I get bad auth or bad protocol version response. 1) Wich lib are using? mqtt node module? or plain tls stream to make the packet homemade? 2) You say roomba are using a custom implementation? why mqtt node module doesnt connect? 3) abount the remaining length, the specification says: The Remaining Length is encoded using a variable length encoding scheme which uses a single byte for values up to 127. Larger values are handled as follows. The least significant seven bits of each byte encode the data, and the most significant bit is used to indicate that there are following bytes in the representation. Thus each byte encodes 128 values and a "continuation bit". The maximum number of bytes in the Remaining Length field is four. http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718023

can you share the code you are using to connect and send packets?

thanks a lot!

rwscott1961 commented 7 years ago

Assuming the "username, identifier and password" are the same as the old https ones, I'm pretty sure I have those correct. However, I'm not using a cert with that commonName, stateOrProvinceName, localityName, organizationName, or countryName. Did I mention "right name" was ambiguous when it comes to PKI :) So Im thinking the "wrong authorization" is from the cert.

Not to mention, in some places the password has been base64 encoded, and sometimes not. Details matter :)

As a plus, I'm kinda glad this isn't a piece of cake to figure out. The robot does have access to the entire internal network :)

thoro commented 7 years ago

@rwscott1961 the cert is only needed to emilate the robot, not if you want to access it

Pwd and username are the plain ones used everwhere

@koalazak

1) home made plain tls stream, nothing fancy, just implemented mttq according to spec, can share my class tmrw

2) i believe it has a bug, e.g. Regarding 3) - maybe there's also a protocol issue, and you don't need to subscribe, it just constantly publishes stuff

3) yep that's how it should be, but roomba sends shit 😊

rowanmcfarland commented 7 years ago

I just pulled the certs from my roomba so you can see what it is using, I also have the pem version at the end:


CONNECTED(00000003)
depth=1 C = US, ST = MA, L = Bedford, O = iRobot, OU = HBU, CN = Roomba CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
 0 s:/C=US/O=iRobot/L=Bedford/ST=MA/CN=Roomba-3107462022006660
   i:/C=US/ST=MA/L=Bedford/O=iRobot/OU=HBU/CN=Roomba CA
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIIA3bEwTwar2UwDQYJKoZIhvcNAQELBQAwXzELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRmb3JkMQ8wDQYDVQQKEwZp
Um9ib3QxDDAKBgNVBAsTA0hCVTESMBAGA1UEAxMJUm9vbWJhIENBMB4XDTE2MDYx
NTAyNDMwOFoXDTI2MDYxNTAyNDMwOFowXzELMAkGA1UEBhMCVVMxDzANBgNVBAoM
BmlSb2JvdDEQMA4GA1UEBwwHQmVkZm9yZDELMAkGA1UECAwCTUExIDAeBgNVBAMM
F1Jvb21iYS0zMTA3NDYyMDIyMDA2NjYwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAo4m/YbtfAF13NyfK3F0olNwgmL3Sj9eSb8ZMvlbtbS/lCRDuSEdj
43L7RzHPUdAOoEf5741JteZYnyC2Z0J8/kALAXcKtXUoPE0StxBGJJ0zzcdNryn/
ByaAHi7pj1G2OpE3Dy6hVddECCCbPm4DrR/xmUEyN8eEidpApUYDXTT3gyWW6VbN
xtAtuuwkOHLjKXRFrbLqN0u3SPui7mz4sqDuT4c1V8zUBLzYSRFJJ9tKoiozsafN
+EBaM73VTNKfpWbTX0rHumQn/CY9/FDJW4ISNf0Fe7nCwR5V/vgpM1D905bkmgwO
WbtqhUzk8UhxrWvSPtBqttOzQPfC8HUosQIDAQABo14wXDAdBgNVHQ4EFgQUJ9WU
9k+xEi6rrLG7Hf7qiQM8dR0wDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IB
AQANVao+f1wLanEZ4zDz/sHQ5j63iRRuKcnrb7RFuNl4Upfx7hcPzCZCTQPi697u
4Bjax+wlkLDFNMZWMtUxXr+DM7k31Pd/O9VOSpVmECxSFn+Lu8v5NoUdke+v1NF4
o1BqsBCcAZEGbWvijPNFgqaVjGAaXnipmFdhgAmDeflxZqKw2jj4+scHV3WjMxTJ
QejvxSg7fuDWOQhm/wfxp5R8g4nMPqJH9vQbo/czdm5UGAn0W6T4dCVpuZI9/NF/
S2F+QcNMMZ3ooIibgL6l8tjBwZ4cKrOPG/rPdPO3XiVZZcdJRgCp8DHUGWn1cCxv
axIy6+GggyKXu+56j5TcktCD
-----END CERTIFICATE-----
 1 s:/C=US/ST=MA/L=Bedford/O=iRobot/OU=HBU/CN=Roomba CA
   i:/C=US/ST=MA/L=Bedford/O=iRobot/OU=HBU/CN=Roomba CA
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIBATANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJVUzEL
MAkGA1UECBMCTUExEDAOBgNVBAcTB0JlZGZvcmQxDzANBgNVBAoTBmlSb2JvdDEM
MAoGA1UECxMDSEJVMRIwEAYDVQQDEwlSb29tYmEgQ0EwHhcNMTUwMzEzMDAwMDAw
WhcNMjUxMjMxMDAwMDAwWjBfMQswCQYDVQQGEwJVUzELMAkGA1UECBMCTUExEDAO
BgNVBAcTB0JlZGZvcmQxDzANBgNVBAoTBmlSb2JvdDEMMAoGA1UECxMDSEJVMRIw
EAYDVQQDEwlSb29tYmEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDIooRE+Q2qQ/3SiYbTtwBUwyY/YMncCMrhMoDcvkfJEawL1bHG9eL9c4qXSzec
t22lnY93LsZ80+0nQic5bPz21y89KNAC6Df4Yb4TWUwaZIDocNKjzC4keAKvxmVD
xycKMRM7Vf/f12gVRqXOeFZJUb+RzeIfWGvvNcqSEU234C0REQhtPaT+6jK/Qx04
lepgw8EYM4eoT5Ks10PIGzXemMZu7T44lvCcksog00YAMZaJ7skZ+vnBQhhjQdh+
mJGZtvMCG7Mk1cucu5JPVZwmzT9YKA6NMb3wEsujMI3bhY3QnFtF+a+IrbdjbNy+
/i2mT8yoCs/Q9TaKerT124DDAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwICBDANBgkq
hkiG9w0BAQsFAAOCAQEAWE45Bxe2wpf3/5IRUF0bmf8eXKunsSPlM7+dSo/DKuUz
vyDBQt07NIp9e+OQp3Fojo94C14b27I9UmRPFJRDD3gI8wNKExKCvkUNEAIRVf3w
uRef860RwFodfJWjD4yBEQInLxxCRlCLTJ0gcqiRV8X6HSFCnLGJtIvKqF8hLwdP
m5WfPXr/zHzilTC7745FCZFlOtim5O+nMZMeHZp2urssjFLPvrkb1Q9l+FbF6jMr
gTzcLAd1L3a+NKR/i1TKZ+rn9tNnA9aUAXN9BnxResfBkIEKoQ6HJoFlZyfzKAiW
CRju2zTBnR6vg+kWjPxVCwcGRdzAZeDgc8xFqTxRMw==
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/O=iRobot/L=Bedford/ST=MA/CN=Roomba-3107462022006660
issuer=/C=US/ST=MA/L=Bedford/O=iRobot/OU=HBU/CN=Roomba CA
---
No client certificate CA names sent
Server Temp Key: DH, 1024 bits
---
SSL handshake has read 2506 bytes and written 499 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-SHA256
    Session-ID: 1B81BDF873C57FD50CB9096DA1FDC8A66EBD6705A0CB0433B9625094B5587978
    Session-ID-ctx: 
    Master-Key: 49D5EF728940DC31FDDDA97E4D1D16CAB58DB6BDBBA8ACDB38B54F0660964B72A72BDA931C2737F83D9E6E1BD28EB13A
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1486937197
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---
[root@localhost ~]# openssl s_client -showcerts -servername 192.168.1.150 -connect 192.168.1.150:8883 < /dev/null | openssl x509 -outform PEM > roomba.pem
[root@localhost ~]# cat roomba.pem 
-----BEGIN CERTIFICATE-----
MIIDnjCCAoagAwIBAgIIA3bEwTwar2UwDQYJKoZIhvcNAQELBQAwXzELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRmb3JkMQ8wDQYDVQQKEwZp
Um9ib3QxDDAKBgNVBAsTA0hCVTESMBAGA1UEAxMJUm9vbWJhIENBMB4XDTE2MDYx
NTAyNDMwOFoXDTI2MDYxNTAyNDMwOFowXzELMAkGA1UEBhMCVVMxDzANBgNVBAoM
BmlSb2JvdDEQMA4GA1UEBwwHQmVkZm9yZDELMAkGA1UECAwCTUExIDAeBgNVBAMM
F1Jvb21iYS0zMTA3NDYyMDIyMDA2NjYwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAo4m/YbtfAF13NyfK3F0olNwgmL3Sj9eSb8ZMvlbtbS/lCRDuSEdj
43L7RzHPUdAOoEf5741JteZYnyC2Z0J8/kALAXcKtXUoPE0StxBGJJ0zzcdNryn/
ByaAHi7pj1G2OpE3Dy6hVddECCCbPm4DrR/xmUEyN8eEidpApUYDXTT3gyWW6VbN
xtAtuuwkOHLjKXRFrbLqN0u3SPui7mz4sqDuT4c1V8zUBLzYSRFJJ9tKoiozsafN
+EBaM73VTNKfpWbTX0rHumQn/CY9/FDJW4ISNf0Fe7nCwR5V/vgpM1D905bkmgwO
WbtqhUzk8UhxrWvSPtBqttOzQPfC8HUosQIDAQABo14wXDAdBgNVHQ4EFgQUJ9WU
9k+xEi6rrLG7Hf7qiQM8dR0wDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IB
AQANVao+f1wLanEZ4zDz/sHQ5j63iRRuKcnrb7RFuNl4Upfx7hcPzCZCTQPi697u
4Bjax+wlkLDFNMZWMtUxXr+DM7k31Pd/O9VOSpVmECxSFn+Lu8v5NoUdke+v1NF4
o1BqsBCcAZEGbWvijPNFgqaVjGAaXnipmFdhgAmDeflxZqKw2jj4+scHV3WjMxTJ
QejvxSg7fuDWOQhm/wfxp5R8g4nMPqJH9vQbo/czdm5UGAn0W6T4dCVpuZI9/NF/
S2F+QcNMMZ3ooIibgL6l8tjBwZ4cKrOPG/rPdPO3XiVZZcdJRgCp8DHUGWn1cCxv
axIy6+GggyKXu+56j5TcktCD
-----END CERTIFICATE-----```
rwscott1961 commented 7 years ago

I'm missing something, can't get past the

20 02 00 05

I look forward to the code ....

As for the cloud API, I have to use 1485737522, in place of 1486234474, in the timestamp field to avoid the TooNew or TooOld error, accurate to the second! However I haven't been able to get the app_id correct. If you leave the app_id as a zero length string, you get a nice python stack trace :)

koalazak commented 7 years ago

The thing with the cert with a valid CommonName is that the mobile app is validating the CN field in the roomba cert with the format 'Roomba-{number16}' if it is not valid, then the mobile app disconnect. (the validation is in the mobile app, so you need a selfisgned cert whit this CN if you want to perform a sslsplit to sniff the trafic)

well, you are getting a response (20 02 00 05), im not :p can you share the code you are using? @rwscott1961

koalazak commented 7 years ago

ok, now im sending raw data via tls connection with the content you mention @Thoro:

 var bufferAsArray = [
    0x10, 0x40,
    0x00, 0x04, 0x4d, 0x51, 0x54, 0x54,
    0x04,
    0xc0,
    0x00, 0x00,
    0x00, 0x10,
    0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36
    0x00, 0x10,
    0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36
    0x00, 0x10,
    0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36
  ];
  client.write(new Buffer(bufferAsArray));

and im getting 0x05 ret code too (20 02 00 05)

1) How are you encoding the robot id and password? new Buffer('1234567890123456') ? no reverse, no nothing. 2) The password is the same as we have and use in the 1.6.6 firmware? without the mentioned :1:timestap:pass? 16bytes length? 3) maybe my robot changes his password with all the MITM stuff I try. Can you try the cmd to get the password? (pressing the home button for some seconds then send the command) and sendme the hex values for the correct commando working?

thanks!

fgomecs commented 7 years ago

And... new victim here :) I will be patient and see how you'll do. Thanks geniuses! I wish I could half 10% of your programming experience.

thoro commented 7 years ago

@koalazak

1) just normal string, no mutations 2) yep, 16 bytes, like I wrote, password too 3) could be, whole code attached, just need to enter IP, Username and Password, and you should get loads of output, if not something else is going on -> beta vs. release ... or something like that

Firmware: v2.0.0-34

Btw. using Node v0.12.9 because of my sorrounding frameworks, so adapt where necessary.

irobot.tar.gz

jb-home commented 7 years ago

Reminder: As far as I know the password changes everytime you put the roomba in discovery mode.

koalazak commented 7 years ago

Hi @Thoro, thanks for the code! I get ret code 05 unauthorize with your code too :/ I dont kwnow whats going on... Sniffing I see the password in format 1:1486234474:ONE_PASSOWRD16bytes its weired...

thoro commented 7 years ago

That's interesting.

And when you use that password from sniffing?

koalazak commented 7 years ago

ret code 05 too

rwscott1961 commented 7 years ago

On Mon, 2017-02-13 at 00:07 -0800, JensBonse wrote:

Reminder: As far as I know the password changes everytime you put the roomba in discovery mode.

If this is true, how does the app re-connect without going through the setup procedure??

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

koalazak commented 7 years ago

@JensBonse I dont think so. (when you link a roomba with other device, the old device stills works for example) And i see the same password in the sniff data.