public void StartStealthEnumeration() { var output = new BlockingCollection <Wrapper <OutputBase> >(); var writer = _options.Uri == null ? StartOutputWriter(output) : StartRestWriter(output); foreach (var domainName in _utils.GetDomainList()) { Console.WriteLine($"Starting stealth enumeration for {domainName}\n"); var domainSid = _utils.GetDomainSid(domainName); var data = LdapFilter.GetLdapFilter(_options.CollectMethod, _options.ExcludeDC, true); switch (_options.CollectMethod) { case CollectionMethod.ObjectProps: Console.WriteLine("Doing stealth enumeration for object properties"); foreach (var entry in _utils.DoSearch(data.Filter, SearchScope.Subtree, data.Properties, domainName)) { var resolved = entry.ResolveAdEntry(); OutputBase props; if (resolved.ObjectType.Equals("computer")) { props = ObjectPropertyHelpers.GetComputerProps(entry, resolved); } else { props = ObjectPropertyHelpers.GetUserProps(entry, resolved); } if (props != null) { output.Add(new Wrapper <OutputBase> { Item = props }); } } break; case CollectionMethod.Session: Console.WriteLine("Doing stealth enumeration for sessions"); foreach (var path in SessionHelpers.CollectStealthTargets(domainName)) { var sessions = SessionHelpers.GetNetSessions(path, domainName); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } } break; case CollectionMethod.ComputerOnly: Console.WriteLine("Doing stealth enumeration for sessions"); foreach (var path in SessionHelpers.CollectStealthTargets(domainName)) { var sessions = SessionHelpers.GetNetSessions(path, domainName); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } } Console.WriteLine("Doing stealth enumeration for admins"); foreach (var entry in _utils.DoSearch( data.Filter, SearchScope.Subtree, data.Properties, domainName)) { foreach (var admin in LocalAdminHelpers.GetGpoAdmins(entry, domainName)) { output.Add(new Wrapper <OutputBase> { Item = admin }); } } break; case CollectionMethod.Default: Console.WriteLine("Doing stealth enumeration for sessions"); foreach (var path in SessionHelpers.CollectStealthTargets(domainName)) { var sessions = SessionHelpers.GetNetSessions(path, domainName); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } } Console.WriteLine("Doing stealth enumeration for admins"); foreach (var entry in _utils.DoSearch( "(&(objectCategory=groupPolicyContainer)(name=*)(gpcfilesyspath=*))", SearchScope.Subtree, new[] { "displayname", "name", "gpcfilesyspath" }, domainName)) { foreach (var admin in LocalAdminHelpers.GetGpoAdmins(entry, domainName)) { output.Add(new Wrapper <OutputBase> { Item = admin }); } } Console.WriteLine("Doing stealth enumeration for groups"); foreach (var entry in _utils.DoSearch("(|(memberof=*)(primarygroupid=*))", SearchScope.Subtree, new[] { "samaccountname", "distinguishedname", "dnshostname", "samaccounttype", "primarygroupid", "memberof", "serviceprincipalname" }, domainName)) { var resolvedEntry = entry.ResolveAdEntry(); foreach (var group in GroupHelpers.ProcessAdObject(entry, resolvedEntry, domainSid)) { output.Add(new Wrapper <OutputBase> { Item = group }); } } break; case CollectionMethod.SessionLoop: Console.WriteLine("Doing stealth enumeration for sessions"); foreach (var path in SessionHelpers.CollectStealthTargets(domainName)) { var sessions = SessionHelpers.GetNetSessions(path, domainName); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } } break; case CollectionMethod.LoggedOn: Console.WriteLine("Doing LoggedOn enumeration for stealth targets"); foreach (var path in SessionHelpers.CollectStealthTargets(domainName)) { var sessions = SessionHelpers.GetNetLoggedOn(path, domainName); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } sessions = SessionHelpers.GetRegistryLoggedOn(path); foreach (var s in sessions) { output.Add(new Wrapper <OutputBase> { Item = s }); } } break; case CollectionMethod.Group: Console.WriteLine("Doing stealth enumeration for groups"); foreach (var entry in _utils.DoSearch(data.Filter, SearchScope.Subtree, data.Properties, domainName)) { var resolvedEntry = entry.ResolveAdEntry(); foreach (var group in GroupHelpers.ProcessAdObject(entry, resolvedEntry, domainSid)) { output.Add(new Wrapper <OutputBase> { Item = group }); } } break; case CollectionMethod.LocalGroup: //This case will never happen break; case CollectionMethod.GPOLocalGroup: Console.WriteLine("Doing stealth enumeration for admins"); foreach (var entry in _utils.DoSearch( data.Filter, SearchScope.Subtree, data.Properties, domainName)) { foreach (var admin in LocalAdminHelpers.GetGpoAdmins(entry, domainName)) { output.Add(new Wrapper <OutputBase> { Item = admin }); } } break; case CollectionMethod.Trusts: var trusts = DomainTrustEnumeration.DoTrustEnumeration(domainName); foreach (var trust in trusts) { output.Add(new Wrapper <OutputBase> { Item = trust }); } break; case CollectionMethod.ACL: Console.WriteLine("Doing stealth enumeration for ACLs"); foreach (var entry in _utils.DoSearch( data.Filter, SearchScope.Subtree, data.Properties, domainName)) { foreach (var acl in AclHelpers.ProcessAdObject(entry, domainName)) { output.Add(new Wrapper <OutputBase> { Item = acl }); } } break; default: throw new ArgumentOutOfRangeException(); } output.CompleteAdding(); writer.Wait(); Console.WriteLine($"Finished stealth enumeration for {domainName}"); } if (!_options.CollectMethod.Equals(CollectionMethod.SessionLoop)) { return; } if (_options.MaxLoopTime != null) { if (DateTime.Now > _options.LoopEnd) { Console.WriteLine("Exiting session loop as LoopEndTime as passed"); return; } } Console.WriteLine($"Starting next session run in {_options.LoopTime} minutes"); new ManualResetEvent(false).WaitOne(_options.LoopTime * 60 * 1000); if (_options.MaxLoopTime != null) { if (DateTime.Now > _options.LoopEnd) { Console.WriteLine("Exiting session loop as LoopEndTime as passed"); return; } } Console.WriteLine("Starting next enumeration loop"); StartStealthEnumeration(); }
public void StartEnumeration() { //Let's determine what LDAP filter we need first var data = LdapFilter.GetLdapFilter(_options.CollectMethod, _options.ExcludeDC, _options.Stealth); var ldapFilter = data.Filter; var props = data.Properties; var c = _options.CollectMethod; foreach (var domainName in _utils.GetDomainList()) { _noPing = 0; _timeouts = 0; Console.WriteLine($"Starting enumeration for {domainName}"); _watch = Stopwatch.StartNew(); _currentDomain = domainName; _currentDomainSid = _utils.GetDomainSid(domainName); _currentCount = 0; var outputQueue = new BlockingCollection <Wrapper <OutputBase> >(); if (_options.ComputerFile == null) { var inputQueue = new BlockingCollection <Wrapper <SearchResultEntry> >(1000); var taskhandles = new Task[_options.Threads]; var writer = _options.Uri == null ? StartOutputWriter(outputQueue) : StartRestWriter(outputQueue); if (c.Equals(CollectionMethod.Trusts) || c.Equals(CollectionMethod.Default)) { foreach (var domain in DomainTrustEnumeration.DoTrustEnumeration(domainName)) { outputQueue.Add(new Wrapper <OutputBase> { Item = domain }); } if (_options.CollectMethod.Equals(CollectionMethod.Trusts)) { outputQueue.CompleteAdding(); writer.Wait(); continue; } } if (c.Equals(CollectionMethod.Container)) { foreach (var container in ContainerHelpers.GetContainersForDomain(domainName)) { outputQueue.Add(new Wrapper <OutputBase> { Item = container }); } if (_options.CollectMethod.Equals(CollectionMethod.Container)) { outputQueue.CompleteAdding(); writer.Wait(); continue; } } for (var i = 0; i < _options.Threads; i++) { taskhandles[i] = StartRunner(inputQueue, outputQueue); } _statusTimer.Start(); IEnumerable <Wrapper <SearchResultEntry> > items; if ((c.Equals(CollectionMethod.ComputerOnly) || c.Equals(CollectionMethod.Session) || c.Equals(CollectionMethod.LocalGroup) || c.Equals(CollectionMethod.LoggedOn)) && _options.Ou != null) { items = _utils.DoWrappedSearch(ldapFilter, SearchScope.Subtree, props, domainName, _options.Ou); } else { items = _utils.DoWrappedSearch(ldapFilter, SearchScope.Subtree, props, domainName); } foreach (var item in items) { inputQueue.Add(item); } inputQueue.CompleteAdding(); Utils.Verbose("Waiting for enumeration threads to finish"); Task.WaitAll(taskhandles); _statusTimer.Stop(); if (_options.CollectMethod.Equals(CollectionMethod.ACL)) { foreach (var a in AclHelpers.GetSyncers()) { outputQueue.Add(new Wrapper <OutputBase> { Item = a }); } AclHelpers.ClearSyncers(); } PrintStatus(); outputQueue.CompleteAdding(); Utils.Verbose("Waiting for writer thread to finish"); writer.Wait(); _watch.Stop(); Console.WriteLine($"Finished enumeration for {domainName} in {_watch.Elapsed}"); Console.WriteLine($"{_noPing} hosts failed ping. {_timeouts} hosts timedout."); _watch = null; } else { var inputQueue = new BlockingCollection <Wrapper <string> >(1000); var taskhandles = new Task[_options.Threads]; var writer = _options.Uri == null?StartOutputWriter(outputQueue) : StartRestWriter(outputQueue); for (var i = 0; i < _options.Threads; i++) { taskhandles[i] = StartCompListRunner(inputQueue, outputQueue); } _statusTimer.Start(); using (var reader = new StreamReader(_options.ComputerFile)) { string line; while ((line = reader.ReadLine()) != null) { inputQueue.Add(new Wrapper <string> { Item = line }); } inputQueue.CompleteAdding(); } Utils.Verbose("Waiting for enumeration threads to finish"); Task.WaitAll(taskhandles); _statusTimer.Stop(); PrintStatus(); outputQueue.CompleteAdding(); Utils.Verbose("Waiting for writer thread to finish"); writer.Wait(); _watch.Stop(); Console.WriteLine($"Finished enumeration for {domainName} in {_watch.Elapsed}"); Console.WriteLine($"{_noPing} hosts failed ping. {_timeouts} hosts timedout."); _watch = null; } } if (!_options.CollectMethod.Equals(CollectionMethod.SessionLoop)) { return; } if (_options.MaxLoopTime != null) { if (DateTime.Now > _options.LoopEnd) { Console.WriteLine("Exiting session loop as LoopEndTime as passed"); return; } } Console.WriteLine($"Starting next session run in {_options.LoopTime} minutes"); new ManualResetEvent(false).WaitOne(_options.LoopTime * 60 * 1000); if (_options.MaxLoopTime != null) { if (DateTime.Now > _options.LoopEnd) { Console.WriteLine("Exiting session loop as LoopEndTime as passed"); return; } } Console.WriteLine("Starting next enumeration loop"); StartEnumeration(); }