The TrendNet TEW–827DRU Vulnerability Assessment Series: Identification

exploits Aug 13, 2020

Today we are going to talk about the vulnerability assessment I performed on a TRENDNet TEW–827DRU hardware revision 2, firmware version 2.04. I enjoyed this vulnerability assessment, mostly because there were a lot of vulnerabilities to discover, but also because it allowed me to tests out some new exploitation techniques involving ASLR. More on that later. For now, let’s all don our white hats and dive right in.

TEW–827DRU Router

In the Beginning

Just like all vulnerability assessments we need a firmware to look at. To the internet! Specifically, even more specifically this page to download the firmware. TRENDNet is a little more stingy than most companies with their firmwares, only providing the most recent version. At least I could only find the most recent version, but older versions probably exist out there somewhere. My next step is to pop the firmware into Centrifuge. For you it might be to binwalk it and begin analysis. Either way, our first step is to establish how to communicate with this router.

Centrifuge Report

Who’s it gonna call?

Centrifuge tells me to start looking at /etc/init.d/rcS to see what executes at boot. Not a very interesting file, but based on the parameters provided, “S” and “boot”, it will run every service file in /etc/rc.d/ that starts with an “S”.

rcS function

S service files

The only file that looks like it might run a server is S50uhttpd. Google is our friend so let’s see what it has to say about uhttpd. Turns out uHTTPd is a general purpose web server written by the OpenWrt/LuCI developers. Because it is general purpose, it’s likely that uHTTPd will offload most of the heavy lifting to another program built specifically for this router.

The website mentions there should be a configuration file at /etc/config/uhttpd that contains configuration data on how the server will be run. It’s not a very long configuration file. Little bit of info about ports, some index pages, various timeouts, but the part that caught my eye was the interpreter. It looks like all requests related to asp, cgi, js, xml, and txt files will be passed off to /www/cgi/ssi. This guy will probably handle all that heavy lifting that was mentioned earlier.

uHTTPd interpreter

We can take this information back to Centrifuge and see what the code analysis view says about the ssi binary. It’s number one in the list with 536 potential flaws. Awwwww yissss.

ssi Potential Flaws

Vulnerability Identification

So, 536 is a lot of potential flaws to look at. I don’t think anyone wants to read through my analysis of each one so I’ll go over two that are not vulnerable and then we’ll talk about the ones which, spoiler alert, are vulnerable.

The two type of exploits we are looking for are buffer overflows and command injections. With buffer overflows we need are looking for strcpy, sprintf, sscanf, or other string related functions that rely on a NULL to stop the operation. Once identified we need two things to be true for it to be exploitable. First, the destination needs to be on the stack otherwise we can’t control execution. Second, we need to control the source data.

In the example below, the destination for the strcpy is an offset from $fp which was previously set to $sp so the destination is on the stack. The source is the return from a call to uci_safe_get with the parameter network.wan.ifname. We cannot control the WAN interface’s name so this strcpy is not overflowable. The prototype for strcpy is given below, just for reference.

char *strcpy(char *destination, const char *source);

“Safe” strcpy

With a command injection we are looking for system, popen, or execve calls that execute user controlled strings. In the example below system is called with a static string so there is nothing to inject.

int system(char *command);

Safe system

This is the process I went through for most of the 536 calls. I was able to skip deep analysis on some because they were in functionality that I couldn’t reach or the code path looked too complicated to easily hit. But, I at least glanced through them all.

The Identified Vulnerabilities

After looking through the 536 “flaws” listed in Centrifuge I had a list of 7 blocks of code that contained potential vulnerabilities.

  1. Buffer overflow when parsing the parameters passed to ssi binary.
  2. Buffer overflow when providing the primary and secondary DNS server when configuring WAN DHCP through the setup wizard.
  3. Buffer overflow when providing the primary and secondary DNS server when configuring WAN static IP through the setup wizard.
  4. Multiple buffer overflows and command injections when parsing parameters for WAN PPTP configuration through the setup wizard.
  5. Multiple buffer overflows and command injections when parsing parameters for WAN L2TP configuration through the setup wizard.
  6. Buffer overflow and command injection when providing the MAC address as part of a running the setup wizard for DHCP.
  7. Buffer overflow and command injection when providing the target of a ping or traceroute.


This buffer overflow is early in main of the ssi binary so I feel pretty confident this will be a valid exploit. The source for the strcpy is the environment variable QUERY_STRING. This variable will be set to any string after the “?” in a URL.

QUERY_STRING buffer overflow

If the request was passed to ssi the QUERY_STRING would be “key=value”. Pseudo code for this would look something like this:

query_string = get_env("QUERY_STRING");
if (NULL != query_string) {
    strcpy(dest, query_string);

This is one of those vulnerabilities I always look for, but NEVER expected to find. Well, here it is.

#2 and #3

The code blocks for exploit number two and number three are the same, except for the variable offsets, so we’ll go over them at the same time.

DNS Buffer Overflow

Pseudo code for this block is pretty simple:

primary_dns = safe_getenv("cameo.wan.wan_primary_dns");
secondary_dns = safe_getenv("cameo.wan.wan_secondary_dns");
sprintf(var_90, "%s %s", primary_dns, secondary_dns);

It appears that if we can control the value for cameo.wan.wan_primary_dns and wan_secondary_dns then we can overflow the buffer. A quick grep through the filesystem shows that those variables appear in a few different places as arguments for whatever request is being made. This looks like a good exploit too.

#4 and #5 and #6

Command Injection and Buffer Overflow

The functions for number four, five, and six are full of blocks of code like this. The purpose appears to be getting user input variables to change current configuration values using the uci binary. If we can control [email protected][0].hostname we could either overflow a stack buffer or, more simply, perform a command injection. This is a unicorn exploit and there are a lot of them. Pseudo code:

hostname = safe_getenv("[email protected][0].hostname");
sprintf(var_114, "uci set network.wan.hostname=%s", hostname);


Ping/Traceroute Vulnerability

The last potential vulnerability appears in an error case when it fails to convert the “hostname” to an IP address. Just like the previous three, this one is a twofer with a command injection and buffer overflow.


Woof. We have our work cut out for us, in a good way though. Next time, we emulate all these to see if they are actually exploits.


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.

Stay connected with our writings on firmware exploitation!

Join today and be the first to know when we release new content. Your email will never be shared.