Introduction:
I bought another camera to play with. This one is wireless, HD, and allows 2-way communication. There are more features. They're listed here: https://www.walmart.com/ip/Minion-Stuart-Cam-HD-Wifi-Camera-Walmart-Exclusive/54905488 I bought it for two reasons. One was to just have it pointing at my plants outside and second was to use it for analysis. I wrote a guide for myself for doing analysis of IoT devices and embedded devices. It's very high level and I'll try to follow it. The things I need to know are:
- What the system looks like / system model
- Inputs and outputs
- What it does during normal operations
The System:
Hardware:
First thing I did after I got the camera was to take it apart. There are internal connections that I don't care about, such as mic, speakers, camera, and IR lights. I did notice four connections for UART though.
Those I care about. Thankfully these connections were labeled. I got some wire and soldered it to RX, TX, and GROUND. I drilled a hole at the bottom of the camera and routed the wires through. I got this idea from here: http://blog.senr.io/blog/hackawebcamcom-upcoming-workshop-preview
This is what it turned out to be:
Now we can try to use UART to gather more information.
So far we know that the camera has UART, Wireless, and from the manual, I know it has two modes. One is for setting up the camera and the other is for normal operations after the setup is complete. It also has LED indicators.
Now to gather more information. I connected to the camera using FTDI Friend from Adafruit. I connected GROUND, RX, TX. https://learn.adafruit.com/ftdi-friend/overview
We have to figure out UART baudrate. There are couple of ways to do this but easiest is to just load up Arduino software then use Serial Monitor and go through the common buadrate speeds. Whenever you see text you can read/recognize, you'll know that's the buadrate.
I used the following command to start my serial connection:
screen /dev/ttyUSB0 115200 8N1
I plugged in the camera and started receiving data in my terminal.
Finally, it dropped me directly into root shell. I didn't have to login.
Here are some resources on how to gather information(some commands wont work due to embedded device creators decided not to include them):
# cat /proc/cpuinfo
Processor : ARMv7 Processor rev 1 (v7l)
processor : 0
model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 373.55
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc05
CPU revision : 1
Processor : ARMv7 Processor rev 1 (v7l)
processor : 1
model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 375.60
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc05
CPU revision : 1
Hardware : iMAPx15
Revision : 0000
Serial : 0000000000000000
# cat /proc/meminfo
MemTotal: 254704 kB
# lsusb
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0001
# mount
rootfs on / type rootfs (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=92180k,nr_inodes=23045,mode=755)
proc on /proc type proc (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777)
tmpfs on /tmp type tmpfs (rw,relatime)
tmpfs on /root type tmpfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
/dev/mtdblock5 on /mnt/config type jffs2 (rw,relatime)
# ls /dev/mtdblock*
/dev/mtdblock0 /dev/mtdblock2 /dev/mtdblock4 /dev/mtdblock6
/dev/mtdblock1 /dev/mtdblock3 /dev/mtdblock5
# cat /proc/partitions
major minor #blocks name
31 0 512 mtdblock0
31 1 64 mtdblock1
31 2 64 mtdblock2
31 3 10240 mtdblock3
31 4 10240 mtdblock4
31 5 512 mtdblock5
31 6 11136 mtdblock6
# df -h
Filesystem Size Used Available Use% Mounted on
devtmpfs 90.0M 0 90.0M 0% /dev
tmpfs 124.4M 0 124.4M 0% /dev/shm
tmpfs 124.4M 44.0K 124.3M 0% /tmp
tmpfs 124.4M 4.0K 124.4M 0% /root
/dev/mtdblock5 512.0K 196.0K 316.0K 38% /mnt/config
# du / -h -d 1
0 /var
0 /mnt
700.0K /ko
4.0K /root
0 /proc
3.1M /bin
0 /media
0 /dev
876.0K /etc
1.9M /usr
584.0K /package
48.0K /libexec
216.0K /opt
5.4M /lib
0 /home
44.0K /tmp
212.0K /sbin
4.0K /system
0 /sys
13.0M /
Now that we're done gathering info about hardware and storage, we can gather information about software and OS.
Software and OS:
# uname -a
Linux IPC 3.10.0-InfoTMIC+ #495 SMP PREEMPT Mon Nov 7 10:33:53 CST 2016 armv7l GNU/Linux
# cat /etc/os-release
NAME=Buildroot
VERSION=2014.02-git
ID=buildroot
VERSION_ID=2014.02-git
PRETTY_NAME="Buildroot 2014.02-git"
# cat /etc/issue
Welcome to IPC
# cat /proc/version
Linux version 3.10.0-InfoTMIC+ (qa1@localhost.localdomain) (gcc version 4.7.3 (Buildroot 2014.02-git) ) #495 SMP PREEMPT Mon Nov 7 10:33:53 CST 2016
# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 IPC
# cat /etc/hostname
IPC
# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.0.0.7:9232 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:www 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:9595 0.0.0.0:* LISTEN
udp 0 0 0.0.0.0:10000 0.0.0.0:*
raw 1408 0 0.0.0.0:1 0.0.0.0:* 1
raw 2112 0 0.0.0.0:1 0.0.0.0:* 1
# ps
[CUT]
747 root my_watch_dog
748 root /opt/ipnc/avserver_x15.bin
752 root [IMAP mt9d111 CH]
753 root audioEng
757 root {exe} ash /sbin/update_speaker_volume.sh
764 root /sbin/syslogd -n -C4096
767 root /sbin/klogd -n
838 root -sh
852 root wpa_supplicant -Dnl80211 -iwlan0 -c/tmp/wpa_supplicant.conf
853 root {check_cameng.sh} /bin/sh /sbin/check_cameng.sh
854 root {exe} ash /sbin/keep_scan.sh
857 root {exe} ash /sbin/check_netcapture.sh
910 root cameng
911 root goahead
1186 root udhcpc -A 3 -i wlan0 -h x15
1286 root netcapture
9956 root sleep 30
10105 root sleep 10
10156 root sleep 5
10158 root sleep 1
10159 root ps
# lsof |grep \.sh
757 /bin/busybox /sbin/update_speaker_volume.sh
853 /bin/busybox /sbin/check_cameng.sh
854 /bin/busybox /sbin/keep_scan.sh
857 /bin/busybox /sbin/check_netcapture.sh
# ls /lib/*
/lib/ld-uClibc-0.9.33.2.so /lib/libnsl-0.9.33.2.so
/lib/ld-uClibc.so.0 /lib/libnsl.so.0
/lib/lib8270enc.so /lib/libnvram.so
/lib/libOMX.Infotm.Video.Encoder.so /lib/libopencv.so
/lib/libc.so.0 /lib/libpthread-0.9.33.2.so
/lib/libcrypto.so /lib/libpthread.so.0
/lib/libcrypto.so.1.0.0 /lib/libresolv-0.9.33.2.so
/lib/libcurl.so /lib/libresolv.so.0
/lib/libcurl.so.4 /lib/librt-0.9.33.2.so
/lib/libcurl.so.4.4.0 /lib/librt.so.0
/lib/libdl-0.9.33.2.so /lib/libsdutils.so
/lib/libdl.so.0 /lib/libshmav.so
/lib/libg1dec_dwl.so /lib/libssl.so
/lib/libgcc_s.so /lib/libssl.so.1.0.0
/lib/libgcc_s.so.1 /lib/libthread_db-0.9.33.2.so
/lib/libh1enc.so /lib/libthread_db.so.1
/lib/libiw.so /lib/libuClibc-0.9.33.2.so
/lib/libiw.so.29 /lib/libutil-0.9.33.2.so
/lib/libm-0.9.33.2.so /lib/libutil.so.0
/lib/libm.so.0
# env
TSLIB_ROOT=/usr/bin
HISTFILESIZE=1000
INPUTRC=/etc/inputrc
TSLIB_TSDEVICE=/dev/input/event3
USER=root
HOSTNAME=IPC
TSLIB_TSEVENTTYPE=INPUT
LD_LIBRARY_PATH=/usr/lib:/usr/local/share/minigui/res
HOME=/root
QTDIR=/usr/lib/
PAGER=/bin/more
TSLIB_FBDEVICE=/dev/fb0
PS1=#
TSLIB_PLUGINDIR=/usr/lib/ts
TSLIB_CONSOLEDEVICE=none
LOGNAME=root
TERM=vt102
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin/X11:/usr/local/bin:/opt/ipnc
TSLIB_CONFFILE=/etc/ts.conf
DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile
HISTSIZE=1000
SHELL=/bin/sh
QWS_DISPLAY=LinuxFB:mmWidth=800:mmHeight=480
PWD=/root
QWS_MOUSE_PROTO=tslib:/dev/input/event3
TSLIB_CALIBFILE=/etc/pointercal
EDITOR=/bin/vi
# cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
kmem:x:9:
wheel:x:10:root
cdrom:x:11:
dialout:x:18:
floppy:x:19:
video:x:28:
audio:x:29:
tape:x:32:
www-data:x:33:
utmp:x:43:
plugdev:x:46:
staff:x:50:
lock:x:54:
haldaemon:x:68:
dbus:x:81:
netdev:x:82:
ftp:x:83
nobody:x:99:
nogroup:x:99:
users:x:100:
default:x:1000:
# cat /etc/passwd
root::0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
operator:x:37:37:Operator:/var:/bin/sh
haldaemon:x:68:68:hald:/:/bin/sh
dbus:x:81:81:dbus:/var/run/dbus:/bin/sh
ftp:x:83:83:ftp:/home/ftp:/bin/sh
nobody:x:99:99:nobody:/home:/bin/sh
sshd:x:103:99:Operator:/var:/bin/sh
default:x:1000:1000:Default non-root user:/home/default:/bin/sh
# cat /etc/shadow
root::10933:0:99999:7:::
bin:*:10933:0:99999:7:::
daemon:*:10933:0:99999:7:::
adm:*:10933:0:99999:7:::
lp:*:10933:0:99999:7:::
sync:*:10933:0:99999:7:::
shutdown:*:10933:0:99999:7:::
halt:*:10933:0:99999:7:::
uucp:*:10933:0:99999:7:::
operator:*:10933:0:99999:7:::
ftp:*:10933:0:99999:7:::
nobody:*:10933:0:99999:7:::
default::10933:0:99999:7:::
# lsmod
Module Size Used by Tainted: G
bcmdhd 419460 0
af_packet 15288 4
enable_32k_rtc 524 0
# ls /bin/
amixer fdflush mktemp rmdir
ash fgrep more run-parts
audioEng flash mount sed
brctl flash_cp mountpoint setarch
busybox flash_read mt setserial
cameng flash_write mv sh
cat ftpget my_watch_dog sleep
catv ftpput netcapture stty
chattr getopt netstat su
chgrp goahead nice sync
chmod grep ntpdate tar
chown gunzip nvram_clear touch
cp gzip nvram_cmd true
cpio hostname nvram_get umount
date info_msg nvram_pre_check uname
dd kill nvram_renew upload.cgi
df linux32 nvram_set upload_all.cgi
dhd_helper linux64 nvram_show upload_linux.cgi
dmesg ln pidof usleep
dnsdomainname login ping vi
dumpkmap ls pipe_progress watch
echo lsattr printenv wl
egrep lzop ps wpa_cli
ethtool mkdir pwd wpa_supplicant
false mknod rm zcat
# ls /sbin/
10get ipaddr poweroff
10put iplink reboot
Ethernet_check.sh iproute remove_webs.sh
av_check_kill.sh iprule resolve_server_addr.sh
blkid iptunnel restart_udhcpc.sh
bt_reset.sh iwconfig rmmod
check_cameng.sh iwgetid route
check_ethernet.sh iwlist runlevel
check_netcapture.sh iwpriv sdapp.sh
check_wpa_cmd.sh iwspy setconsole
common.sh keep_scan.sh shkill.sh
config_cameng.sh kill_check.sh sta_check.sh
config_netcapture.sh kk start-stop-daemon
connect_tplinkseedonk.sh klogd swapoff
devmem lan.sh swapon
extract_webs.sh loadkmap switch_root
factory_reset_do.sh logread sysctl
freeramdisk losetup syslogd
fsck lsmod timeUpdate.sh
getty makedevs tz.sh
halt mdev udhcpc
hdparm mkswap update_speaker_volume.sh
hwclock mmc_check.sh upgrade.sh
ifconfig modprobe upload_kill.sh
ifdown nameif vconfig
ifup nfs_mount.sh wan.sh
init nslookup.sh watchdog
insmod p2p_lan.sh
ip pivot_root
Now we know a bit more about the system (and we'll discover more later on). We can move into gathering info about networking.
Networking:
# ifconfig -a
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:171 errors:0 dropped:0 overruns:0 frame:0
TX packets:171 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:11498 (11.2 KiB) TX bytes:11498 (11.2 KiB)
wl0.1 Link encap:Ethernet HWaddr 44:2C:05:XX:XX:XX
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr 44:2C:05:XX:XX:XX
inet addr:10.0.0.7 Bcast:10.0.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1253 errors:0 dropped:8 overruns:0 frame:0
TX packets:541 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:135614 (132.4 KiB) TX bytes:70738 (69.0 KiB)
# iwconfig
wlan0 IEEE 802.11 ESSID:"" Nickname:""
Mode:Master Frequency:2.412 GHz Access Point: 14:91:82:XX:XX:XX
Bit Rate=72 Mb/s Tx-Power:32 dBm
Retry min limit:10 RTS thr:off Fragment thr:off
Encryption key:off
Power Managementmode:All packets received
Link Quality=5/5 Signal level=-57 dBm Noise level=-91 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:1 Invalid misc:0 Missed beacon:0
lo no wireless extensions.
wl0.1 IEEE 802.11 ESSID:"StuartCam" Nickname:""
Mode:Master Frequency:2.412 GHz Access Point: 44:2C:05:XX:XX:XX
Bit Rate=72 Mb/s Tx-Power:32 dBm
Retry min limit:10 RTS thr:off Fragment thr:off
Power Management:off
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.0.0.1 0.0.0.0 UG 0 0 0 wlan0
10.0.0.0 * 255.255.255.0 U 0 0 0 wlan0
# netstat -t
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.0.0.7:48428 ec2-54-165-153-153.compute-1.amazonaws.com:5104 ESTABLISHED
tcp 54 0 10.0.0.7:38514 ec2-54-236-101-95.compute-1.amazonaws.com:5104 CLOSE_WAIT
# cat /etc/resolv.conf
search Belkin # wlan0
nameserver 10.0.0.1 # wlan0
nameserver 8.8.8.8 # wlan0
We know a bit more about the hardware, software, networking, and etc. Now we should determine our inputs and outputs. This may help us discover attack surfaces as well. Since I'm the only person working on this and I have limited time, I can't go too deep into this.
Hardware inputs: Mic, Camera, Wireless, Mode switch(setup/normal usage), and power.
Hardware outputs: Speakers, IR lights, indicator LEDs, and Wireless.
Wireless output/input: well, it just does 2.4GHz. There is no bluetooth or other radio device.
When setup mode is enabled, by flipping the switch in the back, wl0.1 is turned on and it works as an AP. wlan0 is still on and if you did setup already, it will continue its connection to your AP while you configure the device through AP created on wl0.1.
Software outputs/inputs: It has some services running on it that make connection to AWS servers. We saw that when running netstat command. We also saw some ports open when running netstat as well, mainly port 80. There is a web server running on it. While testing, I noticed that when the switch is flipped to setup mode, more files are added in the web directory. When switch is flipped to normal operations mode, there is just one file in the web directory. There are more things but this is just phase one.
Normal operations:
When you first get the camera, you'll have to set it up using a mobile app. The switch in the back is set to Setup mode. This creates an AP you connect to using your phone. After that you can run the setup application. You can select your AP that you want the wireless camera to connect to. After connection is made, you can setup an account and attach the camera to your account. After setup is done, you can flip the switch to normal operations mode.
The camera connects to cloud service to receive more information about configurations. It also sends out video to the AWS server.
Attacking:
If an attacker wanted remote shell on the device, there are some issues. First is, the camera is behind a NAT. It's not something you can find while scanning the internet. Another issue is, the attack surface is low. There are a few ports open. The web server, in normal operations mode, only serves one page.
Note:
So far, I haven't found any vulnerabilities. I may or may not continue researching this. Hopefully the commands and the process was useful though.