12 September, 2017

Enlarge your botnet with: top D-Link routers (DIR8xx D-Link routers cruisin’ for a bruisin’)

In this article, we are going to discuss vulnerabilities detected in the top D-Link routers:

  • DIR890L
  • DIR885L
  • DIR895L
  • and other DIR8xx D-Link routers cruising for a bruising.

The devices use the same code, thus giving a magnificent and quite tempting opportunity to attackers to add them to a botnet. Moreover, we have managed to make Mirai for the devices by modifying its compilation script a bit.

We will also say a couple of words about our interaction with the developer (which has brought no results, while the vulnerabilities are still not closed). Two vulnerabilities are related to the cgibin – the main CGI file that generates web interface pages to control the router. The other vulnerability deals with system recovery.

Stealing login and password

One HTTP request – login/password is in your bag.

The first detected vulnerability lies in phpcgi. Phpcgi is a symlink to cgibin and is responsible for processing requests to .php, .asp and .txt pages. It parses data sent via URL, HTTP headers or in the body of the POST request. phpcgi creates a long string which is later processed into sets of keys and values for the $_GET, $_POST, $_SERVER dictionaries as well as other variables of the php script. While finishing request analysis, the symlink checks user authorization. If a user is not authorized, it adds the AUTHORIZED_GROUP variable with -1 value to the string.

The problem here is that in terms of security the parsing process cannot be called flawless. Every key-value pair is encoded as follows: _TYPE_KEY=VALUE, where TYPE is GET, POST, SERVER or nothing. After that, the pairs are linked with the line break symbol ‘\n’.

By sending the POST request, we can add a key with the SomeValue{69c90e256be360ad980ca26f621f2003f22fc8a173440dabd89573a4d6bbc248}3dAUTHORIZED_GROUP=1 value. This key will be processed into _GET_SomeKey=SomeValue\nAUTHORIZED_GROUP=1, which will enable us to start scripts, though limited in their amount, as an authorized user. By sending a request to http:⁄/ and adding the pair SERVICES=DEVICE.ACOUNT, we will call the /htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml.php script that will return login and password from the router.

It is quite evident that it enables cyber-criminals to start scripts stored in the /htdocs/webinc/getcfg folder. There is also the DEVICE.ACCOUNT.xml.php script in the given directory that can provide attackers with a good deal of critical information including a login and password to the device.

In other words, if attackers send a request to http:⁄/ and add the SERVICES=DEVICE.ACOUNT pair, the device will respond with the page containing a login and password to the device.

That is more than enough for attackers to, for example, use their custom malicious firmware to update the device.

Full Superuser access (RCE to Root) to the device

Get root-shell with an HTTP request.

The second vulnerability is a stack overflow vulnerability caused by an execution error [HNAP].

To send a message via the protocol, an attacker sends a request to the http:⁄/ page and specifies the type of the request in the SOAPACTION header. It is the procedure of authorization request processing that is vulnerable. The “http:⁄/purenetworks.com/HNAP1/Login” value is used to call the authorization function. It is possible to specify different key-value pairs in a request body (there is a defined set of used keys): Action, Username, LoginPassword, and Captcha. After that these keys are encoded with html tags. E.g.: Here is the value

The main problem here is the function that extracts key-value pairs, while there is a designated buffer in the stack with the size of 0x400 byte. Nonetheless, attackers can send up to 0x10000 bytes of data with the help of strncpy, which causes a huge stack overflow. Strncpy overflows the current stack and then “shoots a security shot” overflowing the calling function stack as well, because variable ‘dest’ may hold up to 0x80 bytes, while there are 0x400 bytes for a value.

In addition, when exiting the function, in the R0 registry there is a pointer to the string. Thus, it is possible to specify an sh command set, change a return address to a ‘system’ function. Then, the only thing attackers have to do is to decide what they want to do with the controlled device.

Updating firmware in Recovery mode.

One reboot and you’re a root.

The third analyzed vulnerability is that, when the router is started, it sets up a recovery web server for several seconds. The server provides unauthorized cyber-criminals with an opportunity to update the device software, if they are connected to the device and, therefore, to a local network, with an Ethernet cable.

So, the only thing needed to exploit the vulnerability is to restart the device either by exploiting the vulnerabilities described above, or by sending the “EXEC REBOOT SYSTEM” command for service jcpd. This service is accessible from the local network via the 19541 port, can be easily used to restart the router without requiring authorization from a cyber-criminal, and is working permanently (no setting can turn it off). To get complete control over the device, an attacker needs to upload a modified firmware to the router.

Research timeline

However, that is not it, and the communication with the D-Link security team deserves special attention. Please, find the timeline below:

04/26/2017 – We notified the developer about the vulnerabilities detected in the hnap protocol.

04/28/2017 – D-Link employees replied that the vulnerabilities had been already patched in the beta version of their firmware that could be found at support.dlink.com.
N.B. There was no notion about the firmware at the D-Link web site.

04/28/2017 – 05/03/2017 – We analyzed the firmware version D-Link referred to in their reply and found out that one of the vulnerabilities the developer were notified about was still not fixed.

05/03/2017 – 05/09/2017 – We managed to find another vulnerability in the firmware, informed D-Link and asked them how was it going with fixing the previous one. They answered that the very process of detecting, fixing and assessing a vulnerability takes some time.

06/01/2017 – We notified CERT about the vulnerabilities. Here the reply its representative sent us:


Thank you for your vulnerability report submission. After review, we have decided not to handle the case.

We recommend continuing to work with the vendor before proceeding with public disclosure.”

6/02/2017 – For almost a month there was no word from D-Link. So, we decided that it was a high time to remedy the situation somehow. So, we warned D-Link that we would disclose the vulnerability to the public if they went on doing nothing about the problem.

06/06/2017 – The company replied with a description of its vulnerability response process and sent a beta firmware, which fixed the phpcgi vulnerability. The other vulnerability, reported to D-Link, was still ignored by the developer, though (perhaps, D-Link security team still believed that it was fixed by their beta-firmware).

Once again, we wrote to D-Link about the unpatched vulnerability. No wonder, there was no response. Here is the last message we have received from the developer:

Good Day,

Our R&D is working on a solution for the report. Until they establish why it happens, a proposed solution, and the scope of the issue (if it effects other models) we won’t generally discuss the report.

I should have some updates early this week.

I have no authority on how you conduct your work. Once we have a fix we announce/disclose the details support.dlink.com with accreditation to the 3rd party.

Typically the cycle of fixes is a couple of weeks for beta you can validate. Once validated we will offer it to the public as a beta, then it will move on to long term QA as an RC to be released. A full release cycle will usually take up to 90 days.

If you choose to publish sooner please provide a URL that we can reference for the report. If you choose to  request a CVE-id that is all we will need to accredit your report.

In the middle of August, we visited support.dlink.com and found out the developer uploaded the very same beta-firmware. 2 bugs out of 3 are still to be patched.

So, the bottom line of our research is:

  • D-Link has closed one of the detected vulnerabilities in the DIR890L router only, leaving other devices unsafe.
  • Two other vulnerabilities were (and are still) ignored by the developer.

Well done, D-Link!