示例#1
0
 def get_entity(dce, domain_handle, samr_obj):
     resp = samr.hSamrOpenAlias(dce,
                                domain_handle,
                                aliasId=samr_obj['RelativeId'])
     info = samr.hSamrQueryInformationAlias(dce, resp['AliasHandle'])
     alias = Alias(samr_obj['Name'], samr_obj['RelativeId'],
                   info['Buffer']['General'])
     samr.hSamrCloseHandle(dce, resp['AliasHandle'])
     return alias
示例#2
0
 def get_entity(dce, domain_handle, samr_obj):
     resp = samr.hSamrOpenGroup(dce,
                                domain_handle,
                                groupId=samr_obj['RelativeId'])
     info = samr.hSamrQueryInformationGroup(dce, resp['GroupHandle'])
     group = Group(samr_obj['Name'], samr_obj['RelativeId'],
                   info['Buffer']['General'])
     samr.hSamrCloseHandle(dce, resp['GroupHandle'])
     return group
示例#3
0
    def list_groups(self, remote_name, remote_host):
        """
        List groups
        :param remote_name: (string) remote name to use in rpc connection string
        :param remote_host: (string) remote host to connect to
        :return: (list) List of local groups found, each item contains (groupName, RelativeId, GroupGeneralInfo) 
        """
        rpc_transport = self.__set_rpc_connection(remote_name, remote_host)
        dce = self.__dce_connect(rpc_transport)
        entries = []

        try:
            # Acquire domain handles for BUILTIN and MACHINE domain
            domain_handles = [
                self.__obtain_domain_handle(dce, self.BUILTIN_DOMAIN),
                self.__obtain_domain_handle(dce, self.MACHINE_DOMAIN)
            ]

            for domain_handle in domain_handles:
                status = STATUS_MORE_ENTRIES
                enumeration_context = 0
                while status == STATUS_MORE_ENTRIES:
                    try:
                        resp = samr.hSamrEnumerateAliasesInDomain(
                            dce,
                            domain_handle,
                            enumerationContext=enumeration_context)
                    except DCERPCException as e:
                        if str(e).find('STATUS_MORE_ENTRIES') < 0:
                            raise ListGroupException(e)

                    for group in resp['Buffer']['Buffer']:
                        # Get group information for each group
                        r = samr.hSamrOpenAlias(dce, domain_handle,
                                                samr.MAXIMUM_ALLOWED,
                                                group['RelativeId'])

                        info = samr.hSamrQueryInformationAlias(
                            dce, r['AliasHandle'], samr.
                            ALIAS_INFORMATION_CLASS.AliasGeneralInformation)
                        entry = (group['Name'], group['RelativeId'],
                                 info['Buffer']['General'])
                        entries.append(entry)
                        samr.hSamrCloseHandle(dce, r['AliasHandle'])

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

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

        dce.disconnect()

        return entries
示例#4
0
 def get_entity(dce, domain_handle, samr_obj):
     resp = samr.hSamrOpenUser(dce,
                               domain_handle,
                               userId=samr_obj['RelativeId'])
     info = samr.hSamrQueryInformationUser2(
         dce, resp['UserHandle'],
         samr.USER_INFORMATION_CLASS.UserAllInformation)
     user = User(samr_obj['Name'], samr_obj['RelativeId'],
                 info['Buffer']['All'])
     samr.hSamrCloseHandle(dce, resp['UserHandle'])
     return user
