A look inside an IPCAM

By | July 16, 2015

My mother had decided to buy an outdoor IPCAM and I had to help configure it. Unfortunately it seems to have som bugs. So lets have a look inside and see if they can be fixed. The cam itself does work, but is not very useful if you have to sit and monitor it yourself. The software for the cam has a motion sensor feature that can be configured to automatically send an e-mail with an attached image. The problem i ran into was that connections with SMTP did not work. So lets have a look at what we are dealing with.

The hardware

Vendor: www.safehome.dk

Brand: Compact P2P VGA Camera Outdoor (IP Camera Wireless)

Model: VGA 615W

Extracting the firmware

Embedded devices likely run some custom made minimal real-time OS, but for CE-devices (consumer electronics) embedded linux distrobutions is often used, e.g. uClinux. There are various ways to get a hold on the firmware. The firmware source/binaries might be avaliable from vendor’s website or it could be extracted from the device through telnet, ssh, serial communication via com-port/blinking leds read by a photo-diode , JTAG, dumped from a desoldered chip, etc.

The manual for the cam has a default login to the web-configuration which is user “admin” and password “123456”. Also the cam has telnet enabled, so an obvious guess would be to login as “root” with “123456”.

This works so lets have a look at the OS and programs running.

uname -r does not seem to be available trying following instead

# cat /proc/version
# Linux version 2.6.21 (root@mailzxh-desktop) (gcc version 3.4.2) #636 Fri Nov 1
6 10:03:21 CST 2012

# ps aux
1 root 1528 S init
2 root 0 SWN [ksoftirqd/0]
3 root 0 SW< [events/0]
4 root 0 SW< [khelper]
5 root 0 SW< [kthread]
6 root 0 SW< [kblockd/0]
7 root 0 SW< [khubd]
8 root 0 SW< [kswapd0]
9 root 0 SW [pdflush]
10 root 0 SW [pdflush]
11 root 0 SW< [aio/0]
12 root 0 SW< [scsi_tgtd/0]
13 root 0 SW [mtdblockd]
14 root 0 SW< [kmmcd]
20 root 1092 S nvram_daemon
23 root 0 SWN [jffs2_gcd_mtd6]
25 root 0 SWN [jffs2_gcd_mtd7]
28 root 1528 S telnetd
29 root 1696 S /system/system/bin/daemon.v5.5
30 root 1480 S /system/system/bin/cmd_thread
31 root 1480 S /system/system/bin/gmail_thread
32 root 1532 S /bin/sh
33 root 1696 S /system/system/bin/daemon.v5.5
36 root 1480 S /system/system/bin/cmd_thread
39 root 1480 S /system/system/bin/gmail_thread
40 root 1696 S /system/system/bin/daemon.v5.5
41 root 1696 S /system/system/bin/daemon.v5.5
42 root 1480 S /system/system/bin/cmd_thread
43 root 1480 S /system/system/bin/gmail_thread
50 root 0 SW [RtmpCmdQTask]
51 root 0 SW [RtmpWscTask]
89 root 1696 S /system/system/bin/daemon.v5.5
133 root 1696 S /system/system/bin/daemon.v5.5
134 root 1696 S /system/system/bin/daemon.v5.5
135 root 1696 S /system/system/bin/daemon.v5.5
138 root 1696 S /system/system/bin/daemon.v5.5
139 root 1696 S /system/system/bin/daemon.v5.5
140 root 1696 S /system/system/bin/daemon.v5.5
142 root 10736 S /system/system/bin/encoder
143..228 several /system/system/bin/encoder
229 root 10736 S /system/system/bin/encoder
230 root 10736 S /system/system/bin/encoder
2597 root 1524 S /sbin/udhcpc -i eth2 -n
2642 root 1532 S -sh
2658 root 10736 S /system/system/bin/encoder
2659 root 10736 S /system/system/bin/encoder
2682 root 1528 R ps aux

