Showing posts with label upnp. Show all posts
Showing posts with label upnp. Show all posts

Saturday, January 26, 2013

SMART Airconditioner, Part II

I started trying to figure out my air conditioner, and have made some fairly good progress.

Unfortunately, though I've been able to do a simple proof of concept; it's ambiguous as to how I can really make use of the resulting code - the terms of service narrowly define only interfaces provided by Samsung can be used to access their services.

I'd wager that a restful service is "provided by Samsung" in all of the technical senses, but I don't really have the desire to explore the legal interpretations of that.

Anyway...


As a first step, you want to authenticate your restful client against the Samsung SSO interface.

I made use of Mechanize and providing my credentials to correctly generate an authorisation cookie for the samsung service; in an identical fashion to how chrome would do this step.

There are a few steps to this, and a lot of javascript going back and forth.

A post to https://account.samsung.com/account/check.do to get the login form (with a ServiceID and ActionID); followed by submitting the actual login form.
There's yet more javascript that changes the form submit to location, so you end up manually pointing your requests at https://account.samsung.com/account/startSignIn.do

A final form submit completes the sign in, and you have a cookie somewhere in there generated.
After that, a fairly overwhelming interface renders itself. A lot of javascript happens to dynamically load UI controls and so forth.

Rather than deal with this tag soup, I took my DUID (the mac address from before) and relied on the existing cookie to go forward.

Mechanize wasn't going to let me do much with POST and raw XML, and I tried a few different clients - I didn't find one I was happy with.

RestClient was close, but to be honest I would likely just use Net::HTTP directly in other situations.
After I had the authorisation, I sat in chrome and watched what was happening.
First, there's a call to understand your device's capabilities - selectDevice().

You tend to get a lot of data back, and it took me a while to figure out that this is probably just the same UPnP service description file I was looking for.

Interestingly, Samsung spell out all of the operations you can perform on the machine - it's certainly not a WSDL, but not too hard to see how they would create a number of dynamic UPnP control devices/services/UIs.

      <Power type="string">
        <AvailableList>
          <On/>
          <Off/>
        </AvailableList>
      </Power>
      <OperationMode type="string">
        <AvailableList>
          <Auto/>
          <Cool/>
          <Dry/>
          <Wind/>
          <Heat/>
        </AvailableList>
      </OperationMode>


Actually using the interface they provide, I saw requests to:
http://global.samsungsmartappliance.com/Communication/setControl

After a bit of probing, this looks very like the 'key value pair' style of controlling a UPnP device.
For example, to switch on your AC:

POST http://global.samsungsmartappliance.com/Communication/setControl
Cookie: (What you had before)
duid: (mac address)
<ControlCommand LastUpdateTime="1359114535"><Device><Status Power="On" /></Device></ControlCommand>

The response to this is an acknowledgement and a UUID, known as a CommandId.

The website them proceeds to spam the hell out of the services - 1-2 requests a second, polling - just to see if your command worked at all; and to update the device status.

GET checkControl
CommandId: UUIDFromBefore

<rsp stat="ok"><ControlResult DUID="...">Processing</ControlResult></rsp>

GET checkControl
CommandId: UUIDFromBefore


<rsp stat="ok"><ControlResult DUID="...">Success</ControlResult></rsp>

Given the previous work sniffing packets, I would think I've just sent basically the UPnP packets to the AC, and global.samsung.com would be doing little to no transformation of them; beyond adding/removing from a queue.

At this point, I was ready to try controlling the AC with my restful code and start publishing it to github - unfortunately; I thought to read the ToS and found the narrowly worded agreement.

While I'd usually consider that hard to enforce, I don't really want to find out the ramifications of "unauthorised use of a computer" in Australian law - even if the end service is a Thing in My House that arguably doesn't need traffic going to Korea for it.


However, since I now have a pretty good idea of the other half of the conversation; I'm going to look closely at UPnP in the local environment again. If the services look similar, and it's just a matter of the same requests; but over UDP, I'm sorted!

Thursday, January 24, 2013