示例#5
0
	def __fetchlist(self, rpctransport):
		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']

		self.log.info('[+] Found domain: {0}'.format(domains[0]['Name']))
		self.log.info("[*] Enumerating RID {0} in the {1} domain..\n".format(self.rid, domains[0]['Name']))
		resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, domains[0]['Name'])
		resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId'])
		domainHandle = resp['DomainHandle']

		request = samr.SamrOpenGroup()
		request['DomainHandle'] = domainHandle
		request['DesiredAccess'] = samr.MAXIMUM_ALLOWED
		request['GroupId'] = self.rid

		try:
			resp = dce.request(request)
		except samr.DCERPCSessionError:
				raise

		request = samr.SamrGetMembersInGroup()
		request['GroupHandle'] = resp['GroupHandle']
		resp = dce.request(request)
		rids = resp.fields['Members'].fields['Data'].fields['Members'].fields['Data'].fields['Data']

		mutex = Lock()
		for rid in rids:
			try:
				resp = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED, rid.fields['Data'])
				rid_data = samr.hSamrQueryInformationUser2(dce, resp['UserHandle'], samr.USER_INFORMATION_CLASS.UserAllInformation)
			except samr.DCERPCSessionError as e:
				# Occasionally an ACCESS_DENIED is rasied even though the user has permissions?
				# Other times a STATUS_NO_SUCH_USER is raised when a rid apparently doesn't exist, even though it reported back as existing.
				self.log.debug(e)
				continue
			if self.fqdn:
				rid_data = rid_data['Buffer']['All']['UserName'].replace('$', '') + '.' + self.fqdn
			else:
				rid_data = rid_data['Buffer']['All']['UserName'].replace('$', '')
			samr.hSamrCloseHandle(dce, resp['UserHandle'])

			if self.dns_lookup:
				# Threading because DNS lookups are slow
				t = Thread(target=self.get_ip, args=(rid_data, mutex,))
				t.start()
			else:
				self.log.info(rid_data)
				self.data.append(rid_data)
		dce.disconnect()
示例#6
0
    def enumerate_users_in_group(self, dce, domain_handle):
        request = samr.SamrOpenGroup()
        request['DomainHandle'] = domain_handle
        request['DesiredAccess'] = samr.MAXIMUM_ALLOWED
        request['GroupId'] = self.rid

        try:
            resp = dce.request(request)
        except samr.DCERPCSessionError:
            raise

        request = samr.SamrGetMembersInGroup()
        request['GroupHandle'] = resp['GroupHandle']
        resp = dce.request(request)
        self.log.info(
            '[*] Group RID detected. Enumerating users/hosts in group..\n')

        try:
            rids = resp['Members']['Members']
        except AttributeError:
            self.log.info('[-] No users in group')
            return

        mutex = Lock()
        for rid in rids:
            try:
                resp = samr.hSamrOpenUser(dce, domain_handle,
                                          samr.MAXIMUM_ALLOWED, rid['Data'])
                rid_data = samr.hSamrQueryInformationUser2(
                    dce, resp['UserHandle'],
                    samr.USER_INFORMATION_CLASS.UserAllInformation)
            except samr.DCERPCSessionError as e:
                # Occasionally an ACCESS_DENIED is rasied even though the user has permissions?
                # Other times a STATUS_NO_SUCH_USER is raised when a rid apparently doesn't exist, even though it reported back as existing.
                self.log.debug(e)
                continue
            if self.fqdn:
                rid_data = rid_data['Buffer']['All']['UserName'].replace(
                    '$', '') + '.' + self.fqdn
            else:
                rid_data = rid_data['Buffer']['All']['UserName'].replace(
                    '$', '')
            samr.hSamrCloseHandle(dce, resp['UserHandle'])

            if self.dns_lookup:
                # Threading because DNS lookups are slow
                t = Thread(target=self.get_ip, args=(
                    rid_data,
                    mutex,
                ))
                t.start()
            else:
                self.log.info(rid_data)
                self.data.append(rid_data)
示例#7
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
示例#8
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
示例#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']

            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
