refirm labs
  • Company
    • Leadership
    • Partners
    • Careers
    • News
    • Announcements
  • Products
    • Binwalk Enterprise (Centrifuge)
    • Binwalk Open Source
    • Product Comparison
  • Solutions
    • Enterprise IT
    • Industrial IoT
    • Telecom Providers
    • Device Manufacturers
    • Binwalk for Educators
  • Resources
  • Blog
  • Contact
  • Login
    • Binwalk Enterprise
    • Partner Portal
  • Get a DemoNew
refirm labs
refirm labs
  • Company
    • Leadership
    • Partners
    • Careers
    • News
    • Announcements
  • Products
    • Binwalk Enterprise (Centrifuge)
    • Binwalk Open Source
    • Product Comparison
  • Solutions
    • Enterprise IT
    • Industrial IoT
    • Telecom Providers
    • Device Manufacturers
    • Binwalk for Educators
  • Resources
  • Blog
  • Contact
  • Login
    • Binwalk Enterprise
    • Partner Portal
Get a Demo

D-Link: A Firmware Security Analysis – Part 2

August 23, 2019

The Technical Side of Firmware Analysis

In part one of the firmware security analysis we talked about choosing a target, downloading the firmware, and submitting it to Centrifuge which was pretty simple.

Centrifuge provided a lot of useful information about the firmware, most importantly the potential flaws in the code analysis section.

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.

 

Starting the Search

The best place to begin the search: the administration server that runs at boot. The administration server will likely be exposed to the internet. Therefore, it’s our best starting point in my opinion.

If you can access to the actual camera, you can simply connect a UART cable, access the shell, and get a process listing to identify the server. But I prefer not to buy hardware until I have an actual vulnerability identified, and I actually have all the information I need at my fingertips from the unpacked firmware.

Centrifuge identified a startup script. I’ll start with that. But if you don’t have access to Centrifuge, then a good place to start is the /etc/init.d script and see what services run at boot.

Startup Commands
Startup Commands

At this point I like to use binwalk to unpack the firmware locally for easier browsing. Looking through the startup scripts requires reading comments and looking at function calls to identify what runs at boot. The start of /etc_ro/rcS is shown below. These files are usually commented pretty well, which is helpful with the identification process.

/etc_ro/rcS

Working through all the scripts eventually leads to a mention of a webserver, alpahpd. The path to get there was:

/etc_ro/rcS -> /sbin/internet.sh -> /sbin/lan.sh -> /sbin/web.sh

So now we have our starting point!

 

The Target: alphapd Web Server

We can either dive right into disassembling alphapd in our tool of choice (IDA, Ghidra, Radare2, Binary Ninja, etc) or look at the Code Analysis section in Centrifuge to greatly narrow down our choices.

Centrifuge will call out both potential buffer overflows (if the destination is a stack variable) and command injections (if the parameter is a non-static string). This significantly reduces the number of function calls we need to examine from 300+ down to a respectable 32, which is a pretty substantial time save. The Code Analysis view gives all the information we need to start our analysis of the function calls in our disassembler of choice, which for me is IDA.

Code Analysis of alphapd
Code Analysis of alphapd

The server is already running by the time our exploit would be processed so we can skip any calls in main and calls prior to the message processing loop.

 

Buffer Overflow Requirements

For buffer overflows we look for two things. First, the destination must be a stack variable no matter the function call. If this is not true, then we won’t be able to overwrite the return address and control execution (more on this later). Second, we need to control some portion of the source data. Let’s look at an example.

Non-vulnerable strcpy Centrifuge
Non-vulnerable strcpy Centrifuge
Non-vulnerable strcpy IDA
Non-vulnerable strcpy IDA

The prototype for strcpy is:

strcpy(destination, source);

Function arguments in MIPS are $a0, $a1, $a2, $a3 for the first four args, then the stack if more arguments are required. To identify if the destination is on the stack, we need to see how $a0 is set.

MIPS executes instructions based on a 5 stage pipeline. As a call is executed, what comes after that call (the jalr) is also executed. This operation takes place in what is known as the delay slot.

In this example, the delay slot is where the first argument is set. It is simply $a0 = STACK ADDRESS + OFFSET. Therefore, the destination is on the stack.

Next is whether or not the source, $a1, is a user controllable string. From the code snippet noyes_select, it appears the string “No” or “Yes” will be the source. Since this is not a user controllable string, it will never result in a buffer overflow. This is simply a poor coding practice.

 

Command Injections

