OK, you voted to not be lazy, and thus I’ve stuck to it. Where am I at with upgrading the DS-2CD2132 hikvision cameras? Well, not super far.
We ran into a snag. The new firmware only works in the chinese region. I guess I could accept that, but it does have the english strings in it, and, if i log in and unpack them in place, its correct. So lets talk about how to get there. (the 2nd reason for wanting to have persistent access is I want to run iptables on the device to prevent it from doing more than I am expecting).
OK, we got the serial attached. If you stop the boot in U-Boot (hit ^U), you get a little shell. If we then modify the bootargs to add init=/bin/sh, we end up with a real ‘shell’ instead of the dreaded ‘psh’ they use for restricted access.
So
setenv console=ttyS0 initrd=0xc0a00000,0x400000 rw root=/dev/ram dbg=0 init=/bin/sh boot ... /bin/sh: can't access tty; job control turned off #
Now we want to run all but the last two lines of /etc/init.d/rcS
/bin/mount -t proc proc /proc /bin/mount -t sysfs sysfs /sys /bin/mount -t ramfs ramfs /home /etc/S_udev
And we are in. But, how to get more software on there?
It seems the dropbear (which we can start as dropbear -R) suffers from this issue, so we can’t ‘ssh … cat’ to get files in and out of mtdblock.
To make dropbear more useful, lets get rid of the psh shell for root (the device has a hard-coded backdoor user of ‘root’ with password ‘hiklinux’). PS, i decoded the password running mpirun and john-the-ripper.
# cat /etc/passwd root:ToCOv8qxP13qs:0:0:root:/root/:/bin/psh
OK, lets fix that:
# echo root:ToCOv8qxP13qs:0:0:root:/root/:/bin/sh > /etc/passwd
(this is all in the initramfs, so don’t worry, its not permanent yet).
I was going down the path of ‘uuencode’ and paste it in. Since we have awk, we can write a tiny uudecode:
$ cat uu.awk function x(l, p) { n = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_"; return index(n, substr(l, p + 1, 1)); } /^begin/ {} /^[^be]/ { len = x($0, 0); for(i = 1; len > 0; i += 4) { a = x($0, i); b = x($0, i + 1); c = x($0, i + 2); d = x($0, i + 3); printf("%c", a * 4 + b / 16); if(len > 1) { printf("%c", b * 16 + c / 4); if(len > 2) { printf("%c", c * 64 + d); } } len -= 3; } }
However, busybox awk won’t output a null:
# awk 'BEGIN {printf "%c%c", 1, 0 }' > /tmp/l # ls -al /tmp/l -rw-r--r-- 1 root root 1 Jan 19 00:31 /tmp/l
Making it somewhat tricky to put a new binary on there.
So, we could use echo:
# echo -n -e \\x1\\x0 > /tmp/l # ls -l /tmp/l# echo -n -e \\x1\\x0 > /tmp/l # ls -l /tmp/l -rw-r--r-- 1 root root 2 Jan 19 00:32 /tmp/l
So yeah, we could write some hack that took in a binary, converted it to echo statements, and then paste that in. Let’s try.
$ cat convert-to-echo.c #include #include #include <sys/types.h> #include <sys/stat.h> #include int main(int argc, char **argv) { int fd = open(argv[1], O_RDONLY, 0); int i, n; char line[16]; if (fd < 0) { perror("open"); } while ((n = read(fd, line, sizeof(line))) > 0) { printf("echo -n -e "); for (i = 0; i < n; i++) { printf("\\\\x%x", line[i]); } printf("\n"); } }
OK, that’s some good hack. And, OMG, that actually works, we can now cross-compile some new binaries to put in the initramfs (or the mount of /dav) to get us going.
We can get the ‘dav’ filesystem mounted (its ubifs) via this snippet from /etc/app:
# awk[\042=" \047='] MTDDEV=`/bin/awk "\\$4==\"\042app_pri\042\" {print \\$1}" /proc/mtd` # init env variables APP_PRT=no CFG_PRT=no loop=0 if [ "$MTDDEV" == "mtd13:" ] ; then if [ "$KRN_PRT" = "pri" ] ; then # try app pri: /dev/mtd13 /usr/sbin/mount_app pri APP_PRT=pri else # KRN_PRT == sec # try app second partition: /dev/mtd14 /usr/sbin/mount_app sec APP_PRT=sec fi # end of "$KRN_PRT" == "pri" # process cfg partition cfg_pri_need_rcy=0 # try cfg pri: /dev/mtd15 /usr/sbin/mount_ubifs_prt.sh 15 3 /davinci if [ "$?" = "0" ] ; then /usr/sbin/check_dir /davinci if [ "$?" = "0" ] ; then CFG_PRT=pri else /usr/sbin/umount_ubifs_prt.sh /davinci 3 fi fi if [ "$CFG_PRT" = "no" ] ; then /bin/echo "format cfg pri partition and mount" /usr/sbin/format_ubifs_prt.sh 15 3 cfg_pri /bin/mount -t ubifs /dev/ubi3_0 /davinci cfg_pri_need_rcy=1 fi #process cfg sec: /dev/mtd16 /usr/sbin/mount_ubifs_prt.sh 16 4 /config if [ "$?" = "0" ] ; then /usr/sbin/check_dir /config if [ "$?" = "0" ] ; then CFG_PRT=sec else /usr/sbin/umount_ubifs_prt.sh /config 4 fi fi if [ "$CFG_PRT" != "sec" ] ; then /bin/echo "format cfg sec partition and mount" /usr/sbin/format_ubifs_prt.sh 16 4 cfg_sec /bin/mount -t ubifs /dev/ubi4_0 /config /bin/cp -a /davinci/* /config/ fi if [ "$cfg_pri_need_rcy" = "1" ] ; then /bin/echo "recover cfg pri partition" /bin/cp -a /config/* /davinci/ fi export APP_PRT export CFG_PRT fi
OK, that’s enough for right now, we can get stuff on there, i should be able to patch it w/o trouble now.
Leave a Reply