Gaining Root Access to Smart Home Gateway

Published: 05-09-2019 mypc

Recently I bought a Risco Smart Home Gateway, and as I expected it is a rebranded off-the-shelf micro computer. When delivered, the HDMI and optical S/PDIF outputs and IR input hinted that it was not just a dedicated smart home gateway. The OS seems to be loaded from a micro SD card, comparable to e.g. a Raspberry Pi. Also, the z-wave controller is just a USB dongle and not built-in.

After configuring, its network interface shows up on my router as SolidRun. A quick search finds the SolidRun CuBox-i, most probably the CuBox i2eX or CuBox i4p, because it also has an eSata port.

These range from $100 - $150. Not too bad, considering the Risco Smart Home Gateway is around €300. Of course, this includes a z-wave adapter (around €50) and their special software. Their software is actually much less flexible than e.g. Domoticz, but I am sure it makes up for that in security and robustness.

Solid Run has a community site for developers with plenty of information.

The CuBox is an ARM micro computer with an FreeScale i.MX6 SoC and that means it can run several flavors of Linux, Kodi and in theory and old version of Android. An in-depth review can be found here.

I won’t judge the performance or review it further, but it might be worth mentioning that by know it is at least superseded by the Raspberry Pi 4, because it can play h265 video.

Now if you are bored with your Risco Smart Home you could just install a different image on the micro SD card and use it as a media player or something, but let’s see if we can gain more control over it as is.

You could use Wireshark to intercept messages between the Risco Smart Home device and the alarm system, but first I want to try to SSH in and/or inspect the software it is running.

In this post, I will display the IP as 192.168.0.xxx. Accessing that IP in the browser shows nothing running on port 80, but the IP is pingable.

nmap -v -sT 192.168.0.xxx on the IP shows:

PORT     STATE SERVICE
22/tcp   open  ssh
8080/tcp open  http-proxy
8443/tcp open  https-alt

Opening http://192.168.0.xxx:8080 in the browser it redirects to http://192.168.0.xxx:8443/static/index.html:

HTTP ERROR 404

Problem accessing /static/index.html. Reason:

    Not Found

Powered by Jetty://

Opening https://192.168.0.xxx:8443 in the browser gives the same as 8080, but with SSL. It uses a self-signed certificate by openHAB. This is open-source home automation software and this may be useful if we gain access to the device!

It is possible to create an SSH connection, but it requests a password. Trying some default root passwords failed. Now we know the certificate is from openHAB, maybe the CuBox is running openHAB? The default credentials openhabian/openhabian do not work.

It may be possible to inspect the micro SD to get more information. When disconnecting the gateway from power/utp the alarm does not go off (good!), and the micro SD can be inspected on a different machine:

The micro sd has several partitions: boot, postgre, rootfs, and scratch.

rootfs: there is a /home dir, but it is empty. there is a /linuxrc dir that seems to point at bin/busybox. This seems to be a BusyBox installation.

scratch: contains some ssh certificates. Copied to local disk.

After reconnecting the gateway to power and UTP the message “Communication with the Gateway failed.” is shown in Risco cloud. After a couple of minutes it works fine. However, the button controller that was paired (that did not work) is not showing up anymore. The Fibaro plug does show up and still works as expected.

It is not possible to login with default BusyBox credentials, so after disconnecting again, taking a closer look at the volume scratch: it contains a file @ssh/sshd_config with a line PermitRootLogin yes.

So assuming this is the SSH config that is used runtime, we need to somehow find the root password, and then we can SSH with ssh root@192.168.0.xxx

Following this suggestion:

see the /etc/shadow or /etc/passwd (if the /etc/shadow not exist) with texteditor

I found that, indeed, /etc/shadow contains (values are fake):

root:$1$foo$bar:10933:0:99999:7:::

So there is in fact a root entry with a hashed password visible. One option would be to update the hash string with a hash string of a password that we already know, a method I used years ago when adding users for a deprecated application by directly inserting lines into a database table. However, I have no idea what effect this would have on an OS, so I would prefer to refrain from modifying the filesystem at this point. Additionally, assuming that the provided SD card image always uses the same root password, it would be valuable to know the password to be able to log into other devices.

Another option would be to try to retrieve the password from the root entry in /etc/shadow. More information about why passwords are stored in /etc/shadow instead of /etc/passwd here.

From this article I also learned how to read the shadow file: the password entry ($1$foo$bar) is in fact three properties separated by $. The $1 indicates MD5 hashing was used, which is notoriously easy to crack. The second part (“foo”) is the salt and the third part (“bar”) is the hash from the password + salt.

This article also shows that using the hash calculated from the salt and the password with openssl. This is great, because know we can write a small script to try out many passwords without trying to login to SSH and being kicked out for too many failed responses. The command looks like this, with -1 indicating md5, foo as the salt and secret the actual password.

openssl passwd -1 -salt foo secret # output: $1$foo$ygQElgzdVoe51UiGBN5TV/

It is easy to do this in a bash script, but of course there already exists some open source tool: John the Ripper (info on usage)

  • First run sudo unshadow rootfs/etc/passwd rootfs/etc/shadow > mypasswd.txt where unshadow is a util from john.
  • Now remove all the entries from mypasswd.txt except the root user.
  • Now run john mypasswd.txt --fork=4.

The fork flag enables multi threading, in this case on 4 threads. While the command is running, I see that 4 out of 8 cores have a 100% load. After approximately 7 hours a password is found. Please note, that the other threads keep running, but a nice overview is giving of how long the processes have been running and at what passwords they are trying.

Logging in to SSH as root works! (So it was indeed the correct sshd_config). A prompt is shown with only ”#“. Running df -h gives:

Filesystem                Size      Used Available Use% Mounted on
/dev/root                 2.8M      2.3M    444.0K  84% /mnt/initrd
devtmpfs                239.2M         0    239.2M   0% /dev
/dev/disk/by-label/rootfs
                          1.0G    284.2M    544.7M  34% /
tmpfs                   249.4M      4.0K    249.4M   0% /dev/shm
tmpfs                   249.4M      9.1M    240.2M   4% /tmp
tmpfs                   249.4M    120.0K    249.2M   0% /run
/dev/mmcblk0p1           63.0M      5.9M     57.1M   9% /boot
/dev/mmcblk0p3            1.0G     93.7M    828.9M  10% /var/lib/pgsql
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /var/spool
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /var/log
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/ssl/private
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/ssh
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /etc/nextgen
/dev/mmcblk0p4            1.0G     23.7M    898.7M   3% /home

cat /var/log/messages works and gives a lot of information, e.g. a daemon is running on user “nextgen” called Risco Service Manager.

It was a fun exercise to try to get into a device you own, but don’t have remote access too. Next steps could be to try to install extra services on the device that could interact with the Risco Service Manager, or to intercept messages to or from the Risco Service Manager.

Published with permission from Risco