Rooting K9608-2W
Let's say you have one of these and you want shell access for some reason, like setting the date & time programatically. By adding a couple magic files to a USB mass storage device, connecting it to your NVR and rebooting, you will be able to login via telnet.
Login to the web user interface of your NVR, go to Settings (wrench and screwdriver icon). If you see the following info listed in the DevInfo tab, then these instructions should work for you. This may work with other software versions too but no promises.
Dev model | K9608-2W |
HW version | 2.1.0 |
SW version | 2.7.13.0_22922330 |
Reldatetime | 2018/10/26 10:58 |
Grab a thumb drive or whatever USB mass storage device is handy. Make sure the partition table is simple and has fat32 as the first primary partition. This is usually the default setup for a new device so you probably don't have to do anything. Mount it and get started making the three files as below in the top level directory.
me@here:/media/me/SANDISK$ echo 1000000001 > enable_log_forever
me@here:/media/me/SANDISK$ cat <<EOF>dvr_app
#!/bin/sh
/usr/sbin/telnetd &
exec /media/usb1/dvr_app_chain "\$@"
EOF
me@here:/media/me/SANDISK$ cat <<EOF>dvr_app_chain
#!/bin/sh
umount /root/dvr_app/dvr_app
exec /root/dvr_app/dvr_app "\$@"
EOF
me@here:/media/me/SANDISK$
Unmount/eject, pop it in the NVR, reboot the NVR, wait a bit and then telnet to it using the same IP or hostname you used to get to the web interface. Login with username root and password j1/_7sxw
me@here:~$ telnet nvr-host
Trying 192.168.31.337...
Connected to nvr-host.
Escape character is '^]'.
(none) login: root
Password:
Welcome to HiLinux.
# uptime
05:42:38 up 2:35, 1 users, load average: 13.88, 12.32, 11.89
# ls /
a.out bin etc linuxrc mnt oem root sys usr
a2.out dev lib media nfsroot proc sbin tmp var
#
One of the startup scripts contains the following snippet:
if [ -e $MOUNT_DIR/enable_log_forever ];then
echo "enable log2 found."
rv=$(cat $MOUNT_DIR/enable_log_forever)
if [ "$rv" == "1000000001" ];then
if [ -e $MOUNT_DIR/dvr_app ];then
echo "mount bind dvr_app."
mount --bind $MOUNT_DIR/dvr_app /root/dvr_app/dvr_app
fi
In short, if the file enable_log_forever
exists and contains 1000000001
then bind-mount dvr_app
from the USB device over the top of the normal /root/dvr_app/dvr_app
before running it later in the same startup script.
The shell won't allow us to unmount dvr_app
from inside of the script running as that name, so we pass off execution to an arbitrary script called dvr_app_chain
directly from the USB mountpoint. From there, we can unmount our dvr_app
and run the orriginal with the arguments that were passed along the way. Any additional commands that we want to run can be added to either script.
One side effect is that logs will be written to your USB device. Rebooting without this USB device present will revert to running normally without telnetd.
- Kill run_IOTDaemon.sh. It's the script responsible for spawning IOTDaemon once a minute. This service reaches out to ngw.dvr163.com offering remote access to your video along with all sorts of other controls, including a reverse shell.
- Change the root password. Using bind-mount, you can set up a passwd file on your USB mass storage device.
- Run dropbear instead of telnetd.
- Update the squashfs with all of your changes so that you don't depend on the USB mass storage device any more. For extra credit, add an NFS mount to hold larger packages.
- Run ntpd. The clock drift on this thing is terrible. The built in mechanism for ntp is to stop recording, update clock, then start recording again. This is appropriate for a big time shift, but not so hot for regularly maintaining time sync.
Please post comments with suggestions or requests for this document. Have a device you want root on and don't mind sending one to me? Tweet at @octosavvi.
Congrats! It is annoying how often the little (and sometimes invisible) things slow us down.
Yep, I definitely support killing IOTDaemon. Looks like it gets started by the real app.out in your firmware, so you might need to create a script like dummy-daemon.sh:
Then you can
mount --bind /media/usb1/dummy-daemon.sh /opt/bin/IOTDaemon
. I'm just speculating that app.out might try to restart IOTDaemon at some point. So having a replacement that will run forever and do nothing should keep it happy.The easy way to run dropbear is to find a binary already compiled for your kernel (
uname -a
will help identify) and drop it on your USB drive. Frequently you can find some OpenWRT or other embedded firmware which runs on the same CPU and with a close enough kernel version that no compiling is required. In case you have to compile yourself, there are many guides and tools out there for that. Dropbear may need some extra flags to use config files from /media/usb1/ instead of /etc/ but that shouldn't be too hard to sort out. Presumably connections to the NVR would be over a trusted LAN, so SSH may not be all that important.Under no circumstances should you ever install or use a password on this device that is also used anywhere else on your network. This is regardless of whether you run telnetd or dropbear. Imagine this thing has a keylogger dumping everything you do to the manufacturer at all times. I recommend connecting devices like this to a managed switch and blocking traffic from that port to the Internet. Don't just block from the IP assigned to the NVR; setting up an interface alias with another IP only takes an instant.
Re-packing firmware is a much bigger challenge. An older project firmware-mod-kit tries to help with this process, but doesn't work with all systems. It is almost guaranteed that devices will get bricked somewhere along the process of developing your own firmware. Sometimes I have been able to recover by uboot, tftp, jtag, or pulling flash chips from boards and manually programming them. Occasionally, I still fail because of layered security measures elsewhere on the board. Expect this to be a long and painful process where you will learn a lot and probably end up with some unusable hardware.
That said, you are in a pretty good environment to practice given that you have UART and USB access on this device. Normally, the system does
mount -t squashfs /dev/mtdblock4 /opt
so you could try rebuilding that squashfs with mksquashfs, drop the file on your USB drive and thenmkdir /opt2; mount -t squashfs /media/usb1/new-opt.bin /opt2
. Then compare the two directories (diff -qr /opt /opt2
). If it looks good, try mounting over the top of /opt and let it run for a while. So far no permanent changes have been made so recovery is as simple as pulling the USB drive and rebooting. Next thing is to overwrite /dev/mtdblock4 with something likedd if=/media/usb1/new-opt.bin of=/dev/mtdblock4
and cross your fingers. This is where you might get lucky or might end up with a brick. Experimenting with /opt is much safer than starting with /, but could still have all sorts of unwanted impacts, like breaking the normal firmware installation method, making it really hard to recover. And there might be other obstacles like /dev/mtdblock4 being read only until some magic bit is flipped.If you get through all of that and end up with new squashfs images for / and /opt installed on the flash chip, you are probably happy. Unless you have multiple devices and want to modify all of them without so many risky dd steps. In this case, packaging up everything into a new firmware image would be ideal, but is still more work. The updater probably won't let you install something that looks like the same version as what is already installed. It looks like there is a basic crc32 checking but maybe not be any sort of hashing or signatures to contend with, so that makes life much easier. But this is still a pretty big task when faced with an upgrade tool where source code is not available.
Speaking of /bin/upgrade, it looks like that might be run as a daemon. If so, it is probably another thing worth killing and replacing with dummy-daemon.sh since it has some shell execution capabilities which can probably be leveraged remotely.
Anyway, I'm happy to hear that you have a working USB hack and I hope this is the start of an enjoyable adventure. Best of luck!