Esempio n. 1
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()
Esempio n. 2
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
Esempio n. 3
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()
Esempio n. 4
0
    def doSAMRAdd(self, rpctransport):
        dce = rpctransport.get_dce_rpc()
        servHandle = None
        domainHandle = None
        userHandle = None
        try:
            dce.connect()
            dce.bind(samr.MSRPC_UUID_SAMR)

            samrConnectResponse = samr.hSamrConnect5(
                dce, '\\\\%s\x00' % self.__target,
                samr.SAM_SERVER_ENUMERATE_DOMAINS
                | samr.SAM_SERVER_LOOKUP_DOMAIN)
            servHandle = samrConnectResponse['ServerHandle']

            samrEnumResponse = samr.hSamrEnumerateDomainsInSamServer(
                dce, servHandle)
            domains = samrEnumResponse['Buffer']['Buffer']
            domainsWithoutBuiltin = list(
                filter(lambda x: x['Name'].lower() != 'builtin', domains))

            if len(domainsWithoutBuiltin) > 1:
                domain = list(
                    filter(lambda x: x['Name'].lower() == self.__domainNetbios,
                           domains))
                if len(domain) != 1:
                    logging.critical(
                        "This server provides multiple domains and '%s' isn't one of them.",
                        self.__domainNetbios)
                    logging.critical("Available domain(s):")
                    for domain in domains:
                        logging.error(" * %s" % domain['Name'])
                    logging.critical(
                        "Consider using -domain-netbios argument to specify which one you meant."
                    )
                    raise Exception()
                else:
                    selectedDomain = domain[0]['Name']
            else:
                selectedDomain = domainsWithoutBuiltin[0]['Name']

            samrLookupDomainResponse = samr.hSamrLookupDomainInSamServer(
                dce, servHandle, selectedDomain)
            domainSID = samrLookupDomainResponse['DomainId']

            if logging.getLogger().level == logging.DEBUG:
                logging.info("Opening domain %s..." % selectedDomain)
            samrOpenDomainResponse = samr.hSamrOpenDomain(
                dce, servHandle, samr.DOMAIN_LOOKUP | samr.DOMAIN_CREATE_USER,
                domainSID)
            domainHandle = samrOpenDomainResponse['DomainHandle']

            if self.__noAdd or self.__delete:
                try:
                    checkForUser = samr.hSamrLookupNamesInDomain(
                        dce, domainHandle, [self.__computerName])
                except samr.DCERPCSessionError as e:
                    if e.error_code == 0xc0000073:
                        raise Exception("Account %s not found in domain %s!" %
                                        (self.__computerName, selectedDomain))
                    else:
                        raise

                userRID = checkForUser['RelativeIds']['Element'][0]
                if self.__delete:
                    access = samr.DELETE
                    message = "delete"
                else:
                    access = samr.USER_FORCE_PASSWORD_CHANGE
                    message = "set password for"
                try:
                    openUser = samr.hSamrOpenUser(dce, domainHandle, access,
                                                  userRID)
                    userHandle = openUser['UserHandle']
                except samr.DCERPCSessionError as e:
                    if e.error_code == 0xc0000022:
                        raise Exception(
                            "User %s doesn't have right to %s %s!" %
                            (self.__username, message, self.__computerName))
                    else:
                        raise
            else:
                if self.__computerName is not None:
                    try:
                        checkForUser = samr.hSamrLookupNamesInDomain(
                            dce, domainHandle, [self.__computerName])
                        raise Exception(
                            "Account %s already exists! If you just want to set a password, use -no-add."
                            % self.__computerName)
                    except samr.DCERPCSessionError as e:
                        if e.error_code != 0xc0000073:
                            raise
                else:
                    foundUnused = False
                    while not foundUnused:
                        self.__computerName = self.generateComputerName()
                        try:
                            checkForUser = samr.hSamrLookupNamesInDomain(
                                dce, domainHandle, [self.__computerName])
                        except samr.DCERPCSessionError as e:
                            if e.error_code == 0xc0000073:
                                foundUnused = True
                            else:
                                raise

                try:
                    createUser = samr.hSamrCreateUser2InDomain(
                        dce,
                        domainHandle,
                        self.__computerName,
                        samr.USER_WORKSTATION_TRUST_ACCOUNT,
                        samr.USER_FORCE_PASSWORD_CHANGE,
                    )
                except samr.DCERPCSessionError as e:
                    if e.error_code == 0xc0000022:
                        raise Exception(
                            "User %s doesn't have right to create a machine account!"
                            % self.__username)
                    elif e.error_code == 0xc00002e7:
                        raise Exception("User %s machine quota exceeded!" %
                                        self.__username)
                    else:
                        raise

                userHandle = createUser['UserHandle']

            if self.__delete:
                samr.hSamrDeleteUser(dce, userHandle)
                logging.info("Successfully deleted %s." % self.__computerName)
                userHandle = None
            else:
                samr.hSamrSetPasswordInternal4New(dce, userHandle,
                                                  self.__computerPassword)
                if self.__noAdd:
                    logging.info(
                        "Successfully set password of %s to %s." %
                        (self.__computerName, self.__computerPassword))
                else:
                    logging.info(
                        "Successfully added machine account %s with password %s."
                        % (self.__computerName, self.__computerPassword))

        except Exception as e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()

            logging.critical(str(e))
        finally:
            if userHandle is not None:
                samr.hSamrCloseHandle(dce, userHandle)
            if domainHandle is not None:
                samr.hSamrCloseHandle(dce, domainHandle)
            if servHandle is not None:
                samr.hSamrCloseHandle(dce, servHandle)
            dce.disconnect()
Esempio n. 5
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
Esempio n. 6
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