Exploring the Operating System of Reolink RLC-810A
Published at – 16 min read – 3232 words

In Part 4 of our series, we focused on the file system and before concluding, we were able to extract files from two UBIFS images contained within the firmware. Here in Part 5, we will try to better understand the structure of the root file system by introducing some basic concepts of the operating system used by Reolink RLC-810A, namely Linux.
Why Linux?
Linux kernel is one of the most widely used operating systems in the world, if not the first by popularity. You might think that commercial operating systems such as Windows or macOS are the most widely used, but on the other hand a whole army of embedded devices (such as the camera in this series) have based their firmware on Linux.
Created in the early 1990s by Linus Torvalds, the Linux kernel is a monolithic, modular, multitasking kernel primarily developed in response to the commercialization of the Unix operating system maintained by AT&T. The Linux kernel and the entire ecosystem above it is largely open-source — every person on the planet is free to be able to consult the sources and modify them.
The choice of Linux as the basis for embedded device firmware stems from a number of features that are essential for development. First among them is the flexibility of Linux — i.e, through being modular, it is possible to load additional components at runtime that enrich Linux with new features. The second is given by the stability of the kernel, thanks to Linux’s dedicated developer community and the wide dissemination of the kernel that has allowed more eyes on code development. The third reason is perhaps one of the most important — it is free. When you market a device, there are a number of licenses that the company has to pay for (hardware, various devices, etc.). For companies that use Linux in their products, there is no cost.
Before we begin to analyze the various folders, it is important to note that almost all operating systems used for embedded devices are a distribution based on the Linux kernel. The characteristics of being open-source, having extensive online support, and being a fairly stable kernel have made the entire family of Linux/Unix-based operating systems the ideal operating system for this type of device.
The Folders of the File System.
Let’s continue our analysis and explore in detail the structure of the operating system. First, we change the directory to rootfs
. Then, we run ls
to get a more complete overview of the directories.
bin dev etc init lib linuxrc mnt proc root sbin sys tmp usr var
As we might expect, this is the FileSystem Hierarchy Standard feature used for file systems in Unix-like operating systems. In fact, the standard defines which folders and virtual file systems are to be mounted at boot time by the operating system and what each folder contains. This standard is shared among all Unix-like operating systems to ensure compatibility between programs on different platforms.
Let’s explore each folder and file in more detail:
bin
: contains binary files shared by all users. In this folder we find the shell, cat, ls, cp, and many others.dev
: contains files for peripherals (devices). Most Unix-like operating systems adopt the “Everything as a file” approach where each peripheral is described by some special files that allow manipulating the state of a device. It also contains other pseudo-virtual devices such as/dev/null
which produces no output or/dev/random
which generates pseudo-random numbers.etc
: contains system configuration files. It is a very interesting folder that allows you to understand how the manufacturer configured the camera.init
: the executable that U-Boot loads and executes at the beginning of booting.lib
: contains essential libraries for binaries in /bin/ and /sbin/.linuxrc
: file that is executed by init to start populating and mounting some virtual file systems (such as dev, proc).mnt
: destination used to mount additional file systems (temporarily).proc
: virtual file system that contains information about active processes (mainly readable as text files).root
: the root folder for the “root” or “supervisor” user.sbin
: folder similar to sbin, differing only in the binaries it contains. In this case, they are binaries that must be run by root for system administration.sys
: file system that allows interfacing directly with hardware devices.tmp
: temporary folder. The files inside are generally deleted when the system is rebooted.usr
: contains applications and files used by users. Applications such as browsers, instant messaging, and anything not used by the system are put in this folder.var
: files with variable data. In particular, we have/var/log
which contains the logs produced by the various system components and applications.
Now that we have introduced the different folders, we can begin to explore their contents one by one. Over the course of the next few articles, we will be looking at getting to the bottom of some of the folders to better understand their meaning.
Bin Folder
The bin folder contains the essential binary files for the operating system. Inside we find executables such as ls
(to get a list of files), cp
(to copy a file), echo
(to print a string to the screen), etc.
In our case, we can proceed to see the various binaries in more detail using ls
.
ash chmod date echo fgrep hostname linux64 mkdir netstat ping rc_profile setarch su umount zcat
busybox chown dd ed fsync hush ln mknod nice ping6 rev setserial sync uname
cat conspy df egrep getopt iostat login more nvtrtspd pq_video_rtsp rm sh tar uncompress
catv cp dmesg false grep ipcalc ls mount nvtrtspd_2ch printenv rmdir sleep test_vos usleep
chattr cpio dnsdomainname fatattr gunzip kill lsattr mpstat nvtrtspd_ipc ps scriptreplay stat touch vi
chgrp cttyhack dumpkmap fdflush gzip linux32 lzop mv pidof pwd sed stty true watch
Many of these are commands routinely found in any operating system. The mkdir
(make directory) command in Linux/Unix allows users to create or make new directories. With mkdir
, you can also set permissions, create multiple directories (folders) at once, etc. What is immediately eye-catching, however, are some particular binary files that are not customarily found in Unix-like distributions, such as nvtrtspd
or pq_video_rtsp
. We will return to these because they seem to be interesting binaries.
Let’s then proceed to identify the shell. The shell is a command-line interface used to interface with the operating system — you can execute commands, request programs to start, and change settings. Along with the kernel, it is a fundamental component of an operating system.
There are several popular textual shells — with Bash being the most famous. Bash is used for GNU/Linux systems, but also cmd.exe for Windows, Z Shell for macOS. For Reolink RLC-810A, the shell is contained within a binary file called busybox
. Depending on how the application has been configured, there can be either bash or zshell.
BusyBox
BusyBox is a tool that allows many standard Unix applications to be encapsulated in one small executable that can be released within the firmware without too much complication. The main advantage is a reduced operating system size, since only one binary is needed to execute multiple commands. Calling different commands with a single executable works by symbolic links that invoke the single binary.
Considered the Swiss Army Knife of Embedded Linux, Busybox is primarily written in the C language and is currently used by a variety of embedded device distributions, including BuildRoot and OpenWRT.
Every command in the system is symbolically linked to the BusyBox binary. When any command is executed, busybot reads from argv[0]
the name of the command to be executed and in argv[i]
all the parameters of that command. The link between command name and binary on BusyBox is confirmed by a simple file ls
in the /bin
folder.
ls: symbolic link to busybox
By exclusion, we find the only files that are custom binaries, not BusyBox’s own: nvtrtspd
, nvtrtspd_2ch
, nvtrtspd_ipc
, pq_video_rtsp
, rc_profile
, test_vos
. We can move some binaries to an ad-hoc folder for the future, at which time we will delve by reverse engineering into the functionality and features of each program.
The Configuration Files (etc)
Once we have concluded the somewhat tedious binaries part, we can delve into another folder that will prove very interesting: etc. The etc
folder contains all the configuration files for system applications. These configuration files are shared among all users accessing the system.
Originally the etc
folder was to contain all files that did not belong to any particular category (hence the use of “et cetera” from Latin), but it quickly became the de facto file configuration folder. Some modern interpretations refer “etc” to “Editable Text Configuration” or “Extended Tool Chest.”
Resuming with our analysis, we continue by focusing on each file found. For the sake of simplicity and breadth, I preferred to include all relevant files within the /etc/
folder in alphabetical order.
Device Tree of Sensors (application.dtb)
The first file we analyze within the /etc/
folder is called application.dtb
and is a device tree — a file that allows us to describe a particular hardware configuration. We run the command used during Part 3 to view its contents:
dtc -I dtb -O dts -o - application.dtb
and here is the result:
/dts-v1/;
{
sensor@1 {
dev_name = "nvt_sen_imx291";
cfg = "sen_imx291_cfg1\0sen_imx291_cfg2";
sie = <0x00 0x01>;
};
sensor@2 {
dev_name = "nvt_sen_imx323";
cfg = "sen_imx323_cfg1";
sie = <0x03>;
};
};
The device tree is used to describe two optical sensors, apparently not used in this camera. It is used by a testing program included in the firmware, but almost never used by the end user.
bootchartd.conf
The bootchard.conf
file allows you to import some settings to the famous bootchart
tool that is used to measure Linux boot performance. In normal contexts, whether it is a computer or a cellular device, we do not have much interest in spending a few extra seconds during boot up.
However, when it comes to embedded devices, every second is crucial because the concept of “waiting” does not exist for the end user. For example, to start recording any video, we just turn on a camera and press a button. The user does not know that a series of operations are being performed at that time and therefore expects to be able to use the tool right away!
The tool is also useful in embedded contexts to try to detect dangerous bottlenecks. In the case of Reolink, there are two settings given to the kernel: sample_period
(i.e., the time interval to measure performance) and process_accounting
, which allows tracking all processes executed at startup.
firmware.info
The firmware.info
file contains some useful information about the firmware and the Software Development Kit used to generate the embedded distribution. It is not very useful for operating system purposes, but it allows you to extrapolate additional pieces of information.
SDK_VER="NVT_NT96660_Linux_V0.4.8"
BUILDDATE="Tue Mar 1 18:25:28 CST 2016"
fstab, group, and hostname
The fstab
file indicates which virtual file systems to mount, in what location, and possibly other parameters. The fstab file is read by the mount command that occurs automatically at startup to determine the overall file system structure.
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,exec,mode=1777,size=5M 0 0
tmpfs /var/run tmpfs defaults,rw,nosuid,mode=0755 0 0
tmpfs /mnt/tmp tmpfs defaults,noatime,nosuid,nodev,exec,mode=1777,size=20M 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
The group
file, on the other hand, reports the division of users into different groups. In itself, it is not very interesting for our investigation. root:x:0:
.
The hostname
file reports the name of the machine — BAICHUAN
, a clear reference to the company behind Reolink.
inetd.conf
The inetd.conf
file is the configuration file for the inetd
daemon and each line represents a service that is managed by this daemon. The inetd
daemon allows you to control the Internet services that are made available by the machine. The daemon starts services based on the configuration file. Specifically we find ftpd
which is started on port 21 by root and makes file uploading/downloading available from sd and tftpd
on port 69.
[..redacted..]
21 stream tcp nowait root ftpd ftpd -w /mnt/sd
69 dgram udp nowait root tftpd tftpd -l -c
inittab
The inittab
file specifies the initial configuration to be performed by the init
process for BusyBox. It consists of entries that follow the format:
Identifier:Level:Action:Command
where:
- identifier: a string that uniquely identifies an entry;
- level: level associated with the entry, represented by a number (0 to 9). Each entry is executed at the time the system is in the level equal to the entry;
- action: specifies to the process
init
how to treat the process; and - command: the command to be executed.
::sysinit:sh /etc/init.d/rcS
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/init.d/rcK
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
The following actions are specified by the inittab:
- at system startup, start the initial scripts (
/etc/init.d/rcS
); - if the system is rebooted, then it also restarts the init process; and
- when any action between reboot or shutdown is recorded, then run the
/etc/init.d/rcK
script and unmount the filesystem.
mdev.conf
Mdev is the tool developed ad-hoc by BusyBox to replace udev
. Udev is the device manager for Linux-like operating systems and runs as a daemon. Unlike Unix-based operating systems that rely solely on device management via static text files on /dev
, udev allows dynamic management of the creation or removal of these special files.
The syntax that follows mdev.conf is quite arty:
[-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...]
In our case, we find: mmcblk[0-2] root:root 660 */etc/mdev-script/autosd.sh
. It translates to “If you find devices that are mmcblk, then run the autosd.sh script”. Mmcblk is the name of the subsystem that SD/MMC devices use when they are connected to the board. When a new microSD is detected, the autosd.sh
script checks a number of parameters at the hardware level (microSD name, type) and if it matches, then it tries to create a new hard link to the contents of the microSD. Since a very thorough check is done on the type of microSD card, it explains why some microSDs may not work.
passwd
The passwd
file is used to configure which users have access to the login system and with what combination of username and password they can log in. The syntax for understanding a passwd file is as follows:
username:password:userid:groupid:useridinfo:homedirectory:shell
where:
- username: the username that is used during login.
- password: if there is only one
x
character, then the password is encrypted and its contents are available in the file/etc/shadow
; most of the times if the password is not encrypted, it is hashed with DES. - userid: is the ID of the user.
- groupid: is the group to which the user belongs.
- useridinfo: additional field that allows storing additional information about the user.
- homedirectory: absolute path where the user will be located once logged in.
- shell: absolute path to the shell to be started.
For Reolink RLC-810A, in particular, we find this file:
root:XF4sg5T82tV4k:0:0:root:/root:/bin/sh
It means that the default user for the webcam is the following username: root
, and the hashed password is XF4sg5T82tV4k
. With hashcat, we can retrieve original password: bc2020
. This password does not allow us to enter exposed interfaces on the Network such as via browser. Rather, if we attached the board via UART to a terminal, we could get inside the system using that particular username/password combination.
Including a passwd
file and leaving the password visible within a firmware poses no additional risk if the login requires physical, local access to the board. However, I cannot comment with respect to the security of this login since I have not found any information regarding this password. If anyone finds out more, they can write me an e-mail.
profile and profile_prjcfg
The profile
file is used to initialize the default system-wide shell. In fact, when the shell is started as an interactive type shell, it reads the /etc/profile
file, executes the commands within it, and reads another file ~/.bash_profile
which is the equivalent of the profile file, however specific to a user.
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
# source profile_prjcfg on /etc/init.d/rcS (init script cycle) and /etc/profile (after startup cycle)
source /etc/profile_prjcfg
export PATH="/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/bin:/sbin"
export LD_LIBRARY_PATH="/lib:/usr/local/lib:/usr/lib:/mnt/app"
export TERMINFO=/usr/share/terminfo
#export LD_PRELOAD="libnvtlibc.so"
if [ -f /etc/hostname ]; then
/bin/hostname -F /etc/hostname
fi
# coredump setting
echo 1 > /proc/sys/kernel/core_uses_pid
ulimit -c unlimited
echo "/var/log/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
export HOSTNAME=`/bin/hostname`
export PS1='[\u@\h:\w]\$ '
echo "$HOSTNAME Linux shell..."
Some interesting commands in this file are the following:
source /etc/profile_prjcfg
: run theprofile_prjcfg
file, setting some environment variables.echo 1 > /proc/sys/kernel/core_uses_pid
andecho "/var/log/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
: these two options are used to configure thecore
tool to generate core dumps when an application fails.ulimit -c unlimited
: there is no memory limit for the shell. Theulimit
command allows you to set a memory limit that the shell or one of the shell-started programs must adhere to, or else be “decapitated” (i.e., killed) by the operating system. Using this command poses serious problems since a process is free to be able to allocate as much memory as it requires. Sometimes it becomes necessary to increase the memory available to a process (and thus bypass the limit) when a program has some strange memory leak. The workaround, however, should be temporary and not permanent in production. This suggests a low-quality development practice.
As for the profile_prjcfg
file, it is mainly a set of environment variables that are set. For now, their meaning is unknown since most of the environment variable names are based on the Novatek SDK. We will try to find some clues that can help clarify the ideas.
export MODEL=/home/zfj/520_project/sdk/v2.02/NT9852x_linux_sdk_v2.02.000/na51055_linux_sdk_bc/configs/Linux/cfg_IPCAM1_523_EVB/ModelConfig.mk
export BOARD_DRAM_ADDR="0x00000000"
export BOARD_DRAM_SIZE="0x08000000"
export BOARD_FDT_ADDR="0x00100000"
export BOARD_FDT_SIZE="0x00100000"
export BOARD_SHMEM_ADDR="0x00200000"
export BOARD_SHMEM_SIZE="0x00100000"
[.... continues ....]
Again, we can see how the building phase of a firmware leaves some metadata behind. The developer who built the embedded distribution included within the file in production some references, which are obviously nonexistent. This is not the first time we will notice this and during the course of our series we will find many more.
Other Configuration Files
Within the /etc
folder are other configuration files such as services
, udhcpdw.conf
, wifiap_wpa2.conf
, and wpa_supplicant.conf
. Interestingly enough, some services (e.g., configuration files for Wi-Fi) that are not minimally used by this camcorder are nevertheless present within the firmware. In fact, the RLC-810A camera has only one way to be connected to the Internet: Ethernet, which it also uses as an electrical resource thanks to PoE (Power Over Ethernet).
Here we conclude our analysis of the configuration and binary files. It was interesting to see how each configuration file gave us some clues about the machine’s enabled services and how it operated. Next week, in Part 6 of our series, we will focus on the /lib
folder and the subsequent folders to be analyzed.
Reolink Serie
- Part 1 – Introduction to Firmware Analysis of a Reolink IP Camera
- Part 2 – Booting an Embedded OS: the Booting and U-Boot Phase
- Part 3 – Dissecting Reolink RLC-810A Hardware: A Detailed View
- Part 4 – Understanding the UBI File System in Embedded Devices
- Part 5 – Exploring the Operating System of Reolink RLC-810A
- Part 6 – Techniques for Setting up Peripherals via PIO and DMA
- Part 7 – Reverse Engineering the OMNIVISION OS12D40 Driver