Exemplo n.º 1
0
    def enum(self):

        #logging.info('Retrieving endpoint list from %s' % addr)

        entries = []

        protodef = PassPolDump.KNOWN_PROTOCOLS['{}/SMB'.format(self.protocol)]
        port = protodef[1]

        logging.info("Trying protocol %s..." % self.protocol)
        rpctransport = transport.SMBTransport(self.addr, port, r'\samr', self.username, self.password, self.domain, self.lmhash, self.nthash, self.aesKey, doKerberos = self.doKerberos)

        dce = rpctransport.get_dce_rpc()
        dce.connect()

        dce.bind(samr.MSRPC_UUID_SAMR)

        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle'] 

        resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
        domains = resp['Buffer']['Buffer']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, domains[0]['Name'])

        resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
        domainHandle = resp['DomainHandle']

        self.logger.success('Dumping password policy')
        self.get_pass_pol(self.addr, rpctransport, dce, domainHandle)
Exemplo n.º 2
0
    def dump(self, addr):

        logging.info('Retrieving endpoint list from %s' % addr)

        # Try all requested protocols until one works.
        entries = []
        for protocol in self.__protocols:
            protodef = PassPolDump.KNOWN_PROTOCOLS[protocol]
            port = protodef[1]

            logging.info("Trying protocol %s..." % protocol)
            rpctransport = transport.SMBTransport(addr, port, r'\samr', self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey, doKerberos = self.__doKerberos)

            dce = rpctransport.get_dce_rpc()
            dce.connect()

            dce.bind(samr.MSRPC_UUID_SAMR)

            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle'] 

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, domains[0]['Name'])

            resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
            domainHandle = resp['DomainHandle']

            self.__logger.success('Dumping password policy')
            self.get_pass_pol(addr, rpctransport, dce, domainHandle)
Exemplo n.º 3
0
    def __fetchList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        entries = []

        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle'] 

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            print('Found domain(s):')
            for domain in domains:
                print(" . %s" % domain['Name'])

            logging.info("Looking up users in domain %s" % domains[0]['Name'])

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,domains[0]['Name'] )

            resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(dce, domainHandle, enumerationContext = enumerationContext)
                except DCERPCException as e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise 
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    r = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED, user['RelativeId'])
                    print("Found user: %s, uid = %d" % (user['Name'], user['RelativeId'] ))
                    info = samr.hSamrQueryInformationUser2(dce, r['UserHandle'],samr.USER_INFORMATION_CLASS.UserAllInformation)
                    entry = (user['Name'], user['RelativeId'], info['Buffer']['All'])
                    entries.append(entry)
                    samr.hSamrCloseHandle(dce, r['UserHandle'])

                enumerationContext = resp['EnumerationContext'] 
                status = resp['ErrorCode']

        except ListUsersException as e:
            logging.critical("Error listing users: %s" % e)

        dce.disconnect()

        return entries
Exemplo n.º 4
0
    def __fetchList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        entries = []

        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle'] 

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            print 'Found domain(s):'
            for domain in domains:
                print " . %s" % domain['Name']

            print "Looking up users in domain %s" % domains[0]['Name']

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,domains[0]['Name'] )

            resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
            domainHandle = resp['DomainHandle']

            done = False
            
            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(dce, domainHandle, enumerationContext = enumerationContext)
                except Exception, e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise 
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    r = samr.hSamrOpenUser(dce, domainHandle, samr.USER_READ_GENERAL | samr.USER_READ_PREFERENCES | samr.USER_READ_ACCOUNT, user['RelativeId'])
                    print "Found user: %s, uid = %d" % (user['Name'], user['RelativeId'] )
    
                    info = samr.hSamrQueryInformationUser2(dce, r['UserHandle'],samr.USER_INFORMATION_CLASS.UserAllInformation)
                    entry = (user['Name'], user['RelativeId'], info['Buffer']['All'])
                    entries.append(entry)
                    samr.hSamrCloseHandle(dce, r['UserHandle'])

                enumerationContext = resp['EnumerationContext'] 
                status = resp['ErrorCode']

        except ListUsersException, e:
            print "Error listing users: %s" % e
Exemplo n.º 5
0
    def connectSamr(self, domain):
        rpc = transport.DCERPCTransportFactory(self.__stringBindingSamr)
        rpc.set_smb_connection(self.__smbConnection)
        self.__samr = rpc.get_dce_rpc()
        self.__samr.connect()
        self.__samr.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(self.__samr)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(self.__samr, serverHandle, domain)
        resp = samr.hSamrOpenDomain(self.__samr, serverHandle=serverHandle, domainId=resp['DomainId'])
        self.__domainHandle = resp['DomainHandle']
        self.__domainName = domain
Exemplo n.º 6
0
    def get_netdomain(self):

        resp = samr.hSamrConnect(self._rpc_connection)
        server_handle = resp['ServerHandle']

        # We first list every domain in the SAM
        resp = samr.hSamrEnumerateDomainsInSamServer(self._rpc_connection, server_handle)

        results = list()
        for domain in resp['Buffer']['Buffer']:
            results.append(domain['Name'])

        return results
Exemplo n.º 7
0
    def get_netdomain(self):

        resp = samr.hSamrConnect(self._rpc_connection)
        server_handle = resp['ServerHandle']

        # We first list every domain in the SAM
        resp = samr.hSamrEnumerateDomainsInSamServer(self._rpc_connection,
                                                     server_handle)

        results = list()
        for domain in resp['Buffer']['Buffer']:
            results.append(domain['Name'])

        return results
