Example #1
0
        private GPO ProcessGPOObject(ISearchResultEntry entry,
                                     ResolvedSearchResult resolvedSearchResult)
        {
            var ret = new GPO
            {
                ObjectIdentifier = resolvedSearchResult.ObjectId
            };

            ret.Properties.Add("domain", resolvedSearchResult.Domain);
            ret.Properties.Add("name", resolvedSearchResult.DisplayName);
            ret.Properties.Add("distinguishedname", entry.DistinguishedName.ToUpper());
            ret.Properties.Add("domainsid", resolvedSearchResult.DomainSid);
            ret.Properties.Add("highvalue", false);

            if ((_methods & ResolvedCollectionMethod.ACL) != 0)
            {
                ret.Aces           = _aclProcessor.ProcessACL(resolvedSearchResult, entry).ToArray();
                ret.IsACLProtected = _aclProcessor.IsACLProtected(entry);
            }

            if ((_methods & ResolvedCollectionMethod.ObjectProps) != 0)
            {
                ret.Properties = ContextUtils.Merge(ret.Properties, LDAPPropertyProcessor.ReadGPOProperties(entry));
                if (_context.Flags.CollectAllProperties)
                {
                    ret.Properties = ContextUtils.Merge(_ldapPropertyProcessor.ParseAllProperties(entry),
                                                        ret.Properties);
                }
            }


            return(ret);
        }
