Exemple #1
0
    def call_modules(self):
        module_logger = CMEAdapter(
            extra={
                'module': self.module.name.upper(),
                'host': self.host,
                'port': self.args.port,
                'hostname': self.hostname
            })

        context = Context(self.db, module_logger, self.args)
        context.localip = self.local_ip

        if hasattr(self.module, 'on_request') or hasattr(
                self.module, 'has_response'):
            self.server.connection = self
            self.server.context.localip = self.local_ip

        if hasattr(self.module, 'on_login'):
            self.module.on_login(context, self)

        if self.admin_privs and hasattr(self.module, 'on_admin_login'):
            self.module.on_admin_login(context, self)

        if (not hasattr(self.module, 'on_request')
                and not hasattr(self.module, 'has_response')) and hasattr(
                    self.module, 'on_shutdown'):
            self.module.on_shutdown(context, self)
    def init_module(self, module_path):

        module  = None
        server  = None
        context = None

        module = self.load_module(module_path)

        if module:
            module_logger = CMEAdapter(getLogger('CME'), {'module': module.name.upper()})
            context = Context(self.db, module_logger, self.args)

            module_options = {}

            for option in self.args.module_options:
                key, value = option.split('=', 1)
                module_options[str(key).upper()] = value

            module.options(context, module_options)

            if hasattr(module, 'on_request') or hasattr(module, 'has_response'):

                if hasattr(module, 'required_server'):
                    args.server = getattr(module, 'required_server')

                if not self.server_port:
                    self. server_port = self.args.server_port

                server = CMEServer(module, context, self.logger, self.args.server_host, self.server_port, self.args.server)
                server.start()

            return module, context, server
Exemple #3
0
    def init_module_chain(self):
        server_port_dict = {'http': 80, 'https': 443}
        modules = self.get_modules()

        #Initialize all modules specified in the chain command and add the objects to chain_list
        for chained_module in self.chain_list:
            for module in modules:
                if module.lower() == chained_module['name'].lower():
                    chained_module['object'] = self.load_module(
                        modules[module]['path'])

        for module in self.chain_list:
            module_logger = CMEAdapter(getLogger('CME'),
                                       {'module': module['name'].upper()})
            context = Context(self.db, module_logger, self.args)

            if module['object'] != self.chain_list[-1]['object']:
                module['options']['COMMAND'] = 'dont notice me senpai'
            getattr(module['object'], 'options')(context, module['options'])

            if hasattr(module['object'], 'required_server'):
                self.args.server = getattr(module['object'], 'required_server')

        if not self.args.server_port:
            self.args.server_port = server_port_dict[self.args.server]

        if self.is_module_chain_sane():
            server_logger = CMEAdapter(getLogger('CME'),
                                       {'module': 'CMESERVER'})
            context = Context(self.db, server_logger, self.args)

            server = CMEChainServer(self.chain_list, context, self.logger,
                                    self.args.server_host,
                                    self.args.server_port, self.args.server)
            server.start()
            return self.chain_list, server

        return None, None
Exemple #4
0
    def call_modules(self):
        module_logger = CMEAdapter(extra={
                                          'module': self.module.name.upper(),
                                          'host': self.host,
                                          'port': self.args.port,
                                          'hostname': self.hostname
                                         })

        context = Context(self.db, module_logger, self.args)
        context.localip  = self.local_ip

        if hasattr(self.module, 'on_request') or hasattr(self.module, 'has_response'):
            self.server.connection = self
            self.server.context.localip = self.local_ip

        if hasattr(self.module, 'on_login'):
            self.module.on_login(context, self)

        if self.admin_privs and hasattr(self.module, 'on_admin_login'):
            self.module.on_admin_login(context, self)

        if (not hasattr(self.module, 'on_request') and not hasattr(self.module, 'has_response')) and hasattr(self.module, 'on_shutdown'):
            self.module.on_shutdown(context, self)