示例#10
0
    def list_users(self, remote_name, remote_host):
        """
        List users
        :param remote_name: (string) remote name to use in rpc connection string
        :param remote_host: (string) remote host to connect to
        :return: (list) List of users found, each item contains (userName, RelativeId, UserAllInfo)
        """
        # Create an DCE/RPC session
        rpc_transport = self.__set_rpc_connection(remote_name, remote_host)
        dce = self.__dce_connect(rpc_transport)
        entries = []

        try:
            # Obtain domain handle
            domain_handle = self.__obtain_domain_handle(dce)
            status = STATUS_MORE_ENTRIES
            enumeration_context = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(
                        dce,
                        domain_handle,
                        enumerationContext=enumeration_context)
                except DCERPCException as e:
                    if str(e).find('STATUS_MORE_ENTRIES') < 0:
                        raise ListUsersException(e)

                for user in resp['Buffer']['Buffer']:
                    # Get user information for each user
                    r = samr.hSamrOpenUser(dce, domain_handle,
                                           samr.MAXIMUM_ALLOWED,
                                           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'])

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

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

        dce.disconnect()

        return entries
示例#11
0
 def _process_raw_entry_info(cls, connection, entry_raw_info):
     """
     This context manager will automatically handle opening and closing Active Directory handles from impacket,
     when trying to extract information regarding the entry.
     :param connection: (dce, domain_handle)
     :param entry_raw_info: entry inforamtion as received from impacket samr buffer.
     """
     entry_resp = cls.OPEN_FUNC(*connection, MAXIMUM_ALLOWED,
                                entry_raw_info[cls.ID_LOCATION])
     entry_handle = entry_resp[cls.HANDLE]
     dce = connection[0]
     entry_info = cls.PROCESS_INFO_FUNC(dce, entry_handle)
     try:
         yield entry_info
     finally:
         samr.hSamrCloseHandle(dce, entry_handle)
示例#12
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
示例#13
0
class SAMRGroupDump:
    def __init__(self, username, password, domain, target, rid, dns_lookup,
                 output):
        self.username = username
        self.password = password
        self.domain = domain
        self.port = 445
        self.target = target
        self.rid = rid
        self.dns_lookup = dns_lookup
        self.log = logging.getLogger('')
        self.output_file = ""
        self.data = []

        if output:
            if not (output).endswith(".txt"):
                output += ".txt"
            self.output_file = output

    @classmethod
    def from_args(cls, args):
        return cls(args.username, args.password, args.domain, args.target,
                   args.rid, args.dns_lookup, args.output)

    def dump(self):
        self.log.info('[*] Retrieving endpoint list from {0}'.format(
            self.target))
        stringbinding = r'ncacn_np:{0}[\pipe\samr]'.format(self.target)
        logging.debug('StringBinding {0}'.format(stringbinding))
        rpctransport = transport.DCERPCTransportFactory(stringbinding)
        rpctransport.set_dport(self.port)
        rpctransport.setRemoteHost(self.target)

        if hasattr(rpctransport, 'set_credentials'):
            rpctransport.set_credentials(self.username, self.password,
                                         self.domain)

        self.__fetchlist(rpctransport)

    def __fetchlist(self, rpctransport):
        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']

        self.log.info('[+] Found domain: {0}'.format(domains[0]['Name']))
        self.log.info("[*] Enumerating RID {0} in the {1} domain..\n".format(
            self.rid, domains[0]['Name']))
        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle,
                                                 domains[0]['Name'])
        resp = samr.hSamrOpenDomain(dce,
                                    serverHandle=serverHandle,
                                    domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']

        request = samr.SamrOpenGroup()
        request['DomainHandle'] = domainHandle
        request['DesiredAccess'] = samr.MAXIMUM_ALLOWED
        request['GroupId'] = self.rid

        try:
            resp = dce.request(request)
        except Exception, e:
            if 'STATUS_NO_SUCH_DOMAIN' in str(e):
                raise

        request = samr.SamrGetMembersInGroup()
        request['GroupHandle'] = resp['GroupHandle']
        resp = dce.request(request)
        domain_computers = resp.fields['Members'].fields['Data'].fields[
            'Members'].fields['Data'].fields['Data']

        mutex = Lock()
        for host in domain_computers:
            resp = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED,
                                      host.fields['Data'])
            rid_data = samr.hSamrQueryInformationUser2(
                dce, resp['UserHandle'],
                samr.USER_INFORMATION_CLASS.UserAllInformation)
            rid_data = rid_data['Buffer']['All']['UserName'].replace('$', '')
            samr.hSamrCloseHandle(dce, resp['UserHandle'])

            if self.dns_lookup:
                # Threading because DNS lookups are slow
                t = Thread(target=self.get_ip, args=(
                    rid_data,
                    mutex,
                ))
                t.start()
            else:
                self.log.info(rid_data)
                self.data.append(rid_data)
        dce.disconnect()