Exemplo n.º 8
0
    def getDomainMachines(self):
        if self.__kdcHost is not None:
            domainController = self.__kdcHost
        elif self.__domain is not '':
            domainController = self.__domain
        else:
            raise Exception('A domain is needed!')

        logging.info('Getting machine\'s list from %s' % domainController)
        rpctransport = transport.SMBTransport(domainController, 445, r'\samr', self.__username, self.__password,
                                              self.__domain, self.__lmhash, self.__nthash, self.__aesKey,
                                              doKerberos=self.__doKerberos, kdcHost = self.__kdcHost)
        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle'] 

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            logging.info("Looking up users in domain %s" % domains[0]['Name'])

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,domains[0]['Name'] )

            resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(dce, domainHandle, samr.USER_WORKSTATION_TRUST_ACCOUNT,
                                                            enumerationContext=enumerationContext)
                except DCERPCException, e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    self.__machinesList.append(user['Name'][:-1])
                    logging.debug('Machine name - rid: %s - %d'% (user['Name'], user['RelativeId']))

                enumerationContext = resp['EnumerationContext'] 
                status = resp['ErrorCode']
        except Exception as e:
            raise e

        dce.disconnect()
Exemplo n.º 9
0
    def __fetchList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        entries = []

        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle'] 

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            print 'Found domain(s):'
            for domain in domains:
                print " . %s" % domain['Name']

            logging.info("Looking up users in domain %s" % domains[0]['Name'])

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,domains[0]['Name'] )

            resp = samr.hSamrOpenDomain(dce, serverHandle = serverHandle, domainId = resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(dce, domainHandle, enumerationContext = enumerationContext)
                except DCERPCException, e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise 
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    r = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED, user['RelativeId'])
                    print "Found user: %s, uid = %d" % (user['Name'], user['RelativeId'] )
                    info = samr.hSamrQueryInformationUser2(dce, r['UserHandle'],samr.USER_INFORMATION_CLASS.UserAllInformation)
                    entry = (user['Name'], user['RelativeId'], info['Buffer']['All'])
                    entries.append(entry)
                    samr.hSamrCloseHandle(dce, r['UserHandle'])

                enumerationContext = resp['EnumerationContext'] 
                status = resp['ErrorCode']

        except ListUsersException, e:
            logging.critical("Error listing users: %s" % e)
Exemplo n.º 10
0
    def rpc_get_local_admins(self):
        binding = r'ncacn_np:%s[\PIPE\samr]' % self.addr

        dce = self.dce_rpc_connect(binding, samr.MSRPC_UUID_SAMR)

        if dce is None:
            logging.warning('Connection failed: %s' % binding)
            return

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            sid = RPC_SID()
            sid.fromCanonical('S-1-5-32')

            logging.debug('Opening domain handle')

            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        desiredAccess=samr.DOMAIN_LOOKUP
                                        | MAXIMUM_ALLOWED,
                                        domainId=sid)
            domainHandle = resp['DomainHandle']

            resp = samr.hSamrOpenAlias(dce,
                                       domainHandle,
                                       desiredAccess=samr.ALIAS_LIST_MEMBERS
                                       | MAXIMUM_ALLOWED,
                                       aliasId=544)

            resp = samr.hSamrGetMembersInAlias(dce,
                                               aliasHandle=resp['AliasHandle'])

            for member in resp['Members']['Sids']:
                sid_string = member['SidPointer'].formatCanonical()

                logging.debug('Found SID: %s' % sid_string)

                self.sids.append(sid_string)
        except DCERPCException as e:
            logging.debug('Exception connecting to RPC: %s' % e)
        except Exception as e:
            raise e

        dce.disconnect()
Exemplo n.º 11
0
    def connectSamr(self, domain):
        rpc = transport.DCERPCTransportFactory(self.__stringBindingSamr)
        rpc.set_smb_connection(self.__smbConnection)
        self.__samr = rpc.get_dce_rpc()
        self.__samr.connect()
        self.__samr.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(self.__samr)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(self.__samr, serverHandle,
                                                 domain)
        resp = samr.hSamrOpenDomain(self.__samr,
                                    serverHandle=serverHandle,
                                    domainId=resp['DomainId'])
        self.__domainHandle = resp['DomainHandle']
        self.__domainName = domain
Exemplo n.º 12
0
    def __getLocalAdminSids(self):
        dce = self.__getDceBinding(self.__samrBinding)
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin')
        resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']
        resp = samr.hSamrOpenAlias(dce, domainHandle, desiredAccess=MAXIMUM_ALLOWED, aliasId=544)
        resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle'])
        memberSids = []
        for member in resp['Members']['Sids']:
            memberSids.append(member['SidPointer'].formatCanonical())
        dce.disconnect()
        return memberSids
Exemplo n.º 13
0
    def __getLocalAdminSids(self):
        dce = self.__getDceBinding(self.__samrBinding)
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin')
        resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']
        resp = samr.hSamrOpenAlias(dce, domainHandle, desiredAccess=MAXIMUM_ALLOWED, aliasId=544)
        resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle'])
        memberSids = []
        for member in resp['Members']['Sids']:
            memberSids.append(member['SidPointer'].formatCanonical())
        dce.disconnect()
        return memberSids
Exemplo n.º 14
0
    def hSamrChangePasswordUser(self):
        try:
            serverHandle = samr.hSamrConnect(self.dce, self.address +
                                             '\x00')['ServerHandle']
            domainSID = samr.hSamrLookupDomainInSamServer(
                self.dce, serverHandle, self.domain)['DomainId']
            domainHandle = samr.hSamrOpenDomain(
                self.dce, serverHandle, domainId=domainSID)['DomainHandle']
            userRID = samr.hSamrLookupNamesInDomain(
                self.dce, domainHandle,
                (self.username, ))['RelativeIds']['Element'][0]
            userHandle = samr.hSamrOpenUser(self.dce,
                                            domainHandle,
                                            userId=userRID)['UserHandle']
        except Exception as e:
            if 'STATUS_NO_SUCH_DOMAIN' in str(e):
                logging.critical(
                    'Wrong realm. Try to set the domain name for the target user account explicitly in format DOMAIN/username.'
                )
                return
            else:
                raise e

        try:
            resp = samr.hSamrChangePasswordUser(self.dce,
                                                userHandle,
                                                self.oldPassword,
                                                newPassword='',
                                                oldPwdHashNT=self.oldPwdHashNT,
                                                newPwdHashLM=self.newPwdHashLM,
                                                newPwdHashNT=self.newPwdHashNT)
        except Exception as e:
            if 'STATUS_PASSWORD_RESTRICTION' in str(e):
                logging.critical(
                    'Some password update rule has been violated. For example, the password history policy may prohibit the use of recent passwords.'
                )
            else:
                raise e
        else:
            if resp['ErrorCode'] == 0:
                logging.info('NTLM hashes were changed successfully.')
            else:
                logging.error(
                    'Non-zero return code, something weird happened.')
                resp.dump()