Exemple #5
0
    def proto_flow(self):
        if self.create_conn_obj():
            self.enum_host_info()
            self.proto_logger()
            self.print_host_info()
            self.login()
            if hasattr(self.args, 'module') and self.args.module:
                module_logger = CMEAdapter(
                    extra={
                        'module': self.module.name.upper(),
                        'host': self.host,
                        'port': self.args.smb_port,
                        'hostname': self.hostname
                    })

                context = Context(self.db, module_logger, self.args)
                context.localip = self.local_ip

                if hasattr(self.module, 'on_request') or hasattr(
                        self.module, 'has_response'):
                    self.server.connection = self
                    self.server.context.localip = self.local_ip

                if hasattr(self.module, 'on_login'):
                    self.module.on_login(context, self)

                if self.admin_privs and hasattr(self.module, 'on_admin_login'):
                    self.module.on_admin_login(context, self)

                if (not hasattr(self.module, 'on_request') and
                        not hasattr(self.module, 'has_response')) and hasattr(
                            self.module, 'on_shutdown'):
                    self.module.on_shutdown(context, self)

            else:
                self.call_cmd_args()
    def init_module(self, module_path):

        module = None

        module = self.load_module(module_path)

        if module:
            module_logger = CMEAdapter(extra={'module': module.name.upper()})
            context = Context(self.db, module_logger, self.args)

            module_options = {}

            for option in self.args.module_options:
                key, value = option.split('=', 1)
                module_options[str(key).upper()] = value

            module.options(context, module_options)

        return module
Exemple #7
0
    def init_module(self, module_path):

        module = None
        server = None
        context = None
        server_port_dict = {'http': 80, 'https': 443}

        module = self.load_module(module_path)

        if module:
            module_logger = CMEAdapter(getLogger('CME'),
                                       {'module': module.name.upper()})
            context = Context(self.db, module_logger, self.args)

            module_options = {}

            for option in self.args.module_options:
                if '=' not in option:
                    self.logger.error(
                        'All module options should be in KEY=VALUE format, use the --show-options flag to view available module options'
                    )
                    sys.exit(1)

                key, value = option.split('=', 1)
                module_options[str(key).upper()] = value

            module.options(context, module_options)

            if hasattr(module, 'on_request') or hasattr(
                    module, 'has_response'):

                if hasattr(module, 'required_server'):
                    self.args.server = getattr(module, 'required_server')

                if not self.args.server_port:
                    self.args.server_port = server_port_dict[self.args.server]

                server = CMEServer(module, context, self.logger,
                                   self.args.server_host,
                                   self.args.server_port, self.args.server)
                server.start()

            return module, context, server
