def write_membership(self, resolved_entry, membership, out): if membership in self.ad.groups: parent = self.ad.groups[membership] pd = ADUtils.ldap2domain(membership) pr = self.resolve_ad_entry(parent) out.write(u'%s,%s,%s\n' % (pr['principal'], resolved_entry['principal'], resolved_entry['type'])) else: logging.warning('Warning: Unknown group %s', membership)
def rpc_resolve_sids(self): binding = r'ncacn_np:%s[\PIPE\lsarpc]' % self.addr dce = self.dce_rpc_connect(binding, lsat.MSRPC_UUID_LSAT) if dce is None: logging.warning('Connection failed') return try: resp = lsat.hLsarOpenPolicy2(dce, lsat.POLICY_LOOKUP_NAMES | MAXIMUM_ALLOWED) except Exception as e: if str(e).find('Broken pipe') >= 0: return else: raise policyHandle = resp['PolicyHandle'] try: resp = lsat.hLsarLookupSids(dce, policyHandle, self.sids, lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta) except DCERPCException as e: if str(e).find('STATUS_NONE_MAPPED') >= 0: logging.warning('SID lookup failed, return status: STATUS_NONE_MAPPED') raise elif str(e).find('STATUS_SOME_NOT_MAPPED') >= 0: # Not all could be resolved, work with the ones that could resp = e.get_packet() else: raise domains = [] for entry in resp['ReferencedDomains']['Domains']: logging.debug('Found referenced domain: %s' % entry['Name']) domains.append(entry['Name']) i = 0 for entry in resp['TranslatedNames']['Names']: domain = domains[entry['DomainIndex']] domainEntry = self.ad.get_domain_by_name(domain) if domainEntry is not None: domain = ADUtils.ldap2domain(domainEntry['attributes']['distinguishedName']) if entry['Name'] != '': logging.debug('Resolved SID to name: %s@%s' % (entry['Name'], domain)) self.admins.append({'computer': self.hostname, 'name': unicode(entry['Name']), 'use': ADUtils.translateSidType(entry['Use']), 'domain': domain, 'sid': self.sids[i]}) i = i + 1 else: logging.warning('Resolved name is empty [%s]', entry) dce.disconnect()
def resolve_ad_entry(self, entry): resolved = {} account = '' dn = '' domain = '' if entry['attributes']['sAMAccountName']: account = entry['attributes']['sAMAccountName'] if entry['attributes']['distinguishedName']: dn = entry['attributes']['distinguishedName'] domain = ADUtils.ldap2domain(dn) resolved['principal'] = unicode('%s@%s' % (account, domain)).upper() if not entry['attributes']['sAMAccountName']: # This doesn't make sense currently but neither does it in SharpHound. # TODO: figure out what the intended result is if 'ForeignSecurityPrincipals' in dn: resolved['principal'] = domain.upper() resolved['type'] = 'foreignsecurityprincipal' else: resolved['type'] = 'unknown' else: accountType = entry['attributes']['sAMAccountType'] if accountType in [268435456, 268435457, 536870912, 536870913]: resolved['type'] = 'group' elif accountType in [805306369]: resolved['type'] = 'computer' short_name = account.rstrip('$') resolved['principal'] = unicode('%s.%s' % (short_name, domain)).upper() elif accountType in [805306368]: resolved['type'] = 'user' elif accountType in [805306370]: resolved['type'] = 'trustaccount' else: resolved['type'] = 'domain' return resolved
def fromLDAP(identifier, sid=None): dns_name = ADUtils.ldap2domain(identifier) return ADDomain(name=dns_name, sid=sid, distinguishedname=identifier)