Controlling a Smart TV with SOAP

With Smart TVs on the rise in the last couple of years (and the shortened lifespan of consumer electronics in general) a large number of people actually have one in their home. With the average viewing time per person being almost three hours of TV per day, these devices have probably become the most frequently turned on computers in home networks - aside from smartphones and tablets obviously. Yet they haven't nearly gotten the same kind of attention when it comes to security or privacy related issues.

Since the advanced feature sets of these TVs are very cumbersome to use with a regular remote, the manufacturers have had a brilliant idea - let's just create an app for that. Almost every new TV has an app for Android and iOS which allows one to watch the guide, switch the channel or turn the device on and off. Since I wanted to automate a few things and a public API wasn't available (who'd have tought), I decided to do some reverse engineering (on a Sony KDL50W685).

The whole thing was actually way simpler than I expected. I started Wireshark, paired my i-Device to my TV (which makes sense security-wise) and sent some commands. As it turns out, the TV provides a SOAP API on port 80. There was actually quite a lot of communication between the two devices, but as it turns out the "Power"-command is a single message.

So the rest of the communication is probably authentication, right?
Wrong.

Simply taking the SOAP message (which contains an IRCC command) and replaying it actually works. I wrote a small Python script to do this.

import requests

headers = {
    'User-Agent': 'TVSideView/2.0.1 CFNetwork/672.0.8 Darwin/14.0.0',
    'Content-Type': 'text/xml; charset=UTF-8',
    'SOAPACTION': '"urn:schemas-sony-com:service:IRCC:1#X_SendIRCC"',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate',
    'Connection': 'keep-alive',
}

content = """<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:X_SendIRCC xmlns:u="urn:schemas-sony-com:service:IRCC:1">
      <IRCCCode>AAAAAQAAAAEAAAAvAw==</IRCCCode>
    </u:X_SendIRCC>
  </s:Body>
</s:Envelope>"""

url = 'http://this-is-the-ip-of-the-tv/sony/IRCC'

response = requests.post(url, data=content, headers=headers)
print(response)

Of course there are a lot of cool things you can do with this kind of technology - for example using Kinect to automatically turn your TV on and off if you approach it, our using gesture control, but there are also some big problems. If you have a small Video-on-Demand box (with something like Netflix) you can usually control this with your TV remote. This works because of HDMI CEC and also works when sending the remote commands via the SOAP API.

This means that you could actually write malware to continuously purchase digital content and ramp up quite the bill for the vicitm. Additionally, if you do this during work hours, say, twelve o'clock on a Thursday, chances are, no one will actually see what is happening on the TV.