示例#14
0
    def fetchList(self, rpctransport):
        dce = DCERPC_v5(rpctransport)
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)

        # Setup Connection
        resp = samr.hSamrConnect2(dce)
        if resp['ErrorCode'] != 0:
            raise Exception('Connect error')

        resp2 = samr.hSamrEnumerateDomainsInSamServer(
            dce,
            serverHandle=resp['ServerHandle'],
            enumerationContext=0,
            preferedMaximumLength=500)
        if resp2['ErrorCode'] != 0:
            raise Exception('Connect error')

        resp3 = samr.hSamrLookupDomainInSamServer(
            dce,
            serverHandle=resp['ServerHandle'],
            name=resp2['Buffer']['Buffer'][0]['Name'])
        if resp3['ErrorCode'] != 0:
            raise Exception('Connect error')

        resp4 = samr.hSamrOpenDomain(dce,
                                     serverHandle=resp['ServerHandle'],
                                     desiredAccess=samr.MAXIMUM_ALLOWED,
                                     domainId=resp3['DomainId'])
        if resp4['ErrorCode'] != 0:
            raise Exception('Connect error')

        self.__domains = resp2['Buffer']['Buffer']
        domainHandle = resp4['DomainHandle']
        # End Setup

        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:
                    self.logger.error('Error enumerating domain user(s)')
                    break
                resp = e.get_packet()
            self.logger.success('Enumerated domain user(s)')
            for user in resp['Buffer']['Buffer']:
                r = samr.hSamrOpenUser(dce, domainHandle, samr.MAXIMUM_ALLOWED,
                                       user['RelativeId'])
                info = samr.hSamrQueryInformationUser2(
                    dce, r['UserHandle'],
                    samr.USER_INFORMATION_CLASS.UserAllInformation)
                (username, uid, info_user) = (user['Name'], user['RelativeId'],
                                              info['Buffer']['All'])
                self.logger.highlight('{}\\{:<30} {}'.format(
                    self.domain, user['Name'], info_user['AdminComment']))
                self.users.append(user['Name'])
                samr.hSamrCloseHandle(dce, r['UserHandle'])

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

        dce.disconnect()
