Recently, we discovered a new zero-day vulnerability in Linksys MR8300 router, affecting the latest version 1.0 of the router’s firmware. After reporting and disclosing the issue with Linksys, the vulnerability was fixed, and the newer firmware version is no longer vulnerable. As a CVE numbering authority, we also reported this issue, now published as CVE-2022-38132, with a CVE score of 8.8.

The vulnerability is an easy-to-exploit Command Injection that can be triggered from the web configuration interface of the router and could allow remote code execution.
In this article, we will present the end-to-end scenario of the vulnerability and the possible exploitation.

Background

Dynamic DNS (DDNS) service is a method of automatically updating a named server in the DNS for devices that change their location, configuration, or IP address frequently. Our router supports this functionality, in its web interface, post-authentication.

Registration to the DDNS service web page looks like this:

The user provides a user name, password, and hostname to register with one of the DDNS providers. After pressing “Ok” the data is sent to the backend, where it is handled by service_ddns.sh bash script on the router.

Code Analysis

In the service_ddns.sh file, the update_noip_server function is responsible for processing the user’s DDNS information and sending the request to the DDNS provider.

The script fetches the username and password provided by the user and fills them into a URL.

Then the curl command line with the former URL is created:

And eventually, the command line is executed:

The Vulnerability

Improper Input sanitization:

The structure of the constructed URL is very similar to the pattern of https://<ip>:<port>, but in this case, the “@” symbol ensures that the web request will be sent to the dynupdate.no-ip.com domain. However, the ‘#’ symbol could be provided as part of the password. ‘#’ marks a comment line in bash and in curl commands, causing everything after it to be ignored.

Providing:

Will yield:

This allows us to create a request to an arbitrary domain and port, only by specifying username and password, while commenting out the original hard coded domain.

This on its own could lead to various security consequences, but it is still not a remote code execution.

 

Uploading File to the Router:

The output of the curl command could be redirected to a file on the file system. By using the “-o” flag of curl, it’s possible to download a file from our server to an arbitrary path on the device.

From curl help prompt:

We can provide the following arguments:

Which will yield:

Causing a file from our server to be downloaded to /tmp/strace path on the device. This allows us to overwrite any file in the router’s file system.

 

Remote Code Execution:

After successfully uploading files from the remote server to the device, our final goal is to obtain reliable code execution on the router.

In the device itself, we found a directory of cron jobs, which run in different constant time intervals.

The directory is

And it’s content is:

Inside the cron.everyminute directory, we found the arp_mon_everyminute.sh bash script file, that is executed every minute on the device.

Providing:

Will yield:

This will overwrite the arp_mon_everyminute.sh file with our script, which will be executed in the router every minute.

However, sending this username and password shows an error message that the password length is too long. Client-side protection against long strings is popular in various web interfaces, yet often possible to bypass, by altering the sent request with tools such as burp suite. Indeed, we saw that in this case, the protection is applied only on the client side, and manually changing the API request made it possible to send the long string of the password to the server.

This way we achieved code execution on the device.

Full Scenario

In our case, we deployed an apache web server at 192.168.1.56 IP, and 5443 port. Accessing to `win.sh` URL on the server will return the following bash script as simple text:

From the router’s web page, using burp suite, we captured the API request to SetDDNSSettings,  and edited it this way:

Resulting with the following request:

We sent the request, and after a minute we saw the newly created file in the router’s file system:

Mitigation for CVE-222-38132

Linksys issued a fix to the vulnerability, in the 1.1 version of their firmware.

The firmware is available to download from this link. It’s recommended to update the device firmware to the newest release version.

Wrap Up

The firmware has a command injection vulnerability, that can be triggered by the user, by providing a specially crafted username and password on the DDNS registration page. This can lead to downloading a file from a malicious remote server, overwriting any file on the router’s file system, and ultimately executing the file on the device using the cron job mechanism.

This is yet another example of the importance of updating the software versions in our connected devices. Continuously scanning the software components that make up our firmware to detect outdated and vulnerable components is critical to ensure the safety of our connected products and devices.

 

About the Author

Roman Kesler

Roman is the VP of Research at Cybellum. On top of being a leading cybersecurity researcher and team leader, Roman has a talent for explaining complex cybersecurity concepts in a simple manner, as seen in his popular video series "Roman Explains".

Did you find this interesting? Share it with others:

< Back to Blog