CyStack Advisory ID CSA-2019-03
CVE IDs CVE-2019-16057
Severity Critical

Synopsis

CyStack Security discovered a remote code execution vulnerability in the D-Link DNS-320 ShareCenter device which its version is lower or equal 2.05.B10 . By exploiting the vulnerability, a remote, unauthenticated attacker can access to all application commands with root permission. This device is a popular network storage device and interestingly, in the past, it was also reported that it contains a backdoor itself.

Details

While doing some research on network devices we found a command injection vulnerability at the login module of a D-Link DNS-320 device. The flaw exists at a hidden feature called SSL Login which its required parameter, port, can be poisoned.

Login interface

In this article, I will show how we found out the flaw and analyze what happened in the old version of the firmware.

Extract firmware

Firstly, we download the firmware

$ mkdir /tmp/dns_320 && cd mkdir /tmp/dns_320
$ wget ftp://ftp2.dlink.com/SECURITY_ADVISEMENTS/DNS-320/DNS-320_REVA_FIRMWARE_PATCH_2.05.B10.ZIP
$ unzip DNS-320_REVA_FIRMWARE_PATCH_2.05.B10.ZIP

Next, we use Binwalk and Firmware Modification Kit to extract it

# If you do not have these tools, install them first
$ sudo apt-get install git build-essential zlib1g-dev liblzma-dev bsdmainutils python
$ wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/firmware-mod-kit/fmk_099.tar.gz
$ tar -xvf fmk_099.tar.gz fmk/
$ cd fmk/src/others/ && make && cd -
$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ python3 get-pip.py
$ git clone https://github.com/ReFirmLabs/binwalk.git && cd binwalk && python3 setup.py install && cd -
$ binwalk -eM DLINK_DNS320.2.05b10\(2.13.0226.2016\)
$ ./fmk/unsquashfs_all.sh _DLINK_DNS320.2.05b10\(2.13.0226.2016\).extracted/3F5020.squashfs

# All binaries are now in the following folder
$ cd squashfs-root/

Analysis

Our target binary is /cgi/login_mgr.cgi which handles login requests. We focus on function cgiMain()

Firstly, if the parameter cmd equals "login" then sub_9958 will be called

Function cgiMain() calls sub_9958()

sub_9924() will be called with parameter port

Let's take a look at sub_9924(). We can see that if an attacker control parameter v1 which is port, he will be able to arbitrarily execute commands, which is the key point in this vulnerability

Exploitation

By poisoning the parameter port, we can perform an RCE attack like below

Fixing

D-Link team released a patch for this issue on 11/04/2019. According to their release notes, the patch is for login_mgr.cgi allows attackers pipe commands to the user.log.  I don't know exactly what issue they found related to the flaw I'm addressing in this article, but the patch worked. They fixed it by type casting parameter port to Integer.

Timeline

  • 14/08/2019 - CyStack reports to D-Link team
  • 15/08/2019 - CyStack gets the first response from D-Link team and asks they some information
  • 06/09/2019 - D-Link team confirms this issue and works on a patch
  • 07/09/2019 - CVE-2019-16057 is assigned for the vulnerability (reserved status)
  • 11/09/2019 - D-Link team includes this CVE to their release notes and allows CyStack to disclose the issue.