Introduction to Firmware Analysis of a Reolink IP Camera

Embedded devices continue to increase in popularity and one category, in particular, that has become en vogue as of late is the Internet of Things (IoT). The emergence of these next generation technologies has driven the home automation evolution from simple light bulbs to cloud-connected printers, smart refrigerators, etc.

However, this evolution has some disadvantages: The perennial need to be connected to the Internet and an increase in the potential attack surface. Issues related (more broadly) to cybersecurity and (more specifically) your privacy are imperative to avoid, so that elements related to your private life are not exposed. For the time being, it appears that many IoT manufacturers simply ignore this.

In this series of articles, which will be published on a weekly basis, we will be taking an in-depth look at the technical functioning of an IP camera from the company Reolink ― in an effort to better understand the potential risks of an IoT device. Starting from higher level details, then onto the lowest level details, and then delving into the user interface, we will explain how the camera was created and developed. Now, let’s begin here by exploring an IP camera.

Embedded Devices

To begin analyzing firmware, it is necessary to first introduce a few notions about embedded devices: What are they? and Why have they been called that?

We can identify two broad categories in everyday devices: Those that are designed for a specific purpose and those called general-purpose. As an example, devices that are designed for a specific purpose are household appliances, home automation, cameras, printers, heating systems, etc. In these examples, only one purpose can be identified ― in the case of a microwave oven, the device will only heat food and certainly not show a film.

In contrast, general-purpose devices, such as computers, mobile phones, and smartwatches are machines that can perform any kind of task ― from writing an email to watching a movie. Their purpose depends on what the user wants to do with them. One can develop projects, watch a film, compose music, and much more.

Generally, specific purpose devices have far fewer resources than what we expect from general-purpose devices. The main reason they have fewer resources available is that they are designed for a single purpose, so they only have one task to perform. The design of specific purpose devices is very critical and requires a lot of precision to avoid unnecessary expenditure of time and money.

Such devices are often called embedded devices because they are “immersed” in reality: They perform very specific jobs and tasks in a physical context. Let’s think, for example, of how many chips we could find in a house: air conditioning system, home automation to switch on/off a light bulb, burglar alarm system, household appliances, etc. Let’s now imagine a more complex environment, such as a car (control units, car radios) and industries (assembly line, sensors).

While all devices are based on the Von Neumann Architecture, what actually varies and makes the difference is the type of architecture (16-bit/32-bit/64-bit and ARM/MISP/Coldfire) and the available hardware resources. Furthermore, embedded devices do not work in isolation, as they are usually configured to work and perform a task that depends on information from other systems (like a heating controller controlling the heat pump).

For embedded device designers, the most complex challenges they face are working with limited resources and having to communicate with other systems in a standard way. In addition, there is another subtle problem that is overlooked and has only recently come to light.

At the end of the millennium, several people theorized about the application of Internet connectivity to embedded devices, calling the concept the “Internet Of Things”. Although wanting to be precise, in practice Internet-connected devices had already been developed in the early 1980s. One of the first embedded devices was a beverage dispensing machine (The “Only” Coke Machine on the Internet), which was connected to the Internet at Carnegie Mellon University. Programmers would connect to the machine through the Internet to check if there was a beverage available.

Since the creation of the concept of the Internet of Things in the early 2000s, these devices have begun to spread ― first in an industrial setting and then into the homes of almost all of us. Thanks to extensive marketing campaigns, various embedded devices have entered our homes (alarms, printers, televisions, smart locks, etc.). However, it is not all “peaches and cream” as marketers would have us believe.

With the introduction of networking to embedded devices, several challenges have emerged and some are still being actively discussed today. Lack of security, short software lifecycle (with one update in five years), proprietary security protocols, and the mantra “security by obscurity” make IoT devices a target for attackers trying to break into an infrastructure. In addition, dependence on the manufacturer is a point of centralization that could potentially be a problem, especially when the manufacturer ceases to exist. Technical problems at data centers, proprietary servers, and infrastructure can also negatively impact an IoT experience. Isn’t it just wonderful to not be able to access your device because AWS is momentarily down in your area?

Let’s point out that the Internet of Things category is a subcategory of embedded devices ― not all devices we see around the house are connected to the Internet (fortunately). However, this is not the case with Reolink’s IP camera.

Structure of the Article Series

Here is the timeline for the upcoming articles in this series. Our goal would be releasing one article per week on Wednesday. We have tried to divide the topics to be addressed into different sections:

Note: The articles list will be expanded as the articles are being released.

To highlight all the issues regarding IoT, we have decided to take firmware from a well-known manufacturer and analyze it manually and step-by-step to better understand how embedded devices work and how secure they actually can be.