Exemplo n.º 15
0
    def dump(self, addr):

        logging.info('Retrieving endpoint list from %s' % addr)

        # Try all requested protocols until one works.
        entries = []
        for protocol in self.__protocols:
            protodef = PassPolDump.KNOWN_PROTOCOLS[protocol]
            port = protodef[1]

            logging.info("Trying protocol %s..." % protocol)
            rpctransport = transport.SMBTransport(addr,
                                                  port,
                                                  r'\samr',
                                                  self.__username,
                                                  self.__password,
                                                  self.__domain,
                                                  self.__lmhash,
                                                  self.__nthash,
                                                  self.__aesKey,
                                                  doKerberos=self.__doKerberos)

            dce = rpctransport.get_dce_rpc()
            dce.connect()

            dce.bind(samr.MSRPC_UUID_SAMR)

            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                     domains[0]['Name'])

            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        domainId=resp['DomainId'])
            domainHandle = resp['DomainHandle']

            self.__logger.success('Dumping password policy')
            self.get_pass_pol(addr, rpctransport, dce, domainHandle)
Exemplo n.º 16
0
    def enum(self):

        #logging.info('Retrieving endpoint list from %s' % addr)

        entries = []

        protodef = PassPolDump.KNOWN_PROTOCOLS['{}/SMB'.format(self.protocol)]
        port = protodef[1]

        logging.info("Trying protocol %s..." % self.protocol)
        rpctransport = transport.SMBTransport(self.addr,
                                              port,
                                              r'\samr',
                                              self.username,
                                              self.password,
                                              self.domain,
                                              self.lmhash,
                                              self.nthash,
                                              self.aesKey,
                                              doKerberos=self.doKerberos)

        dce = rpctransport.get_dce_rpc()
        dce.connect()

        dce.bind(samr.MSRPC_UUID_SAMR)

        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
        domains = resp['Buffer']['Buffer']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                 domains[0]['Name'])

        resp = samr.hSamrOpenDomain(dce,
                                    serverHandle=serverHandle,
                                    domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']

        self.logger.success('Dumping password policy')
        self.get_pass_pol(self.addr, rpctransport, dce, domainHandle)
Exemplo n.º 17
0
    def getUserSID(self):
        stringBinding = r'ncacn_np:%s[\pipe\samr]' % self.__kdcHost

        rpctransport = transport.DCERPCTransportFactory(stringBinding)

        if hasattr(rpctransport, 'set_credentials'):
            rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash)

        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']
        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, self.__domain)
        domainId = resp['DomainId']
        resp = samr.hSamrOpenDomain(dce, serverHandle, domainId = domainId)
        domainHandle = resp['DomainHandle']
        resp = samr.hSamrLookupNamesInDomain(dce, domainHandle, (self.__username,))
        # Let's pick the relative ID
        rid = resp['RelativeIds']['Element'][0]['Data']
        logging.info("User SID: %s-%s"% (domainId.formatCanonical(), rid))
        return domainId, rid
Exemplo n.º 18
0
	def hSamrSetInformationUser(self):
		try:
			serverHandle = samr.hSamrConnect(self.dce, self.address + '\x00')['ServerHandle']
			domainSID = samr.hSamrLookupDomainInSamServer(self.dce, serverHandle, self.domain)['DomainId']
			domainHandle = samr.hSamrOpenDomain(self.dce, serverHandle, domainId=domainSID)['DomainHandle']
			userRID = samr.hSamrLookupNamesInDomain(self.dce, domainHandle, (self.username,))['RelativeIds']['Element'][0]
			userHandle = samr.hSamrOpenUser(self.dce, domainHandle, userId=userRID)['UserHandle']
		except Exception as e:
			if 'STATUS_NO_SUCH_DOMAIN' in str(e):
				logging.critical('Wrong realm. Try to set the domain name for the target user account explicitly in format DOMAIN/username.')
				return
			else:
				raise e
		try:
			resp = samr.hSamrSetNTInternal1(self.dce, userHandle, self.newPassword, self.newPwdHashNT)
		except Exception as e:
			raise e
		else:
			if resp['ErrorCode'] == 0:
				logging.info('Credentials were injected into SAM successfully.')
			else:
				logging.error('Non-zero return code, something weird happened.')
				resp.dump()
Exemplo n.º 19
0
    def __get_domain_handels(dce: DCERPC) -> Dict[str, str]:
        """
        Request domain handel using DCERPC

        :param dce: DCE/RPC session
        :return: mapping of domain name -> domain handel
        """
        domains = {}
        resp = samr.hSamrConnect(dce)
        server_handle = resp['ServerHandle']
        resp = samr.hSamrEnumerateDomainsInSamServer(dce, server_handle)
        raw_domains = resp['Buffer']['Buffer']
        domain_names = [domain["Name"] for domain in raw_domains]
        logger.info(f'Found domain(s): {", ".join(domain_names)}')
        for domain_name in domain_names:
            resp = samr.hSamrLookupDomainInSamServer(dce, server_handle,
                                                     domain_name)
            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=server_handle,
                                        domainId=resp['DomainId'])
            domain_handle = resp['DomainHandle']
            domains[domain_name] = domain_handle

        return domains