Example #2
0
    static public JObject GetDomainGPOs()
    {
        DirectoryEntry    rootDse  = new DirectoryEntry("LDAP://rootDSE");
        DirectoryEntry    root     = new DirectoryEntry("GC://" + rootDse.Properties["defaultNamingContext"].Value.ToString());
        DirectorySearcher searcher = new DirectorySearcher(root)
        {
            Filter = "(objectClass=groupPolicyContainer)"
        };

        SearchResultCollection GPOs = searcher.FindAll();

        // new dictionary for data from each GPO to go into
        Dictionary <string, Dictionary <string, string> > GPOsData = new Dictionary <string, Dictionary <string, string> >();

        foreach (SearchResult GPO in GPOs)
        {
            // new dictionary for data from this GPO
            Dictionary <string, string> GPOData = new Dictionary <string, string>();

            DirectoryEntry GPODE     = GPO.GetDirectoryEntry();
            string         GPODN     = GPO.GetDirectoryEntry().Properties["distinguishedName"].Value.ToString();
            string[]       GPOUIDsp0 = GPODN.Split(',');
            string[]       GPOUIDsp1 = GPOUIDsp0[0].Split('=');
            string         GPOUID    = GPOUIDsp1[1];
            GPOData.Add("UID", GPOUID);
            GPOData.Add("DistinguishedName", GPODN);

            DirectoryEntry gpoObject = new DirectoryEntry($"LDAP://{GPODN}");
            //GPOData.Add("SDDL", gpoObject.ObjectSecurity.ToString());
            GPOData.Add("DisplayName", gpoObject.Properties["displayName"].Value.ToString());
            GPOsData.Add(GPOUID, GPOData);
        }

        JObject DomainGPOsJson = (JObject)JToken.FromObject(GPOsData);

        //Console.WriteLine(DomainGPOsJson.ToString());

        return(DomainGPOsJson);
    }
        /// <summary>
        /// Converts a SaerchResultEntry into an LdapWrapper
        /// </summary>
        /// <param name="searchResultEntry"></param>
        /// <returns></returns>
        internal static LdapWrapper CreateLdapWrapper(SearchResultEntry searchResultEntry)
        {
            //Look for a null DN first. Not sure why this would happen.
            var distinguishedName = searchResultEntry.DistinguishedName;

            if (distinguishedName == null)
            {
                return(null);
            }

            var accountName    = searchResultEntry.GetProperty("samaccountname");
            var samAccountType = searchResultEntry.GetProperty("samaccounttype");
            var accountDomain  = Helpers.DistinguishedNameToDomain(distinguishedName);
            var objectSid      = searchResultEntry.GetSid();
            var objectId       = searchResultEntry.GetObjectIdentifier();

            //If objectsid/id is null, return
            if (objectSid == null && objectId == null)
            {
                return(null);
            }

            var    objectType = LdapTypeEnum.Unknown;
            string objectIdentifier;

            LdapWrapper wrapper;

            //Lets see if its a "common" principal
            if (objectSid != null && CommonPrincipal.GetCommonSid(objectSid, out var commonPrincipal))
            {
                accountName      = commonPrincipal.Name;
                objectType       = commonPrincipal.Type;
                objectIdentifier = Helpers.ConvertCommonSid(objectSid, accountDomain);
            }
            else
            {
                //Its not a common principal. Lets use properties to figure out what it actually is
                if (samAccountType != null)
                {
                    if (samAccountType == "805306370")
                    {
                        return(null);
                    }

                    objectType = Helpers.SamAccountTypeToType(samAccountType);
                }
                else
                {
                    var objectClasses = searchResultEntry.GetPropertyAsArray("objectClass");
                    if (objectClasses == null)
                    {
                        objectType = LdapTypeEnum.Unknown;
                    }
                    else if (objectClasses.Contains("groupPolicyContainer"))
                    {
                        objectType = LdapTypeEnum.GPO;
                    }
                    else if (objectClasses.Contains("organizationalUnit"))
                    {
                        objectType = LdapTypeEnum.OU;
                    }
                    else if (objectClasses.Contains("domain"))
                    {
                        objectType = LdapTypeEnum.Domain;
                    }
                }

                objectIdentifier = objectId;
            }

            //Override GMSA object type
            if (searchResultEntry.GetPropertyAsBytes("msds-groupmsamembership") != null)
            {
                objectType  = LdapTypeEnum.User;
                accountName = accountName?.TrimEnd('$');
            }

            //Depending on the object type, create the appropriate wrapper object
            switch (objectType)
            {
            case LdapTypeEnum.Computer:
                accountName = accountName?.TrimEnd('$');
                wrapper     = new Computer(searchResultEntry)
                {
                    DisplayName    = $"{accountName}.{accountDomain}".ToUpper(),
                    SamAccountName = accountName
                };

                var hasLaps = searchResultEntry.GetProperty("ms-mcs-admpwdexpirationtime") != null;
                wrapper.Properties.Add("haslaps", hasLaps);
                wrapper.Properties.Add("highvalue", false);
                break;

            case LdapTypeEnum.User:
                wrapper = new User(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}".ToUpper()
                };
                wrapper.Properties.Add("highvalue", false);
                break;

            case LdapTypeEnum.Group:
                wrapper = new Group(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}".ToUpper()
                };

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

            case LdapTypeEnum.GPO:
                accountName = searchResultEntry.GetProperty("displayname");
                wrapper     = new GPO(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}".ToUpper()
                };
                wrapper.Properties.Add("highvalue", false);
                break;

            case LdapTypeEnum.OU:
                accountName = searchResultEntry.GetProperty("name");
                wrapper     = new OU(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}".ToUpper()
                };
                wrapper.Properties.Add("highvalue", false);
                break;

            case LdapTypeEnum.Domain:
                wrapper = new Domain(searchResultEntry)
                {
                    DisplayName = accountDomain.ToUpper()
                };
                wrapper.Properties.Add("highvalue", true);
                break;

            case LdapTypeEnum.Unknown:
                wrapper = null;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //Null wrappers happen when we cant resolve the object type. Shouldn't ever happen, but just in case, return null here
            if (wrapper == null)
            {
                Console.WriteLine($"Null Wrapper: {distinguishedName}");
                return(null);
            }

            //Set the DN/SID for the wrapper going forward and a couple other properties
            wrapper.DistinguishedName = distinguishedName;
            wrapper.Properties.Add("name", wrapper.DisplayName);
            wrapper.Properties.Add("domain", wrapper.Domain);
            wrapper.Properties.Add("objectid", objectIdentifier.ToUpper());
            wrapper.Properties.Add("distinguishedname", distinguishedName);
            wrapper.ObjectIdentifier = objectIdentifier;

            //Some post processing
            PostProcessWrapper(wrapper);

            //Cache the distinguished name from this object
            Cache.Instance.Add(wrapper.DistinguishedName, new ResolvedPrincipal
            {
                ObjectIdentifier = wrapper.ObjectIdentifier,
                ObjectType       = objectType
            });

            //If the objectidentifier is a SID, cache this mapping too
            if (objectIdentifier.StartsWith("S-1-5"))
            {
                Cache.Instance.Add(wrapper.ObjectIdentifier, objectType);
            }

            //Return our wrapper for the next step in the pipeline
            return(wrapper);
        }
