0x01 拆解

我从banggood买了一个Digoo BB-M2 Mini WiFi HD 720P安全摄像头。它的成本约为20欧元(即146RMB左右),这对于摄像头产品来说相当便宜。

1

这里我们先分析一下这个IP摄像机的串行接口。

第一步是去除设备底部的盖子。可以看到这里只用了三个螺丝固定。

2

此外,相机模块的背板必须取下来,用一个螺丝固定。之后,我们就可以看到PCB了。

3

现在可以从外壳中拔下所有东西了,比如电源,扬声器和电源连接器。

4

这里可以看到它的红外模块(夜间模式),现在我们不需要这个模块,所以我们先不管它,我们把motors(电机)和USB电源重新插入。

5

现在可以清晰识别到PCB上的接口了。在下图左侧,就是有三个焊盘的接口。使用示波器可以识别此引脚的功能。

6

为此,我们使用PicoScope。这是一个具有很好软件包的USB示波器。

7

PicoScope软件可以解码串行信号。由此,可以识别中间焊盘作为串行接口的传输信号。

8

正确的串行配置如下所示:

9

现在可以使用USB到串行转换器访问串行接口来连接到IP摄像机。现在可以接收和发送命令了。

11

硬件的规格:

12

0x02 分析

在上面知道了如何识别这个IP摄像机的串行端口后,我们就可以在这个IP摄像机上焊接导线了,并将USB连接到串行适配器了。

20

重要的是,导线不会在IP摄像机上产生短路。

21

使用picocom可以读写串行总线。如果串行总线适配器未列入白名单,则必须使用root权限执行该命令。

$ sudo picocom -b 115200 /dev/ttyUSB0
picocom v1.7
 
port is : /dev/ttyUSB0
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv
imap is : 
omap is : 
emap is : crcrlf,delbs,
 
Terminal ready

现在我们必须插入IP摄像机,并将引导消息打印在picocom控制台上。

U-Boot SPL 2013.07 (Sep 22 2016 - 21:41:56)
pll_init:347
l2cache_clk = 450000000
pll_cfg.pdiv = 8, pll_cfg.h2div = 4, pll_cfg.h0div = 4, pll_cfg.cdiv = 1, pll_cfg.l2div = 2
nf=36 nr = 1 od0 = 1 od1 = 1
cppcr is 02404900
CPM_CPAPCR 0470890d
nf=50 nr = 1 od0 = 1 od1 = 1
cppcr is 03204900
CPM_CPMPCR 0320490d
cppcr 0x9a7b5510
apll_freq 860160000 
mpll_freq 1200000000 
ddr sel mpll, cpu sel apll
ddrfreq 400000000
cclk 860160000
l2clk 430080000
h0clk 300000000
h2clk 300000000
pclk 150000000
CPM_DDRCDR(0000002c) = a0000002
 
 
U-Boot 2013.07 (Sep 22 2016 - 21:41:56)
 
Board: ISVP (Ingenic XBurst T10 SoC)
DRAM: 64 MiB
Top of RAM usable for U-Boot at: 84000000
Reserving 423k for U-Boot at: 83f94000
Reserving 32784k for malloc() at: 81f90000
Reserving 32 Bytes for Board Info at: 81f8ffe0
Reserving 124 Bytes for Global Data at: 81f8ff64
Reserving 128k for boot params() at: 81f6ff64
Stack Pointer at: 81f6ff48
Now running in RAM - U-Boot at: 83f94000
MMC: msc: 0
the manufacturer f8
SF: Detected FM25Q64
 
In: serial
Out: serial
Err: serial
Net: CPM_MACCDR(54) = a0000017
Jz4775-9161
Hit any key to stop autoboot: 0 
the manufacturer f8
SF: Detected FM25Q64
 
SF: 2621440 bytes @ 0x40000 Read: OK
## Booting kernel from Legacy Image at 80600000 ...
 Image Name: Linux-3.10.14
 Image Type: MIPS Linux Kernel Image (gzip compressed)
 Data Size: 2037043 Bytes = 1.9 MiB
 Load Address: 80010000
 Entry Point: 8039a050
 Verifying Checksum ... OK
 Uncompressing Kernel Image ... OK
 
