A Beginner’s Firmware Analysis: Part One

An old-fashioned detective in a trench coat peers at the firmware of a device's board through a magnifying glass.

The Objective

The purpose of this series is to use binwalk and other free and open source tools to analyze the firmware of a D-Link DNS-340L and investigate the CVE-2024-10914. If that sounded like gibberish to you, you’re in the right place! If not, you’re still in the right place, just skip to “The Analysis” section.

First, we will analyze the firmware image to learn more about the device. A device’s firmware is the “software” that includes the code and data to control the device’s hardware. Firmware is small and specially designed to run on a device’s hardware. Firmware is sometimes referred to as the “software for hardware”, but this is a bit of a misnomer, as firmware handles input/output tasks, communication with other devices, and device startup, whereas software facilitates interaction with hardware, such as browsing the internet. Our goal is to examine the device’s firmware to learn more about this program and the device itself.

Later, we will reverse engineer a file from the firmware to find the vulnerable code the CVE-2024-10914 exploited. Reverse engineering is the process of analyzing software, hardware, or a device to understand how it works. Sometimes, reverse engineering aims to determine how something was made or how to replicate it, but it can also be used to find vulnerabilities.

As a quick note before we start, while this article is designed to be as beginner-friendly as possible (literally, it’s copy and paste), it isn’t designed to answer all questions that might pop up in your head along the way. I’ll do my best to summarize the tooling, provide step-by-step instructions, and explain the “why” for a process, but there’s only so much information my little article can hold. All this to say that if you are wondering why I glossed over something, it is through design so that a beginner may see the bigger picture and gain confidence rather than become frustrated.

Disclaimer: This article does not share any information that isn’t already publicly and easily accessible on the internet. The point of this article is to provide an educational and amiable walkthrough for beginners. This article and its content are for educational and ethical purposes only; therefore, its author and editor assume no liability and are not responsible for misuse or damage. It is your responsibility to follow the law.

The Jist

This is a beginner’s walkthrough writeup on the recent D-Link NAS devices vulnerability CVE-2024-10914, which has a base score of 9.8 critical out of 10. This vulnerability is a command injection that allows an attacker to inject a command through a crafted HTTP GET request. This vulnerability affects multiple versions, including DNS-320, DNS-320LW, DNS-325, and DNS-340L.

While this walkthrough will not cover it, there is another vulnerability CVE-2024-11067 which is a buffer overflow bug with a base score of 7.5 that affects the D-Link router versions DSR-150, DSR-150N, DSR-250, DSR-250N.

Both vulnerabilities can lead to remote code execution, and thousands of these devices are connected to the internet. The negative publicity these vulnerabilities stirred led to public outrage after D-Link announced it would not patch or update the devices to mitigate them as all of the affected devices reached their End of Life deadline (May 1, 2024). In other words, the manufacturer is not required to address the vulnerabilities, and any user of these devices should replace them.

The Setup

Before we embark on our exciting escapade, we need to install several prerequisites so that later we can focus on the fun part.

First, you need binwalk, a free and open source tool to analyze firmware images.

On Ubuntu 24.04 and similar Linux distributions, you can run the following command in the terminal to install binwalk:

sudo apt install binwalk

There are a few other ways to install binwalk, such as the binwalk’s GitHub repository steps to install a Docker image for binwalk.

Additionally, we need firmware to analyze it. Download the DNS340L’s firmware from the D-Link’s DNS-340L product webpage.

When you visit the link, you’ll see a page like so:

However, scroll to the bottom of the page under “Support” and you’ll notice an dropdown option titled “Firmware” where you can download the 1.08 version of the DNS-340L:

The Analysis

Open your terminal and navigate to the directory where you downloaded the DNS340L firmware zip folder. By default, this directory would be Downloads. In this example below, I navigate to a directory I moved the zip folder to that is named after the device:

vmuser@vm$ cd Downloads
vmuser@vm:~/Downloads$ cd DNS340L 
vmuser@vm:~/Downloads/DNS340L$ ls
	'dns-340l_fw_reva1_1-08_eu_multi_20180731 (1).zip'

Next, we’ll unzip the folder. Unzip should be preinstalled on Ubuntu, but in case it’s not, the command is sudo apt install unzip. Use the unzip command like so (make sure that if the folder you downloaded has ” ‘ ” marks to include them.):

vmuser@vm:~/Downloads/DNS340L$ unzip 'dns-340l_fw_reva1_1-08_eu_multi_20180731 (1).zip'

When we look at our directory, we’ll notice two more additions:

vmuser@vm:~/Downloads/DNS340L$ ls
	'DLINK_DNS-340L_1.08b01(1.01.0502.2018).zip'  'DNS-340L_A1_Release Note_for Firmware_v1.08.doc'  'dns-340l_fw_reva1_1-08_eu_multi_20180731 (1).zip'

