Talos Vulnerability Report

TALOS-2024-1953

MC Technologies MC LR Router web interface I/O configuration OS command injection vulnerabilities

November 21, 2024
CVE Number

CVE-2024-28027,CVE-2024-28025,CVE-2024-28026

SUMMARY

Three OS command injection vulnerabilities exist in the web interface I/O configuration functionality of MC Technologies MC LR Router 2.10.5. A specially crafted HTTP request can lead to arbitrary command execution. An attacker can make an authenticated HTTP request to trigger these vulnerabilities.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

MC Technologies MC LR Router 2.10.5 (QEMU)

PRODUCT URLS

MC LR Router - https://mc-technologies.com/en/produkt/100800/

CVSSv3 SCORE

7.2 - CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

CWE

CWE-78 - Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’)

DETAILS

The MC LR Router from MC Technologies comes in two-port and four-port variants, as well as models that support transparent serial-to-TCP translations and 1-in/1-out digital I/O. The router boasts support for IPsec and and OpenVPN VPN implementations, firewall capabilities, remote management via HTTP and SNMP, and configurable alerting via SMS and email.

The MC-LR Industrial Router from MC Technologies comes in two-port and four-port variants, as well as models that support transparent serial-to-TCP translations and 1-in/1-out digital I/O. The router boasts support for IPsec and and OpenVPN VPN implementations, firewall capabilities, remote management via HTTP and SNMP, and configurable alerting via SMS and email.

The MC LR router can be configured via a locally-hosted HTTP interface. The HTTP server in use is busybox’s httpd, hosting a variety of cgi-bin files written in C. There are three authenticated OS command injection vulnerabilities in the cgi-bin file responsible for handling configuration and control of the various I/O on the device. User input provided via three distinct HTTP parameters can be injected directly into OS commands that are called with root privileges via calls to system.

The vulnerable file is located at /wbm/cgi-bin/p/adm/io and is accessible via HTTP at the URI /cgi-bin/p/adm/io. The vulnerable function, which we refer to as form_handler, begins at offset 0x8cec. This function is responsible for handling HTTP requests made to the io endpoint. A partial, annotated decompilation is included below for reference.

int form_handler(
    struct cgi* cgi,
    struct param* params,
    int num_params,
    REQUEST_TYPE req_type,
) {
    if (num_params > 0)
    {
        param_t* current_param = params;
        int num_parsed_params = 0;
        // [1] For each HTTP parameter ...
        do
        {
        	if (req_type == GET)
        	{
                int io_idx = -1;
                char** command;
                int command_status = 0;

     // [2] Craft unique commands based on whether the parameter was titled `btn`, `out`, or `timer`
              ...

It is at this point in the function where the first of the three vulnerabilities arise. This section of the function acts almost like a switch-case over the possible parameters (btn1, out1, timer1), using each to construct a slightly different OS command and execute it.

CVE-2024-28025 - btn1 parameter

int btn_ret = sscanf(current_param->key, "btn%u", &io_idx);
if (btn_ret == 1 && io_idx == 1)
{
    // [3] If the key was `btn1` then inject the attacker-controlled value into the command and execute it
    if (asprintf(&command, "/usr/sbin/vout %s %u vo_manual", current_param->value, 1) > 0)
    {
        system(command);
        return -1;
    }
}

Note that if the current parameter is btn1 then both btn_ret and io_idx will be 1, satisfying the conditional. Inside the conditional, an OS command is constructed using the provided value of the parameter and the command is executed.

CVE-2024-28026 - out1 parameter

int out_ret = sscanf(current_param->key, "out%u", &io_idx);
if (out_ret == 1 && io_idx == 1)
{
    // [4] Similar to `3`, but `out1` instead of `btn1`
    if (asprintf(&command, "/usr/sbin/vout %s %u vo_manual", current_param->value, 1) > 0)
    {
        system(command);
        return -1;
    }
}

Note that if the current parameter is out1 then both out_ret and io_idx will be 1, satisfying the conditional. Inside the conditional, an OS command is constructed using the provided value of the parameter and the command is executed.

CVE-2024-28027 - timer1 parameter

int timer_ret = sscanf(current_param->key, "timer%u", &io_idx);
if (timer_ret == 1 && io_idx == 1)
{
    // [5] Similar to `[3]` and `[4]`, but `timer1` instead of `btn1` or `out1`
    if (asprintf(&command, "/usr/sbin/vout oneshot %u %s", 1, current_param->value) > 0)
    {
        system(command);
        return -1;
    }
}

Note that if the current parameter is timer1 then both timer_ret and io_idx will be 1, satisfying the conditional. Inside the conditional, an OS command is constructed using the provided value of the parameter and the command is executed.

It is important for us to state that in the above decompilations we excluded a significant amount of HTML generation that, for the purposes of this report, only increased clutter and difficulty in understanding the vulnerable code. As indicated previously, there are three distinct parameters that can cause unique command injections - btn1, out1 and timer1. Respectively, the vulnerable calls to system are crafted at [3], [4], and [5] with very little differentiation. The attacker controlled value of those parameters is injected directly into the shell command without sanitization, and will be executed with root privileges.

TIMELINE

2024-03-07 - Initial Vendor Contact
2024-03-12 - Vendor Disclosure
2024-04-02 - Request confirmation of receipt
2024-05-15 - Announcement of upcoming 90 day period expiration sent to vendor
2024-06-04 - Phone call to vendor. Vendor Disclosure sent to different recipient.
2024-06-24 - Email from vendor. Content unclear. Matter potentially resolved.
2024-07-02 - Status request sent to vendor
2024-08-21 - Announcement of upcoming 90 day period expiration sent to vendor
2024-09-03 - Upcoming release announcement
2024-11-21 - Public Release

Credit

Discovered by Matt Wiseman of Cisco Talos.