from __future__ import print_function

import sys
import os

from libs.pentestlymodule import PentestlyModule

class Module(PentestlyModule):
    meta = {
        'name': 'User Login',
        'author': 'Cory Duplantis (@ctfhacker)',
        'description': 'Attempts to login to all hosts with port 445 using given credentials.',
        'query': 'SELECT ip_address FROM ports WHERE port=445',
        'options': (
            ('username', '', False, 'Username for login'),
            ('password', '', False, 'Password for login'),
            ('userpass_file', '', False, 'One username/password combo per line, seperated by a space'),
            ('domain', 'WORKGROUP', False, 'Domain to login'),
        ),
    }

    def module_pre(self):
        self.create_table()

    def module_run(self, hosts):
        username = str(self.options['username'])
        password = str(self.options['password'])
        domain = self.options['domain']
        userpass_file = self.options['userpass_file']
        creds = []
        pass_the_hash = False

        if userpass_file:
            if not os.path.exists(userpass_file):
                self.error("File does not exist: {}".format(userpass_file))
                return

            with open(userpass_file, 'r') as f:
                creds = f.read().splitlines()

            creds = [line.split() for line in creds]

        if not username and not password and not userpass_file:
            creds += [('', '')]

        if username or password:
            creds += [(username, password)]

        cache = self.query("SELECT domain,username,password,host FROM pentestly_creds")
        cache = [(str(x[0].lower()), str(x[1].lower()), str(x[2]), str(x[3])) for x in cache]

        self.output("Creds: {}".format(creds))
        for username, password in creds:

            for host in hosts:
                if ':' in password\
                    and len(password.split(':')[0]) == len(password.split(':')[1]) == 32:
                    pass_the_hash = True
                    self.alert("Attempting to pass-the-hash for domain. If local admin, change domain to workgroup")

                # Don't retry to login if tried once
                if (domain.lower(), username.lower(), password, host) in cache:
                    self.output("Already tried logging in with {}:{}@{}, skipping".format(username, password, host))
                    continue

                self.smb.hosts[host] = {'port':445, 'user':username, 'passwd':password, 'domain':domain}
                if pass_the_hash:
                    result = self.smb.login_hash(host, username, password, domain)
                else:
                    result = self.smb.login(host, username, password, domain)
                    
                if result:
                    self.alert('Success - {}:{}@{}'.format(username, password, host))
                else:
                    self.output('Fail - {}:{}@{}'.format(username, password, host))
                self.add_pentestly_creds(host=host, username=username, password=password, domain=domain, success=str(result))

            self.test_execute()