The same process is used to identify valid command injections. In this case, there is no destination. But we still need to control the source.

alphapd has a nice function, doSystem, that combines vsnprintf and system which means we are looking for an $a0 with some kind of format string in it. This method makes it quick and easy to identify potential vulnerabilities.

The example below is automatically discounted because a static string is passed as the argument with no chance of user controlled data.

doSystem Centrifuge
doSystem Centrifuge
doSystem IDA
doSystem IDA

 

User Controllable Buffer Overflow

Now let’s look at a buffer overflow that is user controllable:

strcpy Centrifuge
strcpy Centrifuge
strcpy Centrifuge

In this example, our destination is on the stack. The second parameter is set by the $s1 register. So now we travel back up the disassembly to see if it’s controllable.

$s1 Regsiter
$s1 Regsiter

The $s1 register is set to the contents of the $v0 register, which is used for return values from functions. In this case, the most recent function call is websGetVar, an alphapd function that retrieves variables from the URL. After some thought, we might end up with some pseudo code that looks like this.

sub_443138(request, argument_count, argument_value):
 char wep_encr[4]
 if (2 == argument_count):
 NVRAM_GET(wep_encr, “WEPEncryption”)
 if (“WEPEncryption” in $URL)
 strcpy(wep_encr, $URL[“WEPEncryption”])
 if (argv[1] == wep_encr):
 return “checked”
 return “”

Basically this function checks if supplied arguments are equal to the value of WEPEncryption from non-volatile random access memory or the URL. If they are equal, it returns the string “checked” or an empty string if they are not equal. If we can cause this function to be executed with WEPEncryption in the URL, then the contents of that value will be copied directly to the stack.

So the question is: who calls this function?

Lucky for us, there is only one reference to this function call.

websParaDefine
websParaDefine

Not a lot of information to go on here other than the string RadioOfWEPEncryWay. Doing a quick grep for that string shows it in one location.

RadioOfWEPEncryWay
RadioOfWEPEncryWay

By referencing our pseudo code, we can assume that the returned string “checked” or an empty string will be used to set the radio buttons on the wireless.htm page.

We also know that if wireless.htm is requested withWEPEncryption in the URL, it should copy that string directly to the stack.

There’s a little bit of handwaving going on here, but I did look through a lot of disassembly to figure out that websParaDefine function correlates the strings between %% and an associated processing function. Add all this together, and we end up with a request that looks something like this:

https://IP:PORT/wireless.htm?WEPEncryption=AAAAAAAAAAAAAAAAA

Those ’A’s should end up on the function’s stack.

 

To Be Continued…

I cherry picked some nice examples for the purpose of this security analysis. But the reality is, most of the potential vulnerabilities in firmware you examine are pretty complicated and take some time to understand, at least for me.

A good rule of thumb I follow: if it looks too complicated to execute the code path, then skip it. Have I missed vulnerabilities because of this rule? Probably. But I’m all about that low- to middle-of-the-tree-hanging-fruit.

Now that we have identified a potentially user controlled buffer overflow, next time we’ll dive in to how to emulate the server to determine if we can call this function and crash it.

 

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.

Share Post
Surveillance Cameras in Parts ...
Hackable Dahua Cameras
Unsecured IoT: 8 Ways Hackers Exploit Firmware Vulnerabilities
Unsecured IoT: 8 Ways Hackers ...

Recent Posts

  • Reverse Engineering My Router’s Firmware with binwalk

    February 7, 2020

    A few days ago I decided to reverse engineer my router’s firmware image with binwalk. I’ve bought the TP-Link Archer C7 home router. Not one ...
  • Identifying the Cable Haunt Vulnerability Using the Centrifuge Platform®

    February 5, 2020

    On February 4th, 2020 we deployed a new analyzer to the Centrifuge Platform, our automated firmware analysis platform which detects the presence of the Cable ...
  • D-Link: A Firmware Security Analysis – Part 4

    November 6, 2019

    Part 4 of our series on firmware security analysis focuses on how to exploit the vulnerability Evan discovered in his analysis of the camera firmware.
See All >
  • <<
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • >>

refirm labs Logo

8110 Maple Lawn Blvd.
Suite 200
Fulton, MD 20759

info@refirmlabs.com
Call +1 (240) 389-2443
Popular
  • About Us
  • Products
  • Resources
  • Blog
Solutions
  • Enterprise IT
  • Industrial IoT
  • Telecom Providers
  • Device Manufacturers

Facebook

  • Privacy Policy
  • Terms of Use

ReFirm Labs, Inc.