ActronConnect Air Conditioner Module – Part 2: Reverse Engineering.

“Security isn’t a dirty word, Blackadder!” – General Melchett.

This post is part of a 3 part series, starting with part 1 and finishing with part 3.

After finding that the new wireless air conditioner control module I bought couldn’t be directly controlled, I needed to reverse engineer how the system worked to determine if it was possible for me to change it in any way.

There’s many means of discovery, but I’ll describe the rough process I used this time.

Step 1 – The Controller.

The first attempt at discovery was simply me putting the IP address of the controller into a web browser. I was very excited to see that the controller responded immediately with a web server showing diagnostic information from the air conditioner. The information was presented in JSON format which made me hopeful that they had provided a JSON method to send commands to the air conditioner. It turned out that wasn’t the case. I wrote an application to send all of the variations that I would expect to use of the JSON data back to the air conditioner, but to no avail. It appears that this site was simply for the developers to perform testing with. That was evident by the complete lack of UI design, the sub-1 second refresh period on the page, and the fact that one of the developers that developed it had their name and the name of their company (the company that was hired by Actron to develop the controller) all over the HTML.

Step 2 – The App and the Controller.

Ok, so at this point I was assuming that I had simply failed to determine the method to send the commands to the controller. No problem, I’ll just see what the phone app sends to the controller. I broke out one of my very very old school, ah, security auditing tools, to allow me to capture the traffic between the air conditioner and the phone. I would normally carry out those kinds of activities from my router, but given the air conditioner and the phone were in the same subnet – the traffic was not traversing the router. I was able to trick the phone and the air conditioner into thinking that I was the other device (I being one of my development machines). I opened wireshark and eagerly awaited the incoming packets, expecting to see the communication between the phone and the controller. Luckily for me, the good people at wireshark didn’t build in a tumbleweed animation to display when there are no packets being captured. That’s right, no traffic. Well nothing of substance anyway – a few broadcasts here and there, but no application traffic. Ok, I was kind of expecting that – whilst I knew the app was communicating with a cloud service somewhere, I’ve seen other apps in the past talk directly when they realise they are on the same network, and bypass the cloud service. Not how it works here however.

Step 3 – The App and the Cloud Service.

Ok, I can play this game. Now came time to use the router to capture traffic to the web server. I put a capture rule in on my Cisco router to pick up any traffic coming from the phone destined for the internet. The router saves the data in a format readable by wireshark. I opened the packet capture and sure enough, there was all of the traffic. Fortunately, and unfortunately, this traffic was encrypted. Not the end of the world though, encrypted data can still be read – it’s just a bit more complex.

The plan at this point, was to create a local web site to proxy requests to the cloud web service. I’d apply a fake certificate, load that certificate into the phone, and then redirect the app to my local web server through some DNS record “adjustments.” That means the app would have used encrypted data to my server, who would then decrypt it, capture it, and then encrypt it for communication with the real web server. Before going to that much effort however, I thought if the app is talking to the cloud service then the air conditioner controller must be as well.

Step 4 – The Controller and the Cloud Service.

I used the same technique again to capture the traffic although this time from the air conditioner. The result was most interesting and rather concerning.

  1. Unlike the traffic from the phone, this traffic was NOT encrypted. This made my life a lot easier for reverse engineering – but that’s not the point. Whilst I agree that you shouldn’t encrypt traffic for the fun of it, there is data here that I consider worthy of protection.
  2. The controller sends “usage” data directly to Actron. That I wasn’t expecting. I need to read the agreement again, but I’m sure there wasn’t a question asking me for my consent to send usage data directly to Actron. The payload of the data included the MAC address of my controller. If Actron recorded this information when they sold the product, they could then link that usage data to the customer. Not that I’m overly concerned about my personal air conditioner habits becoming public knowledge (that sounded dodgy), but it’s very much not the point – companies need to be very particular when it comes to privacy policies and behaviours. The risk for themselves and their customers is too great to do otherwise.
  3. The controller sends ALL of its diagnostics information to the cloud service repeatedly. That information includes – and this is the bad part, my wireless SSID and key, plus all other SSIDs that the controller can detect in the area. So two things – one, having your air conditioner providing information about SSIDs of other people in the area to this cloud service is not ideal, and two, whilst the wireless key seems to be encoded/encrypted, I have no idea what the strength of that is, and am not comfortable with that being sent in so obvious a manner.

So what I’m basically saying is the device sends usage data back to head office (in clear text), it sends a list of all of the wireless SSIDs in range of my house back to the cloud service (in clear text), and it sends my wireless credentials to the cloud service (more or less in clear text). I’m extremely curious to understand why Actron believes they need to capture the password for my wireless network. I can only assume their software developers were not aware of secure coding practices and secure application design practices and simply captured all of the data from the controller, however that concerns me as much as them specifically targeting that information.

This is sadly one of the big problems with industrial component companies starting to integrate with computers. It’s not their area of expertise and the consultants they bring in don’t seem to be concerned about basic security or have a solid understanding of the overall environment in which they operate. It’s not quite as bad as a pace-maker with wireless remote control and no password, but it’s the same concept.

Step 5 – Understanding the cloud service.

It looks like Actron hired a development company to produce the device and the code and that collectively (I can only assume), they decided to use another product called Ninja Blocks who provide an amazon based cloud service for managing home devices – like light bulbs, power points, and apparently air conditioners.

