Hacking A Reolink NVR

Dec 8, 2018 @ 7:38pm

So I recently saw a great Amazon deal, the Reolink NVR (RLN8-410) with 4 POE cameras was $320 so I grabbed that and 1 Amcrest 4K camera (IP8M-2493EW). I got it setup and immediately found two things, while it completely supports ONVIF (an open, XML-SOAP based protocol to communicate with security cams and NVRs), there is no web interface (they claim there is, but it's an browser addon that only works on Windows and Mac). They also have a desktop client, but surprise it too doesn't work on Linux.

I then tried getting my Amcrest camera working, and it oddly doesn't work, it sees it, and then says it's offline, and then finds it again when I hit scan, but with a different port (port 80) and refuses to connect, trying to delete it or scan again just crashes the UI. So obviously it's connecting and not working. All well.

All of this has made me determined to change the NVR software, get something open, that I can get to read my 4K camera, that will allow me to download history via Linux, and something with a functional web interface. This is going to be my story on hacking the RLN8-410


Note: If you just want to know how to root your NVR, jump to the bottom

So my first thought, check for telnet/ssh or something easy to get shell access with:

$ nmap 192.168.1.153 Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-08 20:14 EST Nmap scan report for 192.168.1.153 Host is up (0.0020s latency). Not shown: 994 closed ports PORT STATE SERVICE 80/tcp open http 443/tcp open https 554/tcp open rtsp 6001/tcp open X11:1 8000/tcp open http-alt 9000/tcp open cslistener Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds


Nope, nothing easy, but I might investigate them later.

So my next thought is these things are never designed with security in mind, so lets grab the firmware from their site, RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak, I already flashed it after buying to see if that fixed my problems, it didn't. My first thought was see if I can just unpack it (sometimes these things are tarballs that are unpacked prior to flashing).

$ file RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak: data


Nope, no idea, what about hexdump?

$ hexdump -C -n100 RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak 00000000 13 59 72 32 a9 20 21 5a 02 23 00 00 75 62 6f 6f |.Yr2. !Z.#..uboo| 00000010 74 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |t1..............| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 76 31 2e 30 |............v1.0| 00000030 2e 30 2e 31 00 00 00 00 00 00 00 00 00 00 00 00 |.0.1............| 00000040 00 00 00 00 84 05 00 00 d0 37 04 00 00 00 00 00 |.........7......| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000060 00 00 00 00 |....| 00000064


Now we are getting somewhere, uboot is a popular embedded bootloader, so can uboot read this file?

mkimage -l RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak edman007@caterpillar:~/tmp/nvr-client$


Nope, it doesn't do anything, I'm really not sure what is that (I'd assume some sort of bootloader thing, but I still don't know). I am still struggling to figure out what is at the front of this firmware file, if I want to reflash this device I need to understand the firmware, reading it isn't enough. If anyone know what this is (and more importantly, how to generate it).

My next thought was let's see if we can find anything in it, and for that there is binwalk, lets see what that does.

$ binwalk RLN8-410_180811/HI3535_NVR_8IP_REOLINK_L300_0811_4509_1606.6MP.pak DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 214960 0x347B0 CRC32 polynomial table, little endian 408916 0x63D54 uImage header, header size: 64 bytes, header CRC: 0x5B4BC1EC, created: 2015-06-24 03:30:19, image size: 2358664 bytes, Data Address: 0x80008000, Entry Point: 0x80008000, data CRC: 0x9735E1B3, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-3.4.35_hi3535" 427596 0x6864C xz compressed data 2767644 0x2A3B1C CramFS filesystem, little endian, size: 4206592 version 2 sorted_dirs CRC 0x6BFDA868, edition 0, 2620 blocks, 777 files 6974236 0x6A6B1C CramFS filesystem, little endian, size: 13959168 version 2 sorted_dirs CRC 0x3906E558, edition 0, 7916 blocks, 909 files 20933404 0x13F6B1C JPEG image data, JFIF standard 1.01


Now that's helpful, the CRC32 table is checksums, if I ever want to reflash it I'll need some tool to regenerate it. The uImage header is further down in the file, and there is an xz blob, two CramFS images, and then some sort of image.


I extracted all the data (binwalk makes this easy with the -e option), and then I had something to work with.

* The xz data - That's the compressed Linux kernel (decompressing it and running strings on it makes that easy)
* The next is a CramFS filesystem, that is the root filesystem for the NVR
* The next CramFS filesystem, that's more binaries, but I don't recognize the file structure, I'll deal with it later
* An image, I extracted it to get the boot splash. Not very exciting.

Inspecting the RootFS

The rootfs provides a lot of opportunities to see any security holes. First step, /etc/passwd, and /etc/passwd- ...what is that doing there? That's an editor backup, and should never be on your released product. So far piss poor security has already been confirmed. But first the contents of /etc/passwd:

root:$1$g021J7o9$RkRXhgz.ci.wiPxwYgaCY0:0:0::/root:/bin/sh


That's got a hash, john the ripper can crack it. After a night of cracking, I got a root password, 20120515. Nice and easy, but I had nowhere to use it. So I continued on.

Next step is the boot process, if I want access I need to know what it does when it boots. In linux that is init, this is the process that calls the first initscript, it's also what setups your login terminals and such. It's configuration file is /etc/inittab, so lets check that out:

$ cat cramfs-root/etc/inittab # <I snipped out some comments> ::sysinit:/etc/init.d/rcS ::sysinit:/bin/mkdir /dev/shm # <snip> # Example of how to put a getty on a serial line (for a terminal) ::respawn:/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..." #::respawn:/sbin/getty -L ttyS1 9600 vt100 # # Example how to put a getty on a modem line. #::respawn:/sbin/getty 57600 ttyS2 # Stuff to do when restarting the init process ::restart:/sbin/init # Stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a


So, first thing... "Auto login as root ..." What? Really? that's ttyS000, that means a root shell is just always open on it's serial port (what serial port?). So I finally broke down and opened it up, and right in the middle was an empty connector labeled "UART", which is low voltage serial. So I just need a UART device to connect to it. I looked around and I had both a BeagleBone and a Raspberry Pi near me with UART. So I grabbed the BeagleBone and pulled the front panel USB cable off the NVR (this used the same connector as the UART connector), in the process I broke the connector (it was glued in place) but that was fine. I plugged it in, use the voltmeter and checked the voltages with respect to ground (the chassis), the rear most wire was 5V (power), the front most was 0V (ground), and the middle two were 3-ish. I isolated the 5V power so as to not back power the BeagleBone's power supply and connected the rest up. It just worked, I got a "#", so I had a root shell.

# minicom -b 115200 -D /dev/ttyO1 Welcome to minicom 2.7 OPTIONS: I18n Compiled on Apr 22 2017, 09:14:19. Port /dev/ttyO1, 01:30:25 Press CTRL-A Z for help on special keys # # uname -a Linux (none) 3.4.35_hi3535 #6 SMP Wed Jun 24 11:30:14 CST 2015 armv7l GNU/Linux # cat /proc/cpuinfo Processor : ARMv7 Processor rev 1 (v7l) processor : 0 BogoMIPS : 1987.37 processor : 1 BogoMIPS : 1993.93 Features : swp half thumb fastmult edsp tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x4 CPU part : 0xc09 CPU revision : 1 Hardware : hi3535 Revision : 0000 Serial : 0000000000000000




And I've confirmed that it's linux, some poking around shows it's busybox (and not much else), /mnt/sda is the internal hard drive (where it saves all the videos), the root filesystem is read only (so I can't change the password or services that start on boot, not without flashing it). /mnt/app is where the second CramFS image is mounted, it appears to be the SW reolink wrote. Their application is "dvr", so /mnt/app/dvr starts up the Reolink SW. There appears to be some sort of watchdog device running as well, if I kill the dvr process the device reboots a few minutes later. I need more if I want to put my own SW on it. Though now it's not looking too bad, adding a few lines to a boot script somewhere can get me to run my own code on boot, and I can access it via /mnt/sda, I have plenty of space.


