I had a lot of success with various Chinese IP cameras as all of them supported standard ONVIF protocol, which allowed to almost entirely avoid their custom software and apps. However, my latest purchase was not that successful. I bought a mini 1080p camera from aliexpress which I intended to use in a van. As soon as I received it, I went to check it with nmap and it turns out that it only has port 80 open. That means no ONVIF, no RTSP streams.

The only way to use this camera is through iMiniCam app on android, custom Internet Explorer ActiveX plugin or a horrible MJPEG stream. Since I wanted to record the stream on a raspberry, I needed some usable stream format. I tried wiresharking IE stream, but I couldn’t figure out what protocol it was. All I knew that it was going through HTTP. And so it is reverse engineering time!
Opening the case revealed a HiSilicon Hi3518E V200 SoC which is quite common across IP cams. The sensor is OV2710, which is a 1080p sensor, but the provided streams are only 720p. Bummer.


There were also two test points which I suspected to be a serial console. A quick check with a scope confirmed that so I soldered some wires to connect it to an USB adapter. Baud rate is 115200. Be aware that voltage level is 3.3V.

This is the output during bootup:
System startup U-Boot 2010.06 (Sep 08 2018 - 14:16:59) Check Flash Memory Controller v100 ... Found SPI Nor(cs 0) ID: 0xc2 0x20 0x17 Block:64KB Chip:8MB Name:"MX25L6406E" SPI Nor total size: 8MB MMC: EMMC/MMC/SD controller initialization. Card did not respond to voltage select! No EMMC/MMC/SD device found ! *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Hisilicon ETH net controler hieth_init :0 MAC: 00-00-23-34-45-66 PHY not link. Hit any key to stop autoboot: 0 8192 KiB hi_fmc at 0:0 is now current device ## Booting kernel from Legacy Image at 82000000 ... Image Name: Linux-3.4.35 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 2442376 Bytes = 2.3 MiB Load Address: 80008000 Entry Point: 80008000 Loading Kernel Image ... OK OK Starting kernel ... Uncompressing Linux... done, booting the kernel. Booting Linux on physical CPU 0 Linux version 3.4.35 (zg@ESNTD_ZGLUX) (gcc version 4.8.3 20131202 (prerelease) (Hisilicon_v300) ) #179 Tue Oct 9 09:55:26 CST 2018 CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177 CPU: VIVT data cache, VIVT instruction cache Machine: hi3518ev200 Memory policy: ECC disabled, Data cache writeback Built 1 zonelists in Zone order, mobility grouping on. Total pages: 8128 Kernel command line: mem=32M console=ttyAMA0,115200 root=/dev/mtdblock4 rootfstype=squashfs mtdparts=hi_sfc:256k(boot),128k(env),128k(conf),2752k(os),3904k(rootfs),1024k(userfs) PID hash table entries: 128 (order: -3, 512 bytes) Dentry cache hash table entries: 4096 (order: 2, 16384 bytes) Inode-cache hash table entries: 2048 (order: 1, 8192 bytes) Memory: 32MB = 32MB total Memory: 27476k/27476k available, 5292k reserved, 0K highmem Virtual kernel memory layout: vector : 0xffff0000 - 0xffff1000 ( 4 kB) fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) vmalloc : 0xc2800000 - 0xff000000 ( 968 MB) lowmem : 0xc0000000 - 0xc2000000 ( 32 MB) modules : 0xbf000000 - 0xc0000000 ( 16 MB) .text : 0xc0008000 - 0xc044a000 (4360 kB) .init : 0xc044a000 - 0xc046a344 ( 129 kB) .data : 0xc046c000 - 0xc049a8e0 ( 187 kB) .bss : 0xc049a904 - 0xc04d8bb8 ( 249 kB) SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 NR_IRQS:32 VIC @fe0d0000: id 0x00641190, vendor 0x41 sched_clock: 32 bits at 49MHz, resolution 20ns, wraps every 86767ms Console: colour dummy device 80x30 Calibrating delay loop... 266.24 BogoMIPS (lpj=133120) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 512 Initializing cgroup subsys freezer CPU: Testing write buffer coherency: ok Setting up static identity map for 0x80345470 - 0x803454c8 dummy: NET: Registered protocol family 16 Serial: AMBA PL011 UART driver uart:0: ttyAMA0 at MMIO 0x20080000 (irq = 5) is a PL011 rev2 console [ttyAMA0] enabled uart:1: ttyAMA1 at MMIO 0x20090000 (irq = 30) is a PL011 rev2 uart:2: ttyAMA2 at MMIO 0x200a0000 (irq = 25) is a PL011 rev2 bio: create slab <bio-0> at 0 SCSI subsystem initialized hi-spi-master hi-spi-master.0: with 1 chip select slaves attached hi-spi-master hi-spi-master.1: with 2 chip select slaves attached usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb Switching to clocksource timer0 NET: Registered protocol family 2 IP route cache hash table entries: 1024 (order: 0, 4096 bytes) TCP established hash table entries: 1024 (order: 1, 8192 bytes) TCP bind hash table entries: 1024 (order: 0, 4096 bytes) TCP: Hash tables configured (established 1024 bind 1024) TCP: reno registered UDP hash table entries: 256 (order: 0, 4096 bytes) UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) NET: Registered protocol family 1 RPC: Registered named UNIX socket transport module. RPC: Registered udp transport module. RPC: Registered tcp transport module. RPC: Registered tcp NFSv4.1 backchannel transport module. VFS: Disk quotas dquot_6.5.2 Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) squashfs: version 4.0 (2009/01/31) Phillip Lougher NFS: Registering the id_resolver key type jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc. fuse init (API version 7.18) msgmni has been set to 53 Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254) io scheduler noop registered io scheduler deadline registered (default) io scheduler cfq registered brd: module loaded Check Flash Memory Controller v100 ... Found. SPI Nor(cs 0) ID: 0xc2 0x20 0x17 Block:64KB Chip:8MB Name:"MX25L6436F" SPI Nor total size: 8MB 6 cmdlinepart partitions found on MTD device hi_sfc 6 cmdlinepart partitions found on MTD device hi_sfc Creating 6 MTD partitions on "hi_sfc": 0x000000000000-0x000000040000 : "boot" 0x000000040000-0x000000060000 : "env" 0x000000060000-0x000000080000 : "conf" 0x000000080000-0x000000330000 : "os" 0x000000330000-0x000000700000 : "rootfs" 0x000000700000-0x000000800000 : "userfs" SPI Nand ID Table Version 1.9 No NAND device found ESNTD Kernel NVRAM initialized ESNDT GPIO HZ[1000] Ver 1.0 ... PTZ Speed 8 (5 [1--10 @@ 1000]) PTZ Cfg 0 PTZ Startpost 0, Speed 8, SavePos:-1--1 esndt gpio init max moto step 20000 Init Power Key->>OK PTZ Cfg Step 1050 - 16500 ->>OK esntd_hiadc_init --> OK himii: probed ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver hiusb-ehci hiusb-ehci.0: HIUSB EHCI hiusb-ehci hiusb-ehci.0: new USB bus registered, assigned bus number 1 hiusb-ehci hiusb-ehci.0: irq 15, io mem 0x100b0000 hiusb-ehci hiusb-ehci.0: USB 0.0 started, EHCI 1.00 hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver hiusb-ohci hiusb-ohci.0: HIUSB OHCI hiusb-ohci hiusb-ohci.0: new USB bus registered, assigned bus number 2 hiusb-ohci hiusb-ohci.0: irq 16, io mem 0x100a0000 hub 2-0:1.0: USB hub found hub 2-0:1.0: 1 port detected Initializing USB Mass Storage driver... usbcore: registered new interface driver usb-storage USB Mass Storage support registered. mousedev: PS/2 mouse device common for all mice i2c /dev entries driver hisi_i2c hisi_i2c.0: Hisilicon [i2c-0] probed! hisi_i2c hisi_i2c.1: Hisilicon [i2c-1] probed! hisi_i2c hisi_i2c.2: Hisilicon [i2c-2] probed! usbcore: registered new interface driver usbhid usbhid: USB HID core driver TCP: cubic registered Initializing XFRM netlink socket NET: Registered protocol family 17 NET: Registered protocol family 15 lib80211: common routines for IEEE802.11 drivers Registering the dns_resolver key type VFS: Mounted root (squashfs filesystem) readonly on device 31:4. Freeing init memory: 128K ||||\ ||||| ||| || |||||| |||||| |\ \|| \||| |\ || || || ||||\ |||\ \| |\ |\ || || || || usb 1-1: new high-speed USB device number 2 using hiusb-ehci \|| \| |||\ || || || || \ || \| \||\ || || ||\ ||||| \||||\ || ||\ || |||||\ www.esntd.com [RCS]: /etc_ro/init.d/S00devs [RCS]: /etc_ro/init.d/S01udev usbdev11 -> /dev/usbdev1.2 Not recognise ACTION:change Not recognise ACTION:change Not recognise ACTION:change [RCS]: /etc_ro/init.d/S80network Start User Init ...! mmz_start: 0x82000000, mmz_size: 32M Hisilicon Media Memory Zone Manager Module himedia: init ok hi3518e_base: module license 'Proprietary' taints kernel. Disabling lock debugging due to kernel taint load sys.ko for Hi3518EV200...OK! PHY: himii:01 - Link is Up - 10/Half load tde.ko ...OK! load region.ko ....OK! load vgs.ko for Hi3518EV200...OK! ISP Mod init! load viu.ko for Hi3518EV200...OK! load vpss.ko ....OK! load rc.ko for Hi3518EV200...OK! load venc.ko for Hi3518EV200...OK! load chnl.ko for Hi3518EV200...OK! load h264e.ko for Hi3518EV200...OK! load jpege.ko for Hi3518EV200...OK! load ive.ko for Hi3518EV200...OK! ==== Your input Sensor type is ov2710 ==== *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0040: 0x00000000 --> 0x00000002 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0044: 0x00000000 --> 0x00000002 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0000: 0x00000001 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0004: 0x00000000 --> 0x00000000 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f007c: 0x00000000 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0080: 0x00000000 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0084: 0x00000000 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0088: 0x00000000 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f008c: 0x00000000 --> 0x00000002 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0090: 0x00000000 --> 0x00000002 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0094: 0x00000000 --> 0x00000001 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x2003002c: 0x000C4003 --> 0x000C4001 [END] acodec inited! insert audio mipi_init init phy power successful! load hi_mipi driver successful! ==== Your input Sensor type is ov2710 ==== Hisilicon Watchdog Timer: 0.01 initialized. default_margin=60 sec (nowayout= 0, nodeamon= 0) Load wifi ...! ESNDO_Startup ... rtusb init rtusbSTA ---> === pAd = c2d58000, size = 860832 === <-- RTMPAllocTxRxRingMemory, Status=0 <-- RTMPAllocAdapterBlock, Status=0 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x8 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x4 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x5 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x6 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x7 RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x9 NVM is EFUSE Endpoint(8) is for In-band Command Endpoint(4) is for WMM0 AC0 Endpoint(5) is for WMM0 AC1 Endpoint(6) is for WMM0 AC2 Endpoint(7) is for WMM0 AC3 Endpoint(9) is for WMM1 AC0 Endpoint(84) is for Data-In Endpoint(85) is for Command Rsp usbcore: registered new interface driver rtusbSTA 1. LDO_CTR0(6c) = a64799, PMU_OCLEVEL c 2. LDO_CTR0(6c) = a6478d, PMU_OCLEVEL 6 FW Version:0.1.00 Build:7640 Build Time:201308222153____ ILM Length = 47000(bytes) DLM Length = 0(bytes) Loading FW.... # RTMP_TimerListAdd: add timer obj c2dd8bec! RTMP_TimerListAdd: add timer obj c2dd8c04! RTMP_TimerListAdd: add timer obj c2dd8c1c! RTMP_TimerListAdd: add timer obj c2dd8bd4! RTMP_TimerListAdd: add timer obj c2dd8b8c! RTMP_TimerListAdd: add timer obj c2dd8ba4! RTMP_TimerListAdd: add timer obj c2d6da24! RTMP_TimerListAdd: add timer obj c2d5a1e0! RTMP_TimerListAdd: add timer obj c2d5a1fc! RTMP_TimerListAdd: add timer obj c2d6da7c! RTMP_TimerListAdd: add timer obj c2d5ccf0! RTMP_TimerListAdd: add timer obj c2d5c3a0! RTMP_TimerListAdd: add timer obj c2d5ccd4! RTMP_TimerListAdd: add timer obj c2d5cf14! RTMP_TimerListAdd: add timer obj c2d5cd0c! RTMP_TimerListAdd: add timer obj c2d5cd28! RTMP_TimerListAdd: add timer obj c2d5cd44! RTMP_TimerListAdd: add timer obj c2d6d9f4! RTMP_TimerListAdd: add timer obj c2d6da64! RTMP_TimerListAdd: add timer obj c2d5cf44! RTMP_TimerListAdd: add timer obj c2d5cf5c! RTMP_TimerListAdd: add timer obj c2d5cf74! RTMP_TimerListAdd: add timer obj c2d5cf8c! cfg_mode=9 wmode_band_equal(): Band Equal! Key1Str is Invalid key length(0) or Type(0) Key2Str is Invalid key length(0) or Type(0) Key3Str is Invalid key length(0) or Type(0) Key4Str is Invalid key length(0) or Type(0) 1. Phy Mode = 14 2. Phy Mode = 14 NVM is Efuse and its size =1d[1e0-1fc] 3. Phy Mode = 14 AntCfgInit: primary/secondary ant 0/1 ---> InitFrequencyCalibration InitFrequencyCalibrationMode:Unknow mode = 3 InitFrequencyCalibration: frequency offset in the EEPROM = 86(0x56) <--- InitFrequencyCalibration RTMPSetPhyMode: channel is out of range, use first channel=1 MCS Set = ff 00 00 00 01 <==== rt28xx_init, Status=0 0x1300 = 00064300 RTMPDrvOpen(1):Check if PDMA is idle! RTMPDrvOpen(2):Check if PDMA is idle! Auto login as root ... Jan 1 00:00:09 login[1124]: root login on 'ttyS000' Welcome to HiLinux. # killall: goahead: no process killed Start System Server ... app_startup.sh esndo teldbg.sh web default_cfg.bin goahead usr_init *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200300c4: 0x00000A02 --> 0x00000A00 [END] *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200f0008: 0x00000001 --> 0x00000000 [END] serv=time.nist.gov sync=48 tz=CST_008 *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x200300ec: 0x00000082 --> 0x00000000 [END] ===>rt_ioctl_giwscan. 3(3) BSS returned, data->length = 502 PTZ Speed 8 (5 [1--10 @@ 1000]) mount: mounting /dev/mmcblk0p1 on /sd/ failed: No such file or directory ESN_SENSOR_TYPE IS H62 *** Board tools : ver0.0.1_20121120 *** [debug]: {source/utils/cmdshell.c:166}cmdstr:himm 0x2003002c: 0x000C4001 --> 0x000B4001 [END] SENSOR INIT H62 =============SAMPLE_COMM_VI_SetMipiAttr enWDRMode: 0 ***link down status changed***. PHY: himii:01 - Link is Down linear mode ========================================================= === soih62 720P30fps(Parallel port) init success!===== ========================================================= Failed to connect to wpa_supplicant - wpa_ctrl_open: No such file or directory KS:0001 -> 10 KS:0002 -> 00 KS:0000 -> 00 KS:0022 -> ee KS:0023 -> 02 KS:0001 -> 17 KS:0001 -> 22 KS:0001 -> 32 KS:0001 -> 49 KS:0001 -> 6b KS:0001 -> 9e KS:0001 -> e2 KS:0001 -> 44 KS:0002 -> 01 KS:0001 -> cc KS:0001 -> 8d KS:0002 -> 02 KS:0001 -> ec KS:0000 -> 03 KS:0000 -> 0a KS:0000 -> 11 KS:0000 -> 15 KS:0000 -> 19 KS:0000 -> 1d KS:0000 -> 1f KS:0000 -> 20 KS:0000 -> 1f KS:0000 -> 1d KS:0000 -> 1c KS:0000 -> 1a KS:0000 -> 19 KS:0000 -> 18 KS:0000 -> 17 KS:0000 -> 16 KS:0000 -> 15 Failed to connect to wpa_supplicant - wpa_ctrl_open: No such file or directory Failed to connect to wpa_supplicant - wpa_ctrl_open: No such file or directory RT_ESNTD_WIFICFG_SET 1 ===>rt_ioctl_giwscan. 14(14) BSS returned, data->length = 2392 RT_ESNTD_WIFICFG_SET 0 Failed to connect to wpa_supplicant - wpa_ctrl_open: No such file or directory killall: wpa_supplicant: no process killed rfkill: Cannot open RFKILL control device P2P Font:CST_008 Use Web Port 80 NetIF : ra0 NetIF : ra0 ifconfig: SIOCSIFHWADDR: Operation not supported ifconfig: SIOCSIFHWADDR: Operation not supported route: SIOCADDRT: File exists adding dns 192.168.1.1 adding dns 8.8.8.8 adding dns 192.168.1.1 adding dns 8.8.8.8 udhcpc: option -h NAME is deprecated, use -x hostname:NAME udhcpc (v1.20.2) started deconfig Sending discover... [SAMPLE_RGN_ShowOrHide]-2896: HI_MPI_RGN_GetDisplayAttr (2)) failed with 0xa0038005! [esntd_enc_do_osd_show]-2926: region(2) show failed with 0xffffffff! [SAMPLE_RGN_ShowOrHide]-2896: HI_MPI_RGN_GetDisplayAttr (3)) failed with 0xa0038005! [esntd_enc_do_osd_show]-2926: region(3) show failed with 0xffffffff! To OPEN Audio Module LibName:(libhive_HPF.so) To OPEN Audio Module LibName:(libhive_ANR.so) To OPEN Audio Module LibName:(libhive_AGC.so) To OPEN Audio Module LibName:(libhive_HPF.so) To OPEN Audio Module LibName:(libhive_ANR.so) To OPEN Audio Module LibName:(libhive_AGC.so) ===>rt_ioctl_giwscan. 15(15) BSS returned, data->length = 2623 ==>rt_ioctl_siwfreq::SIOCSIWFREQ(Channel=1) PeerBeaconAtJoinAction(): HT-CtrlChannel=1, CentralChannel=>1 PeerBeaconAtJoinAction(): Set CentralChannel=1 Rcv Wcid(1) AddBAReq Start Seq = 00000001 RTMP_TimerListAdd: add timer obj c2e26434! RT_ESNTD_WIFICFG_SET 1 ===>rt_ioctl_giwscan. 15(15) BSS returned, data->length = 2623 RT_ESNTD_WIFICFG_SET 0 Sending discover... RTMP_TimerListAdd: add timer obj c2e25020! ===>rt_ioctl_giwscan. 15(15) BSS returned, data->length = 2584 serv=time.nist.gov sync=48 tz=CST_008 Sending discover... Rcv Wcid(1) AddBAReq Start Seq = 00000005 Sending select for 192.168.1.190... Lease of 192.168.1.190 obtained, lease time 6749 reconfig deleting routers route: SIOCDELRT: No such process default gw adding dns 192.168.1.1 DHCP _ OK KS:0001 -> a3 KS:0000 -> 18 KS:0001 -> 65 KS:0002 -> 04 KS:0000 -> 0d KS:0022 -> ca KS:0023 -> 08 KS:0000 -> 0b KS:0000 -> 0a KS:0000 -> 09 KS:0001 -> 27 KS:0002 -> 06 KS:0000 -> 01 KS:0000 -> 00 KS:0001 -> 46 KS:0002 -> 05 KS:0000 -> 02 KS:0000 -> 01 serv=time.nist.gov sync=48 tz=CST_008 KS:0000 -> 00 KS:0001 -> 65 KS:0002 -> 04 KS:0000 -> 02 KS:0000 -> 01
Unfortunately uboot is configured with 0 delay and I was unable to interrupt it to get into uboot shell. I tried spamming various combinations but none did the trick. Why would anyone want to protect this piece of garbage software.
On the other hand, I had full terminal access and could explore the file system. This is how the root looks like (remember what I told about garbage?):
total 85 -rwxr--r-- 1 12800 Sep 17 2015 alm.wav -rwxr--r-- 1 21434 Aug 23 2016 ap_start.wav drwxrwxr-x 2 957 Jun 13 2018 bin drwxr-xr-x 2 3 Apr 19 2006 boot -rwxr--r-- 1 4624 Jun 28 2018 clock.wav drwxrwxrwt 6 3520 Jul 24 07:53 dev drwxr-xr-x 3 144 Sep 8 2018 esntd drwxrwxrwt 6 340 Jul 24 07:56 etc drwxr-xr-x 6 185 Jun 13 2018 etc_ro drwxr-xr-x 3 641 Jun 8 2018 hiko drwxr-xr-x 2 3 Apr 19 2006 home drwxr-xr-x 2 704 Jun 8 2018 lib lrwxrwxrwx 1 11 Jun 13 2018 linuxrc -> bin/busybox drwxr-xr-x 2 3 Apr 19 2006 lost+found -rwxr-xr-x 1 1341 Apr 21 2011 mkimg.rootfs -rwxr-xr-x 1 431 Apr 21 2011 mknod_console drwxr-xr-x 2 3 Apr 19 2006 mnt drwxr-xr-x 2 316 Sep 8 2018 mylib drwxr-xr-x 2 3 May 21 2008 nfsroot drwxr-xr-x 2 3 Apr 19 2006 opt dr-xr-xr-x 61 0 Jan 1 1970 proc drwxr-xr-x 2 3 Mar 24 2016 root drwxrwxr-x 2 712 Jul 2 2018 sbin drwxr-xr-x 2 3 Mar 14 2016 sd drwxr-xr-x 2 3 Apr 19 2006 share dr-xr-xr-x 12 0 Jan 1 1970 sys -rwxr--r-- 1 22894 Aug 23 2016 sys_reset.wav drwxrwxrwt 2 40 Jul 24 07:53 tmp drwxrwxr-x 6 62 Jun 8 2018 usr drwxrwxrwt 4 120 Jul 24 07:56 var -rwxr--r-- 1 21740 Aug 23 2016 wifi_ok.wav
After a bit of exploring, it seems that all relevant stuff is happening inside /esntd directory. It contains static web pages under /esntd/web and a 1.5MB /esntd/goahead binary which does pretty much everything.
At this point I got so frustrated that I was going to desolder the SPI chip and dump all the flash to fix the stupid bootloader delay. I have also seen multiple firmware variants for the Hi3518E SoC, which I thought would work and turn it into a proper ONVIF camera. However, after further digging I realised that chances of getting a different firmware to work would be slim (different camera sensors, wifi chips, etc).
Instead, I moved onto analysing that large binary. I got it out of the flash with ftpput utility, which was present in the busybox. I loaded it up in IDA and went skimming through the strings until I found something interesting:
It seems that the only proper stream format is microsoft ASF, which is not that bad. With little digging I could find the url and open the stream on VLC. The URL is http://camera/videostream.asf. It has some parameters such as resolution, rate and channel. The resolution parameter valid values are 8 – 320×240, 16 – 1280×720, 32 – 640×480, 64 – 1280×720. No 1080p resolution :< The rate parameter doesn’t seem to have any effect and the channel parameter seems to be the same as resolution. You can also provide user and pwd parameters so it does not ask for http authentication like so: http://camera/videostream.asf?user=admin&pwd=&resolution=64
There are also some other CGI endpoints:
http://camera/snapshot.cgi – generates image snapshot
http://camera/get_ircfg.cgi – returns IR filter configuration:
var ir_low=100; var ir_high=120; var ir_curr=4; var ir_status=1; var ir_disabled=0; var ir_timer=0;
You can set these values like so: http://camera/set_ircfg.cgi?ir_disabled=1. I assume that ir_low and ir_high parameters are for automatic ir filter switching, but I could not get that to work. I could only control it manually via ir_disabled.
Other endpoints can be easily sniffed via chrome network tools or by analysing the binary.
Bottom line: you are better off buying an IP camera module like this which has a proper ONVIF and RTSP support.
Hi,
I have a chinese IP camera as well. I have access to it using telnet and I have basic controls. However, a lot of the commands seem to have been stripped out, a lot of it seems to be read only, I can’t find what is sending the video and I don’t have a serial connection. Looking at your blog above, looks like you are quite the expert!
So, I was wondering if you could point me in the right direction for some of my issues. eg how did you determine where the serial connection was and how can I tell where the video is being sent from? I’ve been through the directories a number of times but haven’t found anything conclusive.
Thanks
Hi,
Serial port is usually exposed as a connector or test points like in this case. Finding it is easiest by poking various points with oscilloscope and looking for serial-like signal. If you don’t have one, you can just try poking with serial adapter RX line, if you see some garbage data – try different baud rates.
I couldn’t figure out what was used for encoding and serving video (didn’t try much). I found these endpoints by a combination of other blog posts/forums and looking ant firmware binary strings.
You could also try ONVIF manager as some cameras support this protocol. It gives you a list of supported streams with URLs. https://sourceforge.net/projects/onvifdm/
thanks for the info. I found the serial ports but, because they were so small and close together, I managed to blow the board with my soldering.
🙁
Hi,
I bought another camera, same as the one I bricked. I have successfully connected to the serial port and it has a uboot countdown that I can interrupt. So, I think I have access to what you called the uboot shell. However, having done that, I’m now a bit clueless as to what the next step is.
What I want to do is ‘replace’ the crap app that came with the camera and stream and record the video to a better app or a browser, with controls. Would you be able to help me understand the code and change it as required?
Thanks