Z-Way Home Automation Part 2: An Analysis of Publicly Vulnerable Gateways

After my previous post regarding security concerns with the Z-Way home automation controller, John Matherly (founder of Shodan) messaged me that he was launching a scan of port 8083. I was interested to see if any of these devices had been put online publicly, so he sent me the results after the scan completed (thanks, John!). The results were interesting enough that I thought I’d share them in a follow-up post.

After parsing out all of the IPs from Shodan’s results, I ran a script that determined if each IP was actually a Z-Way gateway. This resulted in a list of about 70 publicly accessible gateways. While this number doesn’t seem very large, I thought it was significant given the technical niche that Z-Way caters to.

My next step was to write a script that would enumerate through all of the positively identified gateways and request the attached devices from the Z-Way API, saving the results to a file.

import requests

with open('8083-controllers.txt') as data_file:
    for ip in data_file:
        url = 'http://%s:8083/ZWaveAPI/Data/0' % ip.strip()

        try:
            r = requests.post(url)

            file = open('output/%s.txt' % ip, 'w')
            file.write(r.text)
            file.close()
        except:
            print("%s failed" % ip)

Grepping through the results, I found some interesting device names, including light switches, door locks, baby monitors, and garage door sensors. Next, I wanted to parse the device names as well as determine which IPs had the most devices attached. I parsed the JSON API results again:

import json
import os
for file in os.listdir("output"):
    if file.endswith(".txt"):

        data = json
        with open('output/%s' % file) as data_file:

            data = json.load(data_file)

            devices = data.get('devices')

            for key, value in devices.items():
                try:
                    name = value.get('data').get('givenName').get('value')

                    if name != "":
                        print('%s - %s' % (file, name))
                except:
                    pass

This gave me a simple text file containing each device, along with its associated gateway IP. Here’s the full dump of device names that are publicly exposed (with obfuscated IPs). The below graph plots the number of devices for each IP.

Below is a partial screenshot showing the control interface of the gateway with the most devices:

There are over 200 devices exposed in total and, again, these devices can be controlled remotely without any authentication. I’m not sure what can be done about this; attempting to reach out to these individuals seems impractical.  At minimum, this serves as another reminder to be careful about exposing devices publicly to the internet.

Share this: Facebooktwitterlinkedin