public static IEnumerable <ForeignUser> Get_DomainForeignUser(Args_Get_DomainForeignUser args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainForeignUser();
            }

            var SearcherArguments = new Args_Get_DomainUser
            {
                LDAPFilter      = @"(memberof=*)",
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var ForeignUsers = new List <ForeignUser>();
            var Results      = GetDomainUser.Get_DomainUser(SearcherArguments);

            foreach (LDAPProperty result in Results)
            {
                foreach (var Membership in result.memberof)
                {
                    var Index = Membership.IndexOf(@"DC=");
                    if (Index != 0)
                    {
                        var GroupDomain           = Membership.Substring(Index).Replace(@"DC=", @"").Replace(@",", @".");
                        var UserDistinguishedName = result.distinguishedname;
                        var UserIndex             = UserDistinguishedName.IndexOf(@"DC=");
                        var UserDomain            = result.distinguishedname.Substring(UserIndex).Replace(@"DC=", @"").Replace(@",", @".");

                        if (GroupDomain != UserDomain)
                        {
                            // if the group domain doesn't match the user domain, display it
                            var GroupName   = Membership.Split(',')[0].Split('=')[1];
                            var ForeignUser = new ForeignUser
                            {
                                UserDomain             = UserDomain,
                                UserName               = result.samaccountname,
                                UserDistinguishedName  = result.distinguishedname,
                                GroupDomain            = GroupDomain,
                                GroupName              = GroupName,
                                GroupDistinguishedName = Membership
                            };
                        }
                    }
                }
            }
            return(ForeignUsers);
        }
Exemple #2
0
        public static ForestEx Get_Forest(Args_Get_Forest args = null)
        {
            if (args == null)
            {
                args = new Args_Get_Forest();
            }

            var ForestObject = new ForestEx();

            if (args.Credential != null)
            {
                Logger.Write_Verbose(@"[Get-Forest] Using alternate credentials for Get-Forest");

                string TargetForest = null;
                if (args.Forest.IsNotNullOrEmpty())
                {
                    TargetForest = args.Forest;
                }
                else
                {
                    // if no domain is supplied, extract the logon domain from the PSCredential passed
                    TargetForest = args.Credential.Domain;
                    Logger.Write_Verbose(@"[Get-Forest] Extracted domain '$Forest' from -Credential");
                }

                var ForestContext = new System.DirectoryServices.ActiveDirectory.DirectoryContext(System.DirectoryServices.ActiveDirectory.DirectoryContextType.Forest, TargetForest, args.Credential.UserName, args.Credential.Password);

                try
                {
                    ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetForest(ForestContext);
                }
                catch (Exception e)
                {
                    Logger.Write_Verbose($@"[Get-Forest] The specified forest '{TargetForest}' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: {e}");
                }
            }
            else if (args.Forest.IsNotNullOrEmpty())
            {
                var ForestContext = new System.DirectoryServices.ActiveDirectory.DirectoryContext(System.DirectoryServices.ActiveDirectory.DirectoryContextType.Forest, args.Forest);
                try
                {
                    ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetForest(ForestContext);
                }
                catch (Exception e)
                {
                    Logger.Write_Verbose($@"[Get-Forest] The specified forest '{args.Forest}' does not exist, could not be contacted, or there isn't an existing trust: {e}");
                }
            }
            else
            {
                // otherwise use the current forest
                ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetCurrentForest();
            }

            if (ForestObject.Forest != null)
            {
                // get the SID of the forest root
                string ForestSid = null;
                if (args.Credential != null)
                {
                    ForestSid = (GetDomainUser.Get_DomainUser(new Args_Get_DomainUser {
                        Identity = new[] { @"krbtgt" }, Domain = ForestObject.Forest.RootDomain.Name, Credential = args.Credential
                    }).First() as LDAPProperty).objectsid?.First();
                }
                else
                {
                    ForestSid = (GetDomainUser.Get_DomainUser(new Args_Get_DomainUser {
                        Identity = new[] { @"krbtgt" }, Domain = ForestObject.Forest.RootDomain.Name
                    }).First() as LDAPProperty).objectsid?.First();
                }

                var Parts = ForestSid.Split('-');
                ForestSid = string.Join(@"-", Parts.Take(Parts.Length - 2 + 1));
                ForestObject.RootDomainSid = ForestSid;
                return(ForestObject);
            }
            return(null);
        }