Starting kernel ...
 
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Initializing cgroup subsys cpuacct
[ 0.000000] Linux version 3.10.14 (root@hsx-desktop) (gcc version 4.7.2 (Ingenic 2015.02) )
 #5 PREEMPT ThuSep 22 09:11:41 CST 2016
[ 0.000000] bootconsole [early0] enabled
[ 0.000000] CPU0 RESET ERROR PC:00805077
[ 0.000000] CPU0 revision is: 00d00100 (Ingenic Xburst)
[ 0.000000] FPU revision is: 00b70000
[ 0.000000] CCLK:860MHz L2CLK:430Mhz H0CLK:200MHz H2CLK:200Mhz PCLK:100Mhz
[ 0.000000] Determined physical RAM map:
[ 0.000000] memory: 00439000 @ 00010000 (usable)
[ 0.000000] memory: 00037000 @ 00449000 (usable after init)
[ 0.493476] jz_mac jz_mac.0: MII Probe failed!
[ 0.962286] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
mdev is ok......
ifconfig: SIOCGIFFLAGS: No such device
 
apk-link login: Archive: /system/system/lib/drivers.zip
 creating: drivers/
 inflating: drivers/gpioapp.ko
 inflating: drivers/sensor_jxh42.ko
 inflating: drivers/sensor_jxh62.ko
 inflating: drivers/sensor_jxh61.ko
 inflating: drivers/motoract.ko
 inflating: drivers/rf433.ko
 inflating: drivers/tx-isp.ko
 inflating: drivers/sinfo.ko
 inflating: drivers/eeprom_at24.ko
 inflating: drivers/sensor_ar0130.ko
ifconfig: wlan0: error fetching interface information: Device not found
not find mac===Get wifi ap mac:===
ifconfig: wlan0: error fetching interface information: Device not found
not find mac===Get wifi mac:===
===NetWorkSetMac===FC:cd:dc:ca:19:bb
sscanf return 6
@@@@ APSSID APCAM_FFFFFFCA19FFFFFFBB @@@@
===Get wifi ap mac:E0:B9:4D:ED:9C:98===
===Get wifi mac:E0:B9:4D:ED:9C:98===
===NetWorkSetMac===FC:cd:dc:ca:19:bb
SysParamRead system.ini
RTSP Port 10554
ONVIF Port 10080
SysLanguageRead language.ini
Now Language is English !
/usr/bin/unzip -o /system/www/audio_en.zip -d /tmp
kernelversion = Thu Sep 22 09:11:41 CST 2016 
user0: pwd:
user1: pwd:
user2:admin pwd:
SysDefaultVoiceInit : 2
sysversion:E10.71.1.16.55E
SysParamRead factory.ini
ssid: wifiauth 0 wifikey:
===NetWorkEthInitMac===FC:cd:dc:ca:19:bb
ifconfig: SIOCGIFFLAGS: No such device
ifconfig: SIOCSIFHWADDR: No such device
ifconfig: SIOCGIFFLAGS: No such device
========mac=FC:cd:dc:ca:19:bb===========
route: SIOCDELRT: No such process
ifconfig: SIOCSIFADDR: No such device
route: SIOCADDRT: No such device
dns1:8.8.8.8 dns2:192.168.1.1
===IpcSocketInit=6666===
===IpcSocketInit end=3===
===snetworkethmac:FC:cd:dc:ca:19:bb snetworkwifimac:E0:B9:4D:ED:9C:98===
 SearchAppInit by zxh
ServiceInit by zxh
update Socket proc is start
update socket init
start app update thread
===SearchThreadProc===
Archive: /system/system/bin/encoder.zip
 inflating: encoder