After some digging around, it seemed that I could update my home automation system to send commands to their service in a manner similar to that of the Actron app. However, I’m really not interested in sending this information out to a third party to simply turn my air conditioner on and off, so I needed to continue with my plan to integrate the controller directly.

Step 6 – Understanding the communications protocol.

The only remaining discovery item is to read and understand the traffic. Sometimes this is easy, sometimes it is hard – it depends on the obviousness of the traffic. For example, when I was experimenting with the LIFX light bulb (here), that protocol just looks like raw data – and as such is a bit more complex to reverse engineer. This traffic however was JSON formatted text, so quite easy to read.

After analysing hundreds of packets, it seemed there were only three main flows to worry about.

Flow 1 – Usage Reporting

URL: http://actron-connect.actronair.com.au/usage/log
Action: POST
Frequency: Periodic (generally when something changes)

This one is fairly straight forward – it’s sending my device identifier (the MAC address) plus some usage data. Interestingly enough, when I first wrote the interface to talk to the air conditioner, I didn’t intercept the usage page as I wasn’t overly interested in the data. I did however block the air conditioner getting to the usage site on the firewall however. That actually changed the behaviour of the device – when it couldn’t reach the reporting site, its network behaviour was quite different. I ended up intercepting this as well just to keep the air conditioner controller happy.

Data:

{"blockId":"ACONNECT001122334455","mode":"off","method":"app"}

Flow 2 – Data Reporting

URL: http://actron.ninja.is/rest/v0/block/ACONNECT001122334455/data
Action: POST
Frequency: Periodic (every 20 or so seconds)

The URL itself includes the device identifier (MAC address). There seemed to be 6 different messages sent by the device. Message 1 – 3 contain the information I don’t really want reported back to Actron. Message 4 – 6 however contain current state information for the air conditioner. It’s not overly difficult to work out what the settings correspond to. For example, noticing that fanSpeed was set to 2 when the fan was on high, might imply that 0 and 1 correspond with low and medium. My air conditioner is configured with two zones, so I changed the zone settings a few times on the wall controller to see how the data changed. Basically the enabledZones setting was a list of 8 zones, and it used the first two – with a 1 for on, and a 0 for off.

// 1: Diagnostic Info
{"G":"0","V":2,"D":1,"DA":{"deice_Id":"AConnect","MacAddress":"00:11:22:33:44:55","firmwareVersion":"V0.14d","capabilities":"","BlockID":"ACONNECT001122334455","NumEndpoints":6,"Endpoints":["Info","Network","WifiScan","Settings","ZoneSettings","Live"]}}

// 2: Diagnostic Info (my internal IP address and SSID)
{"G":"0","V":2,"D":2,"DA":{"ConnectionStatus":"111","CurrentConnection":{"SSID":"MySSID","IP":"10.1.1.10","LinkStats":{"errors":"[5,8,9,C]Count=74:`PostHeader::0}HTTP\/1.1 200 OK\r\nCache-Control: private\r\nContent-Type: application\/json; charset=utf-`","stats":[51,0,0,0,9525,14]}},"RemoteServer":"actron.ninja.is"}}

// 3: A wireless scan of my neighbourhood - I've stripped all but 2 SSIDs out though
{"G":"0","V":2,"D":3,"DA":[{"SSID":"SSID1","SigStrength":53,"Security":"WPA2"},{"SSID":"SSID2","SigStrength":48,"Security":"WPA2"}]}

// 4: Current State (Abbreviated)
{"G":"0","V":2,"D":4,"DA":{"amOn":true,"tempTarget":23.0,"mode":2,"fanSpeed":2,"enabledZones":[0,1,0,0,0,0,0,0]}}

// 5: Current State (Zones)
{"G":"0","V":2,"D":5,"DA":[1,0,0,0,0,0,0,0]}

// 6: Current State (Full)
{"G":"0","V":2,"D":6,"DA":{"isOn":false,"mode":2,"fanSpeed":2,"setPoint":21.0,"roomTemp_oC":26.0,"isInESP_Mode":false,"fanIsCont":0,"compressorActivity":2,"errorCode":"","individualZoneTemperatures_oC":[null,null,null,null,null,null,null,null],"enabledZones":[1,0,0,0,0,0,0,0],"liveTimer":null}}

Flow 3 – Command Requests

URL: http://actron.ninja.is/rest/v0/block/ACONNECT001122334455/commands
Action: GET
Frequency: Periodic (every 2 seconds at a minimum)

This flow is where the air conditioner controller requests queued/pending commands from the web service. It looks like the web service responds with a zero content length if there are no pending commands. It also looks like they’re doing a kind of weird version of slow/long polling to cut down on traffic.

At this point, the web service either responds with a zero content length if there are no commands, or it responds with message 4 or 5 from the data reporting flows above. Message 4 allows you to specify power, temperature, fan speed, mode etc, where as message 5 lets you specify the zones.

Anyway, I’ve now captured the traffic from the air conditioner to and from the cloud service. Now all I need to do is create my own web service to impersonate theirs and I’ll be able to completely stop the air conditioner communicating back to the cloud service and more importantly fully integrate it with my home automation system.

Part 3 will cover the integration solution.

~ Mike

2 thoughts on “ActronConnect Air Conditioner Module – Part 2: Reverse Engineering.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s