Our investigation begins on a rainy Saturday and delves into the Reolink RLC-810 A camera, a “jewel” ― or as they say ― PoE (Power over Ethernet) IP camera. An IP camera is a camera connected to the Internet that is reachable through any browser and an IP address (named after the Network layer protocol, or IP, Internet Protocol).

Before we get into the firmware, let’s try to analyze the hardware architecture to get a general overview of the functionality. From there, we will try to read the specifications released by the manufacturer that will surely be useful to us in the future.

The camera supports 4K video (recorded on a microSD card with a size of up to 256GB), renames people or vehicles moving via artificial intelligence, and can also record audio via a microphone located inside the device. It is powered by PoE, an option that allows a device to be powered via Ethernet cable; thus, allowing for a single cable from the camera to the power source/Internet network. It is also equipped with a CMOS 1/2.49’’ sensor that allows it to record video at a 3840x2160 (8 MegaPixel) resolution.

In addition to this, Reolink boasts of having 18 IR LEDs and a view up to 130 feet from where the camera is filming. It connects intelligently to both Google Assistant and Alexa and can be controlled by an Android or iOS app. How do we achieve this kind of functionality? What kind of protocols is the camera using? Considering that a single camera costs around 100 Euros, will they have considered security or has it taken a back seat?

From the documents presented to the client, no additional information was given about the type of hardware architecture (CPU and RAM) or the security of the device. Only the software can reveal clues about what is actually inside the hardware. All that remains is analyzing the firmware inside the camera.

Software Part

In this section, we will expand on the first part of our analysis by introducing the Binwalk tool and begin to obtain the device configuration files.

Embedded customer devices, whether connected to the Internet or not, can be compared in functionality and architecture to a general-purpose computer. They have a CPU that serves the operating system to process information and RAM, where data is stored and accessed. In addition, they often have external storage space (usually microSD) that is mounted as secondary memory and within which the operating system is located.

Recall that having thought of an embedded device as a computer is not always true (think, for example, of a System on a Chip modified), but it is generally taken for granted since the device must have a relatively low design cost. This advantage allows the manufacturer to produce such devices on a larger scale. For this reason, manufacturers try to reuse existing architectures and hardware schemes (with ready-made tools) in order to save resources and time.

In most cases, the software part consists of a minimum size image (from a few MB to hundreds of MB) of a Unix or Linux-based operating system. Such distributions are equipped with some custom binaries, from the company, that constitute the actual controller of the IoT device, as in the case of the Reolink camera.

Let’s now focus on the software part. To begin our investigation, we have two main options: Try to get the firmware from the manufacturer or retrieve the firmware image from a camera “manually”. Actually, we preferred the first option, because it is much easier than opening the IP camera. Within the “Download Center” page, in addition to the manuals and operating instructions, there are firmware updates that can be downloaded as ZIP files.

Now, we have downloaded version v3.1.0.956_22041503, which was released on April 18, 2022. Looking at the changelog and the different versions available, six versions have been released in the last year and all of them have been accompanied by numerous changes. On paper, Reolink looks promising.

We download the firmware file as a ZIP via the wget or curl command:

wget https://url-of-firmware-reolink/firmware-rlc-810a-v3.1.0.956_22041503.zip

And we proceed to unpack:

unzip firmware-rlc-810a-v3.1.0.956_22041503.zip

The ls command, which is used to see the files within the folder, shows two files: The first as a .pdf file that explains the process of doing the firmware update and the second as the .pak file that contains the actual firmware.

Disclaimer: An extensive analysis of any firmware requires a fairly large investment of resources and time. I have spent weeks on this series of articles, but I am aware that this investigation is far from perfect. If you find typos, technical oversights, etc. then please email me.

Analysis through Binwalk

A quick file on the firmware did not highlight the type of file and returned us a simple date; therefore, the file utility was unable to identify the precise type of file. We know that the .pak extension, moreover, is routinely used for firmware, backups, etc. but it does not identify a precise file type.

Our investigation could end here or go on with tedious code writing aimed at analyzing each byte to figure out what type of file it is. Fortunately for us, a utility called Binwalk makes much of this work easier by analyzing and extracting the firmware.

Binwalk is a tool written in Python by ReFirm Labs (which was purchased by Microsoft in 2021) that is able to identify the parts of a file that correspond to a given extension by attempting an extraction. Indeed, recall that while Binwalk is a complete product, it may sometimes fail ― if the firmware is particularly obfuscated, encrypted, or constructed in a way that does not allow extraction.