# busybox
BusyBox v1.12.1 (2012-11-16 09:58:14 CST) multi-call binary
Copyright (C) 1998-2008 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.
Usage: busybox [function] [arguments]...
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as!
Currently defined functions:
[, [[, ash, brctl, cat, chmod, chpasswd, cp, date, df, dos2unix,
echo, envuidgid, expr, fdisk, fetchmail, free, grep, halt, ifconfig,
init, init, insmod, kill, killall, klogd, ln, logger, login, logread,
ls, lsmod, mkdir, mount, mv, netstat, ping, poweroff, ps, reboot,
rm, rmmod, route, sed, sendmail, setuidgid, sh, sleep, sync, sysctl,
syslogd, tar, telnetd, test, tftp, top, touch, udhcpc, udhcpd, umount,
unix2dos, unzip, uptime, usleep, vconfig, vi
The commands available are a bit limited, so i might be easier to copy it all to a PC.
# cat /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / squashfs ro 0 0
proc /proc proc rw 0 0
none /var ramfs rw 0 0
none /etc ramfs rw 0 0
none /tmp ramfs rw 0 0
none /media ramfs rw 0 0
none /sys sysfs rw 0 0
none /dev/pts devpts rw 0 0
/dev/mtdblock6 /system jffs2 rw 0 0
/dev/mtdblock7 /param jffs2 rw 0 0

# cat /proc/partitions
major minor #block
s name
31 0 8192 mtdblock0
31 1 192 mtdblock1
31 2 64 mtdblock2
31 3 64 mtdblock3
31 4 1024 mtdblock4
31 5 3264 mtdblock5
31 6 3072 mtdblock6
31 7 512 mtdblock7
All partitions is MTD (Memory Technology Device)
# cat /proc/mtd
dev: size erasesize name
mtd0: 00800000 00010000 "ALL"
mtd1: 00030000 00010000 "Bootloader"
mtd2: 00010000 00010000 "Config"
mtd3: 00010000 00010000 "Factory"
mtd4: 00100000 00010000 "Kernel"
mtd5: 00330000 00010000 "RootFS"
mtd6: 00300000 00010000 "sys"
mtd7: 00080000 00010000 "param"
From looking around in the directories i found

/system/www/system.ini which stores the configuration made from the website including password for wifi, mail, ftp, etc. It can also be retieved from but do require login in order to do so.

# ls /system/system/bin
daemon.v5.5 cmd_thread findfile mailx
daemon.v5.3 gmail_thread encoder ftp
unzip1 upnpc-static ssmtp

The program /system/system/bin/ftp can be used to copy the partitions to a PC ( running a tftpd server.
#tftp -l /dev/mtdblock0 -r dump.bin -b 512 -p
Also for disassembling software later we need to know the cpu type and OS

# cat /proc/cpuinfo
system type : Ralink SoC
processor : 0
cpu model : MIPS 24K V4.12
BogoMIPS : 239.10
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes
ASEs implemented : mips16 dsp
VCED exceptions : not available
VCEI exceptions : not available

(RaLink mips:6000)

From html file in /system/www/test_mail.htm we can see it calls test_mail.cgi and get_status.cgi, but these files do not seem to exist in the filesystem. Lets find out which web server that is used. Run nmap from PC to scan ports at camera (

Note: when testing mail configuration from the build-in webbased wizard the following URL is used

Keeps getting reply:

Test … Failed

Can not connect to the server

$nmap -p- (ToDo list ports and identified servers, GoAhead-Webs)

Lets identify the web server process

# netstat -ap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0* LISTEN 142/encoder
tcp 0 0* LISTEN 28/telnetd
tcp 0 0* LISTEN 29/daemon.v5.5
tcp 0 157 ESTABLISHED 28/telnetd
udp 0 0* 142/encoder
udp 0 0* 142/encoder
udp 0 0* 29/daemon.v5.5
udp 0 0* 29/daemon.v5.5
udp 0 0* 142/encoder
udp 0 0* 142/encoder
udp 0 0* 142/encoder
udp 0 0* 142/encoder
udp 0 0* 31/gmail_thread
udp 0 0* 142/encoder
udp 0 0* 142/encoder
udp 0 0* 30/cmd_thread
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node PID/Program name Path

Disassembling the software

Lets split the dump into a file for each MTD partition. Size is in hex hence 00030000 is 196608 bytes.

#dd if=dump.bin of=bootloader.bin bs=1 count=196608
#dd skip=196608 if=dump.bin of=config.bin bs=1 count=65536
#dd skip=262144 if=dump.bin of=factory.bin bs=1 count=65536

and so on for the rest of the partitions.

#binwalk rootfs.bin (ToDo: list found data)

Lets mount the binary dump in linux at the PC.

$modprobe mtdram totalsize=3342336 erasesize=256
$modprobe mtdblock
$sudo modprobe mtdchar
$sudo mknod /dev/mtdblock0 b 31 0
$dd if=rootfs.bin of=/dev/mtdblock0
$mount -t jffs2 /dev/mtdblock0 /mnt

$file daemon.v5.5
$readelf -h daemon.v5.5

Todo: list ELF-header (little endian MIPS R3000)

Open files in a disassembler e.g. IDA and configure it for ELF executable for processor type MIPS little endian. First we search for the programs main entry and then we will see the following procedures are called from there.

Process: daemon.v5.5


Lets step further down and see what each procedure does.

In CreatePasswd function /etc/passwd seems to be overwritten with hardcoded root password “123456” hence it can not be changed permanently without modifing daemon.v5.5

watchdog_init sets up the watchdog timer.
DaemonInit creates a thread that calls WatchDogProc with only purpose is to loop, sleep and call watchdog_restart to reset watchdog timer.
If watchdog sends timeout signal then function EncCheckProc is called which logs running processes to /tmp/gps.txt and reboot system.

InitSystemParam reads /system/www/system.ini and calls SeParamDefault that loads hardcoded default settings something like
time server=time.nist.gov
subnet mask=
dns= (google public dns)

ReadFactoryMac calls nvram_bufget to get data from the NIC(network interface controller)’s non volatile ram that stores the MAC address.

ReadRactoryID also utilizes nvram_bufget to retrive the NIC’s device id.

Next functions does not sound that interesting, sounds like basic network configuration, lets just note the names and carry on.

ReadDnsFactory not entirely sure yet, but seems to read DNS address, port, user, pass, heartbeat? settings from /system/www/system.ini

InitNetDrivers calls WifiConfig, WifiDriversInit, EthMacInit(/usr/sbin/network.sh), Usb3GInit

NetWorkStart calls CheckIpAddr, DnsConfig

Networkhread (EtherSigInit(/var/run/udhcpc.pid), NetThreadProc(“net start”), NoteNetChange)

UpdateStart (UpdateAppProc, UpdateSysProc) think this is functions for flashing new firmwares to the device.

SearchInit create socket and?

SearchThread thread for broadcast?

IPCInit sets loopback device for IPC(inter process communication) throught sockets (IPCSocketInit “zqh socket fd=%d”)

IPCThread (IPCThreadProc (IPCRead))

Todo: get in more details and check what the other functions do

Process: cmd_thread

main calls IPCInit and IPCThread

IPCInit seems to bind to a socket.

IPCThread (IPCThreadProc) getppid, IPCRead, execute commands using system(), IPCWrite