===wificam is start===
===wificam insmod ko is start===
===wificam insmod ko is end ===
adc_max : 0
adc_min : 0
GpioDataGpioMux:0
GpioDataGpioMux:0
GPIO_PIN_DIR:0
GpioDataGpioDir:0
GpioMotoInit
GpioAduioOut 0 
===Get wifi ap mac:E0:B9:4D:ED:9C:98===
===Get wifi mac:E0:B9:4D:ED:9C:98===
===NetWorkSetMac===FC:cd:dc:ca:19:bb
SysParamRead system.ini
RTSP Port 10554
ONVIF Port 10080
SysLanguageRead language.ini
Now Language is English !
/usr/bin/unzip -o /system/www/audio_en.zip -d /tmp
kernelversion = Thu Sep 22 09:11:41 CST 2016 
user0: pwd:
user1: pwd:
user2:admin pwd:
SysDefaultVoiceInit : 2
sysversion:E10.71.1.16.55E
SysParamRead factory.ini
===Get wifi ap mac:E0:B9:4D:ED:9C:98===
===Get wifi mac:E0:B9:4D:ED:9C:98===
===NetWorkSetMac===FC:cd:dc:ca:19:bb
sscanf return 6
@@@@ APSSID APCAM_FFFFFFCA19FFFFFFBB @@@@
alarm433 alarmcam.ini
===audio Codec Init===0
< Audio In Init Start >
Samplerate:16000 Bitwidth:16 Soundmode:1 FrmNum:20 NumPerFrm:320 ChnCnt:1
Audio In GetChnParam usrFrmDepth : 20
< Audio In Init End >
Audio In SetInPutVolume vol:11
===AudioInInit OK===
< Audio Out Init Start >
Samplerate:16000 Bitwidth:16 Soundmode:1 FrmNum:20 NumPerFrm:320 ChnCnt:1
< Audio Out Init End >
===AudioOutInit OK===
AudioPlayProc:156
1AlarmTimerParamRead 4 ff-ff-ff-ff
SD/TF Card not insert!
===H264ParamInit===
H264ParamInit bright 128 hue 128 saturation 128 contrast 128 videomode 0 videoenv 0 bitrate 1024 
framerate 15 ratemode 1 bitratesub 15 frameratesub 512 ratemodesub 1 bitratesubsub 10 
frameratesubsub 128 ratemodesubsub 0
===H264StreamInit===
ifconfig: SIOCSIFADDR: No such device
route: SIOCDELRT: No such process
===cmd:route add default gw 192.168.1.1 wlan0===
NetWorkSetInterface 0
killall: udhcpc: no process killed
g_sensor_type = 18 
===InitVideoEncoder===
Encoder_Read_Video_Resolution : 0
#################################Sensor = jxh62 ####################################
=================main profile 1280x720p=====================
i264e[info]: profile Constrained Baseline, level 3.1
i264e[info]: profile Constrained Baseline, level 3.0
===InitVideoEncoder end===0
File size = 261702
Read size = 261702
===H264 osd init===0
===H264 osd1 init===0
H264EncoderThread
===ShowVideoOsd_Time===
===ShowVideoOsd===
name:WIFICAM
channelname------------------:WIFICAM==len=7
===ShowbitrateOsd===
===StartOsdProcess===
===H264SoftWdtThread====
===H264SetParam===
===H264SetParam end===
[chn1] scaler->outwidth = 640 scaler->outheight = 360, 
sscaler.outwidth = 640 sscaler.outheight = 368
===H264IspStart===
IMP_ISP_EnableTuning 0
===H264DeNoise ===
===H264IspStart===
===H264DeNoise===
param.sense[0] = 3 
move->param.sense[0]=3
===IvsInit===0
===IvsThread===
VideoSetFrameRate fpsNum = 15 fpsDen = 1 
StreamLiveProc 0
StreamLiveProc 1
StreamLiveProc 2
StreamLiveProc 3
StreamRecordProc 3
StreamRecordProc 0
StreamRecordProc 1
StreamRecordProc 2
H264SetBitRate channel 0 ratemode 1 bybitrate 1024
frmRateNum = 25 
H264SetBitRate channel 2 ratemode 1 bybitrate 512
frmRateNum = 25 
1AlarmTimerParamRead 0 ff-ff-ff-ff
alarm time param is NULL !
StreamVideoProc 0
StreamVideoProc 1
StreamVideoProc 2
StreamVideoProc 3
P2P media thread is start...
P2P cmd thread is start...
pCfg->filename=
p2pdeviceid:MSC-005484-WGXZE
========version:2000001===========
HDXQ iRet 5
KJB iRet 2
DGM iRet 9
ADH iRet 12
GXD iRet 6
WCAM iRet -10
APLK iRet 12
HSL iRet 5
SSG iRet -6
XXM iRet -11
HSMART iRet 5
SMART iRet -6
SAKJ iRet -6
NAMI iRet -1
NAMI iRet -1
SCAN iRet -6
DRIP iRet 9
DAGRO iRet 9
XLT iRet -11
HS iRet 5
XWL iRet -11
MSC iRet 0
===logcnt=72===
P2pCheckThread
===curtime=1481006280===
Read DateTime:20161206 063800write date ok
===IpcSocketInit=6667===
===IpcSocketInit end=31===
IPCEncoderRecvProc 1
Starting Stream Video Process 0
Starting Stream Video Process 1
Starting Stream Video Process 2
Starting Stream Video Process 3
initialize iRet 0
======PPPP_LoginStatus_Check======
======PPPP_LoginStatus_Check end=0=====
sendto: Network is unreachable
No IGD UPnP Device found on the network !
user0: pwd0:
user1: pwd1:
user2:admin pwd2:
webport 81
web0===81===
web1===81===
======web init============81
motomode : 1
===MotoInit===
MotoReadMotoParam MotoOnStart 0 MotoDisPreset 0 speed 5
GpioMotoDirCmd iRet 0 motocmd:1 speed = 0 
GpioMotoDirCmd iRet 0 motocmd:5 speed = 0 
FactoryGetMotoLevelTimes 3675 value:3675
===MotoLevelMaxTimes===3675
FactoryGetMotoLevelTimesMid 1850 value:1850
===MotoLeftRightCenterTimes===1850
FactoryGetMotoVertTimes 1800 value:1800
===MotoVertMaxTimes===1800
===wifi usb error check status===FactoryGetMotoLevelTimesMid 900 value:900
===MotoUpDownCenterTimes===900
MotoLevelMaxTimes 3675 MotoLeftRightCenterTimes 1850 MotoVertMaxTimes 1800 
MotoUpDownCenterTimes 900
nomal flip 0
nomal mirr 0
recognize start !!!
wifi start !!!
KernelMd5 = 
welcome : 1
szFileName = /tmp/start-ok.wav 
GpioAduioOut 1 
------------------recognize start
------------------recognize invalid data, errorCode:100, error:not enough signal
check lasttimes is ok
=====check lastime iRet=0====
GpioMotoDirCmd iRet 0 motocmd:19 speed = 5 
===XGParamRead===
===wificam is end===
XgPushProc start ****************************************************
MyDomain start ****************************************************
------------------recognize start
------------------recognize invalid data, errorCode:100, error:not enough signal
ircut is switch on
szFileName = /tmp/config-waite.wav 
**************** SmartconnectStart ********************
GpioAduioOut 0 
GpioAduioOut 1 
iRet 0
bFlagInternet 0
bFlagHostResolved 0
bFlagServerHello 0
NAT_Type 0
PPPP_Share_Bandwidth(1) iRet 0
P2pListenThread
start P2pListenThread=MSC-005484-WGXZE license=SPYURW
PPPP_Listen() lock getting...
PPPP_Listen() ...bInternetFlag = 1
===MotoStatus=1===
GpioAduioOut 0 
 