So onto boot scripts, I checkout out the rest of the boot process, in /etc/init.d, and I found more good news in /etc/init.d/S90StartSuvr .

# cat /etc/init.d/S90StartSuvr sleep 3; if [ -r /dev/usb/usbhd1 ];then mount -t vfat /dev/usb/usbhd1 /mnt/usb if [ -r /mnt/usb/autoexec.sh ];then chmod +x /mnt/usb/autoexec.sh /mnt/usb/autoexec.sh else echo "autoexec is not ready for running" fi umount -f /mnt/usb else echo "usb is not ready for autoexec" fi # <snip>


That's right, if there is a thumb drive present, formatted as vfat, it will just go ahead and run the script "autoexec.sh" on boot, as root, and let you do whatever. Now that's the lousy security I expected in this kind of device.

So now, the easy way to root this NVR:

1. Get a thumb drive, format it as FAT32 (vfat).
2. Put this script on the root of the drive, named autoexec.sh
#!/bin/sh #start telnetd telnetd

3. Put the thumb drive in and reboot
4. Login via telnet, username is root, password is 20120515

As a note, it seems to be dependent on the thumb drive a bit, my first try was an old crap thumb drive, and I guess the scripts give udev 3 seconds to find it, if it doesn't show up in 3 seconds it won't work. I ended up switching to a nicer USB microSD reader with a high speed microSD card, that works well.

