This blog post has been created for completing the requirements of the SecurityTube Offensive Internet of Things course.
Student ID: IoTE-728
I bought and examined a MyDLink web camera (DCS-930L, hardware version: B1).
The firmware (v2.14) can be downloaded from here. The firmware release notes can be found here.
I started the investigation of this IoT device by analyzing the firmware first. As Aditya mentioned during the Offensive IoT Exploitation course, the key to the successful examination of an IoT device is possessing the firmware. The firmware can reveal lots of secrets about the device and even vulnerabilities might be found. We can analyze the firmware with the binwalk tool. This tool extracts the compressed firmware and we are able to access to the file system of the device.
First I downloaded the firmware and extracted it with binwalk. After I extracted the firmware, I could access another compressed image, so I had to use binwalk again several times to finally get the root file system. Here are the command lines I used:
> wget http://d2okd4tdjucp2n.cloudfront.net/DCS-930LB1/DCS-930L_Bx_FW_v2.14.04.zip
--2016-12-11 08:19:37-- http://d2okd4tdjucp2n.cloudfront.net/DCS-930LB1/DCS-930L_Bx_FW_v2.14.04.zip
Resolving d2okd4tdjucp2n.cloudfront.net (d2okd4tdjucp2n.cloudfront.net)... 54.230.202.114, 54.230.202.85, 54.230.202.67, ...
Connecting to d2okd4tdjucp2n.cloudfront.net (d2okd4tdjucp2n.cloudfront.net)|54.230.202.114|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3855807 (3.7M) [application/zip]
Saving to: ‘DCS-930L_Bx_FW_v2.14.04.zip’
100%[====================================================================>] 3,855,807 814KB/s in 4.6s
2016-12-11 08:19:41 (812 KB/s) - ‘DCS-930L_Bx_FW_v2.14.04.zip’ saved [3855807/3855807]
> unzip DCS-930L_Bx_FW_v2.14.04.zip
Archive: DCS-930L_Bx_FW_v2.14.04.zip
inflating: dcs930lb1_v2.14.04.bin
> binwalk -e dcs930lb1_v2.14.04.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes, header CRC: 0x5ACE9A9B, created: 2016-09-09 14:07:58, image size: 111116 bytes, Data Address: 0x80200000, Entry Point: 0x80200000, data CRC: 0xEE0479B8, OS: Linux, CPU: MIPS, image type: Standalone Program, compression type: none, image name: "SPI Flash Image"
91040 0x163A0 U-Boot version string, "U-Boot 1.1.3"
105424 0x19BD0 HTML document header
105770 0x19D2A HTML document footer
105780 0x19D34 HTML document header
105972 0x19DF4 HTML document footer
106140 0x19E9C HTML document header
106833 0x1A151 HTML document footer
327680 0x50000 uImage header, header size: 64 bytes, header CRC: 0x1D245367, created: 2016-09-09 14:07:53, image size: 3800824 bytes, Data Address: 0x80000000, Entry Point: 0x8038B000, data CRC: 0x474A7005, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux Kernel Image"
327744 0x50040 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 6462961 bytes
> cd _dcs930lb1_v2.14.04.bin.extracted
> ls -la
total 10096
drwxrwxr-x 2 oit oit 4096 Dec 11 08:21 .
drwxrwxr-x 3 oit oit 4096 Dec 11 08:21 ..
-rw-rw-r-- 1 oit oit 6462961 Dec 11 08:21 50040
-rw-rw-r-- 1 oit oit 3866560 Dec 11 08:21 50040.7z
> binwalk -e 50040
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
3256396 0x31B04C Linux kernel version "2.6.21 (andy@ipcam-linux.alphanetworks.com) (gcc version 3.4.2) #472 Fri Sep 9 22:07:48 CST 2016"
3257408 0x31B440 CRC32 polynomial table, little endian
3285504 0x322200 SHA256 hash constants, little endian
3339176 0x32F3A8 Unix path: /usr/gnemul/irix/
3341104 0x32FB30 Unix path: /usr/lib/libc.so.1
3350344 0x331F48 Copyright string: "Copyright (c) 2010 Alpha Networks Inc."
3355124 0x3331F4 Unix path: /var/run/udhcpc.pid
3437576 0x347408 Unix path: /usr/bin/killall
3447720 0x349BA8 Unix path: /etc/Wireless/RT2860STA/RT2860STA.dat
3447856 0x349C30 Unix path: /etc/Wireless/RT2860/RT2860.dat
3515015 0x35A287 Neighborly text, "neighbor %.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x lost on port %d(%s)(%s)"
3637728 0x3781E0 CRC32 polynomial table, little endian
3850240 0x3AC000 LZMA compressed data, properties: 0x5D, dictionary size: 1048576 bytes, uncompressed size: 8443904 bytes
> cd _50040.extracted
> ls -la
total 10808
drwxrwxr-x 2 oit oit 4096 Dec 11 08:24 .
drwxrwxr-x 3 oit oit 4096 Dec 11 08:24 ..
-rw-rw-r-- 1 oit oit 8443904 Dec 11 08:24 3AC000
-rw-rw-r-- 1 oit oit 2612721 Dec 11 08:24 3AC000.7z
> binwalk -e 3AC000
> cd _3AC000.extracted
> ls -la
total 16164
drwxrwxr-x 3 oit oit 4096 Dec 11 08:25 .
drwxrwxr-x 3 oit oit 4096 Dec 11 08:25 ..
-rw-rw-r-- 1 oit oit 8443904 Dec 11 08:25 0.cpio
-rw-rw-r-- 1 oit oit 8091020 Dec 11 08:25 56274.cpio
drwxrwxr-x 17 oit oit 4096 Dec 11 08:25 cpio-root
> cd cpio-root
> ls
bin dev etc etc_ro home init lib media mnt mydlink proc sbin sys tmp usr var
Then I examined the file system. One possible way to do it is checking certain folders and files where vulnerabilities might be found, for example:
- configuration files under etc or etc_ro
- web server root folder
- init scripts
- binaries under bin and sbin
The other way is searching certain files, or certain strings in files. For example the following command line lists all the shell scripts:
$ find . -name “*.sh”
The most promising extensions are:
- script files (.sh, .pl, .py)
- config files (.conf or .config)
- web related files (.html, .cgi, .php, .js)
This command line lists all the files that contain a “passw” string.
$ grep -iRn passw
I found an interesting script, sbin/chpasswd.sh. The username and password of the administrator is stored in non-volatile RAM.
#!/bin/sh
#
# $Id: chpasswd.sh, v1.01 2015-03-24 steven
#
# usage: chpasswd.sh
#
user=`nvram_get 2860 AdminID`
pass=`nvram_get 2860 AdminPassword`
if [ "$user" == "" ]; then
echo "chpasswd: no user name"
exit 1
fi
echo "$user:$pass" > /tmp/tmpchpw
chpasswd < /tmp/tmpchpw
rm -f /tmp/tmpchpw
Another interesting files are the servercert.pem and serverkey.pem under etc_ro. If the camera images are transported via HTTPS and the web server does not generate new serverkey, but uses the hardcoded one, then we might be able to decript the HTTPS communication and steal the images. However there is a gensslkey.sh script and it is possible that the system generates new key pair during setup.
The web server binary is the alphapd and the web server root seems to be under etc_ro/web.
> ls
account.htm dlink.css errrnet.htm html.htm radioon.gif sounddb.htm video.htm
advanced.htm dloadbar.gif errrvdo.htm image.htm reboot.htm stsdev.htm vjview.htm
api edit.jpg errrwlan.htm imode.htm region.htm stssys.htm waitscan.htm
aplist.htm email.htm factory.htm iphone.htm replyd.htm stsuser.htm wireless.htm
audio.htm errmsg.htm favicon.ico jview.htm replyf.htm support.htm wizard.htm
aview.htm errradv.htm file.htm logout.htm replyk.htm time.htm wizsetup.htm
bootver.htm errraud.htm frmsize.htm lphone.htm replym.htm title.gif wps.htm
cgi errrcam.htm function.js mobile.htm replyu.htm top.htm
crossdomain.xml errrdate.htm helpadva.htm motion.htm restore.htm trash.jpg
dcs930lb2.jpg errrdns.htm helphome.htm mvideo.htm security.gif upgrade.htm
ddns.htm errreml.htm helpstat.htm network.htm setvdo.htm upload.htm
deployjava.js errrftp.htm helptool.htm pack sharp.htm vaview.htm
devmodel.jpg errrimg.htm home.htm radiooff.gif showmsg.js version.htm
The cgi folder indicated that the web server uses cgi technology. The next logical step was to search all the files with .cgi extensions.
> find . -name "*.cgi"
./etc_ro/web/cgi/email.cgi
./etc_ro/web/cgi/iimage.cgi
./etc_ro/web/cgi/iwireless.cgi
./etc_ro/web/cgi/usermod.cgi
./etc_ro/web/cgi/wireless.cgi
./etc_ro/web/cgi/cgiversion.cgi
./etc_ro/web/cgi/strminfo.cgi
./etc_ro/web/cgi/audiocfg.cgi
./etc_ro/web/cgi/sitesurvey.cgi
./etc_ro/web/cgi/upgradestatus.cgi
./etc_ro/web/cgi/isystem.cgi
./etc_ro/web/cgi/iactiveuser.cgi
./etc_ro/web/cgi/common.cgi
./etc_ro/web/cgi/upload.cgi
./etc_ro/web/cgi/userlist.cgi
./etc_ro/web/cgi/sdbdetection.cgi
./etc_ro/web/cgi/dbglevel.cgi
./etc_ro/web/cgi/user.cgi
./etc_ro/web/cgi/motion.cgi
./etc_ro/web/cgi/image.cgi
./etc_ro/web/cgi/inetwork.cgi
./etc_ro/web/cgi/network.cgi
./etc_ro/web/cgi/iaudio.cgi
./etc_ro/web/cgi/system.cgi
./etc_ro/web/cgi/isysdevice.cgi
./etc_ro/web/cgi/datetime.cgi
upload.cgi is interesting, however this is not used to upload files onto the device, but it is used to upload camera images unto a configured FTP site.
I found a telned binary, so I searched for the string “telnet”. I found something in the etc_ro/rcS file. This script file runs when the device is booting. In the script the telnet was commented out for security reason. Telnetd was enabled in older firmwares. I found the exploit on exploit-db: https://www.exploit-db.com/exploits/39437/.
...
#enable usb hot-plug feature
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
nvram_daemon &
sleep 3
internet.sh
#for telnet debugging
#security issue - don't run telnetd here -- andy 2012-07-03
#telnetd
#for syslogd
mkdir -p /var/log