How the Samsung SMART Air conditioners/appliances work remotely

I bought a smart air conditioner, and am marvelling at the fact I can control it from my phone.

What I'm less happy about is the fact I can only control it from my phone; and that my local network has decided to stop letting me talk to the air con.

I fired up wireshark, and here's what I know so far:

Like most devices, the Air Conditioner is running UPnP services basically. There's packets being sent via http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol for my Android phone and the air con to discover each other.


Here's my phone asking over HTTPU (HTTP UDP) for air conditioners via multicast:
NOTIFY * HTTP/1.1
LOCATION: 192.168.1.2
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=20
SERVER: AIR CONDITIONER
MAC_ADDR: 98:0c:82:f4:d4:5c
SPEC_VER: MSpec-1.00
SERVICE_NAME: ControlServer-MLib
MESSAGE_TYPE: CONTROLLER_START



... and the air conditioner starts to respond:

NOTIFY * HTTP/1.1
LOCATION: http://192.168.1.4
NTS: ssdp:alive
CACHE_CONTROL: max-age=60
HOST: 255.255.255.255:1900
SERVER: SSDP,SAMSUNG-AC-BORACAY
MAC_ADDR: 7825AD103D06
SERVICE_NAME: ControlServer-MLib
SPEC_VER: MSpec-1.00
MESSAGE_TYPE: DEVICEDESCRIPTION
NICKNAME: 536D61727420412F432837383235414431303344303629
MODELCODE: SAMSUNG_DEVICE

Unfortunately, my air con actually lives at 192.168.1.7, the web application isn't smart enough to respond to changing IP addresses; even if the web server and everything else is.



I'm not entirely sure why, but my phone tends to flood packets out there - I presume the people who put the phone app together wanted to avoid dodgy local wireless problems; and this now explains why my air con is always discovered quickly, but the screen keeps 'loading'.



Strangely, for the local in home network stuff, it looks like my air conditioner is talking to a samsung owned service to give it status updates, even when I'm on my local network:
211.45.27.216

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 111
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Thu, 24 Jan 2013 10:38:31 GMT


<rsp stat="ok"></rsp>
<device duid="7825AD103D06" message="Off"></device>

Attempt #2: There's an online service you can use.
Now, our clever friends at Samsung have done the right thing and made communication with their services via HTTPS - at least from the android to the soap service. Weirdly, the air conditioner does not speak HTTPS; and seems to be sending packets to the samsung control service, not my phone directly.

I looked at a few packets, but at this point, I was pretty much fed up - I'm not going to do a MITM attack via my router, and redirect traffic to a HTTP proxy I control; I'm not going to reroute traffic, and sticking the app in an android emulator to sniff the packets is annoyingly hard.

So, what's really left to do but... log in to the website and look at what's going on there?





This looks like paydirt - there are numerous javascript files which are hitting endpoints to execute commands.
It's probably a fairly safe assumption to think those endpoints are just RESTful wrappers around the underlying webservice.

Two are of quite a lot of interest, if ... dubious quality:
http://global.samsungsmartappliance.com/Content/js/communication/commMgr.js
http://global.samsungsmartappliance.com/Content/js/communication/Device/Device.js

Looking in firebug/chrome's console, you can see that the device traffic is going back and forth, with an incrementing token continually polling my air conditioner for status.

