Example #1
0
 public static string[] Get_NetFileServer(Args_Get_DomainFileServer args = null)
 {
     return(GetDomainFileServer.Get_DomainFileServer(args));
 }
        public static IEnumerable <UserLocation> Find_DomainUserLocation(Args_Find_DomainUserLocation args = null)
        {
            if (args == null)
            {
                args = new Args_Find_DomainUserLocation();
            }

            var ComputerSearcherArguments = new Args_Get_DomainComputer
            {
                Properties      = new[] { "dnshostname" },
                Domain          = args.Domain,
                LDAPFilter      = args.ComputerLDAPFilter,
                SearchBase      = args.ComputerSearchBase,
                Unconstrained   = args.Unconstrained,
                OperatingSystem = args.OperatingSystem,
                ServicePack     = args.ServicePack,
                SiteName        = args.SiteName,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            if (!string.IsNullOrEmpty(args.ComputerDomain))
            {
                ComputerSearcherArguments.Domain = args.ComputerDomain;
            }

            var UserSearcherArguments = new Args_Get_DomainUser
            {
                Properties      = new[] { "samaccountname" },
                Identity        = args.UserIdentity,
                Domain          = args.Domain,
                LDAPFilter      = args.UserLDAPFilter,
                SearchBase      = args.UserSearchBase,
                AdminCount      = args.UserAdminCount,
                AllowDelegation = args.AllowDelegation,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            if (!string.IsNullOrEmpty(args.UserDomain))
            {
                UserSearcherArguments.Domain = args.UserDomain;
            }

            string[] TargetComputers = null;

            // first, build the set of computers to enumerate
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                if (args.Stealth)
                {
                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}");
                    var TargetComputerArrayList = new System.Collections.ArrayList();

                    if (args.StealthSource.ToString().IsRegexMatch("File|All"))
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers");
                        var FileServerSearcherArguments = new Args_Get_DomainFileServer
                        {
                            Domain          = new[] { args.Domain },
                            SearchBase      = args.ComputerSearchBase,
                            Server          = args.Server,
                            SearchScope     = args.SearchScope,
                            ResultPageSize  = args.ResultPageSize,
                            ServerTimeLimit = args.ServerTimeLimit,
                            Tombstone       = args.Tombstone,
                            Credential      = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            FileServerSearcherArguments.Domain = new[] { args.ComputerDomain }
                        }
                        ;
                        var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments);
                        TargetComputerArrayList.AddRange(FileServers);
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DFS|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers");
                        // { TODO: fix the passed parameters to Get-DomainDFSShare
                        // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName}
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DC|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers");
                        var DCSearcherArguments = new Args_Get_DomainController
                        {
                            LDAP       = true,
                            Domain     = args.Domain,
                            Server     = args.Server,
                            Credential = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            DCSearcherArguments.Domain = args.ComputerDomain;
                        }
                        var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                        TargetComputerArrayList.AddRange(DomainControllers);
                    }
                    TargetComputers = TargetComputerArrayList.ToArray() as string[];
                }
            }
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                if (args.Stealth)
                {
                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}");
                    var TargetComputerArrayList = new System.Collections.ArrayList();

                    if (args.StealthSource.ToString().IsRegexMatch("File|All"))
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers");
                        var FileServerSearcherArguments = new Args_Get_DomainFileServer
                        {
                            Domain          = new[] { args.Domain },
                            SearchBase      = args.ComputerSearchBase,
                            Server          = args.Server,
                            SearchScope     = args.SearchScope,
                            ResultPageSize  = args.ResultPageSize,
                            ServerTimeLimit = args.ServerTimeLimit,
                            Tombstone       = args.Tombstone,
                            Credential      = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            FileServerSearcherArguments.Domain = new[] { args.ComputerDomain }
                        }
                        ;
                        var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments);
                        TargetComputerArrayList.AddRange(FileServers);
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DFS|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers");
                        // { TODO: fix the passed parameters to Get-DomainDFSShare
                        // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName}
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DC|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers");
                        var DCSearcherArguments = new Args_Get_DomainController
                        {
                            LDAP       = true,
                            Domain     = args.Domain,
                            Server     = args.Server,
                            Credential = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            DCSearcherArguments.Domain = args.ComputerDomain;
                        }
                        var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                        TargetComputerArrayList.AddRange(DomainControllers);
                    }
                    TargetComputers = TargetComputerArrayList.ToArray() as string[];
                }
                else
                {
                    Logger.Write_Verbose("[Find-DomainUserLocation] Querying for all computers in the domain");
                    TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                }
            }
            Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}");
            if (TargetComputers.Length == 0)
            {
                throw new Exception("[Find-DomainUserLocation] No hosts found to enumerate");
            }

            // get the current user so we can ignore it in the results
            string CurrentUser;

            if (args.Credential != null)
            {
                CurrentUser = args.Credential.UserName;
            }
            else
            {
                CurrentUser = Environment.UserName.ToLower();
            }

            // now build the user target set
            string[] TargetUsers = null;
            if (args.ShowAll)
            {
                TargetUsers = new string[] { };
            }
            else if (args.UserIdentity != null || args.UserLDAPFilter != null || args.UserSearchBase != null || args.UserAdminCount || args.UserAllowDelegation)
            {
                TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray();
            }
            else
            {
                var GroupSearcherArguments = new Args_Get_DomainGroupMember
                {
                    Identity        = args.UserGroupIdentity,
                    Recurse         = true,
                    Domain          = args.UserDomain,
                    SearchBase      = args.UserSearchBase,
                    Server          = args.Server,
                    SearchScope     = args.SearchScope,
                    ResultPageSize  = args.ResultPageSize,
                    ServerTimeLimit = args.ServerTimeLimit,
                    Tombstone       = args.Tombstone,
                    Credential      = args.Credential
                };
                TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray();
            }

            Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetUsers length: {TargetUsers.Length}");
            if ((!args.ShowAll) && (TargetUsers.Length == 0))
            {
                throw new Exception("[Find-DomainUserLocation] No users found to target");
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                if (args.Delay != 0 || args.StopOnSuccess)
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential
                    });
                }
                else
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential,
                        Quiet      = true
                    });
                }
            }

            var rets = new List <UserLocation>();

            // only ignore threading if -Delay is passed
            if (args.Delay != 0 /* || args.StopOnSuccess*/)
            {
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Total number of hosts: {TargetComputers.Count()}");
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Delay: {args.Delay}, Jitter: {args.Jitter}");

                var Counter = 0;
                var RandNo  = new System.Random();

                foreach (var TargetComputer in TargetComputers)
                {
                    Counter = Counter + 1;

                    // sleep for our semi-randomized interval
                    System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000);

                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})");
                    var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken);
                    if (Result != null)
                    {
                        rets.AddRange(Result);
                    }
                    if (Result != null && args.StopOnSuccess)
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Target user found, returning early");
                        return(rets);
                    }
                }
            }
            else
            {
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Using threading with threads: {args.Threads}");
                Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}");

                // if we're using threading, kick off the script block with New-ThreadedFunction
                // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params
                System.Threading.Tasks.Parallel.ForEach(
                    TargetComputers,
                    TargetComputer =>
                {
                    var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken);
                    lock (rets)
                    {
                        if (Result != null)
                        {
                            rets.AddRange(Result);
                        }
                    }
                });
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(rets);
        }