Exemple #3
0
        public static IEnumerable <object> Find_DomainUserEvent(Args_Find_DomainUserEvent args = null)
        {
            if (args == null)
            {
                args = new Args_Find_DomainUserEvent();
            }

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

            string[] TargetUsers = null;
            if (args.UserIdentity != null || !string.IsNullOrEmpty(args.UserLDAPFilter) || !string.IsNullOrEmpty(args.UserSearchBase) || args.UserAdminCount)
            {
                TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray();
            }
            else if (args.UserGroupIdentity != null || (args.Filter == null))
            {
                // otherwise we're querying a specific group
                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
                };
                Logger.Write_Verbose($@"UserGroupIdentity: {args.UserGroupIdentity.ToJoinedString()}");
                TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray();
            }

            // build the set of computers to enumerate
            string[] TargetComputers = null;
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                // if not -ComputerName is passed, query the current (or target) domain for domain controllers
                var DCSearcherArguments = new Args_Get_DomainController
                {
                    LDAP       = true,
                    Domain     = args.Domain,
                    Server     = args.Server,
                    Credential = args.Credential
                };
                Logger.Write_Verbose($@"[Find-DomainUserEvent] Querying for domain controllers in domain: {args.Domain}");
                TargetComputers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
            }
            Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers length: {TargetComputers.Count()}");
            Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers {TargetComputers.ToJoinedString()}");
            if (TargetComputers == null || TargetComputers.Length == 0)
            {
                throw new Exception("[Find-DomainUserEvent] No hosts found to enumerate");
            }

            var rets = new List <IWinEvent>();

            // only ignore threading if -Delay is passed
            if (args.Delay != 0 || args.StopOnSuccess)
            {
                Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers length: {TargetComputers.Length}");
                Logger.Write_Verbose($@"[Find-DomainUserEvent] 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-DomainUserEvent] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})");
                    var Result = _Find_DomainUserEvent(new[] { TargetComputer }, args.StartTime, args.EndTime, args.MaxEvents, TargetUsers, args.Filter, args.Credential);
                    if (Result != null)
                    {
                        rets.AddRange(Result);
                    }

                    if (Result != null && args.StopOnSuccess)
                    {
                        Logger.Write_Verbose("[Find-DomainUserEvent] Target user found, returning early");
                        return(rets);
                    }
                }
            }
            else
            {
                Logger.Write_Verbose($@"[Find-DomainUserEvent] Using threading with threads: {args.Threads}");

                // 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_DomainUserEvent(new[] { TargetComputer }, args.StartTime, args.EndTime, args.MaxEvents, TargetUsers, args.Filter, args.Credential);
                    lock (rets)
                    {
                        if (Result != null)
                        {
                            rets.AddRange(Result);
                        }
                    }
                });
            }

            return(rets);
        }