My next step is going to be using debian to get some good SW on here and run whatever I want on it.

Comment

Name:
Email (For new comment notifications, optional):
What is 3 + 4 minus one?
Comment:

Seb

Feb 16, 2019 @ 4:54pm
Bonsoir,

J'ai réussi à me connecter en telnet sur mon Réolink NVR.
Je suis comme vous bloqué par le logiciel fournit par Réolink, il bloque mes caméras d'autre marque...
Avez vous une idée ?

melchior-s@bbox.fr

Ed

Feb 17, 2019 @ 5:37pm
I'm actually working on getting other software working on mine, I'm planning on installing debian and some different NVR SW (probably kerberos-io) when I get it working.

As for other SW that you can try, I have found out that Reolink appears to be a rebranded dahua NVR, but I don't know if that helps. I did end up buying a dahua NVR that does work with all cameras, though it seems to have problems playing back the video from the reolink cameras.

Jay

Mar 23, 2019 @ 11:22am
If I get logged in as root, will this allow me to set the NVR to access third party cameras that support ONVIF?

Ed

Mar 23, 2019 @ 8:59pm
Getting root doesn't make stuff work, but it means the SW can be replaced. I'm currently working on doing that, I'm having some issues with drivers, but I can hopefully get those worked out and get different NVR SW running on this.

As for ONVIF, it should support them already, but at least my Amcrest 4K camera is incompatible. The HW does not appear to support 4K and the SW doesn't fall back to SW decoding.

Matthias

Apr 14, 2019 @ 5:30am
I found that my firmware has a different root password although the version seems to be the same.
However, if you start telnetd with -l/bin/sh parameter you get a root shell without needing to login.

#!/bin/sh
#start telnetd
telnetd -l/bin/sh

AL

May 29, 2019 @ 12:27pm
Were you able to install debian on the NVR? Thanks.

DR ADEL

Aug 30, 2019 @ 2:27pm
Very nice, I have a bricked reolink NVR after failed firmware update same brand I am asking for help:
can we write a script in USB drive: install nvr firmware.pak instead of starting telnet?
how to flash the firmware otherwise
thank you

mynamesjeff

Sep 11, 2019 @ 4:16pm
Awesome work, thank you.

Magnus

Feb 25, 2020 @ 8:46am
Any new progress on this?
Would it be possible to have ZoneMinder run on it?

Jason

May 24, 2020 @ 5:20pm
What ever happened with this project? Any further updates? I'd love to hear more.

Ed

May 25, 2020 @ 5:00pm
So to give everyone an update on this, I got stuck getting the network drivers working for it on the 5.x kernels, the 3.4.35 kernel really builds and runs just fine, but it's old and I don't want to use it...And I really haven't tried getting a full image up because the recent distros don't run with such an old kernel.

If you want to try to hack it yourself, my repo's are:

https://dev.edman007.com/git-repo/linux-mainline-kernel.git (my working copy of the kernel)
https://dev.edman007.com/git-repo/hi3535-nvr.git (build scripts at the moment)

And you need an armel distro if you want to try loading it...

Pbcanada

Aug 4, 2020 @ 11:28pm
Have you tried getting shell access to one of the Reolink cameras? I have a couple of these and they also seem to be running a mini Linux of some sort.

Ed

Aug 5, 2020 @ 2:18pm
Not yet, I have the cameras, they'll be next, right now I'm writing a transcoding free NVR app to put on it, then I think I'll get a working OS then work on the cameras.

K

Aug 6, 2020 @ 7:49pm
Firstly, thanks for this page. It's very interesting.

For messing about with the cameras, a good resource is probably https://www.thirtythreeforty.net/posts/2020/05/hacking-reolink-cameras-for-fun-and-profit/

I am more interested in the NVR which is why this page is so useful

So far I have it running an autoexec.sh script but my firmware (RLN8-410-E
build 1909041) does not include telnetd so I haven't managed to get remote access yet

K

Aug 6, 2020 @ 8:59pm
Following the steps above I was able to extract busybox from the 180811 firmware and copied it onto my USB drive. So I can now successfully log in