Exemplo n.º 20
0
    def rpc_get_local_admins(self):
        binding = r'ncacn_np:%s[\PIPE\samr]' % self.addr

        dce = self.dce_rpc_connect(binding, samr.MSRPC_UUID_SAMR)

        if dce is None:
            logging.warning('Connection failed: %s', binding)
            return

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']
            # Attempt to get the SID from this computer to filter local accounts later
            try:
                resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, self.samname[:-1])
                self.sid = resp['DomainId'].formatCanonical()
            # This doesn't always work (for example on DCs)
            except DCERPCException as e:
                # Make it a string which is guaranteed not to match a SID
                self.sid = 'UNKNOWN'


            # Enumerate the domains known to this computer
            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            # Query the builtin domain (derived from this SID)
            sid = RPC_SID()
            sid.fromCanonical('S-1-5-32')

            logging.debug('Opening domain handle')
            # Open a handle to this domain
            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        desiredAccess=samr.DOMAIN_LOOKUP | MAXIMUM_ALLOWED,
                                        domainId=sid)
            domainHandle = resp['DomainHandle']

            resp = samr.hSamrOpenAlias(dce,
                                       domainHandle,
                                       desiredAccess=samr.ALIAS_LIST_MEMBERS | MAXIMUM_ALLOWED,
                                       aliasId=544)
            resp = samr.hSamrGetMembersInAlias(dce,
                                               aliasHandle=resp['AliasHandle'])
            for member in resp['Members']['Sids']:
                sid_string = member['SidPointer'].formatCanonical()

                logging.debug('Found admin SID: %s', sid_string)
                if not sid_string.startswith(self.sid):
                    # If the sid is known, we can add the admin value directly
                    try:
                        siddata = self.ad.sidcache.get(sid_string)
                        logging.debug('Sid is cached: %s', siddata['principal'])
                        self.admins.append({'Name': siddata['principal'],
                                            'Type': siddata['type'].capitalize()})
                    except KeyError:
                        # Append it to the list of unresolved SIDs
                        self.admin_sids.append(sid_string)
                else:
                    logging.debug('Ignoring local group %s', sid_string)
        except DCERPCException as e:
            logging.debug('Exception connecting to RPC: %s', e)
        except Exception as e:
            if 'connection reset' in str(e):
                logging.debug('Connection was reset: %s', e)
            else:
                raise e

        dce.disconnect()
Exemplo n.º 21
0
 def getServerHandle(self):
     resp = samr.hSamrConnect(self.dce)
     return resp['ServerHandle']