Exemple #4
0
        public static IEnumerable <UserProcess> Find_DomainProcess(Args_Find_DomainProcess args = null)
        {
            if (args == null)
            {
                args = new Args_Find_DomainProcess();
            }

            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,
                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;
            }

            // first, build the set of computers to enumerate
            string[] TargetComputers = null;
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                Logger.Write_Verbose(@"[Find-DomainProcess] Querying computers in the domain");
                TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
            }
            if (TargetComputers == null || TargetComputers.Length == 0)
            {
                throw new Exception("[Find-DomainProcess] No hosts found to enumerate");
            }
            Logger.Write_Verbose($@"[Find-DomainProcess] TargetComputers length: {TargetComputers.Length}");

            // now build the user target set
            List <string> TargetProcessName = null;

            string[] TargetUsers = null;
            if (args.ProcessName != null)
            {
                TargetProcessName = new List <string>();
                foreach (var T in args.ProcessName)
                {
                    TargetProcessName.AddRange(T.Split(','));
                }
            }
            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();
            }

            var rets = new List <UserProcess>();

            // only ignore threading if -Delay is passed
            if (args.Delay != 0 || args.StopOnSuccess)
            {
                Logger.Write_Verbose($@"[Find-DomainProcess] Total number of hosts: {TargetComputers.Count()}");
                Logger.Write_Verbose($@"[Find-DomainProcess] 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-DomainProcess] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})");
                    var Result = _Find_DomainProcess(new[] { TargetComputer }, TargetProcessName?.ToArray(), TargetUsers, args.Credential);
                    if (Result != null)
                    {
                        rets.AddRange(Result);
                    }

                    if (Result != null && args.StopOnSuccess)
                    {
                        Logger.Write_Verbose("[Find-DomainProcess] Target user found, returning early");
                        return(rets);
                    }
                }
            }
            else
            {
                Logger.Write_Verbose($@"[Find-DomainProcess] Using threading with threads: {args.Threads}");

                // 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_DomainProcess(new[] { TargetComputer }, TargetProcessName?.ToArray(), TargetUsers, args.Credential);
                    lock (rets)
                    {
                        if (Result != null)
                        {
                            rets.AddRange(Result);
                        }
                    }
                });
            }

            return(rets);
        }
        public static IEnumerable <PropertyOutlier> Find_DomainObjectPropertyOutlier(Args_Find_DomainObjectPropertyOutlier args = null)
        {
            if (args == null)
            {
                args = new Args_Find_DomainObjectPropertyOutlier();
            }

            var UserReferencePropertySet = new[] { "admincount", "accountexpires", "badpasswordtime", "badpwdcount", "cn", "codepage", "countrycode", "description", "displayname", "distinguishedname", "dscorepropagationdata", "givenname", "instancetype", "iscriticalsystemobject", "lastlogoff", "lastlogon", "lastlogontimestamp", "lockouttime", "logoncount", "memberof", "msds-supportedencryptiontypes", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "primarygroupid", "pwdlastset", "samaccountname", "samaccounttype", "sn", "useraccountcontrol", "userprincipalname", "usnchanged", "usncreated", "whenchanged", "whencreated" };

            var GroupReferencePropertySet = new[] { "admincount", "cn", "description", "distinguishedname", "dscorepropagationdata", "grouptype", "instancetype", "iscriticalsystemobject", "member", "memberof", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "samaccountname", "samaccounttype", "systemflags", "usnchanged", "usncreated", "whenchanged", "whencreated" };

            var ComputerReferencePropertySet = new[] { "accountexpires", "badpasswordtime", "badpwdcount", "cn", "codepage", "countrycode", "distinguishedname", "dnshostname", "dscorepropagationdata", "instancetype", "iscriticalsystemobject", "lastlogoff", "lastlogon", "lastlogontimestamp", "localpolicyflags", "logoncount", "msds-supportedencryptiontypes", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "operatingsystem", "operatingsystemservicepack", "operatingsystemversion", "primarygroupid", "pwdlastset", "samaccountname", "samaccounttype", "serviceprincipalname", "useraccountcontrol", "usnchanged", "usncreated", "whenchanged", "whencreated" };

            var SearcherArgumentsForUser = new Args_Get_DomainUser
            {
                Domain          = args.Domain,
                LDAPFilter      = args.LDAPFilter,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };
            var SearcherArgumentsForGroup = new Args_Get_DomainGroup
            {
                Domain          = args.Domain,
                LDAPFilter      = args.LDAPFilter,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };
            var SearcherArgumentsForComputer = new Args_Get_DomainComputer
            {
                Domain          = args.Domain,
                LDAPFilter      = args.LDAPFilter,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            // Domain / Credential
            var TargetForest = string.Empty;

            if (!args.Domain.IsNullOrEmpty())
            {
                if (args.Credential != null)
                {
                    TargetForest = GetDomain.Get_Domain(new Args_Get_Domain {
                        Domain = args.Domain
                    }).Forest.Name;
                }
                else
                {
                    TargetForest = GetDomain.Get_Domain(new Args_Get_Domain {
                        Domain = args.Domain, Credential = args.Credential
                    }).Forest.Name;
                }
                Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Enumerated forest '{TargetForest}' for target domain '{args.Domain}'");
            }

            var SchemaArguments = new
            {
                Credential = args.Credential,
                Forest     = TargetForest
            };

            string[]  ReferenceObjectProperties = null;
            ClassType?ReferenceObjectClass      = null;

            if (args.ReferencePropertySet != null)
            {
                Logger.Write_Verbose(@"[Find-DomainObjectPropertyOutlier] Using specified -ReferencePropertySet");
                ReferenceObjectProperties = args.ReferencePropertySet;
            }
            else if (args.ReferenceObject != null)
            {
                Logger.Write_Verbose(@"[Find-DomainObjectPropertyOutlier] Extracting property names from -ReferenceObject to use as the reference property set");
                ReferenceObjectProperties = args.ReferenceObject.GetType().GetProperties().Select(x => x.Name).ToArray();
                ReferenceObjectClass      = args.ReferenceObject.GetPropValue <ClassType>("objectclass");
                Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Calculated ReferenceObjectClass : {ReferenceObjectClass}");
            }
            else
            {
                Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Using the default reference property set for the object class '{args.ClassName}'");
            }

            IEnumerable <object> Objects;

            if ((args.ClassName == ClassType.User) || (ReferenceObjectClass == ClassType.User))
            {
                Objects = GetDomainUser.Get_DomainUser(SearcherArgumentsForUser);
                if (ReferenceObjectProperties == null)
                {
                    ReferenceObjectProperties = UserReferencePropertySet;
                }
            }
            else if ((args.ClassName == ClassType.Group) || (ReferenceObjectClass == ClassType.Group))
            {
                Objects = GetDomainGroup.Get_DomainGroup(SearcherArgumentsForGroup);
                if (ReferenceObjectProperties == null)
                {
                    ReferenceObjectProperties = GroupReferencePropertySet;
                }
            }
            else if ((args.ClassName == ClassType.Computer) || (ReferenceObjectClass == ClassType.Computer))
            {
                Objects = GetDomainComputer.Get_DomainComputer(SearcherArgumentsForComputer);
                if (ReferenceObjectProperties == null)
                {
                    ReferenceObjectProperties = ComputerReferencePropertySet;
                }
            }
            else
            {
                throw new Exception($@"[Find-DomainObjectPropertyOutlier] Invalid class: {args.ClassName}");
            }

            var PropertyOutliers = new List <PropertyOutlier>();

            foreach (LDAPProperty Object in Objects)
            {
                var ObjectProperties = Object.GetType().GetProperties().Select(x => x.Name).ToArray();
                foreach (var ObjectProperty in ObjectProperties)
                {
                    var val = Object.GetPropValue <object>(ObjectProperty);
                    if (val is Dictionary <string, object> )
                    {
                        var dic = val as Dictionary <string, object>;
                        foreach (var ObjectProperty1 in dic.Keys)
                        {
                            if (!ReferenceObjectProperties.ContainsNoCase(ObjectProperty1))
                            {
                                var Out = new PropertyOutlier
                                {
                                    SamAccountName = Object.samaccountname,
                                    Property       = ObjectProperty1,
                                    Value          = dic[ObjectProperty1]
                                };
                                PropertyOutliers.Add(Out);
                            }
                        }
                    }
                    else if (val != null && !ReferenceObjectProperties.ContainsNoCase(ObjectProperty))
                    {
                        var Out = new PropertyOutlier
                        {
                            SamAccountName = Object.samaccountname,
                            Property       = ObjectProperty,
                            Value          = Object.GetPropValue <object>(ObjectProperty)
                        };
                        PropertyOutliers.Add(Out);
                    }
                }
            }

            return(PropertyOutliers);
        }
Exemple #6
0
        public static IEnumerable <object> Get_DomainGPO(Args_Get_DomainGPO args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainGPO();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };
            var GPOSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            var GPOs = new List <object>();

            if (GPOSearcher != null)
            {
                if (args.ComputerIdentity != null || args.UserIdentity != null)
                {
                    var      GPOAdsPaths   = new List <string>();
                    string[] OldProperties = null;
                    if (SearcherArguments.Properties != null)
                    {
                        OldProperties = SearcherArguments.Properties;
                    }
                    SearcherArguments.Properties = new[] { @"distinguishedname", @"dnshostname" };
                    string TargetComputerName = null;
                    string ObjectDN           = null;

                    if (args.ComputerIdentity.IsNotNullOrEmpty())
                    {
                        var Computer = GetDomainComputer.Get_DomainComputer(new Args_Get_DomainComputer(SearcherArguments)
                        {
                            Identity = new[] { args.ComputerIdentity },
                            FindOne  = true
                        }).First() as LDAPProperty;
                        if (Computer == null)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGPO] Computer '{args.ComputerIdentity}' not found!");
                        }
                        ObjectDN           = Computer.distinguishedname;
                        TargetComputerName = Computer.dnshostname;
                    }
                    else
                    {
                        var User = GetDomainUser.Get_DomainUser(new Args_Get_DomainUser(SearcherArguments)
                        {
                            Identity = new[] { args.UserIdentity },
                            FindOne  = true
                        }) as LDAPProperty;
                        if (User == null)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGPO] User '{args.UserIdentity}' not found!");
                        }
                        ObjectDN = User.distinguishedname;
                    }

                    // extract all OUs the target user/computer is a part of
                    var ObjectOUs = new List <string>();
                    foreach (var item in ObjectDN.Split(','))
                    {
                        if (item.StartsWith(@"OU="))
                        {
                            ObjectOUs.Add(ObjectDN.Substring(ObjectDN.IndexOf($@"{item},")));
                        }
                    }
                    Logger.Write_Verbose($@"[Get-DomainGPO] object OUs: {ObjectOUs}");

                    if (ObjectOUs != null)
                    {
                        // find all the GPOs linked to the user/computer's OUs
                        SearcherArguments.Properties = null;
                        var InheritanceDisabled = false;
                        foreach (var ObjectOU in ObjectOUs)
                        {
                            var ous = GetDomainOU.Get_DomainOU(new Args_Get_DomainOU(SearcherArguments)
                            {
                                Identity = new[] { ObjectOU }
                            });
                            foreach (LDAPProperty ou in ous)
                            {
                                // extract any GPO links for this particular OU the computer is a part of
                                if (ou.gplink.IsNotNullOrEmpty())
                                {
                                    foreach (var item in ou.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                                    {
                                        if (item.StartsWith(@"LDAP"))
                                        {
                                            var Parts    = item.Split(';');
                                            var GpoDN    = Parts[0];
                                            var Enforced = Parts[1];

                                            if (InheritanceDisabled)
                                            {
                                                // if inheritance has already been disabled and this GPO is set as "enforced"
                                                // then add it, otherwise ignore it
                                                if (Enforced == @"2")
                                                {
                                                    GPOAdsPaths.Add(GpoDN);
                                                }
                                            }
                                            else
                                            {
                                                // inheritance not marked as disabled yet
                                                GPOAdsPaths.Add(GpoDN);
                                            }
                                        }
                                    }
                                }

                                //if this OU has GPO inheritence disabled, break so additional OUs aren't processed
                                if (ou.gpoptions == 1)
                                {
                                    InheritanceDisabled = true;
                                }
                            }
                        }
                    }

                    if (TargetComputerName.IsNotNullOrEmpty())
                    {
                        // find all the GPOs linked to the computer's site
                        var ComputerSite = GetNetComputerSiteName.Get_NetComputerSiteName(new Args_Get_NetComputerSiteName {
                            ComputerName = new[] { TargetComputerName }
                        }).First().SiteName;
                        if (ComputerSite.IsNotNullOrEmpty() && !ComputerSite.IsLikeMatch(@"Error*"))
                        {
                            var sites = GetDomainSite.Get_DomainSite(new Args_Get_DomainSite(SearcherArguments)
                            {
                                Identity = new[] { ComputerSite }
                            });
                            foreach (LDAPProperty site in sites)
                            {
                                if (site.gplink.IsNotNullOrEmpty())
                                {
                                    // extract any GPO links for this particular site the computer is a part of
                                    foreach (var item in site.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                                    {
                                        if (item.StartsWith(@"LDAP"))
                                        {
                                            GPOAdsPaths.Add(item.Split(';')[0]);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // find any GPOs linked to the user/computer's domain
                    var ObjectDomainDN = ObjectDN.Substring(ObjectDN.IndexOf(@"DC="));
                    SearcherArguments.Properties = null;
                    SearcherArguments.LDAPFilter = $@"(objectclass=domain)(distinguishedname={ObjectDomainDN})";
                    var objs = GetDomainObject.Get_DomainObject(new Args_Get_DomainObject(SearcherArguments));
                    foreach (LDAPProperty obj in objs)
                    {
                        if (obj.gplink.IsNotNullOrEmpty())
                        {
                            // extract any GPO links for this particular domain the computer is a part of
                            foreach (var item in obj.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                            {
                                if (item.StartsWith(@"LDAP"))
                                {
                                    GPOAdsPaths.Add(item.Split(';')[0]);
                                }
                            }
                        }
                    }
                    Logger.Write_Verbose($@"[Get-DomainGPO] GPOAdsPaths: {GPOAdsPaths}");

                    // restore the old properites to return, if set
                    if (OldProperties != null)
                    {
                        SearcherArguments.Properties = OldProperties;
                    }
                    else
                    {
                        SearcherArguments.Properties = null;
                    }

                    foreach (var path in GPOAdsPaths.Where(x => x != null && x != ""))
                    {
                        // use the gplink as an ADS path to enumerate all GPOs for the computer
                        SearcherArguments.SearchBase = path;
                        SearcherArguments.LDAPFilter = @"(objectCategory=groupPolicyContainer)";
                        objs = GetDomainObject.Get_DomainObject(new Args_Get_DomainObject(SearcherArguments));
                        foreach (LDAPProperty obj in objs)
                        {
                            GPOs.Add(new GPO(obj));
                        }
                    }
                }
                else
                {
                    var IdentityFilter = @"";
                    var Filter         = @"";
                    if (args.Identity != null)
                    {
                        foreach (var item in args.Identity)
                        {
                            var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29");
                            if (IdentityInstance.IsRegexMatch(@"LDAP://|^CN=.*"))
                            {
                                IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                                if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                                {
                                    // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                    // and rebuild the domain searcher
                                    var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                    Logger.Write_Verbose($@"[Get-DomainGPO] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                    SearcherArguments.Domain = IdentityDomain;
                                    GPOSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                    if (GPOSearcher == null)
                                    {
                                        Logger.Write_Warning($@"[Get-DomainGPO] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                    }
                                }
                            }
                            else if (IdentityInstance.IsRegexMatch(@"{.*}"))
                            {
                                IdentityFilter += $@"(name={IdentityInstance})";
                            }
                            else
                            {
                                try
                                {
                                    var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                                    IdentityFilter += $@"(objectguid={GuidByteString})";
                                }
                                catch
                                {
                                    IdentityFilter += $@"(displayname={IdentityInstance})";
                                }
                            }
                        }
                    }

                    if (IdentityFilter != null && IdentityFilter.Trim() != @"")
                    {
                        Filter += $@"(|{IdentityFilter})";
                    }

                    if (args.LDAPFilter.IsNotNullOrEmpty())
                    {
                        Logger.Write_Verbose($@"[Get-DomainGPO] Using additional LDAP filter: {args.LDAPFilter}");
                        Filter += $@"{args.LDAPFilter}";
                    }

                    GPOSearcher.Filter = $@"(&(objectCategory=groupPolicyContainer){Filter})";
                    Logger.Write_Verbose($@"[Get-DomainGPO] filter string: {GPOSearcher.Filter}");

                    SearchResult[] Results = null;
                    if (args.FindOne)
                    {
                        Results = new SearchResult[] { GPOSearcher.FindOne() };
                    }
                    else
                    {
                        var items = GPOSearcher.FindAll();
                        if (items != null)
                        {
                            Results = new SearchResult[items.Count];
                            items.CopyTo(Results, 0);
                        }
                    }
                    if (Results != null)
                    {
                        foreach (var result in Results)
                        {
                            if (args.Raw)
                            {
                                // return raw result objects
                                GPOs.Add(result);
                            }
                            else
                            {
                                GPO GPO;
                                if (args.SearchBase.IsNotNullOrEmpty() && args.SearchBase.IsRegexMatch(@"^GC://"))
                                {
                                    GPO = new GPO(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                                    try
                                    {
                                        var GPODN          = GPO.distinguishedname;
                                        var GPODomain      = GPODN.Substring(GPODN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                        var gpcfilesyspath = $@"\\{GPODomain}\SysVol\{GPODomain}\Policies\{GPO.cn}";
                                        GPO.gpcfilesyspath = gpcfilesyspath;
                                    }
                                    catch
                                    {
                                        Logger.Write_Verbose($@"[Get-DomainGPO] Error calculating gpcfilesyspath for: {GPO.distinguishedname}");
                                    }
                                }
                                else
                                {
                                    GPO = new GPO(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                                }
                                GPOs.Add(GPO);
                            }
                        }
                    }
                }
                GPOSearcher.Dispose();
            }
            return(GPOs);
        }
Exemple #7
0
 public static IEnumerable <object> Get_NetUser(Args_Get_DomainUser args = null)
 {
     return(GetDomainUser.Get_DomainUser(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);
        }