D-Link: A Firmware Security Analysis – Part 3

by Oct 9, 2019

The Firmware Exploitation Methodology

In part two of our firmware analysis, we discovered a potential overflow in the administration server, alphapd. It appears if you send a long string in the WEPEncryption field to wireless.htm, it can cause a buffer overflow.

At this point, we still don’t want to buy the camera until we prove the vulnerability is exploitable. So, how do we prove it? Via emulation!

 

Emulating Binaries Found in Firmware

The easiest way (usually) to quickly emulate binaries that don’t match the architecture of our machine is to use QEMU, which stands for Quick Emulator. QEMU supports a ton of architectures including the one we need, MIPS, and it’s pretty simple to use.

However, we can’t just throw the alphapd binary at QEMU and expect it to run. The device needs to perform a setup process before running alphapd. And, we need to change our root directory so when alphapd runs, it uses the libraries in the firmware. We don’t want it using our local libraries. To do this, we’ll use the chroot command.

Chroot will sandbox our command to a specified directory essentially making it the root directory for that command. Since we are changing the root to the firmware’s directory, we also need a statically linked version of QEMU copied into the root of the firmware. Running the file command will tell us the architecture so we know which version of QEMU to grab.

QEMU Setup

QEMU Setup

The giant MIPS tells us it’s…. MIPS. The LSB, or least-significant byte, indicates it is little endian. From there we can chroot and run alphapd!

First attempt

First attempt

And it’s an immediate fail. But this is expected behavior. We jumped right to running a server on a system that expected some setup to have been performed and none of that happened. Some missing file and missing directory errors are expected. So we just run the server and keep fixing errors as they come up. Some of the errors, like the one we see now alphapd: cannot open pid file will require looking at the disassembly and tracing the errors back to their source. In this case: a missing file.

Missing PID File

Missing PID File

Very early in main, the server attempts to open the PID file along this path /var/run/alphapd.pid. But therun directory does not exist. So, we can just create that directory as well as the PID file.

The next error is a little more challenging and deserves its own blog post. please execute nvram_daemon first

Missing NVRAM Daemon

Missing NVRAM Daemon

The server is waiting for the NVRAM daemon to start. That will never happen because this is hardware based. The only option is to emulate NVRAM as well.

I used a forked version of a tool called nvram-faker. The original can be found here. My forked version can be found here.

This tool compiles to a library that is meant to expose functionality with the same prototype the server is expecting of its NVRAM function calls. Instead of the real call being executed and calling out to hardware, our calls will return prefabbed data from a file.

But how do we make alphapd use our calls instead of the real calls?

Easy.

There’s a handy Linux environment variable, LD_PRELOAD that allows for specifying libraries to be loaded before any others. Preloading it means that its functions will be used before others of the same prototype in later libraries.

The most difficult part of this whole process is compiling the nvram-faker library with the same, or similar enough, toolchain so it will run. It’s not unusual to have to try different toolchains. And you might need to copy over some libraries from that toolchain to the firmware’s lib/ directory. Luckily, I have one that is close enough, but I did need to copy a few libs from the toolchain.

On top of LD_PRELOADing nvram-faker, we also need to create a PID file for the non-existant NVRAM daemon.

alphapd running

alphapd running

Now it’s running but it quickly crashes because it didn’t find a valid value for a variable it requested from NVRAM. We need to find the values that NVRAM is loading by default from the factory. These values usually exist somewhere in the file system. It just takes a little searching.

The nvram-faker library provides logging output each time a value is accessed. Therefore, we know exactly what values the binary is expecting. We can search for these in the unpacked firmware.

NVRAM Default Data

NVRAM Default Data

This directory contains everything we need to populate a file that nvram-faker can parse and use to return values. Once that is set, we can emulate the server and try requesting the main page.

Because we are running a local QEMU, a request to http://127.0.0.1 is sent directly to alphapd. And it actually returns a page. Awesome! That wasn’t so hard, right?

alphapd index

alphapd index

 

Triggering the Firmware Exploit

The server is running now. We can make requests and it will send responses. We can even navigate around the camera’s configuration pages. What happens if we try to trigger our exploit?

Sending the exploit via Firefox

Sending the exploit via Firefox

Hmm. Unable to connect. That’s unfortunate. Did we type something wrong? Does that page not exist? Going back to the terminal where we ran alphapd, we see some interesting output indicating that it may have worked.

Segmentation Fault

Segmentation Fault

Seems like alphapd crashed when it tried to process that URL. Actually, this is good news. It could indicate that we overflowed the stack and jumped to address 0x41414141 (AAAA). Only one way to find out: run a debugger on the server.

Fortunately, QEMU has a handy option (-g) that runs a GDB server and waits for a connection. Once it is waiting, we can use IDA to connect and interactively step through the server while it’s processing the URL we sent.

The part we care about is the epilogue of the function that our overflow occurred in. The epilogue will restore the saved register, frame pointer, stack pointer, global pointer, and return address to their values before this function was called. These values are restored directly from the stack. If everything works, it should be full of ’A’s and they are.

Overflowed Registers

Overflowed Registers

Full System Emulation

We need to take this emulation one step further before we can declare absolute victory. Our emulation was performed on an Intel system. When alphapd tries to execute a system call, it will be attempting to run a MIPS binary on an Intel system, which will fail every time.

So our next step is to emulate the full system so when the server tries to execute other programs, those programs actually work. To perform full system emulation, we will need a virtual machine (VM) that matches the target’s architecture.

Building a VM is an in-depth process so I’m not going to go through it here. But here’s a link that explains how to build a MIPS Debian VM with a newer kernel.

Once everything is up and running in a full system emulation environment, we’ll notice that alphapd now requests a password when logging in, which makes this an authenticated exploit.

Alphapd Login Page

Alphapd Login Page

The next hurdle is that we are forbidden from requesting wireless.htm even after authenticating.

Forbidden Request

Forbidden Request

But if we navigate manually to wireless.htm through the GUI, everything is fine. So why the difference?

We’ll use Firefox’s Web Developer Tools to look at the requests sent to the server. What we find is the lack of a referer field in the forbidden request. Therefore, we need to add this field to our request.

Now when we send the request, the server crashes indicating we successfully overflowed the buffer!

FF Developer Tools

FF Developer Tools

 

To Be Continued…

By emulating the firmware’s alphapd binary, we have proven that the strcpy function is vulnerable by sending a request to the server. So far it’s been completely cost-free to validate. No actual hardware needed.

Next time we are going to put on our big-boy hacking pants and write a ROP chain to exploit this vulnerability. Then watch the magic happen!

 

About the Author

Evan Walls is a vulnerability analyst and developer at Tactical Network Solutions, focusing on embedded system exploitation. When he isn’t searching for new exploits, he teaches training courses developed by TNS, including IoT Firmware Exploitation. Prior to working at TNS he was a Windows developer for the Department of Defense. Now that he’s seen the glory and freedom that is Linux he vowed never to use another windows development machine again.

You can follow him on LinkedIn or GitHub.

Recent Posts
D-Link: A Firmware Security Analysis – Part 4

D-Link: A Firmware Security Analysis – Part 2

In this post we will explore the technical side of firmware security analysis to help identify which of the flaws are potentially exploitable flaws, and which flaws are simply poor programming practices.