Exemplo n.º 22
0
    def get_netlocalgroup(self,
                          queried_groupname=str(),
                          list_groups=False,
                          recurse=False):
        from impacket.nt_errors import STATUS_MORE_ENTRIES
        results = list()

        resp = samr.hSamrConnect(self._rpc_connection)
        server_handle = resp['ServerHandle']

        # We first list every domain in the SAM
        resp = samr.hSamrEnumerateDomainsInSamServer(self._rpc_connection,
                                                     server_handle)
        domains = resp['Buffer']['Buffer']
        domain_handles = dict()
        for local_domain in domains:
            resp = samr.hSamrLookupDomainInSamServer(self._rpc_connection,
                                                     server_handle,
                                                     local_domain['Name'])
            domain_sid = 'S-1-5-{}'.format('-'.join(
                str(x) for x in resp['DomainId']['SubAuthority']))
            resp = samr.hSamrOpenDomain(self._rpc_connection,
                                        serverHandle=server_handle,
                                        domainId=resp['DomainId'])
            domain_handles[domain_sid] = resp['DomainHandle']

        # If we list the groups
        if list_groups:
            # We browse every domain
            for domain_sid, domain_handle in domain_handles.items():
                # We enumerate local groups in every domain
                enumeration_context = 0
                groups = list()
                while True:
                    resp = samr.hSamrEnumerateAliasesInDomain(
                        self._rpc_connection,
                        domain_handle,
                        enumerationContext=enumeration_context)
                    groups += resp['Buffer']['Buffer']

                    enumeration_context = resp['EnumerationContext']
                    if resp['ErrorCode'] != STATUS_MORE_ENTRIES:
                        break

                # We get information on every group
                for group in groups:
                    resp = samr.hSamrRidToSid(self._rpc_connection,
                                              domain_handle,
                                              rid=group['RelativeId'])
                    sid = 'S-1-5-{}'.format('-'.join(
                        str(x) for x in resp['Sid']['SubAuthority']))

                    resp = samr.hSamrOpenAlias(self._rpc_connection,
                                               domain_handle,
                                               aliasId=group['RelativeId'])
                    alias_handle = resp['AliasHandle']
                    resp = samr.hSamrQueryInformationAlias(
                        self._rpc_connection, alias_handle)

                    final_group = rpcobj.Group(resp['Buffer']['General'])
                    final_group.add_attributes({
                        'server': self._target_computer,
                        'sid': sid
                    })

                    results.append(final_group)

                    samr.hSamrCloseHandle(self._rpc_connection, alias_handle)

                samr.hSamrCloseHandle(self._rpc_connection, domain_handle)
        # If we query a group
        else:
            queried_group_rid = None
            queried_group_domain_handle = None

            # If the user is looking for a particular group
            if queried_groupname:
                # We look for it in every domain
                for _, domain_handle in domain_handles.items():
                    try:
                        resp = samr.hSamrLookupNamesInDomain(
                            self._rpc_connection, domain_handle,
                            [queried_groupname])
                        queried_group_rid = resp['RelativeIds']['Element'][0][
                            'Data']
                        queried_group_domain_handle = domain_handle
                        break
                    except (DCERPCSessionError, KeyError, IndexError):
                        continue
                else:
                    raise ValueError(
                        'The group \'{}\' was not found on the target server'.
                        format(queried_groupname))
            # Otherwise, we look for the local Administrators group
            else:
                queried_group_rid = 544
                resp = samr.hSamrLookupDomainInSamServer(
                    self._rpc_connection, server_handle, 'BUILTIN')
                resp = samr.hSamrOpenDomain(self._rpc_connection,
                                            serverHandle=server_handle,
                                            domainId=resp['DomainId'])
                queried_group_domain_handle = resp['DomainHandle']

            # We get a handle on the group, and list its members
            try:
                group = samr.hSamrOpenAlias(self._rpc_connection,
                                            queried_group_domain_handle,
                                            aliasId=queried_group_rid)
                resp = samr.hSamrGetMembersInAlias(self._rpc_connection,
                                                   group['AliasHandle'])
            except DCERPCSessionError:
                raise ValueError(
                    'The name \'{}\' is not a valid group on the target server'
                    .format(queried_groupname))

            # For every user, we look for information in every local domain
            for member in resp['Members']['Sids']:
                attributes = dict()
                member_rid = member['SidPointer']['SubAuthority'][-1]
                member_sid = 'S-1-5-{}'.format('-'.join(
                    str(x) for x in member['SidPointer']['SubAuthority']))

                attributes['server'] = self._target_computer
                attributes['sid'] = member_sid

                for domain_sid, domain_handle in domain_handles.items():
                    # We've found a local member
                    if member_sid.startswith(domain_sid):
                        attributes['isdomain'] = False
                        resp = samr.hSamrQueryInformationDomain(
                            self._rpc_connection, domain_handle)
                        member_domain = resp['Buffer']['General2']['I1'][
                            'DomainName']
                        try:
                            resp = samr.hSamrOpenUser(self._rpc_connection,
                                                      domain_handle,
                                                      userId=member_rid)
                            member_handle = resp['UserHandle']
                            attributes['isgroup'] = False
                            resp = samr.hSamrQueryInformationUser(
                                self._rpc_connection, member_handle)
                            attributes['name'] = '{}/{}'.format(
                                member_domain,
                                resp['Buffer']['General']['UserName'])
                        except DCERPCSessionError:
                            resp = samr.hSamrOpenAlias(self._rpc_connection,
                                                       domain_handle,
                                                       aliasId=member_rid)
                            member_handle = resp['AliasHandle']
                            attributes['isgroup'] = True
                            resp = samr.hSamrQueryInformationAlias(
                                self._rpc_connection, member_handle)
                            attributes['name'] = '{}/{}'.format(
                                member_domain,
                                resp['Buffer']['General']['Name'])
                        attributes['lastlogin'] = str()
                        break
                # It's a domain member
                else:
                    attributes['isdomain'] = True
                    if self._ldap_connection is not None:
                        try:
                            ad_object = self.get_adobject(
                                queried_sid=member_sid)[0]
                            member_dn = ad_object.distinguishedname
                            member_domain = member_dn[member_dn.
                                                      index('DC='):].replace(
                                                          'DC=', '').replace(
                                                              ',', '.')
                            try:
                                attributes['name'] = '{}/{}'.format(
                                    member_domain, ad_object.samaccountname)
                            except AttributeError:
                                # Here, the member is a foreign security principal
                                # TODO: resolve it properly
                                attributes['name'] = '{}/{}'.format(
                                    member_domain, ad_object.objectsid)
                            attributes['isgroup'] = ad_object.isgroup
                            try:
                                attributes['lastlogin'] = ad_object.lastlogon
                            except AttributeError:
                                attributes['lastlogin'] = str()
                        except IndexError:
                            # We did not manage to resolve this SID against the DC
                            attributes['isdomain'] = False
                            attributes['isgroup'] = False
                            attributes['name'] = attributes['sid']
                            attributes['lastlogin'] = str()
                    else:
                        attributes['isgroup'] = False
                        attributes['name'] = str()
                        attributes['lastlogin'] = str()

                results.append(rpcobj.RPCObject(attributes))

                # If we recurse and the member is a domain group, we query every member
                # TODO: implement check on self._domain_controller here?
                if self._ldap_connection and self._domain_controller and recurse and attributes[
                        'isdomain'] and attributes['isgroup']:
                    for domain_member in self.get_netgroupmember(
                            full_data=True,
                            recurse=True,
                            queried_sid=attributes['sid']):
                        domain_member_attributes = dict()
                        domain_member_attributes['isdomain'] = True
                        member_dn = domain_member.distinguishedname
                        member_domain = member_dn[member_dn.
                                                  index('DC='):].replace(
                                                      'DC=',
                                                      '').replace(',', '.')
                        domain_member_attributes['name'] = '{}/{}'.format(
                            member_domain, domain_member.samaccountname)
                        domain_member_attributes[
                            'isgroup'] = domain_member.isgroup
                        domain_member_attributes['isdomain'] = True
                        domain_member_attributes['server'] = attributes['name']
                        domain_member_attributes[
                            'sid'] = domain_member.objectsid
                        try:
                            domain_member_attributes[
                                'lastlogin'] = ad_object.lastlogon
                        except AttributeError:
                            domain_member_attributes['lastlogin'] = str()
                        results.append(
                            rpcobj.RPCObject(domain_member_attributes))

        return results