[Check (Kernel && TF update) 1 time !]
dhcp isn't open...,ipaddr:192.168.1.249 netmask:255.255.255.0 
gateway:192.168.1.1 dns1:8.8.8.8 dns2:192.168.1.1
 
route: SIOCDELRT: No such process
------------------recognize start
------------------recognize invalid data, errorCode:100, error:not enough signal
------------------recognize start
===cmd:route add default gw 192.168.1.1 wlan0===
too many time range can not match signal
------------------recognize invalid data, errorCode:100, error:not enough signal
------------------recognize start
------------------recognize invalid data, errorCode:100, error:not enough signal
dns1:8.8.8.8 dns2:192.168.1.1
===dhcp is start and note encoder network===
NetWorkParamSync in 0
IPCEncoderDec cmd 4
wifi enable = 0 PowerOn = 0 
NetWorkParamSave ipaddr:192.168.1.249
route: SIOCADDRT: File exists
===IPCEncoderSetNetworkParam===
 
apk-link login:

通过按回车键,弹出登录提示。但我们并不知道登录凭据。

0x03 获取root访问权限

访问IP摄像机的串行接口后,下一步就是获取一个root shell。

通过在启动IP摄像机期间按任意键可以进入U-Boot。
这里可以通过“init=/bin/sh”扩展bootargs来启动shell
调整引导参数后,Linux操作系统会以“boot”启动。

