[ 0.000000] Linux version 2.6.38.8 (dropcambuild@ubuntu-dropcam-build) (gcc version 4.5.2 (Sourcery G++ Lite 2011.03-41) ) #15 PREEMPT Mon Oct 1 16:59:51 PDT 2012

[ 0.000000] CPU: ARMv6-compatible processor [4117b365] revision 5 (ARMv6TEJ), cr=00c5387f

[ 0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache

[ 0.000000] Machine: Coconut

[ 0.000000] Memory policy: ECC disabled, Data cache writeback

[ 0.000000] Ambarella: AHB = 0x60000000[0xf0000000],0x01000000 0

[ 0.000000] Ambarella: APB = 0x70000000[0xf1000000],0x01000000 0

[ 0.000000] Ambarella: PPM = 0xc0000000[0xe0000000],0x00200000 9

[ 0.000000] Ambarella: BSB = 0xc8c00000[0xe8c00000],0x00400000 9

[ 0.000000] Ambarella: DSP = 0xc9000000[0xe9000000],0x07000000 9

[ 0.000000] Ambarella: HAL = 0xc00a0000[0xfee00000],0x00009f34 9

[ 0.000000] bootmem_init: high_memory = 0xc8a00000

[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 35052

[ 0.000000] Kernel command line: console=ttyS0 ubi.mtd=lnx root=ubi0:rootfs rw rootfstype=ubifs init=/linuxrc

[ 0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)

[ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)

[ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)

[ 0.000000] Memory: 138MB = 138MB total

[ 0.000000] Memory: 136244k/136244k available, 5068k reserved, 0K highmem

(etc.)

######## ######## ####### ######## ###### ### ## ##

## ## ## ## ## ## ## ## ## ## ## ## ### ###

## ## ## ## ## ## ## ## ## ## ## #### ####

## ## ######## ## ## ######## ## ## ## ## ### ##

## ## ## ## ## ## ## ## ######### ## ##

## ## ## ## ## ## ## ## ## ## ## ## ##

######## ## ## ####### ## ###### ## ## ## ##



Ambarella login:

Getting root via the Ambarella bootloader

___ ___ _________ _

/ _ \ | \/ || ___ \ | |

/ /_\ \| . . || |_/ / ___ ___ | |_

| _ || |\/| || ___ \ / _ \ / _ \ | __|

| | | || | | || |_/ /| (_) || (_) || |_

\_| |_/\_| |_/\____/ \___/ \___/ \__|

----------------------------------------------------------

Amboot(R) Ambarella(R) Copyright (C) 2004-2007

BST (137166), HAL (137166)

Arm freq: 480000000

iDSP freq: 120000000

Core freq: 120000000

Dram freq: 336000000

AHB freq: 120000000

APB freq: 60000000

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot>

amboot> help

The following commands are supported:

help bios boot diag

dump erase nand_erase exec

hal hotboot netboot ping

r8 r16 r32 reboot

reset setenv setmem show

usbdl w8 w16 w32

xmdl bapi

Use 'help' to get help on a specific command

amboot>

console=ttyS0 ubi.mtd=lnx root=ubi0:rootfs rw rootfstype=ubifs init=/linuxrc

amboot> boot console=ttyS0 ubi.mtd=lnx root=ubi0:rootfs rw rootfstype=ubifs init=/bin/sh

[ 3.130000] UBIFS: reserved for root: 0 bytes (0 KiB)

[ 3.130000] VFS: Mounted root (ubifs filesystem) on device 0:13.

[ 3.140000] Freeing init memory: 136K

/bin/sh: can't access tty; job control turned off

/ #

/ # ls -l /etc/shadow

lrwxrwxrwx 1 root root 21 Oct 1 2012 /etc/shadow -> ../mnt/dropcam/shadow

/ # cat /etc/fstab

# /etc/fstab: static file system information.

#

# <file system> <mount pt> <type> <options> <dump> <pass>

#/dev/root / ext2 rw,noauto 0 1

#proc /proc proc defaults 0 0

devpts /dev/pts devpts defaults,gid=5,mode=620 0 0

#tmpfs /tmp tmpfs defaults 0 0

sysfs /sys sysfs defaults 0 0

debugfs /debug debugfs defaults 0 0



# extra mounts

/dev/mtdblock9 /mnt/dropcam jffs2 defaults 0 0

/ # mount -tjffs2 /dev/mtdblock9 /mnt/dropcam

/ # cat /mnt/dropcam/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:::

nobody:*:10933:0:99999:7:::

default::10933:0:99999:7:::

/ # ls /mnt/dropcam/

bpcmap.bin keycert.pem softmac

fv.txt provisioned wpa_supplicant.conf

hwver shadow

$ openssl x509 -in keycert.pem -noout -text | grep CN

Issuer: C=US, CN=Dropcam Certificate Authority, O=Dropcam

Subject: C=US, CN=d024378182da4f37b0e981946989f40a, O=Dropcam

Exploring the running device

# ps

PID USER TIME COMMAND

1 root 0:02 init

2 root 0:00 [kthreadd]

3 root 0:00 [ksoftirqd/0]

4 root 0:00 [kworker/0:0]

5 root 0:00 [kworker/u:0]

6 root 0:00 [khelper]

7 root 0:00 [kworker/u:1]

402 root 0:00 [sync_supers]

404 root 0:00 [bdi-default]

406 root 0:00 [kblockd]

513 root 0:00 [kswapd0]

514 root 0:00 [fsnotify_mark]

515 root 0:00 [aio]

517 root 0:00 [crypto]

558 root 0:00 [mtdblock0]

563 root 0:00 [mtdblock1]

568 root 0:00 [mtdblock2]

573 root 0:00 [mtdblock3]

578 root 0:00 [mtdblock4]

583 root 0:00 [mtdblock5]

588 root 0:00 [mtdblock6]

593 root 0:00 [mtdblock7]

598 root 0:00 [mtdblock8]

603 root 0:00 [mtdblock9]

611 root 0:00 [ubi_bgt0d]

628 root 0:00 [ubifs_bgt0_0]

629 root 0:00 [kworker/0:1]

643 root 0:00 [flush-ubifs_0_0]

646 root 0:00 [jffs2_gcd_mtd9]

699 root 0:00 [kworker/u:2]

735 root 0:00 /bin/ash /usr/bin/bootstrap.sh

736 root 0:00 -sh

738 root 0:00 syslogd -C128 -S

740 root 0:00 klogd

743 root 0:00 /usr/bin/connect

744 root 0:00 logger -t connect

745 root 0:00 /usr/bin/connect

746 root 0:00 /usr/bin/connect

760 root 0:00 [file-storage]

772 root 0:00 [kworker/0:2]

784 root 0:00 [cfg80211]

804 root 0:00 [AR6K Async]

811 root 0:00 [ksdioirqd/mmc1]

822 root 0:00 wpa_supplicant -iwlan0 -c/mnt/dropcam/wpa_supplicant.conf

829 root 0:00 [dsplogd]

830 root 0:00 [vsyncd]

860 root 0:00 [sh]

861 root 0:00 [sh]

868 root 0:00 ps

$ strings connect | tail -1

UPX!

$ upx -d connect

Ultimate Packer for eXecutables

Copyright (C) 1996 - 2013

UPX 3.09 Markus Oberhumer, Laszlo Molnar & John Reiser Feb 18th 2013



File size Ratio Format Name

-------------------- ------ ----------- -----------

789596 <- 420052 53.20% linux/armel connect



Unpacked 1 file.

rm -rf /tmp/connect && mkdir /tmp/connect && tar zx -f /tmp/connect.bin -C /tmp/connect && rm /tmp/connect.bin

$ dd if=./connect of=connect.tar.gz bs=1 skip=473404 count=168451

168451+0 records in

168451+0 records out

168451 bytes (168 kB) copied, 0.364475 s, 462 kB/s

$ tar -tzvf connect.tar.gz

-rw-r--r-- dropcambuild/dropcambuild 10376 2013-04-22 20:25 dispatch.bin

-rw-r--r-- dropcambuild/dropcambuild 1243 2013-04-22 20:25 hello.bin

-rw-r--r-- dropcambuild/dropcambuild 545 2013-04-22 20:25 hwver.bin

-rw-r--r-- dropcambuild/dropcambuild 4279 2013-04-22 20:25 ir.bin

-rw-r--r-- dropcambuild/dropcambuild 879 2013-04-22 20:25 list.bin

-rw-r--r-- dropcambuild/dropcambuild 650 2013-04-22 20:25 main.bin

-rw-r--r-- dropcambuild/dropcambuild 2363 2013-04-22 20:25 monitor.bin

-rw-r--r-- dropcambuild/dropcambuild 708 2013-04-22 20:25 motion.bin

-rw-r--r-- dropcambuild/dropcambuild 2010 2013-04-22 20:25 net.bin

-rw-r--r-- dropcambuild/dropcambuild 2607 2013-04-22 20:25 oldiags.bin

-rw-r--r-- dropcambuild/dropcambuild 3280 2013-04-22 20:25 persistence.bin

-rw-r--r-- dropcambuild/dropcambuild 329 2013-04-22 20:25 platform.bin

-rw-r--r-- dropcambuild/dropcambuild 3365 2013-04-22 20:25 platform_a5s.bin

-rw-r--r-- dropcambuild/dropcambuild 551 2013-04-22 20:25 platform_local.bin

-rw-r--r-- dropcambuild/dropcambuild 822 2013-04-22 20:25 ravg.bin

-rw-r--r-- dropcambuild/dropcambuild 191 2013-04-22 20:25 rtp.bin

-rw-r--r-- dropcambuild/dropcambuild 643 2013-04-22 20:25 settings.bin

-rw-r--r-- dropcambuild/dropcambuild 9931 2013-04-22 20:25 states.bin

-rw-r--r-- dropcambuild/dropcambuild 912 2013-04-22 20:25 status.bin

-rw-r--r-- dropcambuild/dropcambuild 3822 2013-04-22 20:25 streams.bin

-rw-r--r-- dropcambuild/dropcambuild 3047 2013-04-22 20:25 update.bin

-rw-r--r-- dropcambuild/dropcambuild 601 2013-04-22 20:25 usb.bin

-rw-r--r-- dropcambuild/dropcambuild 2602 2013-04-22 20:25 util.bin

-rw-r--r-- dropcambuild/dropcambuild 1468 2013-04-22 20:25 watchdog.bin

-rw-r--r-- dropcambuild/dropcambuild 54727 2013-04-22 20:25 droptalk_pb.bin

-rw-r--r-- dropcambuild/dropcambuild 1504 2013-04-22 20:25 containers.bin

-rw-r--r-- dropcambuild/dropcambuild 5879 2013-04-22 20:25 decoder.bin

-rw-r--r-- dropcambuild/dropcambuild 1038 2013-04-22 20:25 descriptor.bin

-rw-r--r-- dropcambuild/dropcambuild 9360 2013-04-22 20:25 encoder.bin

-rw-r--r-- dropcambuild/dropcambuild 615 2013-04-22 20:25 listener.bin

-rw-r--r-- dropcambuild/dropcambuild 20750 2013-04-22 20:25 protobuf.bin

-rw-r--r-- dropcambuild/dropcambuild 1505 2013-04-22 20:25 text_format.bin

-rw-r--r-- dropcambuild/dropcambuild 1525 2013-04-22 20:25 type_checkers.bin

-rw-r--r-- dropcambuild/dropcambuild 3620 2013-04-22 20:25 wire_format.bin

-rw-r--r-- dropcambuild/dropcambuild 1686 2013-04-22 17:24 a5s_boot.sh

-rw-r--r-- dropcambuild/dropcambuild 78 2013-04-18 16:45 wpa_supplicant_a5s.conf

-rwxr-xr-x dropcambuild/dropcambuild 1286 2013-04-18 16:45 udhcpc.script

-rwxr-xr-x dropcambuild/dropcambuild 1310 2013-04-18 16:45 udhcpc_provision.script

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_01_3D_hwrev_1.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_01_3D_hwrev_2.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_02_3D_hwrev_1.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_02_3D_hwrev_2.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_03_3D_hwrev_1.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_03_3D_hwrev_2.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_04_3D_hwrev_1.bin

-rw-r--r-- dropcambuild/dropcambuild 17536 2013-04-18 16:45 ov9715_04_3D_hwrev_2.bin

-rw-r--r-- dropcambuild/dropcambuild 27453 2013-04-18 16:45 ambarella_udc-pre-v16.ko

-rwxr-xr-x dropcambuild/dropcambuild 86828 2013-04-18 16:45 wmiconfig

Transport encryption and exploring traffic interception

ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA

00 RESERVED 01 REDIRECT 02 START_STREAM 03 STOP_STREAM 04 WIFI_SCAN 05 WIFI_CONNECT 06 RESTART 07 UPDATE 08 DEBUG 09 SET_STATUS_LIGHT 0a SET_ILLUMINATOR_LIGHT 0b SET_AUDIO_GAIN 0c STOP_BACKFILL 0d AUDIO_PAYLOAD 0e SET_IR_LED 0f SET_DPTZ 10 FORCE_IDR 11 EXEC 12 SET_WATERMARK 13 AUDIO_SOUND 14 SET_IMAGE_PROPERTIES 40 PING 80 HELLO 81 STREAM_BEGIN 82 STREAM_END 83 RTP 84 WIFI_SCAN_LIST 85 WIFI_CONNECT_STATUS 86 EVENT 87 BACKFILL_COMPLETE 8a UPDATE_RESULT 8c OFFLINE_DIAGNOSTIC_REPORT 8e STATUS_REPORT

7: "Dropcam Connect - Version: 162, Build: 57 (jenkins-connect-release-node=linux-57, a29560dbb0724e7dbafb19b9ac1268b6fb62f1d6, origin/hotfix/basil)"

9: 2

8: "Build: 181 (jenkins-ambarella-181, 8732f64a79aecdd16bf6562775015c303d71c839), Linux: Linux Ambarella 2.6.38.8 #15 PREEMPT Mon Oct 1 16:59:51 PDT 2012 armv6l GNU/Linux"

1: 1

5: 3

6: 15

4: "0.0.0.0"

2: 4

3: 162

1: "oculus121.dropcam.com"

Conclusions

by Kris BroschIn the last Dropcam post , I wrote about reversing the USB setup procedure that the Dropcam uses to initially connect to your WiFi network. After exploring the USB tunneling protocol, the next step was to take it apart, or at least take off the back of the enclosure:The main controller is an Ambarella A5s system-on-chip, which contains an ARM processor, video processing hardware, USB device controller, and other peripherals. We had actually already guessed that the Dropcam used an Amborella chip based on the iManufacturer USB descriptor field value “Linux 2.6.38.8 with ambarella_udc”. Ambarella chips are also used in GoPro cameras. Quite a bit of work has been done reversing GoPro cameras by other researchers. One researcher, who goes by evilwombat, has done some particularly interesting work, including writing a firmware parser and tools that can be used to load custom code onto GoPro cameras over the USB port, which can be found at his Github page ( https://github.com/evilwombat?tab=repositories ).Here's a picture of the Dropcam with some of the components identified:The most useful thing to identify was the UART (serial) port (zoomed in the picture above, and labeled with TX, RX, 3.3v, and GND). Upon examining the board, that 4-pin footprint looked suspiciously like a serial port. One pad was connected to ground, and another was connected to a thick trace meaning it was likely a power connection, and it is in fact at 3.3v when the camera is powered on. The other two pads were connected to resistors via small traces and they were both at 3.3v with the camera powered on. This is consistent with an embedded system serial port – UARTs usually are at a “high” voltage level when they are idle; the TX line would be high because no data was being transmitted and the RX line would be pulled high when no input is connected. I tried connecting the RX line of a serial adapter to each of the two pads and found that when I configured the adapter for a baudrate of 115200 and powered the Dropcam, I could see Linux boot messages being transmitted:Once I had identified the TX and RX pads and successfully received some data, I soldered some wires to those pads and brought them out of the case so that I could access the serial port with the Dropcam assembled:After the boot messages, there is eventually a login prompt:Unfortunately, I didn't know the root password. I tried logging in as root with a few guessed passwords, but none of them worked. I was considering different ways to dump or modify the Flash chip contents when I happened upon a solution on a forum. After reading some posts on one of the GoPro forums I tried a trick mentioned there to get a bootloader prompt – transmitting a newline immediately upon powering the device on is the key. If you hold down the “Enter” key, repeatedly sending newlines to the serial connection while powering the Dropcam, you can access to the Ambarella bootloader:Once you have access to the bootloader, rooting the Dropcam is just like getting root on any Linux computer where you have access to the bootloader. You can copy the kernel command line shown in the boot messages:And change the init parameter to start a shell:After doing this and watching the kernel boot again, I was left with a root shell:My goal was to edit the /etc/shadow file so that I could log in to the camera after a normal boot. Interestingly, the /etc/shadow file on the Dropcam is a link to /mnt/dropcam/shadow:You therefore need to mount the /mnt/dropcam filesystem to access the shadow file:And then remove the password hashes from it:The /mnt/dropcam filesystem is interesting because it appears to be where camera-specific configuration files are stored:This implies that different cameras might have different root passwords. The wpa_supplicant.conf file contains the configuration for the wireless network. Most interesting of these files, however, is the keycert.pem file, which contains a public/private RSA key pair and a client certificate. The certificate is issued by a “Dropcam Certificate Authority”, and the common name is set to the unique ID of my Dropcam (the same identifier used to set up the camera and view its stream, as discussed in my previous post):This means that each Dropcam has a unique client certificate that it uses to authenticate to the Dropcam cloud servers.Now that I had modified the shadow file, I was able to log in as root without a password and inspect the system after it had booted normally:The /usr/bin/connect binary performs most of the operations of the Dropcam. It handles the TLS connections made out to Dropcam cloud servers (which, based on strings in the connect binary, carry a protocol named droptalk). It also handles loading and unloading the kernel driver, as well as the userspace portions of the USB mass storage network tunnel (which again, based on strings in the binary, is named FSNL). The connect binary is UPX packed, but it can be unpacked easily:One thing that we noticed when looking at this binary was that it contains references to the Lua scripting language. We weren't sure why until we saw that it was writing to a file named /tmp/connect.bin and then running this command via a call to system():The connect binary itself contains an embedded tarball that gets extracted to /tmp/connect when it runs. The tarball contains an assortment of files including a number of compiled Lua scripts:We'll have another blog post coming up detailing how to reverse engineer those compiled Lua scripts, with a tool to make the RE work easier.I wanted to perform a man-in-the-middle attack so that I could decode the TLS traffic from the camera. Every Dropcam has its own client certificate issued by the Dropcam CA; with a copy of my camera's client certificate I could start a TLS connection to the Dropcam servers, but I couldn't yet convince the connect binary to connect to me. In order to perform the man-in-the-middle attack, the simplest option was to patch the server certificate checking code out of the connect binary. This involved flipping one bit in the unpacked binary, re-packing it, and uploading it to the camera.The droptalk transport layer has decent protection against eavesdropping attacks. It uses an OpenSSL TLSv1 connection with ephemeral elliptic curve Diffie-Hellman (ECDHE) key exchange, and either 128 or 256 bit AES encryption. This is the list of the two cipher suites that the connect binary will accept for the droptalk connection:The ECDHE key exchange method made performing a man-in-the-middle on the droptalk connection harder because most tools that I tried to use didn't support that key exchange algorithm. However, I was able to hack some code together that given the camera's private key and certificate would let me intercept and examine the draptalk traffic between my patched connect binary and the Dropcam servers. Here's a picture of my test setup:My Linux machine was configured to act as a wireless access point, using iptables to redirect the dropcam traffic to my listening droptalk interception process. In addition, I had a serial terminal connected to the Dropcam's serial port so I could upload the patched connect binary and examine its behavior. The droptalk protocol is simple – there is a 3-byte header consisting of a one-byte message type followed by a big-endian two-byte length field. Luckily, there is a function in the connect binary for converting droptalk message type identifiers (the first byte in the header) to human-readalble strings for inclusion in debug output:The function provides us with this list of droptalk message types:Message types 0x01 through 0x14 appear to be messages that are sent to the camera, while types 0x80 through 0x8e appear to be intended to originate from the camera. Most of the droptalk messages contain protobufs which are decoded in the Lua code. For example, here's the first HELLO packet that my Dropcam sends when it connects to nexus.dropcam.com, decoded with the protoc tool:The nexus.dropcam.com server always replies with a REDIRECT to an “oculus” server:The client then connects to the “oculus” server and sends another HELLO packet. Most of the configuration options in the Dropcam web interface correspond to droptalk messages that are sent to the camera. When the server is ready to receive data, it sends a START_STREAM message with some video parameters in it. Video data is sent from the camera in RTP droptalk messages containing RTP formatted video data.In this post I've written about the process of reverse engineering the Dropcam from the point of opening the case to having a basic understanding of its network protocols. With the information we've gathered, you could start to piece together a protobuf definition file (.proto file) for the various message types and write your own droptalk client or server. Alternatively, you could use the root shell on the Dropcam to modify or add to its functionality. Comment below, email us , or tweet @IncludeSecurity if you try these things, we'd love to hear what modifications you make to your Dropcam.Stay tuned for the final blog post in this series regarding Lua scripts!