Recently bought cheap "Gembird ICAM-WRHD-02" IP camera to watch over my parrots while being away from home. https://gembird.com/item.aspx?id=11674
Seems it just works OOB but my curiosity of course made me to discover a bit more about the camera :) So after disassembling it I found it to be a generic IPC built on ANYKA AK3918 SOC flashed with Yoosee firmware It has 3 external WIFI antennas but after disassembling it turned out that 2 of these are just decorative and not connected to the WIFI PHY
Quickly looked over the pins on the main board for JTAG but found nothing so decided just to dump the whole flash My camera exemplar has XMC QH64AHIG chip. Though flashrom knows nothing about that chip I was able to use CH341A SPI programmer to read/write it successfully.
So let's look inside:
Dumping flash:
sudo flashrom -p ch341a_spi -r rom.img
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on ch341a_spi.
Reading flash...
Reading flash... done.
Running binwalk to see flash layout:
binwalk rom.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
131204 0x20084 CRC32 polynomial table, little endian
229376 0x38000 uImage header, header size: 64 bytes, header CRC: 0x53E31A68, created: 2020-08-04 09:29:45, image size: 1515312 bytes, Data Address: 0x82208000, Entry Point: 0x82208040, data CRC: 0x868DE94F, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-3.4.35"
229440 0x38040 Linux kernel ARM boot executable zImage (little-endian)
243295 0x3B65F xz compressed data
243516 0x3B73C xz compressed data
1810432 0x1BA000 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 931284 bytes, 356 inodes, blocksize: 131072 bytes, created: 2020-08-10 08:07:12
2859008 0x2BA000 JFFS2 filesystem, little endian
2863648 0x2BB220 Unix path: /var/run/udhcpd.pid
2863715 0x2BB263 Unix path: /var/lib/misc/udhcpd.leases
2867200 0x2BC000 JFFS2 filesystem, little endian
2930264 0x2CB658 JFFS2 filesystem, little endian
3118628 0x2F9624 JFFS2 filesystem, little endian
3124712 0x2FADE8 JFFS2 filesystem, little endian
3125248 0x2FB000 JFFS2 filesystem, little endian
3129896 0x2FC228 JFFS2 filesystem, little endian
3131436 0x2FC82C JFFS2 filesystem, little endian
3132144 0x2FCAF0 JFFS2 filesystem, little endian
3230132 0x3149B4 JFFS2 filesystem, little endian
3236560 0x3162D0 JFFS2 filesystem, little endian
3238588 0x316ABC JFFS2 filesystem, little endian
3354624 0x333000 JFFS2 filesystem, little endian
3731380 0x38EFB4 JFFS2 filesystem, little endian
3907584 0x3BA000 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 4086444 bytes, 281 inodes, blocksize: 131072 bytes, created: 2020-09-16 07:31:57
8047426 0x7ACB42 xz compressed data
8049468 0x7AD33C xz compressed data
8049798 0x7AD486 xz compressed data
8051952 0x7ADCF0 xz compressed data
8052122 0x7ADD9A xz compressed data
Let's look inside rootfs:
Extracting first squash fs partition:
dd if=rom.img of=sqfs1.img bs=1 count=1048576 skip=1810432
unsquashfs sqfs1.img
cat ./squashfs-root/etc/shadow
root:$1$ouLOV500$zvYRvG33R/lxTS.9Gpz5H1:0:0:99999:7:::
bin:*:10933:0:99999:7:::
daemon:*:10933:0:99999:7:::
nobody:*:10933:0:99999:7:::
Seems internet knows nothing about the hash so I decided not to focus on it further since telnet or any other access methods relying on the system accounts are disabled by default:
cat ./squashfs-root/etc/init.d/rcS
#! /bin/sh
echo "mount all file system..."
mkdir /dev/pts
/bin/mount -av
echo "start telnet......"
#telnetd &
runlevel=S
prevlevel=N
umask 022
export runlevel prevlevel
echo "starting mdev..."
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
mkdir /var/cache
mkdir /var/run
mkdir /var/log
mkdir /var/spool
echo "**************************"
echo " Love Linux ! ! ! "
echo "**************************"
/bin/hostname -F /etc/sysconfig/HOSTNAME
#local service
/etc/init.d/rc.local
Interesting part of rc.local file:
....
RESETKEY=`cat /sys/user-gpio/gpio81-RST`
if [ $RESETKEY -eq "0" ]; then
echo "Detected reset button has been pressed."
i=1
while [ $i -le 6 ]
do
if [ -b /dev/mmcblk0p1 ]; then
break
fi
let i++
sleep 1
done
if [ -b /dev/mmcblk0p1 ]; then
echo "Detected TF Card"
cd /
# mount -t vfat -o errors=continue /dev/mmcblk0p1 /mnt/disc1
mount /dev/mmcblk0p1 /mnt/disc1
if [ $? -eq 0 ]; then
echo "mount sdcard ok"
if [ -f /mnt/disc1/gwell_config/custom_setting.ini ]; then
echo "Detected custom_setting.ini"
cp /mnt/disc1/gwell_config/custom_setting.ini /rom/device.config
fi
if [ -f /mnt/disc1/upg.bin.enc ]; then
echo "Detected /mnt/disc1/upg.bin.enc"
ln -s /mnt/disc1/upg.bin.enc /tmp/upg.bin.enc
gwellupdater.sh /tmp/upg.bin.enc
if [ 0 -eq 0 ]; then
exit
else
rm -f /tmp/*
fi
fi
fi
umount /mnt/disc1/
fi
fi
....
From the above it could be seen that placing gwell_config/custom_setting.ini
file on the SD Card allows to override camera settings and it looks like reset button must be pressed during camera initial boot for that
Camera firmware upgrade could be performed by placing upg.bin.enc
inside the root folder of the SD Card but it must be encrypted with RSA key (look at ./squashfs-root/etc/keyrsa/1912ak1.5.00.prv but it is a public key obviously)
I decided to enable telnetd and make SD Card to serve as an external storage with ability to launch custom user binaries during camera startup
With telnetd it's just enough to uncomment #telnetd
in rcS
script. Login as root, no password required
And as for SD Card we need to mark it out with two partitions formatted as VFAT or ExFAT. User binaries should go to the second partition as well as rc.local script which will be triggered during camera boot up
I added the following block at the end of rc.local
init script:
if [ -b /dev/mmcblk0p2 ]; then
mount /dev/mmcblk0p2 /opt
if [ -f /opt/rc.local ]; then
echo "Detected rc.local"
/opt/rc.local &
fi
fi
Now I need to create /opt folder inside unpacked rootfs and re-pack it:
mkdir ./squashfs-root/opt
mksquashfs squashfs-root sqfs1.img -force-uid 1016 -force-gid 1016 -comp xz
Assembling final rom file and flashing it back:
dd if=sqf1.img of=rom.img bs=1 seek=1810432 conv=notrunc
sudo flashrom -p ch341a_spi -w rom.img
Found Unknown flash chip "SFDP-capable chip" (8192 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
Done!
21.06.21 faust93
I seem to have a very similar device, the 1080p one, at least chipset-wise. Basically nothing is enabled on it, though.. http on 80 and port 10000 is open, but I haven't been able to get any sort of access to it outside of the app (IP Pro). I'm hoping there'll be a way to install/activate RTSP or something on it for use with home assistant. Will take it fully apart on the weekend and see if I can dump the firmware somehow.