Pascal

Aug 7, 2020 @ 7:31am
i was on a similar mission as you and found your website after i had gained uart access.. on the RLN16-410 which i have the port is only labeled "J15", the board has markings saying "H3MB06_V110" and "2016-05-19"

i have upgraded it to the latest firmware release which makes it a lot more linux friendly, they have changed the "web" ui to actually contain HTML, but you need adobe flash to play the videos.

i hacked the unit in order to debug a connectivity issue i had between routed networks and the NVR. turns out, they are using 172.16.0.0/16 as their internal camera network (where the PoE ports are connected to) and this overlaps with my other local networks i have here.

on the quest to finding where this could be changed, i had to sadly find both the ip address of the NVR on eth1 (the interface connected to the PoE Ports) as well as the outrageously large subnet mask to be hardcoded into the /mnt/app/dvr binary, so no joy for me.

Pascal

Aug 14, 2020 @ 2:13pm
i finally found a good use for my NVR.. i simply shut it down in my autoexec.sh which basically turns it into a 16 port POE switch.. that's about the best i can get out of this unit.. here's the script:

#!/bin/sh
halt

Nik

Oct 14, 2020 @ 2:06pm
Hi there, thanks a lot for your efforts!

Having an NVR myself and think of migrating it into a virtual environment (VMWare) to get rid of the device itself as I'm using another POE Switch anyways.

Any smart idea how to approach this?
I'm not that Linux-guy as you are and have also no device to to connect to UART port. Any chance for you to provide me an image of your box or even better: Extract the application from the hardware device to install it into any other Linux distribution?

So many thanks in advance, best regards to wherever you are ;-)
Nik

nobitakun

Jan 25 @ 7:40am
Hello;

I may come a little late, but it's worth a try. Our small office bought recently (2 months ago) a set of 6 cameras + NVR RLN8-410 and it's working nicely, I have no complains but we need a feature Reolink isn't willing to make and I plan to program it by myself, it should be pretty easy, so I think it's quite feasible.

Here I go: we need the NVR autodelete records older than a specific number of days. The law here forces any company to have that condition in case you record video within your company.

My plan is to enter to the shell, make some configuration to cron to check on every reboot files older than X days within the folder where the records are stored, and program the NVR to reboot every night.

One issue is that I tried to test your autoexec.sh trick and it seems that it's not working anymore on the lastest firmware, so I think I will have to use the UART port. I have an UART to USB adaptor and I also have a RPi4, so it would be ok either one or the other I suppose.

I've been using Linux for more than 10 years mostly without GUI so I'm pretty used to the shell, but I'm quite new to Linux embedded (I'm a Debian user). Do you think that is possible to accomplish what I'm intented to do? I've been reading the documentation and busybox seems to be using crontab, as well as the command find is available, so it should be a piece of cake.

Thank you very much for your time!

Ed

Jan 25 @ 8:41am
nobitakun,

I don't think that's going to work, the videos are not stored in any file system that can be read by the kernel (I did not investigate it too far), the NVR application writes directly to the block device and the OS can't read the videos.

I think it's going to be easier to rewrite the firmware to something with open source SW, I am still working on that and starting with my own NVR that runs on a regular server which is what I'm currently use. I think I killed my reolink NVR so I need to get a new one, and it will probably be a while before I get it running on real NVR HW.

nobitakun

Jan 26 @ 10:40am
Sorry, this website seems to resend comments on refresh (very odd!), that's why it's getting duplicated. Maybe the last message is remembered? could you delete the other 2 messages?

Ok, back to the topic, what you've told me does not increase my hopes :(. I will try to figure out how to deal with that fs from the kernel, my understanding is that if the device can write and purge videos when the HDD is full, I can, somehow.

I just checked and the NVR I have dates from 2019-11-19 (N2MB02) and I'm running the last firmware released on September 2020.

About my progress, I unpacked the firmware to check and there's no root login anymore.

The only interesting line I see on inittab is:

ttyS0::respawn:-/bin/login

I decrypted the password of the last firmware root's account and it took me like 2 seconds, I don't know why. Here it is: bc2020.

The command I use to open the connection is:

#minicom -b 115200 -D /dev/ttyS0

When I connect through the RPi4 UART0, I get data, but it's gibberish. If I wait a few seconds after I turn the NVR on, I get to what it seems it's a prompt, probabbly due to the /bin/login command executed in inittab, but as it is in gibberish language, I only can guess, so I tried to input root, then, after more gibberish code it seems to prompt for something again, which I assume it's the password, so after I enter it the gibberish starts again and after a few seconds more it keeps printing the message "thermal value 0x00000000" once a second, and it does nothing more. I can't interact in any way, and I think the problem is that the output from inittab command isn't redirected to any ttyS0.

