I recently had a friend lose access to his Night Owl WNVR201 device. He said he lost his password, and I said I'd see what I could do. Through a long day of reverse engineering it, I found out how to reset the password on the device.
My Process
I knew that I'd need to start by getting access to the operating system on the NVR. I started off by taking the top panel off of it, and removing the hard drive in it. When I connected the hard drive to my computer, I noticed that the settings are not stored on the hard drive. It looks like the hard drive is only used to store videos.
Since I didn't see any configuration or operating system files on it, I knew that somewhere on the motherboard, there had to be a flash chip of some kind to store the data.
Looking closely at the board, I saw that it had a MX25L12835FMI-10G chip on the board. This is when I knew I'd need to get my CH341A USB Programmer out of my desk to be able to dump the firmware.
Dumping the Firmware
Dumping the firmware is a relatively easy process. To do this, put the breakout board into the programmer with the number 1 lined up with the dot on the silkscreen diagram.
Note that in the picture, the 1 on the board is lined up with the dot on the silk screen diagram.
Plug the cable into the breakout board with the red side aligned with the 1 on the board. Next clip the connector onto the MX25L12835FMI-10G
chip on the NVR board with the red cable lined up with the dot on the top of the chip. Plug the programmer into the computer, and you're ready to dump the firmware.
Now that we have the programmer connected properly, we can use flashrom to dump the firmware. Running this command was able to dump the firmware to nvr.bin
flashrom -p ch341a_spi -c "MX25L12835F/MX25L12845E/MX25L12865E" -r Documents/dev/nvr.bin
Analyzing the Firmware
Now that we have the firmware for this device, we need to be able to extract the filesystems in the firmware for analysis. We can do this with binwalk.
binwalk -Me nvr.bin
Once this is done, we can see new folders and files that were pulled out of the firmware.
We now have access to the filesystems on it.
I found a few interesting ones:
_nvr.rom.extracted/squashfs-root-1/
contains the applications that run on the device_nvr.rom.extracted/squashfs-root-0/
and_nvr.rom.extracted/squashfs-root/
contain the operating system for the device
I found a script that runs on startup on this device in _nvr.rom.extracted/squashfs-root/root/run_app.sh
This script mounts flash drives attached to the system. Turns out that after mounting the drive, the script checks if a file called restore_factory_config_is_dangerous
exists on the drive. If this file exists, it checks the contents of the file.
If the file contains solely 2012
, it restores the factory configuration. If the file contains 2017
, it restores the factory configuration and resets the users to the default.
Next, this script checks for the file enable_log
, and if it's found, it checks if the file contains 1
. If the file contains 1
, then it enables logging on the device until a reboot occurs.
Next, it checks for enable_log_forever
. If this file contains 1000000001
, then it enables logging permanently. If dvr_app
exists on the drive too, then it will execute that file. If dvr_ui_arm
exists on the drive, it will also execute this file.
Next, if enable_disk_log
exists on the drive, it will do something (I couldn't figure it out).
Finally, this script checks for sysztool
on the drive. If this file exists and contains a1a2a3a4a5b1b2b3b4b5c1c2c3c4c5d1d2d3d4d5a1b2c3d4
, then the device will enter uboot fix mode.
My Solution
To reset the password, I created a flash drive with the file restore_factory_config_is_dangerous
, and put the number 2017
in it.
When I rebooted the device, I had access to it!
The File I Found
For reference, here's the file that I found on the device that gave me this information.
#!/bin/sh
#Restore machine in remote network
date
ifconfig lo up
ifconfig eth0 192.168.1.114 netmask 255.255.255.0 up
route add default gw 192.168.1.1
echo nameserver 8.8.8.8 >> /etc/resolv.conf
#Mount usb disk
MOUNT_DIR=/media/usb1
# check mount status
if [ -r $MOUNT_DIR ];then
echo "mount dir('$MOUNT_DIR') is exist now!"
else
echo "mount dir('$MOUNT_DIR') isn't exist now!"
mkdir $MOUNT_DIR
sleep 2
fi
HDISK_N='x'
HDISK_ID=0
sleep 1
for i in a b c d e f g h i j k l
do
echo "check sd$i..."
if [ -e /sys/block/sd"$i" ];then
echo "sd$i found..."
rv=$(cat /sys/block/sd"$i"/removable)
if [ "$rv" == "1" ];then
echo "usb media sd$i found..."
for n in 1 2 3 4 5 0
do
udisk_index=$n
if [ "$n" -eq "0" ];then
udisk_index="";
fi
if [ -b "/dev/sd$i$udisk_index" ];then
echo "usb media sd$i$udisk_index found..."
mount -t vfat /dev/sd"$i"$udisk_index $MOUNT_DIR
break;
else
echo "usb media sd$i$udisk_index not found..."
fi
done
break
else
if [ '$HDISK' -eq 'x' ];then
HDISK_N=$i
fi
for n in 1 2
do
if [ -b "/dev/sd$i$n" ];then
echo "disk media sd$i$n found..."
HDISK_ID=$n
break;
else
echo "disk media sd$i$n not found..."
fi
done
fi
else
echo "sd$i... not found"
fi
done
#Restore factory config for machine without keypad
if [ -e $MOUNT_DIR/restore_factory_config_is_dangerous ];then
echo "restore flag found."
rv=$(cat $MOUNT_DIR/restore_factory_config_is_dangerous)
if [ "$rv" == "2012" ];then
echo "restore factory config..."
dd if=/dev/zero of=/dev/mtdblock3 bs=1k seek=10 count=10
mv $MOUNT_DIR/restore_factory_config_is_dangerous $MOUNT_DIR/restore_factory_config_is_dangerous_disable
fi
if [ "$rv" == "2017" ];then
echo "restore factory config && clear user..."
dd if=/dev/zero of=/dev/mtdblock3 bs=1k seek=10 count=256
mv $MOUNT_DIR/restore_factory_config_is_dangerous $MOUNT_DIR/restore_factory_config_is_dangerous_disable
fi
else
echo "restore flag 1 not found."
fi
LOG_REDIRECT=0
if [ -e $MOUNT_DIR/enable_log ];then
echo "enable log found."
rv=$(cat $MOUNT_DIR/enable_log)
if [ "$rv" == "1" ];then
touch /tmp/udisk_loging
echo "enable log..."
LOG_REDIRECT=1
ulimit -c unlimited
ulimit -a
echo "$MOUNT_DIR/%e_%t.core" > /proc/sys/kernel/core_pattern
mv $MOUNT_DIR/enable_log $MOUNT_DIR/disable_log
fi
else
echo "enable log not found."
fi
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
if [ -e $MOUNT_DIR/dvr_ui_arm ];then
echo "mount bind dvr_gui."
mount --bind $MOUNT_DIR/dvr_ui_arm /root/dvr_gui/dvr_gui
fi
touch /tmp/udisk_loging
echo "enable log2..."
LOG_REDIRECT=1
ulimit -c unlimited
ulimit -a
echo "$MOUNT_DIR/%e_%t.core" > /proc/sys/kernel/core_pattern
fi
else
echo "enable log2 not found."
fi
if [ -e $MOUNT_DIR/enable_disk_log ];then
echo "enable disk log found."
if [ '$HDISK_N' -neq 'x' -a "$HDISK_ID" -neq "0" ];then
echo "enable disk log2..."
fi
else
echo "enable disk log not found."
fi
if [ -e $MOUNT_DIR/sysztool ];then
echo "sysztool found."
rv=$(cat $MOUNT_DIR/sysztool)
if [ "$rv" == "a1a2a3a4a5b1b2b3b4b5c1c2c3c4c5d1d2d3d4d5a1b2c3d4" ];then
echo "sysztool enter uboot fix mode"
rm $MOUNT_DIR/sysztool
dd if=/dev/zero of=/dev/mtdblock4 bs=1024 count=32
sleep 2
reboot
fi
fi
#ulimit -c unlimited
#echo "1" > /proc/sys/kernel/core_uses_pid
#echo "/root/rec/a1/%e-%t.core" > /proc/sys/kernel/core_pattern
echo "rmem_default:"
cat /proc/sys/net/core/rmem_default
echo "rmem_max:"
cat /proc/sys/net/core/rmem_max
echo "min_free_kbytes:"
cat /proc/sys/vm/min_free_kbytes
#echo 3000000 > /proc/sys/net/core/rmem_default
echo 3000000 > /proc/sys/net/core/rmem_max
echo 3000 > /proc/sys/vm/min_free_kbytes
# set stack size
ulimit -s 4096
cd /root/module
sh load -i
hwclock -s
echo "do you want to run app.out(y or n)?"
read -t 1 -n 1 char
cd /root/dvr_app;./dvr_resource
if [ "$char" == "n" ];then
login
fi
mount -t tmpfs none /root/rec
cd /root/dvr_app;./dvr_reset
if [ -e "/tmp/dvr_resource_dir/pre_run_app.sh" ] ;
then
echo "[pre_run_app] cp"
cp /tmp/dvr_resource_dir/pre_run_app.sh /tmp
echo "[pre_run_app] chmod"
chmod +x /tmp/pre_run_app.sh
echo "[pre_run_app] running..."
/tmp/pre_run_app.sh
echo "[pre_run_app] finish"
else
echo "[pre_run_app] not found"
fi
if [ "$?" == "0" ];then
CURTIME=`date +%y%m%d_%H%M%S`
LOG_FILE=gui_$CURTIME.log
cd /root/dvr_gui;
if [ "$LOG_REDIRECT" == "1" ];then
./dvr_gui > "$MOUNT_DIR/$LOG_FILE" 2>&1 &
else
./dvr_gui &
fi
cd /root/dvr_app;
if [ "$LOG_REDIRECT" == "1" ];then
LOG_FILE=sys_$CURTIME.log
/root/sysztool.hi 600 > "$MOUNT_DIR/$LOG_FILE" 2>&1 &
LOG_FILE=app_$CURTIME.log
./dvr_app > "$MOUNT_DIR/$LOG_FILE" 2>&1
else
./dvr_app
fi
else
echo "System reset!"
fi
What file extension is the file just a txt file or has to be something else.
The file doesn’t need an extension. Just
restore_factory_config_is_dangerous
as the file name.Thank you for sharing this method.
So, the file is it a text file inside a folder ( like yellow new folder windows OS) with the title “restore_factory_config_is_dangerous” or just the text file with the name title
and it has the value “2017” written inside it?
What was your USB drive File System: NTFS or FAT32?
Thank you.
Hey John!
The USB drive needs to be FAT32, and you need to create a file called
restore_factory_config_is_dangerous
at the root of it with the value2017
.If this works for you, would you mind replying back with the model of your DVR? I’d appreciate it!
Hello Dylan,
Thank you for your reply, I did follow your method, unfortunately it didn’t work for me the model number is: BTWN8-1-CN4
I was able to obtain the run_app.sh file by using chip clip and ch341a and follow the same steps as you. It looks like they change the programing in this model, now, the #restore factory in the run_app.sh file looks like this,
#restore factory
if [ -e $MOUNT_DIR/restore_factory_config_is_dangerous -a -r ${CONFIG_DIR} ];then
echo “restore flag found.”
rm ${CONFIG_DIR}/* -rf
mv $MOUNT_DIR/restore_factory_config_is_dangerous $MOUNT_DIR/restore_factory_config_is_dangerous_disable
fi
Based on this, my approach was to make a usb with a file name a “restore_factory_config_is_dangerous” using power shell and another sub directory folder name config with a text file inside it. But, no luck here
What do you think? Any suggestions?
thanks
I have a NVR-HDA10LB-8 and I’ll let you know Thursday if this works; chip clip and ch341a on the way!
The file didn’t work, so they probably switched something up or have a completely different reset system on the older models. According to their website, these models have some sort of forgot password system, but my device has a firmware from 2015.
So what is the file you put in the USB drive the same one as above with 2017 instead 2012 I’m a noob to this help me out DVR avd7b 81s 2
Hey Aaron!
The USB drive needs to be FAT32, and you need to create a file called
restore_factory_config_is_dangerous
at the root of it with the value2017
.If this works for you, would you mind letting me know?