Exemplo n.º 23
0
    def getDomainMachines(self):
        if self.__kdcHost is not None:
            domainController = self.__kdcHost
        elif self.__domain is not '':
            domainController = self.__domain
        else:
            raise Exception('A domain is needed!')

        logging.info('Getting machine\'s list from %s' % domainController)
        rpctransport = transport.SMBTransport(domainController,
                                              445,
                                              r'\samr',
                                              self.__username,
                                              self.__password,
                                              self.__domain,
                                              self.__lmhash,
                                              self.__nthash,
                                              self.__aesKey,
                                              doKerberos=self.__doKerberos,
                                              kdcHost=self.__kdcHost)
        dce = rpctransport.get_dce_rpc()
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            logging.info("Looking up users in domain %s" % domains[0]['Name'])

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                     domains[0]['Name'])

            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        domainId=resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(
                        dce,
                        domainHandle,
                        samr.USER_WORKSTATION_TRUST_ACCOUNT,
                        enumerationContext=enumerationContext)
                except DCERPCException as e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    self.__machinesList.append(user['Name'][:-1])
                    logging.debug('Machine name - rid: %s - %d' %
                                  (user['Name'], user['RelativeId']))

                enumerationContext = resp['EnumerationContext']
                status = resp['ErrorCode']
        except Exception as e:
            raise e

        dce.disconnect()
Exemplo n.º 24
0
    def enumPasswordPolicy(self):
        rpctransport = transport.SMBTransport(self.__addr,
                                              self.__port,
                                              r'\samr',
                                              self.__username,
                                              self.__password,
                                              self.__domain,
                                              self.__lmhash,
                                              self.__nthash,
                                              self.__aesKey,
                                              doKerberos=self.__doKerberos)

        dce = rpctransport.get_dce_rpc()
        dce.connect()

        dce.bind(samr.MSRPC_UUID_SAMR)

        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
        domains = resp['Buffer']['Buffer']

        domain = domains[0]["Name"]
        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                 domains[0]['Name'])

        resp = samr.hSamrOpenDomain(dce,
                                    serverHandle=serverHandle,
                                    domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']

        if self.__host_domain == "":
            domain = "WORKGROUP"
        else:
            domain = self.__host_domain

        resp = samr.hSamrQueryInformationDomain(
            dce, domainHandle,
            samr.DOMAIN_INFORMATION_CLASS.DomainPasswordInformation)

        pass_complexity = resp['Buffer']['Password']['PasswordProperties']
        min_pass_len = resp['Buffer']['Password']['MinPasswordLength']
        pass_hst_len = resp['Buffer']['Password']['PasswordHistoryLength']

        max_pass_age = self.__convert(
            resp['Buffer']['Password']['MaxPasswordAge']['LowPart'],
            resp['Buffer']['Password']['MaxPasswordAge']['HighPart'], 1)

        min_pass_age = self.__convert(
            resp['Buffer']['Password']['MinPasswordAge']['LowPart'],
            resp['Buffer']['Password']['MinPasswordAge']['HighPart'], 1)

        resp = samr.hSamrQueryInformationDomain2(
            dce, domainHandle,
            samr.DOMAIN_INFORMATION_CLASS.DomainLockoutInformation)

        lock_threshold = int(resp['Buffer']['Lockout']['LockoutThreshold'])

        lock_duration = None
        if lock_threshold != 0:
            lock_duration = int(
                resp['Buffer']['Lockout']['LockoutDuration']) / -600000000

        dce.disconnect()

        return {
            'complexity': pass_complexity,
            'minimum_length': min_pass_len,
            'history_length': pass_hst_len,
            'maximum_age': max_pass_age,
            'minimum_age': min_pass_age,
            'lock_threshold': lock_threshold,
            'lock_duration': lock_duration,
        }
Exemplo n.º 25
0
    def _get_server_handle(self, dce):
        samr_connect_resp = samr.hSamrConnect(dce)
        server_handle = samr_connect_resp[self.SERVER_HANDLE]

        return server_handle
Exemplo n.º 26
0
    def __fetchGroupList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        domain = None
        entries = []

        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            domain = domains[0]['Name']

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                     domains[0]['Name'])

            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        domainId=resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateGroupsInDomain(
                        dce,
                        domainHandle,
                        enumerationContext=enumerationContext)
                except DCERPCException as e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise
                    resp = e.get_packet()

                for group in resp['Buffer']['Buffer']:
                    r = samr.hSamrOpenGroup(dce, domainHandle,
                                            samr.MAXIMUM_ALLOWED,
                                            group['RelativeId'])
                    info = samr.hSamrQueryInformationGroup(
                        dce, r['GroupHandle'],
                        samr.GROUP_INFORMATION_CLASS.GroupGeneralInformation)

                    # Query members in group
                    try:
                        members_info = samr.hSamrGetMembersInGroup(
                            dce, r['GroupHandle'])
                        members = {
                            "Count": members_info["Members"]["MemberCount"],
                            "RelativeIds": [],
                        }
                        for member in members_info["Members"]["Members"]:
                            members["RelativeIds"].append(
                                int(vars(member)["fields"]["Data"]))

                        entry = (domain, group['Name'], group['RelativeId'],
                                 info['Buffer']['General'], members)
                        yield entry
                        samr.hSamrCloseHandle(dce, r['GroupHandle'])
                    except DCERPCSessionError:
                        pass

                enumerationContext = resp['EnumerationContext']
                status = resp['ErrorCode']

        except ListUsersException as e:
            print("Error listing group: %s" % e)

        dce.disconnect()
Exemplo n.º 27
0
    def __fetchUserList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        domain = None
        entries = []

        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']

            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            domain = domains[0]['Name']

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                     domains[0]['Name'])

            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        domainId=resp['DomainId'])
            domainHandle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enumerationContext = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(
                        dce,
                        domainHandle,
                        enumerationContext=enumerationContext)
                except DCERPCException as e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise
                    resp = e.get_packet()

                for user in resp['Buffer']['Buffer']:
                    try:
                        r = samr.hSamrOpenUser(dce, domainHandle,
                                               samr.MAXIMUM_ALLOWED,
                                               user['RelativeId'])
                        info = samr.hSamrQueryInformationUser2(
                            dce, r['UserHandle'],
                            samr.USER_INFORMATION_CLASS.UserAllInformation)
                        entry = (domain, user['Name'], user['RelativeId'],
                                 info['Buffer']['All'])
                        yield entry
                        samr.hSamrCloseHandle(dce, r['UserHandle'])
                    except DCERPCSessionError:
                        pass

                enumerationContext = resp['EnumerationContext']
                status = resp['ErrorCode']

        except ListUsersException as e:
            print("Error listing users: %s" % e)

        dce.disconnect()