示例#15
0
    def __samr_users(self, usrdomain=None):
        '''
        Enumerate users on the system
        '''
        self.__samr_domains(True)

        encoding = sys.getdefaultencoding()

        for domain_name, domain in self.domains_dict.items():
            if usrdomain and usrdomain.upper() != domain_name.upper():
                continue

            logger.info('Looking up users in domain %s' % domain_name)

            resp = samr.hSamrLookupDomainInSamServer(self.__dce,
                                                     self.__mgr_handle,
                                                     domain_name)
            resp = samr.hSamrOpenDomain(self.__dce,
                                        serverHandle=self.__mgr_handle,
                                        domainId=resp['DomainId'])
            self.__domain_context_handle = resp['DomainHandle']

            status = STATUS_MORE_ENTRIES
            enum_context = 0
            while status == STATUS_MORE_ENTRIES:
                try:
                    resp = samr.hSamrEnumerateUsersInDomain(
                        self.__dce,
                        self.__domain_context_handle,
                        enumerationContext=enum_context)
                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(self.__dce,
                                           self.__domain_context_handle,
                                           samr.MAXIMUM_ALLOWED,
                                           user['RelativeId'])
                    logger.debug('Found user %s (UID: %d)' %
                                 (user['Name'], user['RelativeId']))
                    info = samr.hSamrQueryInformationUser2(
                        self.__dce, r['UserHandle'],
                        samr.USER_INFORMATION_CLASS.UserAllInformation)
                    entry = (user['Name'], user['RelativeId'],
                             info['Buffer']['All'])
                    self.users_list.add(entry)
                    samr.hSamrCloseHandle(self.__dce, r['UserHandle'])

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

            if self.users_list:
                num = len(self.users_list)
                logger.info('Retrieved %d user%s' %
                            (num, 's' if num > 1 else ''))
            else:
                logger.info('No users enumerated')

            for entry in self.users_list:
                user, uid, info = entry

                print(user)
                print('  User ID: %d' % uid)
                print('  Group ID: %d' % info['PrimaryGroupId'])
                if info['UserAccountControl'] & samr.USER_ACCOUNT_DISABLED:
                    account_disabled = 'True'
                else:
                    account_disabled = 'False'
                print('  Enabled: %s' % account_disabled)

                try:
                    print('  Logon count: %d' % info['LogonCount'])
                except ValueError:
                    pass

                lastLogon = (info['LastLogon']['HighPart'] <<
                             32) + info['LastLogon']['LowPart']
                if lastLogon == 0:
                    lastLogon = '<never>'
                else:
                    lastLogon = str(
                        datetime.fromtimestamp(self.getUnixTime(lastLogon)))

                try:
                    print('  Last Logon: %s' % lastLogon)
                except ValueError:
                    pass

                lastLogoff = (info['LastLogoff']['HighPart'] <<
                              32) + info['LastLogoff']['LowPart']
                if lastLogoff == 0:
                    lastLogoff = '<never>'
                else:
                    lastLogoff = str(
                        datetime.fromtimestamp(self.getUnixTime(lastLogoff)))

                try:
                    print('  Last Logoff: %s' % lastLogoff)
                except ValueError:
                    pass

                pwdLastSet = (info['PasswordLastSet']['HighPart'] <<
                              32) + info['PasswordLastSet']['LowPart']
                if pwdLastSet == 0:
                    pwdLastSet = '<never>'
                else:
                    pwdLastSet = str(
                        datetime.fromtimestamp(self.getUnixTime(pwdLastSet)))

                try:
                    print('  Last password set: %s' % pwdLastSet)
                except ValueError:
                    pass

                if info['PasswordExpired'] == 0:
                    password_expired = 'False'
                elif info['PasswordExpired'] == 1:
                    password_expired = 'True'

                try:
                    print('  Password expired: %s' % password_expired)
                except ValueError:
                    pass

                if info['UserAccountControl'] & samr.USER_DONT_EXPIRE_PASSWORD:
                    dont_expire = 'True'
                else:
                    dont_expire = 'False'

                try:
                    print('  Password does not expire: %s' % dont_expire)
                except ValueError:
                    pass

                pwdCanChange = (info['PasswordCanChange']['HighPart'] <<
                                32) + info['PasswordCanChange']['LowPart']
                if pwdCanChange == 0:
                    pwdCanChange = '<never>'
                else:
                    pwdCanChange = str(
                        datetime.fromtimestamp(self.getUnixTime(pwdCanChange)))

                try:
                    print('  Password can change: %s' % pwdCanChange)
                except ValueError:
                    pass

                try:
                    pwdMustChange = (
                        info['PasswordMustChange']['HighPart'] <<
                        32) + info['PasswordMustChange']['LowPart']
                    if pwdMustChange == 0:
                        pwdMustChange = '<never>'
                    else:
                        pwdMustChange = str(
                            datetime.fromtimestamp(
                                self.getUnixTime(pwdMustChange)))
                except:
                    pwdMustChange = '<never>'

                try:
                    print('  Password must change: %s' % pwdMustChange)
                except ValueError:
                    pass

                try:
                    print('  Bad password count: %d' %
                          info['BadPasswordCount'])
                except ValueError:
                    pass

                try:
                    print('  Full name: %s' % info['FullName'])
                except ValueError:
                    pass

                try:
                    print('  Home directory: %s' % info['HomeDirectory'])
                except ValueError:
                    pass

                try:
                    print('  Home directory drive: %s' %
                          info['HomeDirectoryDrive'])
                except ValueError:
                    pass

                try:
                    print('  Script path: %s' % info['ScriptPath'])
                except ValueError:
                    pass

                try:
                    print('  Profile path: %s' % info['ProfilePath'])
                except ValueError:
                    pass

                try:
                    print('  Admin comment: %s' % info['AdminComment'])
                except ValueError:
                    pass

                try:
                    print('  Workstations: %s' % info['WorkStations'])
                except ValueError:
                    pass

                try:
                    print('  User comment: %s' % info['UserComment'])
                except ValueError:
                    pass

            self.users_list = set()