What is curious is that, after looking deeper I've found that there is indeed code for the autoexec.sh, but it's in a different place.

In inittab I found the line:

::sysinit:/etc/init.d/rcS

So, I went to look, and it was a script to launch a batch of files within /etc/init.d/ with the regex names S[0-9][0-9]*. That made me look for those files, and bingo, I found two: S00_PreReady and S90StartSuvr. The first one contains system commands for mounting the filesystem, assigning name, ip and check the interfaces, but the second contains the autoexec.sh once an USB is placed. I paste the code:

if [ -r /dev/usb/usbhd1 ];then
mount -t vfat /dev/usb/usbhd1 /mnt/usb
if [ -r /mnt/usb/autoexec.sh ];then
chmod +x /mnt/usb/autoexec.sh
/mnt/usb/autoexec.sh
else
echo "autoexec is not ready for running"
fi
umount -f /mnt/usb
else
echo "usb is not ready for autoexec"
fi

Before, I tried to put 3 different USB memories formatted in FAT32 and none worked that's why I gave up, but I will continue trying knowing that it is indeed there. I also want to place a telnetd withint the USB in order to execute it from there once the USB is inserted, but I don't know how right now.

Anyways, I will update on anything else I find :)

nobitakun

Feb 2 @ 11:03am
I didn't success on getting telnet running, the autoexec.sh does not run, no matter how many different USB's I try. I tested it with the simple halt and none of them could stop the system at all, so it means it is not working.

I made sure I format the USB's in vfat with the mkfs.vfat tool from linux, and then copy the autoexec.sh to the root directory, but it seems it's not that simple. I tried Sandisk, Kingston and Transcend, none of them worked. The sizes between 8Gb and 32Gb.

I'm starting to get angry at these guys, as they couldn't care less of implementing such an easy and basic feature. They just answer you with a "I'm sorry, our product does not support that feature, sorry for the inconvenience". But they never thought about it after these many years.

Is there a chance to customise the source firmware, make a package and flash it to the NVR?

Ed

Feb 2 @ 9:36pm
Yea, I'll try to put out some firmware, it's not too hard. I tried doing it, but had issues getting the network drivers working with a 5.x kernel. I'll probably make an image with an older kernel and post that. Right now I'm trying to get a replacement NVR, I think i killed mine. Also, the graphics drivers are proprietary, so if I post firmware, it won't have that (which means no graphics, and no HW decoding/encoding)

As for getting telnet working, my guess is the new firmware might need it on a USB hard drive, not thumb drive, for the autoexec script to work. Otherwise try via the uart, you can just go in once and edit the boot scripts.

ken

Feb 5 @ 2:25pm
I am trying to figure out how I can update the firmware from USB thumb drive on swann dvr. I come across these files and looks similar to what you have listed on this page, I was hoping you could take a look to see something useful?

here is the autoexec.sh script

himd.l 0x20050ee8 | grep "00000035 00000035"

if [ $? = "0" ];then
cd /mnt/usb;
chmod +x update3535;
./update3535 0 all;
else
himd.l 0x20050ee8 |grep "00000020 00000035"
if [ $? = "0" ];then
cd /mnt/usb;
chmod +x update3520;
./update3520 0 all;
fi
fi

update 3535

https://filebin.net/xfm97zh5p02t5rln/update3535?t=ueca1ulz

let me know
thank you

Ken

Feb 5 @ 9:02pm
As far as usb thumb drive, I known swann uses cruzer blade from sandisk, so you might want to give that a try

DanielSz

Apr 7 @ 4:58pm
Hello Ed,

Thanks for pulling this together, it’s really useful. Sad part is I found this after updating to the latest fw on my RLN16-410. It’s one of the older versions. based on the same HiSilicon Hi3535 chipset.

It’s pretty likely that those guys at Reolink also read your article, because I tore apart the latest update file using the same way you did, and the symlink for telnetd vanished.

It’s possible but unlikely that the busybox binary itself has telnetd support compiled in, but I havent’t checked yet. The rootfs is read-only anyway, but getting the proper busybox on the flash drive and making a symlink in the autoexec.sh might could make the trick.

Keep up the good work. I think running anything but the proprietary code is a challenge due to the unit being designed primarily for video decoding.

Cheers,

Daniel