Exemplo n.º 28
0
    def rpc_get_group_members(self, group_rid, resultlist):
        binding = r'ncacn_np:%s[\PIPE\samr]' % self.addr
        unresolved = []
        dce = self.dce_rpc_connect(binding, samr.MSRPC_UUID_SAMR)

        if dce is None:
            return

        try:
            resp = samr.hSamrConnect(dce)
            serverHandle = resp['ServerHandle']
            # Attempt to get the SID from this computer to filter local accounts later
            try:
                resp = samr.hSamrLookupDomainInSamServer(
                    dce, serverHandle, self.samname[:-1])
                self.sid = resp['DomainId'].formatCanonical()
            # This doesn't always work (for example on DCs)
            except DCERPCException as e:
                # Make it a string which is guaranteed not to match a SID
                self.sid = 'UNKNOWN'

            # Enumerate the domains known to this computer
            resp = samr.hSamrEnumerateDomainsInSamServer(dce, serverHandle)
            domains = resp['Buffer']['Buffer']

            # Query the builtin domain (derived from this SID)
            sid = RPC_SID()
            sid.fromCanonical('S-1-5-32')

            logging.debug('Opening domain handle')
            # Open a handle to this domain
            resp = samr.hSamrOpenDomain(dce,
                                        serverHandle=serverHandle,
                                        desiredAccess=samr.DOMAIN_LOOKUP
                                        | MAXIMUM_ALLOWED,
                                        domainId=sid)
            domainHandle = resp['DomainHandle']
            try:
                resp = samr.hSamrOpenAlias(
                    dce,
                    domainHandle,
                    desiredAccess=samr.ALIAS_LIST_MEMBERS | MAXIMUM_ALLOWED,
                    aliasId=group_rid)
            except samr.DCERPCSessionError as error:
                # Group does not exist
                if 'STATUS_NO_SUCH_ALIAS' in str(error):
                    logging.debug('No group with RID %d exists', group_rid)
                    return
            resp = samr.hSamrGetMembersInAlias(dce,
                                               aliasHandle=resp['AliasHandle'])
            for member in resp['Members']['Sids']:
                sid_string = member['SidPointer'].formatCanonical()

                logging.debug('Found %d SID: %s', group_rid, sid_string)
                if not sid_string.startswith(self.sid):
                    # If the sid is known, we can add the admin value directly
                    try:
                        siddata = self.ad.sidcache.get(sid_string)
                        if siddata is None:
                            unresolved.append(sid_string)
                        else:
                            logging.debug('Sid is cached: %s',
                                          siddata['principal'])
                            resultlist.append({
                                'ObjectIdentifier':
                                sid_string,
                                'ObjectType':
                                siddata['type'].capitalize()
                            })
                    except KeyError:
                        # Append it to the list of unresolved SIDs
                        unresolved.append(sid_string)
                else:
                    logging.debug('Ignoring local group %s', sid_string)
        except DCERPCException as e:
            if 'rpc_s_access_denied' in str(e):
                logging.debug(
                    'Access denied while enumerating groups on %s, likely a patched OS',
                    self.hostname)
            else:
                raise
        except Exception as e:
            if 'connection reset' in str(e):
                logging.debug('Connection was reset: %s', e)
            else:
                raise e

        dce.disconnect()
        return unresolved
Exemplo n.º 29
0
    def get_netlocalgroup(self, queried_groupname=str(), list_groups=False,
                          recurse=False):
        from impacket.nt_errors import STATUS_MORE_ENTRIES
        results = list()

        resp = samr.hSamrConnect(self._rpc_connection)
        server_handle = resp['ServerHandle']

        # We first list every domain in the SAM
        resp = samr.hSamrEnumerateDomainsInSamServer(self._rpc_connection, server_handle)
        domains = resp['Buffer']['Buffer']
        domain_handles = dict()
        for local_domain in domains:
            resp = samr.hSamrLookupDomainInSamServer(self._rpc_connection, server_handle, local_domain['Name'])
            domain_sid = 'S-1-5-{}'.format('-'.join(str(x) for x in resp['DomainId']['SubAuthority']))
            resp = samr.hSamrOpenDomain(self._rpc_connection, serverHandle=server_handle, domainId=resp['DomainId'])
            domain_handles[domain_sid] = resp['DomainHandle']

        # If we list the groups
        if list_groups:
            # We browse every domain
            for domain_sid, domain_handle in domain_handles.items():
                # We enumerate local groups in every domain
                enumeration_context = 0
                groups = list()
                while True:
                    resp = samr.hSamrEnumerateAliasesInDomain(self._rpc_connection, domain_handle,
                            enumerationContext=enumeration_context)
                    groups += resp['Buffer']['Buffer']

                    enumeration_context = resp['EnumerationContext']
                    if resp['ErrorCode'] != STATUS_MORE_ENTRIES:
                        break

                # We get information on every group
                for group in groups:
                    resp = samr.hSamrRidToSid(self._rpc_connection, domain_handle, rid=group['RelativeId'])
                    sid = 'S-1-5-{}'.format('-'.join(str(x) for x in resp['Sid']['SubAuthority']))

                    resp = samr.hSamrOpenAlias(self._rpc_connection, domain_handle, aliasId=group['RelativeId'])
                    alias_handle = resp['AliasHandle']
                    resp = samr.hSamrQueryInformationAlias(self._rpc_connection, alias_handle)

                    final_group = rpcobj.Group(resp['Buffer']['General'])
                    final_group.add_attributes({'server': self._target_computer, 'sid': sid})

                    results.append(final_group)

                    samr.hSamrCloseHandle(self._rpc_connection, alias_handle)

                samr.hSamrCloseHandle(self._rpc_connection, domain_handle)
        # If we query a group
        else:
            queried_group_rid = None
            queried_group_domain_handle = None

            # If the user is looking for a particular group
            if queried_groupname:
                # We look for it in every domain
                for _, domain_handle in domain_handles.items():
                    try:
                        resp = samr.hSamrLookupNamesInDomain(self._rpc_connection, domain_handle, [queried_groupname])
                        queried_group_rid = resp['RelativeIds']['Element'][0]['Data']
                        queried_group_domain_handle = domain_handle
                        break
                    except (DCERPCSessionError, KeyError, IndexError):
                        continue
                else:
                    raise ValueError('The group \'{}\' was not found on the target server'.format(queried_groupname))
            # Otherwise, we look for the local Administrators group
            else:
                queried_group_rid = 544
                resp = samr.hSamrLookupDomainInSamServer(self._rpc_connection, server_handle, 'BUILTIN')
                resp = samr.hSamrOpenDomain(self._rpc_connection, serverHandle=server_handle, domainId=resp['DomainId'])
                queried_group_domain_handle = resp['DomainHandle']

            # We get a handle on the group, and list its members
            try:
                group = samr.hSamrOpenAlias(self._rpc_connection, queried_group_domain_handle, aliasId=queried_group_rid)
                resp = samr.hSamrGetMembersInAlias(self._rpc_connection, group['AliasHandle'])
            except DCERPCSessionError:
                raise ValueError('The name \'{}\' is not a valid group on the target server'.format(queried_groupname))

            # For every user, we look for information in every local domain
            for member in resp['Members']['Sids']:
                attributes = dict()
                member_rid = member['SidPointer']['SubAuthority'][-1]
                member_sid = 'S-1-5-{}'.format('-'.join(str(x) for x in member['SidPointer']['SubAuthority']))

                attributes['server'] = self._target_computer
                attributes['sid'] = member_sid

                for domain_sid, domain_handle in domain_handles.items():
                    # We've found a local member
                    if member_sid.startswith(domain_sid):
                        attributes['isdomain'] = False
                        resp = samr.hSamrQueryInformationDomain(self._rpc_connection, domain_handle)
                        member_domain = resp['Buffer']['General2']['I1']['DomainName']
                        try:
                            resp = samr.hSamrOpenUser(self._rpc_connection, domain_handle, userId=member_rid)
                            member_handle = resp['UserHandle']
                            attributes['isgroup'] = False
                            resp = samr.hSamrQueryInformationUser(self._rpc_connection, member_handle)
                            attributes['name'] = '{}/{}'.format(member_domain, resp['Buffer']['General']['UserName'])
                        except DCERPCSessionError:
                            resp = samr.hSamrOpenAlias(self._rpc_connection, domain_handle, aliasId=member_rid)
                            member_handle = resp['AliasHandle']
                            attributes['isgroup'] = True
                            resp = samr.hSamrQueryInformationAlias(self._rpc_connection, member_handle)
                            attributes['name'] = '{}/{}'.format(member_domain, resp['Buffer']['General']['Name'])
                        attributes['lastlogin'] = str()
                        break
                # It's a domain member
                else:
                    attributes['isdomain'] = True
                    if self._ldap_connection is not None:
                        try:
                            ad_object = self.get_adobject(queried_sid=member_sid)[0]
                            member_dn = ad_object.distinguishedname
                            member_domain = member_dn[member_dn.index('DC='):].replace('DC=', '').replace(',', '.')
                            try:
                                attributes['name'] = '{}/{}'.format(member_domain, ad_object.samaccountname)
                            except AttributeError:
                                # Here, the member is a foreign security principal
                                # TODO: resolve it properly
                                attributes['name'] = '{}/{}'.format(member_domain, ad_object.objectsid)
                            attributes['isgroup'] = ad_object.isgroup
                            try:
                                attributes['lastlogin'] = ad_object.lastlogon
                            except AttributeError:
                                attributes['lastlogin'] = str()
                        except IndexError:
                            # We did not manage to resolve this SID against the DC
                            attributes['isdomain'] = False
                            attributes['isgroup'] = False
                            attributes['name'] = attributes['sid']
                            attributes['lastlogin'] = str()
                    else:
                        attributes['isgroup'] = False
                        attributes['name'] = str()
                        attributes['lastlogin'] = str()

                results.append(rpcobj.RPCObject(attributes))

                # If we recurse and the member is a domain group, we query every member
                # TODO: implement check on self._domain_controller here?
                if self._ldap_connection and self._domain_controller and recurse and attributes['isdomain'] and attributes['isgroup']:
                    for domain_member in self.get_netgroupmember(full_data=True, recurse=True, queried_sid=attributes['sid']):
                        domain_member_attributes = dict()
                        domain_member_attributes['isdomain'] = True
                        member_dn = domain_member.distinguishedname
                        member_domain = member_dn[member_dn.index('DC='):].replace('DC=', '').replace(',', '.')
                        domain_member_attributes['name'] = '{}/{}'.format(member_domain, domain_member.samaccountname)
                        domain_member_attributes['isgroup'] = domain_member.isgroup
                        domain_member_attributes['isdomain'] = True
                        domain_member_attributes['server'] = attributes['name']
                        domain_member_attributes['sid'] = domain_member.objectsid
                        try:
                            domain_member_attributes['lastlogin'] = ad_object.lastlogon
                        except AttributeError:
                            domain_member_attributes['lastlogin'] = str()
                        results.append(rpcobj.RPCObject(domain_member_attributes))

        return results