Example #4
0
        /// <summary>
        /// Grab properties from GPO objects
        /// </summary>
        /// <param name="wrapper"></param>
        private static void ParseGPOProperties(GPO wrapper)
        {
            var result = wrapper.SearchResult;

            wrapper.Properties.Add("gpcpath", result.GetProperty("gpcfilesyspath"));
        }
Example #5
0
        internal static LdapWrapper FindLdapType(SearchResultEntry searchResultEntry)
        {
            //Look for a null DN first. Not sure why this would happen.
            var distinguishedName = searchResultEntry.DistinguishedName;

            if (distinguishedName == null)
            {
                return(null);
            }

            var accountName    = searchResultEntry.GetProp("samaccountname");
            var samAccountType = searchResultEntry.GetProp("samaccounttype");
            var accountDomain  = Helpers.DistinguishedNameToDomain(distinguishedName);
            var objectSid      = searchResultEntry.GetSid();
            var objectType     = LdapTypeEnum.Unknown;

            LdapWrapper wrapper;

            //Lets see if its a "common" principal
            if (CommonPrincipal.GetCommonSid(objectSid, out var commonPrincipal))
            {
                accountName = commonPrincipal.Name;
                objectType  = commonPrincipal.Type;
            }
            else
            {
                //Its not a common principal. Lets use properties to figure out what it actually is
                if (samAccountType != null)
                {
                    if (samAccountType == "805306370")
                    {
                        return(null);
                    }

                    objectType = Helpers.SamAccountTypeToType(samAccountType);
                }
                else
                {
                    var objectClasses = searchResultEntry.GetPropArray("objectClass");
                    if (objectClasses == null)
                    {
                        objectType = LdapTypeEnum.Unknown;
                    }
                    else if (objectClasses.Contains("groupPolicyContainer"))
                    {
                        objectType = LdapTypeEnum.GPO;
                    }
                    else if (objectClasses.Contains("organizationalUnit"))
                    {
                        objectType = LdapTypeEnum.OU;
                    }
                    else if (objectClasses.Contains("domain"))
                    {
                        objectType = LdapTypeEnum.Domain;
                    }
                }
            }

            //Depending on the object type, create the appropriate wrapper object
            switch (objectType)
            {
            case LdapTypeEnum.Computer:
                accountName = accountName?.TrimEnd('$');
                wrapper     = new Computer(searchResultEntry)
                {
                    DisplayName = $"{accountName}.{accountDomain}"
                };
                break;

            case LdapTypeEnum.User:
                wrapper = new User(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}"
                };
                break;

            case LdapTypeEnum.Group:
                wrapper = new Group(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}"
                };
                break;

            case LdapTypeEnum.GPO:
                accountName = searchResultEntry.GetProp("displayname");
                wrapper     = new GPO(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}"
                };
                break;

            case LdapTypeEnum.OU:
                accountName = searchResultEntry.GetProp("name");
                wrapper     = new OU(searchResultEntry)
                {
                    DisplayName = $"{accountName}@{accountDomain}"
                };
                break;

            case LdapTypeEnum.Domain:
                wrapper = new Domain(searchResultEntry)
                {
                    DisplayName = accountDomain
                };
                break;

            case LdapTypeEnum.Unknown:
                wrapper = null;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //Set the DN/SID for the wrapper going forward
            if (wrapper == null)
            {
                return(wrapper);
            }
            wrapper.DistinguishedName  = distinguishedName;
            wrapper.SecurityIdentifier = objectSid;

            //Return our wrapper for the next step in the pipeline
            return(wrapper);
        }
Example #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);
        }