Ejemplo n.º 1
0
    def __getLocalAdminSids(self):
        dce = self.__getDceBinding(self.__samrBinding)
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin')
        resp = samr.hSamrOpenDomain(dce,
                                    serverHandle=serverHandle,
                                    domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']
        resp = samr.hSamrEnumerateAliasesInDomain(dce, domainHandle)
        aliases = {}
        for alias in resp['Buffer']['Buffer']:
            aliases[alias['Name']] = alias['RelativeId']
        resp = samr.hSamrOpenAlias(dce,
                                   domainHandle,
                                   desiredAccess=MAXIMUM_ALLOWED,
                                   aliasId=aliases['Administrators'])
        resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle'])
        memberSids = []
        for member in resp['Members']['Sids']:
            memberSids.append(member['SidPointer'].formatCanonical())
        dce.disconnect()
        return memberSids
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    def __fetchAdminSidList(self, rpctransport):
        dce = rpctransport.get_dce_rpc()

        domain = None
        entries = []

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

        admin_sids = []

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

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

            domainNames = []
            for domain in domains:
                domainNames.append(domain['Name'])

            domain = "Builtin"

            resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, domain)

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

            resp = samr.hSamrEnumerateAliasesInDomain(dce, domainHandle)

            for alias in resp['Buffer']['Buffer']:
                if alias['RelativeId'] == 544:
                    # Admin group
                    resp = samr.hSamrOpenAlias(dce,
                                               domainHandle,
                                               desiredAccess=MAXIMUM_ALLOWED,
                                               aliasId=alias['RelativeId'])

                    resp = samr.hSamrGetMembersInAlias(dce,
                                                       resp["AliasHandle"])
                    for member in resp["Members"]["Sids"]:
                        admin_sids.append(
                            member["SidPointer"].formatCanonical())

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

        dce.disconnect()

        return admin_sids
Ejemplo n.º 4
0
    def __getLocalAdminSids(self):
        dce = self.__getDceBinding(self.__samrBinding)
        dce.connect()
        dce.bind(samr.MSRPC_UUID_SAMR)
        resp = samr.hSamrConnect(dce)
        serverHandle = resp['ServerHandle']

        resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin')
        resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId'])
        domainHandle = resp['DomainHandle']
        resp = samr.hSamrEnumerateAliasesInDomain(dce, domainHandle)
        aliases = {}
        for alias in resp['Buffer']['Buffer']:
            aliases[alias['Name']] =  alias['RelativeId']
        resp = samr.hSamrOpenAlias(dce, domainHandle, desiredAccess=MAXIMUM_ALLOWED, aliasId=aliases['Administrators'])
        resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle'])
        memberSids = []
        for member in resp['Members']['Sids']:
            memberSids.append(member['SidPointer'].formatCanonical())
        dce.disconnect()
        return memberSids
Ejemplo n.º 5
0
 def getDomainAliases(self, domainHandle):
     resp = samr.hSamrEnumerateAliasesInDomain(self.dce, domainHandle)
     aliases = {}
     for alias in resp['Buffer']['Buffer']:
         aliases[alias['Name']] = alias['RelativeId']
     return aliases
Ejemplo 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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
 def enumerate(dce, domain_handle):
     return samr.hSamrEnumerateAliasesInDomain(dce, domain_handle)