When you actually execute a command, a fairly simple request is sent:


  1. Request URL:
    http://global.samsungsmartappliance.com/Communication/setControl
  2. Request Method:
    POST
  3. Status Code:
    200 OK
  4. Request Headersview source
    1. Accept:
      application/xml, text/xml, */*; q=0.01
    2. Accept-Charset:
      ISO-8859-1,utf-8;q=0.7,*;q=0.3
    3. Accept-Encoding:
      gzip,deflate,sdch
    4. Accept-Language:
      en-GB,en-US;q=0.8,en;q=0.6
    5. Connection:
      keep-alive
    6. Content-Length:
      122
    7. Content-Type:
      text/xml
    8. Cookie:
      ASP.NET_SessionId=y3akcf55bfxtcnzhd0hyz5ru; Language=en; Country=GB; LoginLanguage=en; iPlanetDirectoryPro=AQIC5wM2LY4Sfcy5aJdOInrRhyDKEyNfWseX44FQLVR9hZI%3D%40AAJTSQACMDIAAlMxAAIwNQ%3D%3D%23; GMT=10.5
    9. Host:
      global.samsungsmartappliance.com
    10. Origin:
      http://global.samsungsmartappliance.com
    11. Referer:
      http://global.samsungsmartappliance.com/
    12. User-Agent:
      Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
    13. X-Requested-With:
      XMLHttpRequest
  5. Request Payload
  6. Response Headersview source
    1. Cache-Control:
      private
    2. Content-Length:
      100
    3. Content-Type:
      text/html; charset=utf-8
    4. Date:
      Thu, 24 Jan 2013 12:40:11 GMT
    5. Server:
      Microsoft-IIS/7.5
    6. X-AspNet-Version:
      2.0.50727
    7. X-AspNetMvc-Version:
      1.0
    8. X-Powered-By:
      ASP.NET


Most of the other status information has included the MAC address of the air conditioner as the "DUID" - it's stripped of colons, but otherwise identical. While we can't tell what's in the session on the samsung side, I would not be surprised if it were a simple variable named DUID, which identifies where the command should be sent.

More interestingly, the requests can be replayed; so assuming you have a valid cookie that contains the right DUID, you can just send restful requests.

I'm going to assume that there's some kind of ESB or similar taking these requests and distributing them from my phone/browser to the aircon; as the traffic to the aircon is different to the endpoint my phone / browser speaks to.
There is a delay, perhaps 3-5 seconds, which is about what I would expect if there was a Giant Messaging Queue in use here; and to be honest the site seems to go down regularly - some service faceplanting it seems likely.

The fact it's jquery + xml being used also suggests there's an Enterprise Service Beast in play - though json is more common, the transformation between formats is a bit easier if you can hit it with an XSLT.


The use of a session would normally make things more secure... but the control to manipulate that value appears to be right out in the open.


  1. Request URL:
    http://global.samsungsmartappliance.com/Communication/selectDevice?_=1359032361539
  2. Request Method:
    GET
  3. Status Code:
    200 OK
  4. Request Headersview source
    1. Accept:
      application/xml, text/xml, */*; q=0.01
    2. Accept-Charset:
      ISO-8859-1,utf-8;q=0.7,*;q=0.3
    3. Accept-Encoding:
      gzip,deflate,sdch
    4. Accept-Language:
      en-GB,en-US;q=0.8,en;q=0.6
    5. Connection:
      keep-alive
    6. Cookie:
      ASP.NET_SessionId=y3akcf55bfxtcnzhd0hyz5ru; Language=en; Country=GB; LoginLanguage=en; iPlanetDirectoryPro=AQIC5wM2LY4Sfcy5aJdOInrRhyDKEyNfWseX44FQLVR9hZI%3D%40AAJTSQACMDIAAlMxAAIwNQ%3D%3D%23; GMT=10.5
    7. duid:
      7825AD103D06
    8. Host:
      global.samsungsmartappliance.com
    9. master_duid:
    10. Referer:
      http://global.samsungsmartappliance.com/
    11. User-Agent:
      Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
    12. X-Requested-With:
      XMLHttpRequest

I doubt you could hijack someone else's air con if you knew the mac address, but for devices associated with your account...


At this point I have two good avenues to explore:
  • Local network - I need to fix the IP addresses, and see what's going on after the SSDP phase. I had to authorise my phone, so I suspect that Samsung provides a third party service that verifies allowed MAC addresses prior to opening all of the communication flood gates.
  • Pretend to be a browser, and invoke the restful services. If I supply my credentials, I can get the session I need - then the API is just a few POST requests away.

I'm likely to do the latter, unless I can figure out how to power cycle my aircon properly, and get it understanding its IP address.