One is a release notes document and the second is another zip folder. Run the unzip command again on this folder:

vmuser@vm:~/Downloads/DNS340L$ unzip 'DLINK_DNS-340L_1.08b01(1.01.0502.2018).zip'
vmuser@vm:~/Downloads/DNS340L$ ls
	'DLINK_DNS-340L_1.08b01(1.01.0502.2018)'  'DLINK_DNS-340L_1.08b01(1.01.0502.2018).zip'  'DNS-340L_A1_Release Note_for Firmware_v1.08.doc'  'dns-340l_fw_reva1_1-08_eu_multi_20180731 (1).zip'

Now when we look at our directory, we’ll see the next addition. We know we don’t need to unzip any more files because there is no .zip appending the file’s name and if we run the file command on this file, we can see it returns data.

This is an indication we found what we were looking for, which is a binary file. While the file ‘DLINK_DNS-340L_1.08b01(1.01.0502.2018)’ is not appended with .bin, we have clues to indicate it is a binary file, which is important to know as this is the file type we can use our next tool binwalk on to find the device’s code.

Our first clue is that the file command returned data, which it usually only does when the command cannot identify the file format or structure. This can happen when the file is an unrecognized binary. Still, it can also happen under other circumstances, such as when the file is compressed with an unknown compression algorithm or encrypted, making it unreadable to the file command.

Our second clue is that the file is not appended with any file format extension, like “.pdf” or “.py”. Binary files are not tied to a specific format and therefore, while the .bin extension is a common convention, it isn’t necessary. Often, firmware files for embedded devices extracted from archives will lack detailed naming or extensions because it’s a binary that’s designed to be recognized programmatically by a computer, not manually by a person.

While the aforementioned clues suffice, for fun we can also use tools like the xxd or objdump commands to view the file’s raw content. To run the command, type the following so that we can pipe the xxd command’s output into the less command and scroll through the output more easily:

xxd 'DLINK_DNS-340L_1.08b01(1.01.0502.2018)' | less

When you run this command, you will receive an extensive, seemingly indecipherable output. When you want to exit, you can press q, but before you do, let’s examine some parts of the output worth mentioning.

00000000: 8000 0000 3085 2c00 b085 2c00 90a0 1e00  ....0.,...,.....
00000010: 4026 4b00 0008 e602 402e 3103 6425 0000  @&K.....@.1.d%..
00000020: e267 9198 920d d887 0000 e602 f7d1 f8a3  .g..............
00000030: 55aa 444e 5333 3430 4c00 55aa 0008 0e01  U.DNS340L.U.....
00000040: 0100 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 a453 3103  .............S1.
00000080: 2705 1956 6c6c 4624 536c 92fa 002c 84f0  '..VllF$Sl...,..
00000090: 0000 8000 0000 8000 f068 2578 0502 0200  .........h%x....
000000a0: 4c69 6e75 782d 332e 322e 3430 0000 0000  Linux-3.2.40....
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 a0e1 0000 a0e1 0000 a0e1 0000 a0e1  ................
000000d0: 0000 a0e1 0000 a0e1 0000 a0e1 0000 a0e1  ................

We can see from the first part of the output as shown above that the file has a binary-like structure containing non-text characters. This is all we need to determine that the file is indeed a binary file, but if we look a little further there is more we can glean (yes, this is a pun on one of glean’s definitions: “to collect bit by bit”).

When we look at the file’s raw contents, we can see hexadecimal numbers (i.e., 4c69 6e75) on the left paired with ASCII representations (i.e., VllF$Sl) on the right. If we look closely at the portion of the output provided above, we can even notice some strings that give us further insight into the device, which could be helpful if we didn’t know the device of origin to begin with.

For example, the section below indicates that this is likely a signature or header for a part of the firmware. In the bytes below, we see 55aa, which can be seen in boot sector headers or firmware, where it acts as a boot signature to determine if the system is bootable or not. Also note that the corresponding ASCII contains “DNS340L”:

55aa 444e 5333 3430 4c00 55aa   U.DNS340L.U.

Further down a few lines, we can see the section below contains the string “Linux-3.2.40”, which is a Linux kernel version embedded systems can run on.

4c69 6e75 782d 332e 322e 3430 0000 0000  Linux-3.2.40....

So we know the file is a binary and confirmed it belongs to a DNS340L device that runs on the Linux kernel version 3.2.40.

Next

In the next article, we’ll continue our analysis of the firmware with the previously mentioned tool, binwalk. Then, we’ll set up our environment to reverse engineer a file from the device’s firmware.

About the Author

Aleks Jones is a technical trainer and course author at the Linux Foundation, focusing on emerging technologies like WebAssembly and cybersecurity. As an editor for the Evil Tux blog, she evaluates technical articles, sharing insight on artificial intelligence and cybersecurity. In her leisure, she participates in capture the flag competitions.

You might also like: