public StealthProducer(IContext context, Channel <ISearchResultEntry> channel) : base(context, channel) { var ldapData = CreateLDAPData(); _query = ldapData.Filter; _props = ldapData.Props; }
public static async IAsyncEnumerable <TypedPrincipal> GetContainerChildObjects(SearchResultEntry entry) { var filter = new LDAPFilter().AddComputers().AddUsers().AddGroups().AddOUs().AddContainers(); foreach (var childEntry in LDAPUtils.QueryLDAP(filter.GetFilter(), SearchScope.OneLevel, CommonProperties.ObjectID, Helpers.DistinguishedNameToDomain(entry.DistinguishedName), adsPath: entry.DistinguishedName)) { var dn = childEntry.DistinguishedName.ToUpper(); if (dn.Contains("CN=SYSTEM") || dn.Contains("CN=POLICIES") || dn.Contains("CN=PROGRAM DATA")) { continue; } var id = childEntry.GetObjectIdentifier(); if (id == null) { continue; } var res = LDAPUtils.ResolveIDAndType(id, Helpers.DistinguishedNameToDomain(childEntry.DistinguishedName)); if (res == null) { continue; } yield return(res); } }
/// <summary> /// Deletes the group with the given name /// </summary> /// <param name="groupName">The group name</param> /// <param name="token">The cancellation token for the operation</param> /// <returns>Flag to indicate if the operation was successful</returns> public async Task <bool> TryDeleteGroupAsync(string groupName, CancellationToken token) { var roles = new List <LDAPObject>(); var filter = new LDAPFilter { Description = "objectClass", Value = "organizationalUnit", FilterType = LDAPFilterType.EqualityMatch }; filter &= new LDAPFilter { Description = "ou", Value = groupName, FilterType = LDAPFilterType.EqualityMatch }; var res = await _session.TrySearch(_session.CurrentScope.Domain, LDAPScope.EntireSubtree, LDAPAliasDereferencing.Always, filter, token); if (res.WasSuccessful) { var success = true; foreach (var obj in res.Objects) { res = await _session.TryRemove(obj, token); success &= res.WasSuccessful; // Abort early if (!success) { return(success); } } return(success); } return(false); }
/// <summary> /// Locates the user, if they exist and session has permissions /// </summary> /// <param name="name">The user name</param> /// <param name="domain">The user domain</param> /// <param name="token">The token to use for the call</param> /// <returns>A LDAPUser, if one exists for the given parameters</returns> public async Task <LDAPUser> FindUserAsync(string name, string domain, CancellationToken token) { // Ensure the session is started await _session.StartAsync(); // Ensure we are bound if (_session.State != LDAPSessionState.Bound) { _log.LogInformation("Unbound session, trying to bind to administrator"); if (!await _session.TryBindAsync(_options.Administrator.AsDistinguishedName(_options.Domain), _options.Credentials, CancellationToken.None)) { return(null); } } // Not entirely sure cn is the best way to go about it, but works for now var filter = new LDAPFilter { Description = "cn", Value = name, FilterType = LDAPFilterType.EqualityMatch }; var res = await _session.TrySearch(name.AsDistinguishedName(domain), LDAPScope.EntireSubtree, LDAPAliasDereferencing.Always, filter, token); if (res.WasSuccessful) { foreach (var obj in res.Objects) { return(new LDAPUser(obj)); } } return(null); }
/// <summary> /// Finds all immediate child objects of a container. /// </summary> /// <param name="distinguishedName"></param> /// <param name="containerName"></param> /// <returns></returns> public IEnumerable <TypedPrincipal> GetContainerChildObjects(string distinguishedName, string containerName = "") { var filter = new LDAPFilter().AddComputers().AddUsers().AddGroups().AddOUs().AddContainers(); foreach (var childEntry in _utils.QueryLDAP(filter.GetFilter(), SearchScope.OneLevel, CommonProperties.ObjectID, Helpers.DistinguishedNameToDomain(distinguishedName), adsPath: distinguishedName)) { var dn = childEntry.DistinguishedName; if (IsDistinguishedNameFiltered(dn)) { _log.LogTrace("Skipping filtered child {Child} for {Container}", dn, containerName); continue; } var id = childEntry.GetObjectIdentifier(); if (id == null) { _log.LogTrace("Got null ID for {ChildDN} under {Container}", childEntry.DistinguishedName, containerName); continue; } var res = _utils.ResolveIDAndType(id, Helpers.DistinguishedNameToDomain(dn)); if (res == null) { _log.LogTrace("Failed to resolve principal for {ID}", id); continue; } yield return(res); } }
/// <summary> /// Finds stealth targets using ldap properties. /// </summary> /// <returns></returns> private async Task <Dictionary <string, ISearchResultEntry> > FindPathTargetSids() { var paths = new ConcurrentDictionary <string, byte>(); var sids = new Dictionary <string, ISearchResultEntry>(); var query = new LDAPFilter(); query.AddComputers("(|(homedirectory=*)(scriptpath=*)(profilepath=*))"); foreach (var domain in Context.Domains) { //Request user objects with the "homedirectory", "scriptpath", or "profilepath" attributes Parallel.ForEach(Context.LDAPUtils.QueryLDAP( query.GetFilter(), SearchScope.Subtree, new[] { "homedirectory", "scriptpath", "profilepath" }, domain), searchResult => { //Grab any properties that exist, filter out null values var poss = new[] { searchResult.GetProperty("homedirectory"), searchResult.GetProperty("scriptpath"), searchResult.GetProperty("profilepath") }.Where(s => s != null); // Loop over each possibility, and grab the hostname from the path, adding it to a list foreach (var s in poss) { var split = s.Split('\\'); if (!(split.Length >= 3)) { continue; } var path = split[2]; paths.TryAdd(path, new byte()); } }); } // Loop over the paths we grabbed, and resolve them to sids. foreach (var path in paths.Keys) { var sid = await Context.LDAPUtils.ResolveHostToSid(path, Context.DomainName); if (sid != null && sid.StartsWith("S-1-5")) { var searchResult = Context.LDAPUtils.QueryLDAP(CommonFilters.SpecificSID(sid), SearchScope.Subtree, _props.ToArray()); sids.Add(sid, searchResult.FirstOrDefault()); } } //Return all the sids corresponding to objects return(sids); }
public void LDAPFilter_GroupFilter_ExtraFilter_FilterCorrect() { var test = new LDAPFilter(); test.AddGroups("objectclass=*"); var filter = test.GetFilter(); _testOutputHelper.WriteLine(filter); Assert.Equal( "(&(|(samaccounttype=268435456)(samaccounttype=268435457)(samaccounttype=536870912)(samaccounttype=536870913))(objectclass=*))", filter); }
/// <summary> /// Gets the list of groups available in LDAP /// </summary> /// <param name="token">The cancellation token for the operation</param> /// <returns>A collection of groups</returns> public async Task <List <LDAPObject> > ListGroupsAsync(CancellationToken token) { var groups = new List <LDAPObject>(); var filter = new LDAPFilter { Description = "objectClass", Value = "organizationalUnit", FilterType = LDAPFilterType.EqualityMatch }; var res = await _session.TrySearch(_session.CurrentScope.Domain, LDAPScope.EntireSubtree, LDAPAliasDereferencing.Always, filter, token); if (res.WasSuccessful) { foreach (var obj in res.Objects) { groups.Add(obj); } } return(groups); }
protected LDAPData CreateLDAPData() { var query = new LDAPFilter(); var props = new List <string>(); var data = new LDAPData(); props.AddRange(CommonProperties.BaseQueryProps); props.AddRange(CommonProperties.TypeResolutionProps); var methods = Context.ResolvedCollectionMethods; if ((methods & ResolvedCollectionMethod.ObjectProps) != 0 || (methods & ResolvedCollectionMethod.ACL) != 0) { query = query.AddComputers().AddContainers().AddUsers().AddGroups().AddDomains().AddOUs().AddGPOs(); props.AddRange(CommonProperties.ObjectPropsProps); if ((methods & ResolvedCollectionMethod.Container) != 0) { props.AddRange(CommonProperties.ContainerProps); } if ((methods & ResolvedCollectionMethod.Group) != 0) { props.AddRange(CommonProperties.GroupResolutionProps); query = query.AddPrimaryGroups(); } if ((methods & ResolvedCollectionMethod.ACL) != 0) { props.AddRange(CommonProperties.ACLProps); } if ((methods & ResolvedCollectionMethod.LocalAdmin) != 0 || (methods & ResolvedCollectionMethod.DCOM) != 0 || (methods & ResolvedCollectionMethod.PSRemote) != 0 || (methods & ResolvedCollectionMethod.RDP) != 0 || (methods & ResolvedCollectionMethod.LoggedOn) != 0 || (methods & ResolvedCollectionMethod.Session) != 0 || (methods & ResolvedCollectionMethod.ObjectProps) != 0) { props.AddRange(CommonProperties.ComputerMethodProps); } if ((methods & ResolvedCollectionMethod.Trusts) != 0) { props.AddRange(CommonProperties.DomainTrustProps); } if ((methods & ResolvedCollectionMethod.GPOLocalGroup) != 0) { props.AddRange(CommonProperties.GPOLocalGroupProps); } if ((methods & ResolvedCollectionMethod.SPNTargets) != 0) { props.AddRange(CommonProperties.SPNTargetProps); } } else { if ((methods & ResolvedCollectionMethod.Container) != 0) { query = query.AddContainers().AddDomains(); props.AddRange(CommonProperties.ContainerProps); } if ((methods & ResolvedCollectionMethod.Group) != 0) { query = query.AddGroups().AddPrimaryGroups(); props.AddRange(CommonProperties.GroupResolutionProps); } if ((methods & ResolvedCollectionMethod.LocalAdmin) != 0 || (methods & ResolvedCollectionMethod.DCOM) != 0 || (methods & ResolvedCollectionMethod.PSRemote) != 0 || (methods & ResolvedCollectionMethod.RDP) != 0 || (methods & ResolvedCollectionMethod.LoggedOn) != 0 || (methods & ResolvedCollectionMethod.Session) != 0 || (methods & ResolvedCollectionMethod.ObjectProps) != 0) { query = query.AddComputers(); props.AddRange(CommonProperties.ComputerMethodProps); } if ((methods & ResolvedCollectionMethod.Trusts) != 0) { query = query.AddDomains(); props.AddRange(CommonProperties.DomainTrustProps); } if ((methods & ResolvedCollectionMethod.SPNTargets) != 0) { query = query.AddUsers(CommonFilters.NeedsSPN); props.AddRange(CommonProperties.SPNTargetProps); } if ((methods & ResolvedCollectionMethod.GPOLocalGroup) != 0) { query = query.AddOUs(); props.AddRange(CommonProperties.GPOLocalGroupProps); } } if (Context.LdapFilter != null) { query.AddFilter(Context.LdapFilter, true); } data.Filter = query; data.Props = props; return(data); }
public async Task WriteAsync(LDAPFilter filter) { switch (filter.FilterType) { case LDAPFilterType.Add: case LDAPFilterType.Or: case LDAPFilterType.Not: var bWriter = new LDAPWriter(); foreach (var f in filter.Children) { await bWriter.WriteAsync(f); } await WriteAsync(bWriter, (int)filter.FilterType, EncodingScope.CONTEXT_SPECIFIC); break; case LDAPFilterType.Substring: var subWriter = new LDAPWriter(); await subWriter.WriteAsync(filter.Description); var subSequenceWriter = new LDAPWriter(); foreach (var sub in filter.Substrings) { await subSequenceWriter.WriteAsync(sub.Value, (int)sub.SubstringType, EncodingScope.CONTEXT_SPECIFIC); } await subWriter.WriteAsync(subSequenceWriter); await WriteAsync(subWriter, (int)filter.FilterType, EncodingScope.CONTEXT_SPECIFIC); break; case LDAPFilterType.EqualityMatch: case LDAPFilterType.GreaterOrEqual: case LDAPFilterType.LessOrEqual: case LDAPFilterType.ApproximateMatch: var valWriter = new LDAPWriter(); await valWriter.WriteAsync(filter.Description); await valWriter.WriteAsync(filter.Value); await WriteAsync(valWriter, (int)filter.FilterType, EncodingScope.CONTEXT_SPECIFIC); break; case LDAPFilterType.Present: var desc = string.IsNullOrEmpty(filter.Value) ? filter.Description : "{0}={1}".ToFormat(filter.Description, filter.Value); await WriteAsync(desc, (int)filter.FilterType, EncodingScope.CONTEXT_SPECIFIC); break; case LDAPFilterType.ExtensibleMatch: var eWriter = new LDAPWriter(); if (!string.IsNullOrEmpty(filter.MatchingRule)) { await eWriter.WriteAsync(filter.MatchingRule, 1, EncodingScope.CONTEXT_SPECIFIC); } if (!string.IsNullOrEmpty(filter.Description)) { await eWriter.WriteAsync(filter.Description, 2, EncodingScope.CONTEXT_SPECIFIC); } await eWriter.WriteAsync(filter.Value, 3, EncodingScope.CONTEXT_SPECIFIC); await eWriter.WriteAsync(filter.AllAttributes, 4, EncodingScope.CONTEXT_SPECIFIC); await WriteAsync(eWriter, (int)filter.FilterType, EncodingScope.CONTEXT_SPECIFIC); break; default: throw new LDAPProtocolException("Unsupported filter type: {0}".ToFormat(filter.FilterType)); } }
public void LDAPFilter_CreateNewFilter_FilterNotNull() { var test = new LDAPFilter(); Assert.NotNull(test); }