isvp# setenv bootargs 'console=ttyS1,115200n8 mem=39M@0x0 ispmem=5M@0x2700000 
rmem=20M@0x2C00000 init/linuxrc rootfstype=squashfs init=/linuxrc rootfstype=squashfs 
root=/dev/mtdblock2 rw mtdparts=jz_sfc:256k(boot),2176k(kernel),3584k(rootfs),2176k(system) 
init=/bin/sh'# setenv bootargs 'console=ttyS1,115200n8 mem=39M@0x0 ispmem=5M@0x2700000 
rmem=20M@0x2C00000 init/linuxrc rootfstype=squashfs init=/linuxrc rootfstype=squashfs
 root=/dev/mtdblock2 rw mtdparts=jz_sfc:256k(boot),2176k(kernel),3584k(rootfs),2176k(system) 
init=/bin/sh'

isvp# boot

引导成功后,它应该会提示root shell

/ # whoami # whoami
root

使用root shell可以在“/etc/passwd”文件打印出root的哈希密码。

/ # cat /etc/passwd etc/passwd 
root:$1$ybdHbPDn$ii9aEIFNiolBbM9QxW9mr0:0:0::/root:/bin/sh

/etc/passwd文件的结构

结构理论上可以将彩虹表与“/etc/passwd”的哈希密码进行比较。
但到目前它还是没有跑出来。

root:$1$ybdHbPDn$ii9aEIFNiolBbM9QxW9mr0:0:0::/root:/bin/sh
Name:Password:User-ID:Group-ID:Comment:Directory:Shell

此外,可以列出可用的busybox命令。
现在我们可以慢慢分析IP-Camera(IP摄像机)的操作系统了。

/ # busybox 
BusyBox v1.22.1 (2014-05-13 08:27:59 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
 
Usage: 

busybox [function [arguments]...]
 or: busybox --list[-full]
 or: busybox --install [-s] [DIR]
 or: function [arguments]...
 
BusyBox 是一个多调用的工具软件. 它结合了许多常见的Unix实用程序
并把它们编译为单个可执行文件。大多数人都把自己想用的每个功能创
建一个bustbox链接,而BusyBox就可以调用它了。
 
Currently defined functions:
 [, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash,
 awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl,
 bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod,
 chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm,
 conspy, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd,
 deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff,
 dirname, dmesg, dnsd, dnsdomainname, dos2unix, du, dumpkmap,
 dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake,
 expand, expr, fakeidentd, false, fbset, fbsplash, fdflush, fdformat,
 fdisk, fgconsole, fgrep, find, findfs, flock, fold, free, freeramdisk,
 fsck, fsck.minix, fstrim, fsync, ftpd, ftpget, ftpput, fuser, getopt,
 getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump,
 hostid, hostname, httpd, hush, hwclock, id, ifconfig, ifdown,
 ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat,
 ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel,
 kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64,
 linuxrc, ln, loadfont, loadkmap, logger, login, logname, logread,
 losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat,
 lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg,
 microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix,
 mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more,
 mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite,
 nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd, od,
 openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress,
 pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv,
 printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev,
 readahead, readlink, readprofile, realpath, reboot, reformime,
 remove-shell, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm,
 rpm2cpio, rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script,
 scriptreplay, sed, sendmail, seq, setarch, setconsole, setfont,
 setkeycodes, setlogcons, setserial, setsid, setuidgid, sh, sha1sum,
 sha256sum, sha3sum, sha512sum, showkey, slattach, sleep, smemcap,
 softlimit, sort, split, start-stop-daemon, stat, strings, stty, su,
 sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl,
 syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test, tftp,
 tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true,
 tty, ttysize, tunctl, ubiattach, ubidetach, ubimkvol, ubirmvol,
 ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, umount, uname,
 unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users,
 usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch,
 watchdog, wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes,
 zcat, zcip

这篇文章主要是用最原始的方法来破解一台摄像机,从拆解Digoo BB-M2摄像机开始,一步步了解它的串口,引导,系统。如若哪里有错,可以提出来。

 

*作者:Matthias Niedermaier

源链接

Hacking more

...