In a previous post we shared our considerations on the impact of vulnerabilities in Internet connected devices that are EoL. We used the vulnerabilities that we identified in the D-Link DSL-2640B DSL gateway as a use case to support our considerations. In this post we describe the technical details of these vulnerabilities.
Before we dive into the technical details, it's important to note that:
- all vulnerabilities are (at least) applicable to the D-Link DSL-2640B (HW revision B2, Firmware version: EU_4.01B)
- all vulnerabilities apply to the latest available firmware (as of 27/03/2020)
- all vulnerabilities have been reported to D-Link
- we are not aware of any security fix released by D-Link
- as the device is EoL, following D-Link's policy, no fix may ever be available
The vulnerabilities described in this post may apply to other hardware revisions, other firmware versions and even completely different models. We did not investigate this further and D-Link did not provide any additional insights.
The following vulnerabilities are described in this post:
- CVE-2020-9275 – D-Link DSL-2640B - Remote credentials exfiltration
- CVE-2020-9279 – D-Link DSL-2640B - Hard-coded privileged account
- CVE-2020-9278 – D-Link DSL-2640B - Unauthenticated configuration reset
- CVE-2020-9277 – D-Link DSL-2640B - CGI Authentication bypass
- CVE-2020-9276 – D-Link DSL-2640B - do_cgi buffer overflow
We hope we provided sufficient technical details of the identified vulnerabilities. Additional information (e.g. video demonstrations) may be provided in the future.
We hope you enjoy the technical remainder of this post! :)
CVE-2020-9275 – D-Link DSL-2640B - Remote credentials exfiltration
This vulnerability allows retrieval of the administrative password by sending a specific UDP packet to port 65002 of the device.
An attacker connected to the WiFi or the local LAN, or who is able to reach the internal device interface in any other way, can retrieve the device password with a single UDP
request.
Most functionality of the device, including the administration panel and the web server, are implemented in a single process named cfm
executed at startup. The cfm
process listens on UDP
port 65002
. Likely to support device configuration from a dedicated application. The screenshot below, shows the function implementing the communication protocol. The function name, pcApplication
, is taken directly from the binary's symbols.
Communication is done using D-Link's proprietrary protocol for which no information is publicly available. Reversing the cfm
binary yields the following structure for the protocol packet.
Several commands are supported and accessible by specifying the command code in the 2 bytes cmd
field. Communication is in plaintext and without authentication. The code only checks, for some commands, that the provided MAC
address matches the device MAC
address.
The command \x00\x01
allows retrieving system information from the device, including the device administrative password which is returned in plaintext. For example:
python -c 'print("\x00\x01"* 5)' | nc -u 192.168.1.1 65002
####MAC_ADDRESS####<boardID=D-4P-W><sysVersion=EU_3-10-02-3B00.A2pB022g2.d20h>
<sysModel=DSL-2640B><local_username=admin><local_password=password>
<local_ipaddress=192.168.1.1>
The MAC address check mentioned earlier is not performed for the \x00\x01
command. Any additional bytes are completely ignored which allowed us to identify the vulnerability in a very trivial manner.
In fact, we found this vulnerability using a rather dumb fuzzing campaign. To start, we simply piped /dev/urandom
into UDP
port 65002
. Obviously, we did not think this approach would yield vulnerabilities in any way. Especially because no traffic monitoring, no payload selection and no target debugging were in place. However, surprisingly, the device kindly returned the administrative password within a few minutes…
time cat /dev/urandom | nc -u 192.168.1.1 65002
&ZLM���<boardID=D-4P-W><sysVersion=EU_3-10-02-3B00.A2pB022g2.d20h>
<sysModel=DSL-2640B><local_username=admin><local_password=a>
<local_ipaddress=192.168.1.1>^C
real 2m53.240s
user 0m0.599s
sys 0m21.439s
Due of the (very) forgiving implementation, any UDP
packet with \x00\x01
at the right location would return the administrative password. Even our initial dumb approach yielded the administrative password within minutes.
Our initial test identified the vulnerability is exploitable from the LAN. Nonetheless, the service seems to be listening on all the interfaces (see below).
Unfortunately, we were unable to verify the vulnerability on the WAN side as we lacked a suitable DSL connection. Using the information we have, we cannot exclude that the vulnerability is also exploitable on WAN side. Of course, we would be happy to hear more insight on this.
CVE-2020-9279 – D-Link DSL-2640B - Hard-coded privileged account
For this vulnerability we identified is a hard-coded user account. An attacker may use these credentials to login into the device in order to perform administrative tasks.
The vulnerability was identified by analyzing the authentication process accessible via the web interface. While the cfm
process provides the communication "plumbing", the actual authentication is delegated to an external library libpsi.so
. The library uses an object-oriented approach for handling the authentication credentials and the incoming authentication requests.
An analysis of the cfm
process revealed a code path supporting authentication for the user named user
.
The default
passwords used for authentication are hard-coded in the libpsi.so
binary.
Reverse engineering this library told us that the following default
credentials can be used for logging into the web interface of the device.
Username: user
Password: 00202b004720
Although the password of the user user
can be changed, no web interface control is provided for modifying it. Therefore, this password will be set to its default state for the entire life time of the device. It is important to note that the account is valid for authenticating to any service relying on lipsi.so
, such as ftp
, telnet
and ssh
. As far as we know, the user user
has similar capabilities as the admin
account.
Interestingly, even though libpsi.so
is only released in binary format, the credentials are clearly visible in the GPL source code of the device (see picture below).
Also, interestingly, these credentials are referred to as ASUS_USER_ACCOUNT
. One may wonder how an ASUS related account ends up in a D-Link device.
The source code itself does not reveal any intention of obfuscation. The credentials seem to be valid for other ASUS devices as well. ASUS refers to them as the ASUS Super account
in some old pages.
One could say that it's basically an ASUS feature
( :-) ) which ended up for some unknown reason in a D-Link device. The supply chain of IoT devices are definitely not devoid any mysteries. We believe it may be the result of some "supply chain magic" rather than malicious intent.
The last remark we would like to make is that this vulnerability may be exploited through browser pivoting. A malicious website, visited with any device connected to the WiFi/LAN, may perform crafted requests towards the gateway.
CVE-2020-9278 – D-Link DSL-2640B - Unauthenticated configuration reset
This vulnerability allows an attacker to reset the device to its default configuration by accessing a specific URL. No authentication is required.
In fact, the following URLs can be accessed without authentication.
- rebootinfo.cgi
- ppppasswordinfo.cgi
- qosqueue.cmd?action=savReboot
- restoreinfo.cgi
Specifically, the device can be reset to default factory configuration by simply requesting the following URL:
http://<device_IP_address>/restoreinfo.cgi
An attacker may reset the administrative password to its default value admin
, log in and perform any administrative tasks on the device, such as upload of malicious firmware or configuration of malicious DNS servers.
While the exploitation of this vulnerability requires access to the device LAN interface, it can also be remotely exploited via browser pivoting. An attacker in control of a malicious website may blindly reset the configuration of the device and, under some conditions, take full control of the device.
CVE-2020-9277 – D-Link DSL-2640B - CGI Authentication bypass
The CVE-2020-9277 vulnerability allows bypassing the authentication process for authenticated resources. An attacker may be able to directly access administrative functions of the web interface, without the need to supply valid credentials.
The web server first identifies (1) whether the requested URL
requires authentication. The check is carried on by analyzing the requested file extension, located at the end
of an URL
. For instance, accessing administrative cgi
modules requires authentication. The authentication is not performed immediately but delayed at a later point in the code.
The code then identifies (2) special resources for which the authentication is not necessary. Examples are images or Javascript
utilities. The code matches the start
of an URL
with the specific string (e.g: /images/
, utils.js
) using the strncmp()
function. If a match is found, no authentication is performed, regardless of the outcome of (1). The request is then further processed as it had been successfully authenticated.
Finally, if a cgi
module is requested, the do_cgi()
function determines (3) the module to be executed by searching the module name anywhere
in the URL
, using the
All the above checks act in isolation, no state is carried over. An attacker can then craft malicious URLs for bypassing authentication for cgi
modules. The attack URL below changes the device admin password to newpass without any need for authentication:
Original URL: http://<device_IP_address>/redpass.cgi?sysPassword=newpass
Attack URL: http://<device_IP_address>/images/redpass.cgi?sysPassword=newpass
This vulnerability gives an attacker full device control and allows performing unauthenticated administrative functions. This vulnerability requires accessing the device LAN interface, but it is suitable for exploitation via browser pivoting, allowing for remote attacks over the Internet.
CVE-2020-9276 – D-Link DSL-2640B - do_cgi buffer overflow
This vulnerability is a buffer overflow occurring in the do_cgi()
function, while parsing the requested cgi
module name. An attacker may execute arbitrary code on the device with administrative privileges, by supplying a malicious cgi
module name in the URL.
The do_cgi
function, in order to identify the module to be executed, copies the module name on the stack. However, it does not check whether the length of the supplied module name fits in the allocated buffer (see picture).
A long cgi
module name will overwrite the return address saved on the stack, allowing for a classical stack buffer overflow which is easy to exploit.
The do_cgi()
function can, in principle, only be accessed after authentication. However, unauthenticated exploitation of this vulnerability is possible by combining it with CVE-2020-9277. In the picture below we exploit this vulnerability without authentication, execute a reverse shell payload.
While the vulnerability is potentially exploitable via browser pivoting, exploitation may not be trivial due to the URL mangling introduced by the browser when applying URL encoding on the outgoing requests.