示例#1
0
        private Task StartListRunner(BlockingCollection <Wrapper <string> > input, BlockingCollection <Wrapper <JsonBase> > output)
        {
            return(Task.Factory.StartNew(() =>
            {
                foreach (var wrapper in input.GetConsumingEnumerable())
                {
                    var item = wrapper.Item;

                    var resolved = _utils.ResolveHost(item);
                    Interlocked.Increment(ref _currentCount);
                    if (resolved == null || !_utils.PingHost(resolved))
                    {
                        Interlocked.Increment(ref _noPing);
                        wrapper.Item = null;
                        continue;
                    }

                    var netbios = Utils.GetComputerNetbiosName(resolved, out var domain);
                    var temp = _utils.GetDomain(domain);
                    if (temp != null)
                    {
                        domain = temp.Name;
                    }

                    var full = new ResolvedEntry
                    {
                        BloodHoundDisplay = resolved,
                        ComputerSamAccountName = netbios,
                        ObjectType = "computer"
                    };

                    var obj = new Computer
                    {
                        Name = resolved
                    };

                    obj.Properties.Add("highvalue", false);
                    var timeout = false;

                    try
                    {
                        foreach (var s in SessionHelpers.GetNetSessions(full, domain))
                        {
                            output.Add(new Wrapper <JsonBase>
                            {
                                Item = s
                            });
                        }
                    }
                    catch (TimeoutException)
                    {
                        timeout = true;
                    }

                    try
                    {
                        obj.LocalAdmins = LocalGroupHelpers
                                          .GetGroupMembers(full, LocalGroupHelpers.LocalGroupRids.Administrators).ToArray();
                    }
                    catch (TimeoutException)
                    {
                        timeout = true;
                    }

                    try
                    {
                        obj.RemoteDesktopUsers = LocalGroupHelpers
                                                 .GetGroupMembers(full, LocalGroupHelpers.LocalGroupRids.RemoteDesktopUsers).ToArray();
                    }
                    catch (TimeoutException)
                    {
                        timeout = true;
                    }

                    try
                    {
                        obj.DcomUsers = LocalGroupHelpers
                                        .GetGroupMembers(full, LocalGroupHelpers.LocalGroupRids.DcomUsers).ToArray();
                    }
                    catch (TimeoutException)
                    {
                        timeout = true;
                    }

                    try
                    {
                        foreach (var s in SessionHelpers.DoLoggedOnCollection(full, domain))
                        {
                            output.Add(new Wrapper <JsonBase>
                            {
                                Item = s
                            });
                        }
                    }
                    catch (TimeoutException)
                    {
                        timeout = true;
                    }

                    if (timeout)
                    {
                        Interlocked.Increment(ref _timeouts);
                    }

                    if (obj.LocalAdmins?.Length == 0)
                    {
                        obj.LocalAdmins = null;
                    }

                    if (obj.RemoteDesktopUsers?.Length == 0)
                    {
                        obj.RemoteDesktopUsers = null;
                    }

                    if (!_options.SessionLoopRunning)
                    {
                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                }
            }));
        }
示例#2
0
        private Task StartRunner(BlockingCollection <Wrapper <SearchResultEntry> > processQueue,
                                 BlockingCollection <Wrapper <JsonBase> > output)
        {
            return(Task.Factory.StartNew(() =>
            {
                foreach (var wrapper in processQueue.GetConsumingEnumerable())
                {
                    var entry = wrapper.Item;
                    var resolved = entry.ResolveAdEntry();

                    if (resolved == null)
                    {
                        Interlocked.Increment(ref _currentCount);
                        wrapper.Item = null;
                        continue;
                    }

                    var sid = entry.GetSid();
                    var domain = Utils.ConvertDnToDomain(entry.DistinguishedName).ToUpper();
                    var domainSid = _utils.GetDomainSid(domain);

                    if (resolved.ObjectType == "user")
                    {
                        var obj = new User
                        {
                            Name = resolved.BloodHoundDisplay
                        };

                        obj.Properties.Add("domain", domain);
                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", false);

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "group")
                    {
                        var obj = new Group
                        {
                            Name = resolved.BloodHoundDisplay
                        };

                        if (sid.EndsWith("-512") || sid.EndsWith("-516") || sid.EndsWith("-519") ||
                            sid.EndsWith("-520") || sid.Equals("S-1-5-32-544") || sid.Equals("S-1-5-32-550") ||
                            sid.Equals("S-1-5-32-549") || sid.Equals("S-1-5-32-551") || sid.Equals("S-1-5-32-548"))
                        {
                            obj.Properties.Add("highvalue", true);
                        }
                        else
                        {
                            obj.Properties.Add("highvalue", false);
                        }

                        obj.Properties.Add("domain", domain);
                        obj.Properties.Add("objectsid", sid);

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "computer")
                    {
                        var obj = new Computer
                        {
                            Name = resolved.BloodHoundDisplay,
                            LocalAdmins = new LocalMember[] {},
                            RemoteDesktopUsers = new LocalMember[] {}
                        };

                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", false);
                        obj.Properties.Add("domain", domain);


                        if (Utils.IsMethodSet(ResolvedCollectionMethod.Group))
                        {
                            if (entry.DistinguishedName.ToLower().Contains("domain controllers"))
                            {
                                _entDcs.Enqueue(new GroupMember
                                {
                                    MemberName = resolved.BloodHoundDisplay,
                                    MemberType = "computer"
                                });
                            }
                        }

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        if (!_utils.PingHost(resolved.BloodHoundDisplay))
                        {
                            Interlocked.Increment(ref _noPing);
                        }
                        else
                        {
                            var timeout = false;
                            try
                            {
                                obj.LocalAdmins = LocalGroupHelpers
                                                  .GetGroupMembers(resolved, LocalGroupHelpers.LocalGroupRids.Administrators)
                                                  .ToArray();
                            }
                            catch (TimeoutException)
                            {
                                timeout = true;
                            }

                            try
                            {
                                obj.RemoteDesktopUsers = LocalGroupHelpers.GetGroupMembers(resolved,
                                                                                           LocalGroupHelpers.LocalGroupRids.RemoteDesktopUsers).ToArray();
                            }
                            catch (TimeoutException)
                            {
                                timeout = true;
                            }

                            try
                            {
                                obj.DcomUsers = LocalGroupHelpers.GetGroupMembers(resolved,
                                                                                  LocalGroupHelpers.LocalGroupRids.DcomUsers).ToArray();
                            }
                            catch (TimeoutException)
                            {
                                timeout = true;
                            }

                            try
                            {
                                foreach (var s in SessionHelpers.GetNetSessions(resolved, domain))
                                {
                                    output.Add(new Wrapper <JsonBase>
                                    {
                                        Item = s
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                timeout = true;
                            }

                            try
                            {
                                foreach (var s in SessionHelpers.DoLoggedOnCollection(resolved, domain))
                                {
                                    output.Add(new Wrapper <JsonBase>
                                    {
                                        Item = s
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                timeout = true;
                            }

                            if (timeout)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }

                        if (!_options.SessionLoopRunning)
                        {
                            output.Add(new Wrapper <JsonBase>
                            {
                                Item = obj
                            });
                        }
                    }
                    else if (resolved.ObjectType == "domain")
                    {
                        var obj = new Domain
                        {
                            Name = resolved.BloodHoundDisplay
                        };

                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", true);

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);
                        ContainerHelpers.ResolveContainer(entry, resolved, ref obj);
                        TrustHelpers.DoTrustEnumeration(resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "gpo")
                    {
                        var obj = new Gpo
                        {
                            Name = resolved.BloodHoundDisplay,
                            Guid = entry.GetProp("name").Replace("{", "").Replace("}", "")
                        };

                        obj.Properties.Add("highvalue", false);

                        AclHelpers.GetObjectAces(entry, resolved, ref obj);
                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);

                        foreach (var a in LocalGroupHelpers.GetGpoMembers(entry, domain))
                        {
                            output.Add(new Wrapper <JsonBase>
                            {
                                Item = a
                            });
                        }

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "ou")
                    {
                        var obj = new Ou
                        {
                            Guid = new Guid(entry.GetPropBytes("objectguid")).ToString().ToUpper()
                        };

                        obj.Properties.Add("name", resolved.BloodHoundDisplay);
                        obj.Properties.Add("highvalue", false);

                        ContainerHelpers.ResolveContainer(entry, resolved, ref obj);
                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }

                    Interlocked.Increment(ref _currentCount);
                    wrapper.Item = null;
                }
            }, TaskCreationOptions.LongRunning));
        }
示例#3
0
        internal void StartStealthEnumeration()
        {
            var output = new BlockingCollection <Wrapper <JsonBase> >();
            var writer = StartOutputWriter(output);

            foreach (var domainName in _utils.GetDomainList())
            {
                Extensions.SetPrimaryDomain(domainName);

                _currentCount = 0;
                _timeouts     = 0;
                _noPing       = 0;
                _watch        = Stopwatch.StartNew();

                Console.WriteLine($"Starting Stealth Enumeration for {domainName}");
                _statusTimer.Start();

                var domainSid = _utils.GetDomainSid(domainName);
                var res       = _options.ResolvedCollMethods;
                var data      = LdapFilter.BuildLdapData(res, _options.ExcludeDC, _options.LdapFilter);

                ContainerHelpers.BuildGpoCache(domainName);

                foreach (var entry in _utils.DoSearch(data.Filter, SearchScope.Subtree, data.Properties, domainName))
                {
                    var resolved = entry.ResolveAdEntry();
                    _currentCount++;
                    if (resolved == null)
                    {
                        continue;
                    }

                    Console.WriteLine(resolved.BloodHoundDisplay);
                    Console.WriteLine(resolved.ObjectType);
                    var domain = Utils.ConvertDnToDomain(entry.DistinguishedName);
                    var sid    = entry.GetSid();

                    if (resolved.ObjectType == "user")
                    {
                        var obj = new User
                        {
                            Name = resolved.BloodHoundDisplay
                        };

                        obj.Properties.Add("domain", domain);
                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", false);

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "group")
                    {
                        var obj = new Group
                        {
                            Name = resolved.BloodHoundDisplay
                        };

                        obj.Properties.Add("domain", domain);
                        obj.Properties.Add("objectsid", sid);

                        if (sid.EndsWith("-512") || sid.EndsWith("-516") || sid.EndsWith("-519") ||
                            sid.EndsWith("-520") || sid.Equals("S-1-5-32-544") || sid.Equals("S-1-5-32-550") ||
                            sid.Equals("S-1-5-32-549") || sid.Equals("S-1-5-32-551") || sid.Equals("S-1-5-32-548"))
                        {
                            obj.Properties.Add("highvalue", true);
                        }
                        else
                        {
                            obj.Properties.Add("highvalue", false);
                        }

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "computer")
                    {
                        var obj = new Computer
                        {
                            Name = resolved.BloodHoundDisplay,
                        };

                        obj.Properties.Add("domain", domain);
                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", false);

                        if (entry.DistinguishedName.ToLower().Contains("domain controllers"))
                        {
                            _entDcs.Enqueue(new GroupMember
                            {
                                MemberType = "computer",
                                MemberName = resolved.BloodHoundDisplay
                            });
                        }

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        GroupHelpers.GetGroupInfo(entry, resolved, domainSid, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "domain")
                    {
                        var obj = new Domain
                        {
                            Name = resolved.BloodHoundDisplay,
                        };

                        obj.Properties.Add("objectsid", sid);
                        obj.Properties.Add("highvalue", true);

                        ObjectPropertyHelpers.GetProps(entry, resolved, ref obj);
                        AclHelpers.GetObjectAces(entry, resolved, ref obj);
                        ContainerHelpers.ResolveContainer(entry, resolved, ref obj);
                        TrustHelpers.DoTrustEnumeration(resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "gpo")
                    {
                        var obj = new Gpo
                        {
                            Name = resolved.BloodHoundDisplay,
                            Guid = entry.GetProp("name").Replace("{", "").Replace("}", "")
                        };

                        obj.Properties.Add("highvalue", false);

                        AclHelpers.GetObjectAces(entry, resolved, ref obj);

                        foreach (var a in LocalGroupHelpers.GetGpoMembers(entry, domain))
                        {
                            output.Add(new Wrapper <JsonBase>
                            {
                                Item = a
                            });
                        }

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                    else if (resolved.ObjectType == "ou")
                    {
                        var obj = new Ou
                        {
                            Guid = new Guid(entry.GetPropBytes("objectguid")).ToString().ToUpper()
                        };

                        obj.Properties.Add("name", resolved.BloodHoundDisplay);
                        obj.Properties.Add("highvalue", false);

                        ContainerHelpers.ResolveContainer(entry, resolved, ref obj);

                        output.Add(new Wrapper <JsonBase>
                        {
                            Item = obj
                        });
                    }
                }

                if (Utils.IsMethodSet(ResolvedCollectionMethod.Session))
                {
                    Console.WriteLine("Doing stealth session enumeration");
                    foreach (var target in SessionHelpers.CollectStealthTargets(domainName))
                    {
                        if (!_utils.PingHost(target.BloodHoundDisplay))
                        {
                            _noPing++;
                            continue;
                        }

                        try
                        {
                            foreach (var session in SessionHelpers.GetNetSessions(target, domainName))
                            {
                                output.Add(new Wrapper <JsonBase>
                                {
                                    Item = session
                                });
                            }
                        }
                        catch (TimeoutException)
                        {
                            _timeouts++;
                        }
                    }
                }

                if (_entDcs.Count > 0)
                {
                    var dObj = _utils.GetForest(domainName);
                    var d    = dObj == null ? domainName : dObj.RootDomain.Name;
                    var n    = $"ENTERPRISE DOMAIN CONTROLLERS@{d}";
                    var obj  = new Group
                    {
                        Name    = n,
                        Members = _entDcs.ToArray()
                    };

                    obj.Properties.Add("domain", d);
                    obj.Properties.Add("objectsid", "S-1-5-9");
                    obj.Properties.Add("highvalue", true);

                    output.Add(new Wrapper <JsonBase>
                    {
                        Item = obj
                    });
                }


                PrintStatus();
                _statusTimer.Stop();

                Console.WriteLine($"Finished stealth enumeration for {domainName} in {_watch.Elapsed}");
                Console.WriteLine($"{_noPing} hosts failed ping. {_timeouts} hosts timedout.");
            }
            output.CompleteAdding();
            Utils.Verbose("Waiting for writer thread to finish");
            writer.Wait();
        }
示例#4
0
        internal void StartSessionLoopEnumeration()
        {
            var output = new BlockingCollection <Wrapper <JsonBase> >();
            var writer = StartOutputWriter(output);

            while (true)
            {
                foreach (var domain in _utils.GetDomainList())
                {
                    Extensions.SetPrimaryDomain(domain);
                    _noPing       = 0;
                    _timeouts     = 0;
                    _currentCount = 0;
                    Console.WriteLine($"Starting Enumeration for {domain}");

                    _watch = Stopwatch.StartNew();

                    if (_options.Stealth)
                    {
                        foreach (var target in SessionHelpers.CollectStealthTargets(domain))
                        {
                            if (!_utils.PingHost(target.BloodHoundDisplay))
                            {
                                _noPing++;
                                continue;
                            }

                            try
                            {
                                foreach (var s in SessionHelpers.GetNetSessions(target, domain))
                                {
                                    output.Add(new Wrapper <JsonBase>
                                    {
                                        Item = s
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                _timeouts++;
                            }

                            PrintStatus();
                            _watch.Stop();
                            Console.WriteLine($"Finished enumeration for {domain} in {_watch.Elapsed}");
                            Console.WriteLine($"{_noPing} hosts failed ping. {_timeouts} hosts timedout.");
                            _watch = null;
                        }
                    }
                    else
                    {
                        var input       = new BlockingCollection <Wrapper <SearchResultEntry> >(1000);
                        var taskHandles = new Task[_options.Threads];
                        var ldapData    = LdapFilter.BuildLdapData(_options.ResolvedCollMethods, _options.ExcludeDC, _options.LdapFilter);

                        for (var i = 0; i < _options.Threads; i++)
                        {
                            taskHandles[i] = StartRunner(input, output);
                        }

                        _statusTimer.Start();

                        foreach (var item in _utils.DoWrappedSearch(ldapData.Filter, SearchScope.Subtree, ldapData.Properties,
                                                                    domain, _options.Ou))
                        {
                            input.Add(item);
                        }

                        input.CompleteAdding();
                        Utils.Verbose("Waiting for enumeration threads to finish");
                        Task.WaitAll(taskHandles);

                        _statusTimer.Stop();
                        PrintStatus();
                        _watch.Stop();
                        Console.WriteLine($"Finished enumeration for {domain} in {_watch.Elapsed}");
                        Console.WriteLine($"{_noPing} hosts failed ping. {_timeouts} hosts timedout.");
                        _watch = null;
                    }
                }

                if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
                {
                    Console.WriteLine("User pressed escape, exiting session loop");
                    output.CompleteAdding();
                    writer.Wait();
                    break;
                }

                if (_options.MaxLoopTime != null)
                {
                    if (DateTime.Now > _options.LoopEnd)
                    {
                        Console.WriteLine("Exiting session loop as LoopEndTime has passed.");
                        output.CompleteAdding();
                        writer.Wait();
                        break;
                    }
                }

                Console.WriteLine($"Starting next session run in {_options.LoopDelay} seconds");
                new ManualResetEvent(false).WaitOne(_options.LoopDelay * 1000);

                if (_options.MaxLoopTime != null)
                {
                    if (DateTime.Now > _options.LoopEnd)
                    {
                        Console.WriteLine("Exiting session loop as LoopEndTime has passed.");
                        output.CompleteAdding();
                        writer.Wait();
                        break;
                    }
                }

                if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)
                {
                    Console.WriteLine("User pressed escape, exiting session loop");
                    output.CompleteAdding();
                    writer.Wait();
                    break;
                }

                Console.WriteLine("Starting next session loop");
            }
        }
        private Task StartCompListRunner(BlockingCollection <Wrapper <string> > input,
                                         BlockingCollection <Wrapper <OutputBase> > output)
        {
            return(Task.Factory.StartNew(() =>
            {
                foreach (var wrapper in input.GetConsumingEnumerable())
                {
                    var item = wrapper.Item;

                    var resolved = _utils.ResolveHost(item);

                    if (!_utils.PingHost(resolved))
                    {
                        Interlocked.Increment(ref _currentCount);
                        Interlocked.Increment(ref _noPing);
                        continue;
                    }

                    var netbios = Utils.GetComputerNetbiosName(resolved);

                    var fullItem = new ResolvedEntry
                    {
                        BloodHoundDisplay = resolved,
                        ComputerSamAccountName = netbios
                    };

                    var c = _options.CollectMethod;

                    if (c.Equals(CollectionMethod.Session) ||
                        c.Equals(CollectionMethod.SessionLoop) ||
                        c.Equals(CollectionMethod.ComputerOnly))
                    {
                        try
                        {
                            var sessions = SessionHelpers.GetNetSessions(fullItem, _currentDomain);
                            foreach (var session in sessions)
                            {
                                output.Add(new Wrapper <OutputBase> {
                                    Item = session
                                });
                            }
                        }
                        catch (TimeoutException)
                        {
                            Interlocked.Increment(ref _timeouts);
                        }
                    }

                    if (c.Equals(CollectionMethod.LocalGroup) || c.Equals(CollectionMethod.ComputerOnly))
                    {
                        try
                        {
                            var admins = LocalAdminHelpers.GetSamAdmins(fullItem);
                            foreach (var admin in admins)
                            {
                                output.Add(new Wrapper <OutputBase> {
                                    Item = admin
                                });
                            }
                        }
                        catch (TimeoutException)
                        {
                            Interlocked.Increment(ref _timeouts);
                        }
                    }

                    if (c.Equals(CollectionMethod.LoggedOn))
                    {
                        var sessions = SessionHelpers.GetNetLoggedOn(fullItem, _currentDomain);
                        sessions = sessions.Concat(SessionHelpers.GetRegistryLoggedOn(fullItem));

                        foreach (var session in sessions)
                        {
                            output.Add(new Wrapper <OutputBase> {
                                Item = session
                            });
                        }
                    }
                    Interlocked.Increment(ref _currentCount);
                    wrapper.Item = null;
                }
            }));
        }
        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();
        }
        private Task StartRunner(BlockingCollection <Wrapper <SearchResultEntry> > processQueue, BlockingCollection <Wrapper <OutputBase> > writeQueue)
        {
            return(Task.Factory.StartNew(() =>
            {
                foreach (var wrapper in processQueue.GetConsumingEnumerable())
                {
                    var entry = wrapper.Item;

                    var resolved = entry.ResolveAdEntry();

                    if (resolved == null)
                    {
                        Interlocked.Increment(ref _currentCount);
                        wrapper.Item = null;
                        continue;
                    }

                    switch (_options.CollectMethod)
                    {
                    case CollectionMethod.ObjectProps:
                        {
                            OutputBase props;
                            if (resolved.ObjectType.Equals("computer"))
                            {
                                props = ObjectPropertyHelpers.GetComputerProps(entry, resolved);
                            }
                            else
                            {
                                props = ObjectPropertyHelpers.GetUserProps(entry, resolved);
                            }

                            if (props != null)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = props
                                });
                            }
                        }
                        break;

                    case CollectionMethod.Group:
                        {
                            var groups = GroupHelpers.ProcessAdObject(entry, resolved, _currentDomainSid);
                            foreach (var g in groups)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = g
                                });
                            }
                        }
                        break;

                    case CollectionMethod.ComputerOnly:
                        {
                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }

                            try
                            {
                                var admins = LocalAdminHelpers.GetSamAdmins(resolved);

                                foreach (var admin in admins)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = admin
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }

                            if (_options.ExcludeDC && entry.DistinguishedName.Contains("OU=Domain Controllers"))
                            {
                                break;
                            }

                            try
                            {
                                var sessions = SessionHelpers.GetNetSessions(resolved, _currentDomain);

                                foreach (var session in sessions)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = session
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }
                        break;

                    case CollectionMethod.LocalGroup:
                        {
                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }

                            try
                            {
                                var admins = LocalAdminHelpers.GetSamAdmins(resolved);

                                foreach (var admin in admins)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = admin
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }
                        break;

                    case CollectionMethod.GPOLocalGroup:
                        foreach (var admin in LocalAdminHelpers.GetGpoAdmins(entry, _currentDomain))
                        {
                            writeQueue.Add(new Wrapper <OutputBase> {
                                Item = admin
                            });
                        }
                        break;

                    case CollectionMethod.Session:
                        {
                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }

                            if (_options.ExcludeDC && entry.DistinguishedName.Contains("OU=Domain Controllers"))
                            {
                                break;
                            }

                            try
                            {
                                var sessions = SessionHelpers.GetNetSessions(resolved, _currentDomain);

                                foreach (var session in sessions)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = session
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }
                        break;

                    case CollectionMethod.LoggedOn:
                        {
                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }
                            var sessions =
                                SessionHelpers.GetNetLoggedOn(resolved,
                                                              _currentDomain);

                            foreach (var s in sessions)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = s
                                });
                            }
                            sessions = SessionHelpers.GetRegistryLoggedOn(resolved);
                            foreach (var s in sessions)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = s
                                });
                            }
                        }
                        break;

                    case CollectionMethod.Trusts:
                        break;

                    case CollectionMethod.ACL:
                        {
                            var acls = AclHelpers.ProcessAdObject(entry, _currentDomain);
                            foreach (var a in acls)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = a
                                });
                            }
                        }
                        break;

                    case CollectionMethod.SessionLoop:
                        {
                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }

                            if (_options.ExcludeDC && entry.DistinguishedName.Contains("OU=Domain Controllers"))
                            {
                                break;
                            }

                            try
                            {
                                var sessions = SessionHelpers.GetNetSessions(resolved, _currentDomain);

                                foreach (var session in sessions)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = session
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }
                        break;

                    case CollectionMethod.Default:
                        {
                            var groups = GroupHelpers.ProcessAdObject(entry, resolved, _currentDomainSid);
                            foreach (var g in groups)
                            {
                                writeQueue.Add(new Wrapper <OutputBase> {
                                    Item = g
                                });
                            }

                            if (!resolved.ObjectType.Equals("computer"))
                            {
                                break;
                            }

                            if (_options.Ou != null && !entry.DistinguishedName.Contains(_options.Ou))
                            {
                                break;
                            }

                            if (!_utils.PingHost(resolved.BloodHoundDisplay))
                            {
                                Interlocked.Increment(ref _noPing);
                                break;
                            }

                            try
                            {
                                var admins = LocalAdminHelpers.GetSamAdmins(resolved);

                                foreach (var admin in admins)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = admin
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }

                            if (_options.ExcludeDC && entry.DistinguishedName.Contains("OU=Domain Controllers"))
                            {
                                break;
                            }

                            try
                            {
                                var sessions = SessionHelpers.GetNetSessions(resolved, _currentDomain);

                                foreach (var session in sessions)
                                {
                                    writeQueue.Add(new Wrapper <OutputBase> {
                                        Item = session
                                    });
                                }
                            }
                            catch (TimeoutException)
                            {
                                Interlocked.Increment(ref _timeouts);
                            }
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    Interlocked.Increment(ref _currentCount);
                    wrapper.Item = null;
                }
            }, TaskCreationOptions.LongRunning));
        }