示例#16
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
示例#17
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()
示例#18
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
示例#19
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()
示例#20
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()
示例#21
0
    def enumerate_user_info(self, dce, domain_handle):
        # Most of this method was built using logic from samrdump.py
        user_request = samr.hSamrOpenUser(dce, domain_handle,
                                          samr.MAXIMUM_ALLOWED, self.rid)
        self.log.info(
            '[*] User RID detected. Enumerating information on user..\n')
        info = samr.hSamrQueryInformationUser(
            dce, user_request['UserHandle'],
            samr.USER_INFORMATION_CLASS.UserAllInformation)
        user = info['Buffer']['All']

        pass_last_set = self.expiration_check(user, 'PasswordLastSet')
        account_expires = self.expiration_check(user, 'AccountExpires')
        pass_expires = self.expiration_check(user, 'PasswordMustChange')
        pass_can_change = self.expiration_check(user, 'PasswordCanChange')
        last_logon = self.expiration_check(user, 'LastLogon')
        account_active = self.attribute_bool(user, samr.USER_ACCOUNT_DISABLED)
        user_may_change_pass = self.attribute_bool(user,
                                                   samr.USER_CHANGE_PASSWORD)
        password_required = self.attribute_bool(
            user, samr.USER_PASSWORD_NOT_REQUIRED)

        workstations_allowed = user['WorkStations']

        if workstations_allowed == '':
            workstations_allowed = 'All'

        self.log.info('User name\t\t\t{0}'.format(user['UserName']))
        self.log.info('User RID\t\t\t{0}'.format(user['UserId']))
        self.log.info('Full Name\t\t\t{0}'.format(user['FullName']))
        self.log.info('Comment\t\t\t\t{0}'.format(user['AdminComment']))
        self.log.info("User's Comment\t\t\t\t{0}".format(user['UserComment']))
        self.log.info('Country/region code\t\t{0}'.format(user['CountryCode']))
        self.log.info('Account active\t\t\t{0}'.format(account_active))
        self.log.info('Account expires\t\t\t{0}\n'.format(account_expires))

        self.log.info('Password last set\t\t{0}'.format(pass_last_set))
        self.log.info('Password expires\t\t{0}'.format(pass_expires))
        self.log.info('Password changeable\t\t{0}'.format(pass_can_change))
        self.log.info('Password required\t\t{0}'.format(password_required))
        self.log.info('Bad Password Count\t\t{0}'.format(
            user['BadPasswordCount']))
        self.log.info(
            'User may change password\t{0}\n'.format(user_may_change_pass))

        self.log.info(
            'Workstations allowed\t\t{0}'.format(workstations_allowed))
        self.log.info('Logon script\t\t\t\t{0}'.format(user['ScriptPath']))
        self.log.info('User profile\t\t\t\t{0}'.format(user['ProfilePath']))
        self.log.info('Home directory\t\t\t{0}'.format(user['HomeDirectory']))
        self.log.info('Home directory drive\t\t{0}\n'.format(
            user['HomeDirectoryDrive']))

        self.log.info('Group Memberships')
        group_rids = samr.hSamrGetGroupsForUser(
            dce, user_request['UserHandle'])['Groups']['Groups']

        for i, group_rid in enumerate(group_rids):
            group_rid = group_rids[i]['RelativeId']
            group_request = samr.hSamrOpenGroup(dce, domain_handle,
                                                samr.MAXIMUM_ALLOWED,
                                                group_rid)
            group_info = samr.hSamrQueryInformationGroup(
                dce, group_request['GroupHandle'])
            group_name = group_info['Buffer']['General']['Name']
            group_comment = group_info['Buffer']['General']['AdminComment']
            self.log.info('Name: {0}\nDesc: {1}\n'.format(
                group_name, group_comment))

        samr.hSamrCloseHandle(dce, user_request['UserHandle'])
        samr.hSamrCloseHandle(dce, group_request['GroupHandle'])