Collecting Shells by the Sea of NAS Vulnerabilities

Steps we took to control any Lenovo ix4–300d remotely

Over the last couple months, ISE Labs has conducted a research project where we have been looking into the security of embedded devices. Our research focused on identifying vulnerabilities in network accessible services; our goal was to identify vulnerabilities that would allow us to weaponize the device. This blog post covers some of the vulnerabilities we identified in the Lenovo ix4–300d, an enterprise Network Attached Storage device (NAS). In this post, we will cover how we identified vulnerabilities and created a workflow that grants attackers the ability remotely exploit this device. This blog will approach our end goal from a down-up perspective. First, we will figure out a way to get a shell on the device. Then, we will begin hunting down the individual pieces we will need to make it remotely exploitable. Without further ado, here is how you can stack some of the vulnerabilities we identified in the Lenovo ix4–300d to get a remotely accessible root shell.

Step 1. Find OS Command Injection (Get a shell)

Most of the devices we audited during our research had some sort of OS command injection vulnerability. The ix4–300d was no exception. When testing for OS command injection, I typically start with functionality that needs to interact with the operating system. This means that I will prioritize functionality that allows the owner to ping devices, enable/configure other services, or read/write files. Using this methodology we identified (CVE-2018–9074, CVE-2018–9075, CVE-2018–9076, CVE-2018–9077, CVE-2018–9078, CVE-2018–9079, CVE-2018–9080, CVE-2018–9081, CVE-2018–9082)

Below is the POST request used in CVE-2018–9075 to exploit one of the OS command injection vulnerabilities we identified. In the password field we have a payload that allows us to open up a netcat listener on port 9000. When we connect to the listener the listening application (/bin/sh) is executed.

POST /cp/PersonalCloudJoin?v=2.3&__c=51701623682412972 HTTP/1.1

Host: 192.168.1.34

Content-Type: application/x-www-form-urlencoded

Content-Length: 177

Cookie: iomega=1766419671992842405

Connection: close client%3Acloudname=TEST&client%3Ausername=rramgattie&client%3Apassword=%2560nc%2520-lp%25209000%2520-e%2520%252Fbin%252Fsh%2560&client%3Adescription=%27&client%3Aencryption=none

There is a common setback with all of the command injections we found on this device. They all require both the __c and iomega tokens of a valid user. We can get around the cookie (iomega) requirement easily with cross-site request forgery (CSRF), but that won’t help us with that pesky __c parameter in the URL. The __c parameter is generated when the user logs into the ix4–300d web application, and stored in the browser’s Local Storage.

If we want to exploit this OS command injection we are going to need to figure out how these tokens are generated or access to the victim’s iomegaUserCookie (__c) token. Whenever I think about stealing some type of value stored in the user’s browser I think about cross-site scripting (XSS). Next step? Find some XSS.

Step 2. Time to find some XSS

When I test for reflected XSS I go through my sitemap and look for all requests that have parameters that end up in the server’s response. Then, I manually go through each of the requests in that subset and look for requests that end up in the server’s response without modification. This methodology found us many instances of XSS in the ix4–300d. Most of the instances we identified made use of the cat URL parameter. Below is an example URL that opens an alert box when visited by an authenticated user.

http://192.168.1.45/manage/security.html?cat=%22%3e%3cscript%3ealert(‘ISE’)%3c%2fscript%3e

To make our attack easier we are going to save the code below into a script and include it as the src of a script tag. For our testing we used python’s SimpleHTTPServer module to host the file. We would have also stolen the user’s iomega cookie, but it is set with the HTTPOnly flag so we cannot access it with JavaScript. However, when the request is sent by the included malicious script, the browser will send the user’s cookies along. Thanks Same-Origin Policy.

Step 3. Mix it all together

Combining these issues we can now carry out a remote attack against a targeted ix4–300d.

1. Steal the user’s iomegaUserCookie from their localStorage through cross-site scripting by tricking the user into visiting our malicious URL.

2. Use the stolen iomegaUserCookie as a URL parameter, where we will exploit the lack of a proper CSRF mitigation to POST our request to join a PersonalCloud.

3. Include our OS command injection payload in the password field.

The JavaScript file below does all of this nicely in a single file.