Exemple #8
0
def connector(target, args, db, module, context, cmeserver):

    try:

        smb = SMBConnection(target, target, None, args.smb_port)

        #Get our IP from the socket
        local_ip = smb.getSMBServer().get_socket().getsockname()[0]

        #Get the remote ip address (in case the target is a hostname) 
        remote_ip = smb.getRemoteHost()

        try:
            smb.login('' , '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain     = smb.getServerDomain()
        servername = smb.getServerName()
        serveros   = smb.getServerOS()

        if not domain:
            domain = servername

        db.add_host(remote_ip, servername, domain, serveros)

        logger = CMEAdapter(getLogger('CME'), {'host': remote_ip, 'port': args.smb_port, 'hostname': u'{}'.format(servername)})

        logger.info(u"{} (name:{}) (domain:{})".format(serveros, servername.decode('utf-8'), domain.decode('utf-8')))

        try:
            '''
                DC's seem to want us to logoff first
                Windows workstations sometimes reset the connection, so we handle both cases here
                (go home Windows, you're drunk)
            '''
            smb.logoff()
        except NetBIOSError:
            pass
        except socket.error:
            pass

        if args.mssql:
            instances = None
            logger.extra['port'] = args.mssql_port
            ms_sql = tds.MSSQL(target, args.mssql_port, logger)
            ms_sql.connect()

            instances = ms_sql.getInstances(10)
            if len(instances) > 0:
                logger.info("Found {} MSSQL instance(s)".format(len(instances)))
                for i, instance in enumerate(instances):
                    logger.highlight("Instance {}".format(i))
                    for key in instance.keys():
                        logger.highlight(key + ":" + instance[key])

            try:
                ms_sql.disconnect()
            except:
                pass

        if args.username and (args.password or args.hash):
            conn = None

            if args.mssql and (instances is not None and len(instances) > 0):
                conn = tds.MSSQL(target, args.mssql_port, logger)
                conn.connect()
            elif not args.mssql:
                conn = SMBConnection(target, target, None, args.smb_port)

            if conn is None:
                return

            if args.domain:
                domain = args.domain

            connection = Connection(args, db, target, servername, domain, conn, logger, cmeserver)

            if (connection.password is not None or connection.hash is not None) and connection.username is not None:
                if module is not None:

                    module_logger = CMEAdapter(getLogger('CME'), {'module': module.name.upper(), 'host': remote_ip, 'port': args.smb_port, 'hostname': servername})
                    context = Context(db, module_logger, args)
                    context.localip  = local_ip

                    if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
                        cmeserver.server.context.localip = local_ip

                    if hasattr(module, 'on_login'):
                        module.on_login(context, connection)

                    if hasattr(module, 'on_admin_login') and connection.admin_privs:
                        module.on_admin_login(context, connection)
                else:
                    if connection.admin_privs and (args.pscommand or args.command):

                        get_output = True if args.no_output is False else False
                        if args.mssql: args.exec_method = 'mssqlexec'

                        if args.command:
                            output = connection.execute(args.command, get_output=get_output)

                        if args.pscommand:
                            output = connection.execute(create_ps_command(args.pscommand), get_output=get_output)

                        logger.success('Executed command {}'.format('via {}'.format(args.exec_method) if args.exec_method else ''))
                        buf = StringIO(output).readlines()
                        for line in buf:
                            logger.highlight(line.strip())

                    if args.mssql and args.mssql_query:
                        conn.sql_query(args.mssql_query)
                        query_output = conn.printRows()
                        
                        logger.success('Executed MSSQL query')
                        buf = StringIO(query_output).readlines()
                        for line in buf:
                            logger.highlight(line.strip())

                    elif not args.mssql:

                        if connection.admin_privs and (args.sam or args.lsa or args.ntds):
                            secrets_dump = DumpSecrets(connection, logger)

                            if args.sam:
                                secrets_dump.SAM_dump()

                            if args.lsa:
                                secrets_dump.LSA_dump()

                            if args.ntds:
                                secrets_dump.NTDS_dump(args.ntds, args.ntds_pwdLastSet, args.ntds_history)

                        if connection.admin_privs and args.wdigest:
                            w_digest = WDIGEST(logger, connection.conn)

                            if args.wdigest == 'enable':
                                w_digest.enable()

                            elif args.wdigest == 'disable':
                                w_digest.disable()

                        if connection.admin_privs and args.uac:
                            UAC(connection.conn, logger).enum()

                        if args.spider:
                            spider = SMBSpider(logger, connection, args)
                            spider.spider(args.spider, args.depth)
                            spider.finish()

                        if args.enum_shares:
                            ShareEnum(connection.conn, logger).enum()

                        if args.enum_lusers or args.enum_disks or args.enum_sessions:
                            rpc_connection = RPCQUERY(connection, logger)

                            if args.enum_lusers:
                                rpc_connection.enum_lusers()

                            if args.enum_sessions:
                                rpc_connection.enum_sessions()

                            if args.enum_disks:
                                rpc_connection.enum_disks()

                        if args.pass_pol:
                            PassPolDump(logger, args.smb_port, connection).enum()

                        if args.enum_users:
                            SAMRDump(logger, args.smb_port, connection).enum()

                        if connection.admin_privs and args.wmi_query:
                            WMIQUERY(logger, connection, args.wmi_namespace).query(args.wmi_query)

                        if args.rid_brute:
                            LSALookupSid(logger, args.smb_port, connection, args.rid_brute).brute_force()

    except socket.error:
        return
def main():
    first_run_setup(logger)

    args = gen_cli_args()

    if args.darrell:
        links = open(
            os.path.join(os.path.dirname(cme.__file__), 'data',
                         'videos_for_darrell.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
        except:
            sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    config = configparser.ConfigParser()
    config.read(os.path.join(cme_path, 'cme.conf'))

    module = None
    module_server = None
    targets = []
    jitter = None
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = config.get('CME', 'workspace')

    if args.verbose:
        setup_debug_logger()

    logging.debug('Passed args:\n' + pformat(vars(args)))

    if args.jitter:
        if '-' in args.jitter:
            start, end = args.jitter.split('-')
            jitter = (int(start), int(end))
        else:
            jitter = (0, int(args.jitter))

    if hasattr(args, 'cred_id') and args.cred_id:
        for cred_id in args.cred_id:
            if '-' in str(cred_id):
                start_id, end_id = cred_id.split('-')
                try:
                    for n in range(int(start_id), int(end_id) + 1):
                        args.cred_id.append(n)
                    args.cred_id.remove(cred_id)
                except Exception as e:
                    logger.error(
                        'Error parsing database credential id: {}'.format(e))
                    sys.exit(1)

    if hasattr(args, 'target') and args.target:
        for target in args.target:
            if os.path.exists(target):
                target_file_type = identify_target_file(target)
                if target_file_type == 'nmap':
                    targets.extend(parse_nmap_xml(target, args.protocol))
                elif target_file_type == 'nessus':
                    targets.extend(parse_nessus_file(target, args.protocol))
                else:
                    with open(target, 'r') as target_file:
                        for target_entry in target_file:
                            targets.extend(parse_targets(target_entry.strip()))
            else:
                targets.extend(parse_targets(target))

    # The following is a quick hack for the powershell obfuscation functionality, I know this is yucky
    if hasattr(args, 'clear_obfscripts') and args.clear_obfscripts:
        shutil.rmtree(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        os.mkdir(os.path.expanduser('~/.cme/obfuscated_scripts/'))
        logger.success('Cleared cached obfuscated PowerShell scripts')

    if hasattr(args, 'obfs') and args.obfs:
        powershell.obfuscate_ps_scripts = True

    p_loader = protocol_loader()
    protocol_path = p_loader.get_protocols()[args.protocol]['path']
    protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath']

    protocol_object = getattr(p_loader.load_protocol(protocol_path),
                              args.protocol)
    protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path),
                                 'database')

    db_path = os.path.join(cme_path, 'workspaces', current_workspace,
                           args.protocol + '.db')
    # set the database connection to autocommit w/ isolation level
    db_connection = sqlite3.connect(db_path, check_same_thread=False)
    db_connection.text_factory = str
    db_connection.isolation_level = None
    db = protocol_db_object(db_connection)

    setattr(protocol_object, 'config', config)

    if hasattr(args, 'module'):

        loader = module_loader(args, db, logger)

        if args.list_modules:
            modules = loader.get_modules()

            for name, props in sorted(modules.items()):
                logger.info('{:<25} {}'.format(name, props['description']))
            sys.exit(0)

        elif args.module and args.show_module_options:

            modules = loader.get_modules()
            for name, props in modules.items():
                if args.module.lower() == name.lower():
                    logger.info('{} module options:\n{}'.format(
                        name, props['options']))
            sys.exit(0)

        elif args.module:
            modules = loader.get_modules()
            for name, props in modules.items():
                if args.module.lower() == name.lower():
                    module = loader.init_module(props['path'])
                    setattr(protocol_object, 'module', module)
                    break

            if not module:
                logger.error('Module not found')
                exit(1)

            if getattr(module, 'opsec_safe') is False:
                ans = input(
                    highlight(
                        '[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ',
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if getattr(module, 'multiple_hosts') is False and len(targets) > 1:
                ans = input(
                    highlight(
                        "[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ",
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if hasattr(module, 'on_request') or hasattr(
                    module, 'has_response'):

                if hasattr(module, 'required_server'):
                    args.server = getattr(module, 'required_server')

                if not args.server_port:
                    args.server_port = server_port_dict[args.server]

                context = Context(db, logger, args)
                module_server = CMEServer(module, context, logger,
                                          args.server_host, args.server_port,
                                          args.server)
                module_server.start()
                setattr(protocol_object, 'server', module_server.server)

    try:
        asyncio.run(
            start_threadpool(protocol_object, args, db, targets, jitter))
    except KeyboardInterrupt:
        logging.debug("Got keyboard interrupt")
    finally:
        if module_server:
            module_server.shutdown()
Exemple #10
0
def main():

    setup_logger()
    logger = CMEAdapter()
    first_run_setup(logger)

    args = gen_cli_args()

    if args.darrell:
        links = open(
            os.path.join(os.path.dirname(cme.__file__), 'data',
                         'videos_for_darrell.harambe')).read().splitlines()
        try:
            webbrowser.open(random.choice(links))
        except:
            sys.exit(1)

    cme_path = os.path.expanduser('~/.cme')

    config = ConfigParser()
    config.read(os.path.join(cme_path, 'cme.conf'))

    module = None
    module_server = None
    targets = []
    jitter = None
    server_port_dict = {'http': 80, 'https': 443, 'smb': 445}
    current_workspace = config.get('CME', 'workspace')

    if args.verbose:
        setup_debug_logger()

    logging.debug('Passed args:\n' + pformat(vars(args)))

    if args.jitter:
        if '-' in args.jitter:
            start, end = args.jitter.split('-')
            jitter = (int(start), int(end))
        else:
            jitter = (0, int(args.jitter))

    if hasattr(args, 'username') and args.username:
        for user in args.username:
            if os.path.exists(user):
                args.username.remove(user)
                args.username.append(open(user, 'r'))

    if hasattr(args, 'password') and args.password:
        for passw in args.password:
            if os.path.exists(passw):
                args.password.remove(passw)
                args.password.append(open(passw, 'r'))

    elif hasattr(args, 'hash') and args.hash:
        for ntlm_hash in args.hash:
            if os.path.exists(ntlm_hash):
                args.hash.remove(ntlm_hash)
                args.hash.append(open(ntlm_hash, 'r'))

    if hasattr(args, 'cred_id') and args.cred_id:
        for cred_id in args.cred_id:
            if '-' in str(cred_id):
                start_id, end_id = cred_id.split('-')
                try:
                    for n in range(int(start_id), int(end_id) + 1):
                        args.cred_id.append(n)
                    args.cred_id.remove(cred_id)
                except Exception as e:
                    logger.error(
                        'Error parsing database credential id: {}'.format(e))
                    sys.exit(1)

    if hasattr(args, 'target') and args.target:
        for target in args.target:
            if os.path.exists(target):
                with open(target, 'r') as target_file:
                    for target_entry in target_file:
                        targets.extend(parse_targets(target_entry))
            else:
                targets.extend(parse_targets(target))

    p_loader = protocol_loader()
    protocol_path = p_loader.get_protocols()[args.protocol]['path']
    protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath']

    protocol_object = getattr(p_loader.load_protocol(protocol_path),
                              args.protocol)
    protocol_db_object = getattr(p_loader.load_protocol(protocol_db_path),
                                 'database')

    db_path = os.path.join(cme_path, 'workspaces', current_workspace,
                           args.protocol + '.db')
    # set the database connection to autocommit w/ isolation level
    db_connection = sqlite3.connect(db_path, check_same_thread=False)
    db_connection.text_factory = str
    db_connection.isolation_level = None
    db = protocol_db_object(db_connection)

    if hasattr(args, 'module'):

        loader = module_loader(args, db, logger)

        if args.list_modules:
            modules = loader.get_modules()

            for m in modules:
                logger.info('{:<25} {}'.format(m, modules[m]['description']))
            sys.exit(0)

        elif args.module and args.show_module_options:

            modules = loader.get_modules()
            for m in modules.keys():
                if args.module.lower() == m.lower():
                    logger.info('{} module options:\n{}'.format(
                        m, modules[m]['options']))
            sys.exit(0)

        elif args.module:
            modules = loader.get_modules()
            for m in modules.keys():
                if args.module.lower() == m.lower():
                    module = loader.init_module(modules[m]['path'])
                    setattr(protocol_object, 'module', module)
                    break

            if not module:
                logger.error('Module not found')
                exit(1)

            if getattr(module, 'opsec_safe') is False:
                ans = raw_input(
                    highlight(
                        '[!] Module is not opsec safe, are you sure you want to run this? [Y/n]',
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if getattr(module, 'multiple_hosts') is False and len(targets) > 1:
                ans = raw_input(
                    highlight(
                        "[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n]",
                        'red'))
                if ans.lower() not in ['y', 'yes', '']:
                    sys.exit(1)

            if hasattr(module, 'on_request') or hasattr(
                    module, 'has_response'):

                if hasattr(module, 'required_server'):
                    args.server = getattr(module, 'required_server')

                if not args.server_port:
                    args.server_port = server_port_dict[args.server]

                context = Context(db, logger, args)
                module_server = CMEServer(module, context, logger,
                                          args.server_host, args.server_port,
                                          args.server)
                module_server.start()
                setattr(protocol_object, 'server', module_server.server)

    try:
        '''
            Open all the greenlet (as supposed to redlet??) threads
            Whoever came up with that name has a fetish for traffic lights
        '''
        pool = Pool(args.threads)
        jobs = []
        for target in targets:
            jobs.append(pool.spawn(protocol_object, args, db, str(target)))

            if jitter:
                value = random.choice(range(jitter[0], jitter[1]))
                logging.debug(
                    "Doin' the Jitterbug for {} seconds".format(value))
                sleep(value)

        for job in jobs:
            job.join(timeout=args.timeout)
    except KeyboardInterrupt:
        pass

    if module_server: module_server.shutdown()
    def __init__(self, args, db, host, module, cmeserver):
        self.args = args
        self.db = db
        self.host = host
        self.module = module
        self.cmeserver = cmeserver
        self.conn = None
        self.hostname = None
        self.domain = None
        self.server_os = None
        self.logger = None
        self.password = None
        self.username = None
        self.hash = None
        self.admin_privs = False
        self.failed_logins = 0

        try:
            smb = SMBConnection(self.host, self.host, None, self.args.smb_port)

            #Get our IP from the socket
            local_ip = smb.getSMBServer().get_socket().getsockname()[0]

            #Get the remote ip address (in case the target is a hostname)
            remote_ip = smb.getRemoteHost()

            try:
                smb.login('' , '')
            except SessionError as e:
                if "STATUS_ACCESS_DENIED" in e.message:
                    pass

            self.host = remote_ip
            self.domain   = smb.getServerDomain()
            self.hostname = smb.getServerName()
            self.server_os = smb.getServerOS()

            if not self.domain:
                self.domain = self.hostname

            self.db.add_host(self.host, self.hostname, self.domain, self.server_os)

            self.logger = CMEAdapter(getLogger('CME'), {
                                                        'host': self.host,
                                                        'port': self.args.smb_port,
                                                        'hostname': u'{}'.format(self.hostname)
                                                       })

            self.logger.info(u"{} (name:{}) (domain:{})".format(
                                                                self.server_os,
                                                                self.hostname.decode('utf-8'),
                                                                self.domain.decode('utf-8')
                                                                ))

            try:
                '''
                    DC's seem to want us to logoff first, windows workstations sometimes reset the connection
                    (go home Windows, you're drunk)
                '''
                smb.logoff()
            except:
                pass

            if self.args.mssql:
                instances = None
                self.logger.extra['port'] = self.args.mssql_port

                mssql = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                mssql.connect()

                instances = mssql.getInstances(10)
                if len(instances) > 0:
                    self.logger.info("Found {} MSSQL instance(s)".format(len(instances)))
                    for i, instance in enumerate(instances):
                        self.logger.highlight("Instance {}".format(i))
                        for key in instance.keys():
                            self.logger.highlight(key + ":" + instance[key])

                try:
                    mssql.disconnect()
                except:
                    pass

            if (self.args.username and (self.args.password or self.args.hash)) or self.args.cred_id:

                if self.args.mssql and (instances is not None and len(instances) > 0):
                    self.conn = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                    self.conn.connect()

                elif not args.mssql:
                    self.conn = SMBConnection(self.host, self.host, None, self.args.smb_port)

        except socket.error:
            pass

        if self.conn:
            if self.args.domain:
                self.domain = self.args.domain

            if self.args.local_auth:
                self.domain = self.hostname

            self.login()

            if ((self.password is not None or self.hash is not None) and self.username is not None):

                if self.module:
                    module_logger = CMEAdapter(getLogger('CME'), {
                                                                  'module': module.name.upper(),
                                                                  'host': self.host,
                                                                  'port': self.args.smb_port,
                                                                  'hostname': self.hostname
                                                                 })
                    context = Context(self.db, module_logger, self.args)
                    context.localip  = local_ip

                    if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
                        cmeserver.server.context.localip = local_ip

                    if hasattr(module, 'on_login'):
                        module.on_login(context, self)

                    if hasattr(module, 'on_admin_login') and self.admin_privs:
                        module.on_admin_login(context, self)

                elif self.module is None:
                    for k, v in vars(self.args).iteritems():
                        if hasattr(self, k) and hasattr(getattr(self, k), '__call__'):
                            if v is not False and v is not None:
                                getattr(self, k)()
    def __init__(self, args, db, host, module, chain_list, cmeserver, share_name):
        self.args = args
        self.db = db
        self.host = host
        self.module = module
        self.chain_list = chain_list
        self.cmeserver = cmeserver
        self.share_name = share_name
        self.conn = None
        self.hostname = None
        self.domain = None
        self.server_os = None
        self.logger = None
        self.password = None
        self.username = None
        self.hash = None
        self.admin_privs = False
        self.failed_logins = 0
        
        try:
            smb = SMBConnection(self.host, self.host, None, self.args.smb_port)

            #Get our IP from the socket
            local_ip = smb.getSMBServer().get_socket().getsockname()[0]

            #Get the remote ip address (in case the target is a hostname) 
            remote_ip = smb.getRemoteHost()

            try:
                smb.login('' , '')
            except SessionError as e:
                if "STATUS_ACCESS_DENIED" in e.message:
                    pass

            self.host = remote_ip
            self.domain   = smb.getServerDomain()
            self.hostname = smb.getServerName()
            self.server_os = smb.getServerOS()

            if not self.domain:
                self.domain = self.hostname

            self.db.add_host(self.host, self.hostname, self.domain, self.server_os)

            self.logger = CMEAdapter(getLogger('CME'), {
                                                        'host': self.host, 
                                                        'port': self.args.smb_port,
                                                        'hostname': u'{}'.format(self.hostname)
                                                       })

            self.logger.info(u"{} (name:{}) (domain:{})".format(
                                                                self.server_os,
                                                                self.hostname.decode('utf-8'), 
                                                                self.domain.decode('utf-8')
                                                                ))

            try:
                '''
                    DC's seem to want us to logoff first, windows workstations sometimes reset the connection
                    (go home Windows, you're drunk)
                '''
                smb.logoff()
            except:
                pass

            if self.args.mssql:
                instances = None
                self.logger.extra['port'] = self.args.mssql_port

                mssql = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                mssql.connect()

                instances = mssql.getInstances(10)
                if len(instances) > 0:
                    self.logger.info("Found {} MSSQL instance(s)".format(len(instances)))
                    for i, instance in enumerate(instances):
                        self.logger.highlight("Instance {}".format(i))
                        for key in instance.keys():
                            self.logger.highlight(key + ":" + instance[key])

                try:
                    mssql.disconnect()
                except:
                    pass

            if (self.args.username and (self.args.password or self.args.hash)) or self.args.cred_id:
                
                if self.args.mssql and (instances is not None and len(instances) > 0):
                    self.conn = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                    self.conn.connect()
                
                elif not args.mssql:
                    self.conn = SMBConnection(self.host, self.host, None, self.args.smb_port)

        except socket.error:
            pass

        if self.conn:
            if self.args.domain:
                self.domain = self.args.domain

            if self.args.local_auth:
                self.domain = self.hostname

            self.login()

            if (self.password is not None or self.hash is not None) and self.username is not None:

                if self.module or self.chain_list:

                    if self.chain_list:
                        module = self.chain_list[0]['object']

                    module_logger = CMEAdapter(getLogger('CME'), {
                                                                  'module': module.name.upper(), 
                                                                  'host': self.host, 
                                                                  'port': self.args.smb_port, 
                                                                  'hostname': self.hostname
                                                                 })
                    context = Context(self.db, module_logger, self.args)
                    context.localip  = local_ip

                    if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
                        cmeserver.server.context.localip = local_ip

                    if self.module:

                        launcher = module.launcher(context, None if not hasattr(module, 'command') else module.command)
                        payload = module.payload(context, None if not hasattr(module, 'command') else module.command)

                        if hasattr(module, 'on_login'):
                            module.on_login(context, self, launcher, payload)

                        if self.admin_privs and hasattr(module, 'on_admin_login'):
                            module.on_admin_login(context, self, launcher, payload)

                    elif self.chain_list:
                        module_list = self.chain_list[:]
                        module_list.reverse()

                        final_launcher = module_list[0]['object'].launcher(context, None if not hasattr(module_list[0]['object'], 'command') else module_list[0]['object'].command)
                        if len(module_list) > 2:
                            for m in module_list:
                                if m['object'] == module or m['object'] == module_list[0]['object']:
                                    continue
                                
                                final_launcher = m['object'].launcher(context, final_launcher)

                        if module == module_list[0]['object']: 
                            final_launcher = None if not hasattr(module_list[0]['object'], 'command') else module_list[0]['object'].command
                        
                        launcher = module.launcher(context, final_launcher)
                        payload  = module.payload(context, final_launcher)

                        if hasattr(module, 'on_login'):
                            module.on_login(context, self)

                        if self.admin_privs and hasattr(module, 'on_admin_login'):
                            module.on_admin_login(context, self, launcher, payload)

                elif self.module is None and self.chain_list is None:
                    for k, v in vars(self.args).iteritems():
                        if hasattr(self, k) and hasattr(getattr(self, k), '__call__'):
                            if v is not False and v is not None:
                                getattr(self, k)()