3

I got a CS-C6N Ezviz camera. My friend gave it to me because he doesn't use it anymore. I was able to get rtsp stream from the camera (but laggy), and I also was able to connect to UART port on the camera's main board at baudrate 115200.

The UART interface gives me U-Boot shell (which I was able to dump firmware, see below) and access to a Busybox protected shell (psh).

The camera runs on ARM(v6) Linux, with a 3.0 kernel.

Here is the repo contains firmware dump and other stuff I found on the camera.

The problem is, the psh provide a really limited set of commands, and some even un-runable even when it's available in the help command:

psh

Now I want to break out of that shell to get a full root shell.

From what I understand, this is the boot process: First, U-boot is loaded, then it loads kernel, then kernel boots, then it loads some sort of "init" (for some reason I can't find that exactly init script/executable). The init will then initialize the system, and finally it loads the vendor's main app ezapp and a protected Busybox shell.

What I have tried:

  • Follow this answer of adding single to boot cmdline: it stills boot to that psh, but the ezapp won't be loaded.

  • Modify the squashfs that contains the ezapp so it will load /bin/sh instead of ezapp, then pass the squashfs as initrd to kernel: not work, system still runs ezapp.

  • Add init=/bin/sh to cmdline: not work, kernel somehow ignore that option.

Here is the output from dmesg command (one of the very few command that can be executed on psh):

[    0.000000] Linux version 3.0.8[svn 59238] (tuyongliang@Cpl-Civil-Camera) (gcc version 4.3.2 (crosstool-NG 1.19.0) ) #219 Tue Jul 23 15:45:36 CST 2019
[    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387f
[    0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine: HIK IPC
[    0.000000] devinfo=c6c_2019
[    0.000000] mem=38797312 byte
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] On node 0 totalpages: 9472
[    0.000000] free_area_init_node: node 0, pgdat c0438dc0, node_mem_map c045b000
[    0.000000]   Normal zone: 74 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 9398 pages, LIFO batch:1
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 9398
[    0.000000] Kernel command line: console=ttyS0,115200 root=/dev/ram0 mem=40M single mtdparts=spi_flash:256k(bld)ro,64k(env),64k(enc)ro,2304k(sys),3968k(ap0
[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 37MB = 37MB total
[    0.000000] Memory: 33016k/33016k available, 4872k reserved, 0K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
[    0.000000]     vmalloc : 0xc2800000 - 0xfe000000   ( 952 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc2500000   (  37 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .init : 0xc0008000 - 0xc00d4000   ( 816 kB)
[    0.000000]       .text : 0xc00d4000 - 0xc0417000   (3340 kB)
[    0.000000]       .data : 0xc0418000 - 0xc0439440   ( 134 kB)
[    0.000000]        .bss : 0xc0439464 - 0xc045a478   ( 133 kB)
[    0.000000] SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:128
[    0.000000] timer mult: 0xfa000000, timer shift: 0x16
[    0.000000] sched_clock: 32 bits at 1000kHz, resolution 1000ns, wraps every 4294967ms
[    0.000000] Console: colour dummy device 80x30
[    0.000000] console [ttyS0] enabled
[    0.000409] Calibrating delay loop... 430.08 BogoMIPS (lpj=2150400)
[    0.060029] pid_max: default: 32768 minimum: 301
[    0.060412] Mount-cache hash table entries: 512
[    0.061131] CPU: Testing write buffer coherency: ok
[    0.061451] hw perfevents: enabled with v6 PMU driver, 3 counters available
[    0.062578] devtmpfs: initialized
[    0.066508] NET: Registered protocol family 16
[    0.071026] fh_pinctrl_init selected_devices_c6c_2019.
[    0.085091] hw-breakpoint: found 6 breakpoint and 1 watchpoint registers.
[    0.085137] hw-breakpoint: maximum watchpoint size is 4 bytes.
[    0.113497] bio: create slab <bio-0> at 0
[    0.119000] fh_dmac fh_dmac.0: FH DMA Controller, 8 channels
[    0.125564] Advanced Linux Sound Architecture Driver Version 1.0.24.
[    0.128599] cfg80211: Calling CRDA to update world regulatory domain
[    0.130430] Switching to clocksource fh_clocksource
[    0.185851] NET: Registered protocol family 2
[    0.186096] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.186698] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[    0.186844] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[    0.186923] TCP: Hash tables configured (established 2048 bind 2048)
[    0.186951] TCP reno registered
[    0.186981] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.187040] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.187726] NET: Registered protocol family 1
[    1.520113] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    1.530885] JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    1.547273] msgmni has been set to 64
[    1.561028] NET: Registered protocol family 38
[    1.561127] io scheduler noop registered (default)
[    1.580949] PWM driver, Number: 8, IO base addr: 0xc2968000
[    1.591785] ttyS.0: ttyS0 at MMIO 0xf0700000 (irq = 30) is a ttyS
[    1.600942] fh serial probe done
[    1.601052] ttyS.2: ttyS2 at MMIO 0xf0880000 (irq = 35) is a ttyS
[    1.607981] fh serial probe done
[    1.627555] brd: module loaded
[    1.731122] loop: module loaded
[    1.759717] I2S probe
[    1.759763] I2S :996
[    1.817310] CLK misc driver init successfully
[    1.869242] m25p80 spi0.0: found gd25q64, expected m25p80
[    1.869444] m25p80 spi0.0: gd25q64 (8192 Kbytes)
[    1.869517] 8 cmdlinepart partitions found on MTD device spi_flash
[    1.869551] Creating 8 MTD partitions on "spi_flash":
[    1.869590] 0x000000000000-0x000000040000 : "bld"
[    1.896270] 0x000000040000-0x000000050000 : "env"
[    1.921226] 0x000000050000-0x000000060000 : "enc"
[    1.949632] 0x000000060000-0x0000002a0000 : "sys"
[    1.976362] 0x0000002a0000-0x000000680000 : "app"
[    2.001175] 0x000000680000-0x0000006f0000 : "cfg"
[    2.029686] 0x0000006f0000-0x0000007f0000 : "mini"
[    2.056291] 0x0000007f0000-0x000000800000 : "share"
[    2.131692] console [netcon0] enabled
[    2.131720] netconsole: network logging started
[    2.176354] fh_rtc fh_rtc.0: rtc core: registered rtc as rtc0
[    2.177280] i2c /dev entries driver
[    2.181064] I2C driver:
[    2.181086]  platform registration... 
[    2.181179]  Clock: 15000khz, Standard-mode HCNT:LCNT = 62:74
[    2.181210]  tx fifo depth: 16, rx fifo depth: 16
[    2.196861]  I2C - (dev. name: fh_i2c - id: 0, IRQ #42
[    2.196882]          IO base addr: 0xc29b0000)
[    2.196950] I2C driver:
[    2.196964]  platform registration... 
[    2.197053]  Clock: 15000khz, Standard-mode HCNT:LCNT = 62:74
[    2.197086]  tx fifo depth: 16, rx fifo depth: 16
[    2.210066]  I2C - (dev. name: fh_i2c - id: 1, IRQ #43
[    2.210087]          IO base addr: 0xc29b8000)
[    2.300492] ALSA device list:
[    2.300524]   No soundcards found.
[    2.307225] TCP cubic registered
[    2.307266] NET: Registered protocol family 17
[    2.307539] Bridge firewalling registered
[    2.307587] lib80211: common routines for IEEE802.11 drivers
[    2.307618] lib80211_crypt: registered algorithm 'NULL'
[    2.307643] Registering the dns_resolver key type
[    2.307713] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
[    2.311028] mmc1 power register success!
[    2.311067] Change SD state from STOR_OFFLINE to STOR_OFFLINE
[    2.341258] GMAC driver:
[    2.341279]  platform registration... 
[    2.357002] fh_gmac fh_gmac.0: eth0: mixed HW and IP checksum settings.
[    2.357051] fh_gmac fh_gmac.0: eth0: mixed no checksumming and other settings.
[    2.357314]  eth0 - (dev. name: fh_gmac - id: 0, IRQ #14
[    2.357334]          IO base addr: 0xc29d8000)
[    2.442672] gmac_rmii: probed
[    2.442716] eth0: PHY ID 001cc816 at 0 IRQ -1 (0:00) active
[    2.482073] fh_rtc fh_rtc.0: setting system clock to 1970-01-01 00:02:00 UTC (120)
[    2.495831] mmc0: new high speed SDIO card at address 0001
[    2.538461] aes driver registered
[    2.540197] Freeing init memory: 816K
[    2.610334] card0 disconnected!

U-Boot commands:

HKVS # help
?       - alias for 'help'
arc_go  - start application at address 'addr'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootmini- load &    run mini sys
bootp   - boot image via network using BOOTP/TFTP protocol
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dhcp    - boot image via network using DHCP/TFTP protocol
echo    - echo args to console
editenv - edit environment variable
fastbootcmd- set boot command
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
format  - format flash except bootloader area
go      - go xxx.bin thru net 
go_orig - start application at address 'addr'
gos     - go xxx.bin thru serial
gpio_get- get the direction and value of gpio
gpio_set- config the direction and value of gpio
help    - print command description/usage
iminfo  - print header information for application image
loadb   - load binary file over serial line (kermit mode)
loadk   - load kernel to DRAM & verify kernel+app
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mtest   - simple RAM read/write test
mw      - memory write (fill)
nm      - memory modify (constant address)
pinctrl - Pin Ctrl
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
rarpboot- boot image via network using RARP/TFTP protocol
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
sf      - SPI flash sub-system
sleep   - delay execution for some time
sspi    - SPI utility commands
tftpboot- boot image via network using TFTP protocol
upa     - update app image
upapp   - update app image
upb     - update bootloader
upbs    - update bootloader from serial
update  - update digicap.dav
updateb - update bootloader
upf     - update firmware, format and update (factory use)
upk     - update uImage
version - print monitor version
wdt     - WDT utility commands
HKVS # 

Something to note:

  • I don't know what passed mtdparts=spi_flash:256k(bld)ro,64k(env),64k(enc)ro,2304k(sys),3968k(ap0 and such stuff to kernel cmdline, but it's definitely not U-boot. Maybe cmdline build-in to kernel?
  • I can't seem to decompress the kernel to load into IDA
  • I saw some "mtd" blocks that could be modified using U-boot, but since I'm not sure, I will not modify them until someone gives a proper answer on modify them.
  • Why U-boot show HKVS? Maybe this is a clone of HKVision camera, or the company Ezviz use SDK from HKVS? Or HKVS is OEM?

UPDATE:

I tried modifying the squashfs and then rewrite it at the same address on the SPI flash, but when the camera boots, it claimed about mismatch checksum, then it drop me to a shell called finsh shell with rt-thread RTOS. I think it's that RTOS's shell. After that, I see a process start downloading firmware from Ezviz server, then write it to flash to revert my edits. I think I can't modify this firmware unless I find a proper way to disable firmware checksum.

Thank you!

5
  • How are you getting the UART interface? Sometimes there's 2 different UARTs. I know on some MDVR devices which use busybox, they have a lot of read only permissions but sometimes the firmware checksum is in a shell script or it checks via the internet in that case you can try "spoof" the url and add your checksum but that's only if you can point the address to your LAN. In the past I really just wanted to get hold of the debug logs without opening up water resistance seals but yeah nothing is easy these days....
    – Jonas
    Commented May 1, 2023 at 10:47
  • 1
    @Jonas I just open the camera's case and found a unsoldered 4 holes connection. I just guess they must be 3.3V, GND, RX and TX pin, but I don't know the order. So I just plug 2 wires randomly at 2 of these ports, and then connects these 2 wires to my serial adapter. You just need to remember to either find the GND pin to connect serial adapter and the camera to common ground, or connect the camera's power to the same power line of your computer. After various trials, I managed to find the two RX and TX pin (which are 2 pins in the middle). Open a serial console at baudrate 115200 and enjoy.
    – raspiduino
    Commented May 1, 2023 at 12:58
  • I am very interested in the methods that you used to get as far as you did while working on the Ezvis CS-C6N. I was wondering if we could get in touch and help each other. I am also working on reverse engineering this camera and would love to learn more from you. I am particularly interested in how you were able to dump the firmware, and get it to the stage that it in in your git repo. I am also curious how you were able modify the squash and put it back onto the camera. Cant wait to hear back from you. Thanks! Commented Jun 16, 2023 at 17:01
  • How can we get in touch?
    – raspiduino
    Commented Jun 17, 2023 at 14:31
  • I have discord at gvl610, can you contact me?
    – raspiduino
    Commented Jun 17, 2023 at 14:33

0

Browse other questions tagged or ask your own question.