Typically, each file has at the beginning a series of bytes, which are hand-picked by the file extension developers, that associate an apparently unknown file with a precise file type. This set of bytes is called the file signature or magic bytes (example 45 50 for PE binaries). The main feature of Binwalk lies in the so-called signature scanning. That is, Binwalk compares (for each byte pair) the list of already known signatures. If indeed Binwalk knows the signature associated with the file, it is possible to try extraction for the type of recognized file (a ZIP file, for example).

For those interested in the details, Binwalk uses the format libmagic to describe already known magic. This allows the list of magic bytes to be created, updated, and modified very easily. The same format is also used for the file utility.

Binwalk also becomes very useful in the case of a heavily obfuscated firmware or file. When the information is heavily obfuscated (not following a certain logic), the entropy of some sections turn out to be very high. By specifying the --entropy option, Binwalk allows the entropy of a file to be displayed in the form of a graph. A complete set of commands, with which to use this powerful tool, is available on Github.

A little often remembered bit of detail is that the tool was created specifically for firmware, not as an analysis tool for files. Perfect for our case! To identify the various parts of the file and proceed with extraction, Binwalk uses a subtle but clever approach. First, it analyzes the file with all the signatures. Next, instead of arbitrarily dividing the file into smaller parts, it tries to parse the file types. Most likely, within the headers of each file, the size of the affected segment or block is also indicated (specifically, this is true for file systems). Binwalk then divides the file into blocks of very specific sizes, which is obtained from the previous step of signature scanning and header file parsing. It then proceeds with the extraction of each “block” using other particular tools chosen according to the type of file being extracted.

We then return to the downloaded firmware and start Binwalk by specifying the filename:

binwalk firmware-rlc-810a-v3.1.0.956_22041503.pak

The results are as follows:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
34600         0x8728          Flattened device tree, size: 17375 bytes, version: 17
468491        0x7260B         eCos RTOS string reference: "ecos pat%d, res check sum fail."
469218        0x728E2         eCos RTOS string reference: "ecos %s"
469688        0x72AB8         eCos RTOS string reference: "ecos %s"
477499        0x7493B         CRC32 polynomial table, little endian
479095        0x74F77         CRC32 polynomial table, little endian
480119        0x75377         CRC32 polynomial table, little endian
509401        0x7C5D9         LZO compressed data
624319        0x986BF         uImage header, header size: 64 bytes, header CRC: 0x7B9F6E31, created: 2021-06-19 06:29:15, image size: 3153472 bytes, Data Address: 0x8000, Entry Point: 0x8000, data CRC: 0xD7FC213, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-4.19.91"
624383        0x986FF         Linux kernel ARM boot executable zImage (little-endian)
637815        0x9BB77         LZ4 compressed data, legacy
649910        0x9EAB6         LZ4 compressed data, legacy
722627        0xB06C3         SHA256 hash constants, little endian
1151908       0x1193A4        Certificate in DER format (x509 v3), header length: 4, sequence length: 774
2580562       0x276052        Certificate in DER format (x509 v3), header length: 4, sequence length: 536
3049852       0x2E897C        AES Inverse S-Box
3486531       0x353343        Base64 standard index table
3711491       0x38A203        LZ4 compressed data, legacy
3777855       0x39A53F        UBI erase count header, version: 1, EC: 0x0, VID header offset: 0x800, data offset: 0x1000

Very interesting! The analysis of the file turned out to be effective. In particular, we can observe how Binwalk looks for the signature and even tries to interpret the header file. For now, we do not bother looking specifically at all the data; although, some are immediately eye-catching. For those who have no experience with file types and file systems in particular, you can paste each file type into a search engine and derive more information.

Binwalk has also listed for each file type the offset, which is the position in bytes that the file type covers. This will be useful later, as it enables us to manually extract files (and act as a litmus test for Binwalk). Through signature scanning, we were able to extract initial information from the firmware. For now, we will not bother to examine the .pak file format in depth.

Specifically, we are interested in the following file types:

  • Flattened Device Tree: Data structure that contains the virtual configuration of the machine.
  • uImage Header: An image that has a U-Boot wrapper that includes the operating system type and loader information. This is the initial information about the architecture, ARM, Little Endian, which mounts an OS based on the Linux kernel version 4.19.91.
  • Linux Kernel ARM Boot Executable zImage: OS loader.
  • UBI Erase Count Header: A type of header specific to the UBI File system.

If some of these terms seem quite unfamiliar, don’t despair. In the next article, we will delve into the boot phase and various components of the operating system (U-Boot) Linux, so that we can extract the firmware and begin the analysis. See you soon with the next installment of our series!