public static void Set_DomainObject(Args_Set_DomainObject args = null) { var SearcherArguments = new Args_Get_DomainObject { Identity = args.Identity, Raw = true, 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 }; // splat the appropriate arguments to Get-DomainObject var RawObject = GetDomainObject.Get_DomainObject(SearcherArguments); foreach (SearchResult obj in RawObject) { var Entry = obj.GetDirectoryEntry(); if (args.Set != null) { try { foreach (var set in args.Set) { Logger.Write_Verbose($@"[Set-DomainObject] Setting '{set.Key}' to '{set.Value}' for object '{obj.Properties[@"samaccountname"][0]}'"); Entry.InvokeSet(set.Key, new[] { set.Value }); } Entry.CommitChanges(); } catch (Exception e) { Logger.Write_Warning($@"[Set-DomainObject] Error setting/replacing properties for object '{obj.Properties[@"samaccountname"][0]}' : {e}"); } } if (args.XOR != null) { try { foreach (var xor in args.XOR) { var PropertyName = xor.Key; var PropertyXorValue = (int)xor.Value; Logger.Write_Verbose($@"[Set-DomainObject] XORing '{PropertyName}' with '{PropertyXorValue}' for object '{obj.Properties[@"samaccountname"][0]}'"); var TypeName = Entry.Properties[PropertyName][0].GetType(); // UAC value references- https://support.microsoft.com/en-us/kb/305144 var PropertyValue = (int)Entry.Properties[PropertyName][0] ^ PropertyXorValue; Entry.Properties[PropertyName][0] = PropertyValue; } Entry.CommitChanges(); } catch (Exception e) { Logger.Write_Warning($@"[Set-DomainObject] Error XOR'ing properties for object '{obj.Properties[@"samaccountname"][0]}' : {e}"); } } if (args.Clear != null) { try { foreach (var clear in args.Clear) { var PropertyName = clear; Logger.Write_Verbose($@"[Set-DomainObject] Clearing '{PropertyName}' for object '{obj.Properties[@"samaccountname"][0]}'"); Entry.Properties[PropertyName].Clear(); } Entry.CommitChanges(); } catch (Exception e) { Logger.Write_Warning($@"[Set-DomainObject] Error clearing properties for object '{obj.Properties[@"samaccountname"][0]}' : {e}"); } } } }
public static IEnumerable <ManagedSecurityGroup> Get_DomainManagedSecurityGroup(Args_Get_DomainManagedSecurityGroup args = null) { if (args == null) { args = new Args_Get_DomainManagedSecurityGroup(); } var SearcherArguments = new Args_Get_DomainGroup { LDAPFilter = @"(&(managedBy=*)(groupType:1.2.840.113556.1.4.803:=2147483648))", Properties = new[] { @"distinguishedName", @"managedBy", @"samaccounttype", @"samaccountname" }, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var ObjectArguments = new Args_Get_DomainObject { LDAPFilter = @"(&(managedBy=*)(groupType:1.2.840.113556.1.4.803:=2147483648))", Properties = new[] { @"distinguishedName", @"managedBy", @"samaccounttype", @"samaccountname" }, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; string TargetDomain = null; if (args.Domain.IsNotNullOrEmpty()) { SearcherArguments.Domain = args.Domain; TargetDomain = args.Domain; } else { TargetDomain = Environment.GetEnvironmentVariable("USERDNSDOMAIN"); } var ManagedGroups = new List <ManagedSecurityGroup>(); // go through the list of security groups on the domain and identify those who have a manager var groups = GetDomainGroup.Get_DomainGroup(SearcherArguments); foreach (LDAPProperty group in groups) { ObjectArguments.Properties = new[] { @"distinguishedname", @"name", @"samaccounttype", @"samaccountname", @"objectsid" }; ObjectArguments.Identity = new[] { group.managedby }; SearcherArguments.LDAPFilter = null; // $SearcherArguments // retrieve the object that the managedBy DN refers to var GroupManager = GetDomainObject.Get_DomainObject(ObjectArguments).First() as LDAPProperty; // Write-Host "GroupManager: $GroupManager" var ManagedGroup = new ManagedSecurityGroup { GroupName = group.samaccountname, GroupDistinguishedName = group.distinguishedname, ManagerName = GroupManager.samaccountname, ManagerDistinguishedName = GroupManager.distinguishedname }; // determine whether the manager is a user or a group if (GroupManager.samaccounttype == SamAccountType.GROUP_OBJECT) { ManagedGroup.ManagerType = ManagerType.Group; } else if (GroupManager.samaccounttype == SamAccountType.USER_OBJECT) { ManagedGroup.ManagerType = ManagerType.User; } ManagedGroup.ManagerCanWrite = "UNKNOWN"; ManagedGroups.Add(ManagedGroup); } return(ManagedGroups); }
public static IEnumerable <object> Get_DomainGroup(Args_Get_DomainGroup args = null) { if (args == null) { args = new Args_Get_DomainGroup(); } 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 ObjectArguments = new Args_Get_DomainObject { 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 GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var Groups = new List <object>(); if (GroupSearcher != null) { if (args.MemberIdentity != null) { string[] OldProperties = null; if (args.Properties != null) { OldProperties = SearcherArguments.Properties; } ObjectArguments.Identity = args.MemberIdentity; ObjectArguments.Raw = true; var Objects = GetDomainObject.Get_DomainObject(ObjectArguments); if (Objects != null) { } foreach (SearchResult obj in Objects) { // convert the user/group to a directory entry var ObjectDirectoryEntry = obj.GetDirectoryEntry(); // cause the cache to calculate the token groups for the user/group ObjectDirectoryEntry.RefreshCache(new string[] { @"tokenGroups" }); foreach (byte[] tokenGroup in ObjectDirectoryEntry.Properties[@"tokenGroups"]) { // convert the token group sid var GroupSid = new System.Security.Principal.SecurityIdentifier(tokenGroup, 0).Value; // ignore the built in groups if (new Regex(@"^S-1-5-32-.*").Match(GroupSid).Success == false) { ObjectArguments.Identity = new string[] { GroupSid }; ObjectArguments.Raw = false; if (OldProperties != null) { ObjectArguments.Properties = OldProperties; } var Group = GetDomainObject.Get_DomainObject(ObjectArguments); if (Group != null) { Groups.AddRange(Group); } } } } } else { var IdentityFilter = ""; var Filter = ""; if (args.Identity != null) { foreach (var samName in args.Identity) { var IdentityInstance = samName.Replace(@"(", @"\28").Replace(@")", @"\29"); if (new Regex(@"^S-1-").Match(IdentityInstance).Success) { IdentityFilter += $@"(objectsid={IdentityInstance})"; } else if (new Regex(@"^CN=").Match(IdentityInstance).Success) { 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-DomainGroup] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (GroupSearcher == null) { Logger.Write_Warning($@"[Get-DomainGroup] Unable to retrieve domain searcher for '{IdentityDomain}'"); } } } else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success) { var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2"))); IdentityFilter += $@"(objectguid={GuidByteString})"; } else if (IdentityInstance.Contains(@"\")) { var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName { OutputType = ADSNameType.Canonical, Identity = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") } }); if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any()) { var GroupDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/')); var GroupName = IdentityInstance.Split(new char[] { '\\' })[1]; IdentityFilter += $@"(samAccountName={GroupName})"; SearcherArguments.Domain = GroupDomain; Logger.Write_Verbose($@"[Get-DomainUser] Extracted domain '{GroupDomain}' from '{IdentityInstance}'"); GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); } } else { IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance}))"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != "") { Filter += $@"(|{IdentityFilter})"; } if (args.AdminCount) { Logger.Write_Verbose(@"[Get-DomainGroup] Searching for adminCount=1"); Filter += "(admincount=1)"; } if (args.GroupScope != null) { switch (args.GroupScope.Value) { case GroupScope.DomainLocal: Filter = "(groupType:1.2.840.113556.1.4.803:=4)"; break; case GroupScope.NotDomainLocal: Filter = "(!(groupType:1.2.840.113556.1.4.803:=4))"; break; case GroupScope.Global: Filter = "(groupType:1.2.840.113556.1.4.803:=2)"; break; case GroupScope.NotGlobal: Filter = "(!(groupType:1.2.840.113556.1.4.803:=2))"; break; case GroupScope.Universal: Filter = "(groupType:1.2.840.113556.1.4.803:=8)"; break; case GroupScope.NotUniversal: Filter = "(!(groupType:1.2.840.113556.1.4.803:=8))"; break; default: break; } Logger.Write_Verbose($@"[Get-DomainGroup] Searching for group scope '{args.GroupScope.Value.ToString()}'"); } if (args.GroupProperty != null) { switch (args.GroupProperty.Value) { case GroupProperty.Security: Filter = "(groupType:1.2.840.113556.1.4.803:=2147483648)"; break; case GroupProperty.Distribution: Filter = "(!(groupType:1.2.840.113556.1.4.803:=2147483648))"; break; case GroupProperty.CreatedBySystem: Filter = "(groupType:1.2.840.113556.1.4.803:=1)"; break; case GroupProperty.NotCreatedBySystem: Filter = "(!(groupType:1.2.840.113556.1.4.803:=1))"; break; default: break; } Logger.Write_Verbose($@"[Get-DomainGroup] Searching for group property '{args.GroupProperty.Value.ToString()}'"); } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainGroup] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } GroupSearcher.Filter = $@"(&(objectCategory=group){Filter})"; Logger.Write_Verbose($@"[Get-DomainGroup] filter string: {GroupSearcher.Filter}"); if (args.FindOne) { var result = GroupSearcher.FindOne(); if (args.Raw) { // return raw result objects Groups.Add(result); } else { Groups.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } else { var Results = GroupSearcher.FindAll(); foreach (SearchResult result in Results) { if (args.Raw) { // return raw result objects Groups.Add(result); } else { Groups.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } if (Results != null) { try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainGroup] Error disposing of the Results object: {e}"); } } } GroupSearcher.Dispose(); } } return(Groups); }
public static IEnumerable <object> Get_ADObject(Args_Get_DomainObject args = null) { return(GetDomainObject.Get_DomainObject(args)); }
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); }
public static void Add_DomainObjectAcl(Args_Add_DomainObjectAcl args = null) { if (args == null) { args = new Args_Add_DomainObjectAcl(); } var TargetSearcherArguments = new Args_Get_DomainObject { Properties = new[] { "distinguishedname" }, Raw = true, Domain = args.TargetDomain, LDAPFilter = args.TargetLDAPFilter, SearchBase = args.TargetSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var PrincipalSearcherArguments = new Args_Get_DomainObject { Identity = args.PrincipalIdentity, Properties = new[] { "distinguishedname", "objectsid" }, Domain = args.PrincipalDomain, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var Principals = GetDomainObject.Get_DomainObject(PrincipalSearcherArguments); if (Principals == null) { throw new Exception($@"Unable to resolve principal: {args.PrincipalIdentity}"); } TargetSearcherArguments.Identity = args.TargetIdentity; var Targets = GetDomainObject.Get_DomainObject(TargetSearcherArguments); foreach (SearchResult TargetObject in Targets) { var InheritanceType = System.DirectoryServices.ActiveDirectorySecurityInheritance.None; var ControlType = System.Security.AccessControl.AccessControlType.Allow; var ACEs = new List <System.DirectoryServices.ActiveDirectoryAccessRule>(); var GUIDs = new List <string>(); if (args.RightsGUID != null) { GUIDs.Add(args.RightsGUID.ToString()); } else { switch (args.Rights) { // ResetPassword doesn't need to know the user's current password case Rights.ResetPassword: GUIDs.Add("00299570-246d-11d0-a768-00aa006e0529"); break; // allows for the modification of group membership case Rights.WriteMembers: GUIDs.Add("bf9679c0 -0de6-11d0-a285-00aa003049e2"); break; // 'DS-Replication-Get-Changes' = 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 // 'DS-Replication-Get-Changes-All' = 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 // 'DS-Replication-Get-Changes-In-Filtered-Set' = 89e95b76-444d-4c62-991a-0facbeda640c // when applied to a domain's ACL, allows for the use of DCSync case Rights.DCSync: GUIDs.Add("1131f6aa-9c07-11d1-f79f-00c04fc2dcd2"); GUIDs.Add("1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"); GUIDs.Add("89e95b76-444d-4c62-991a-0facbeda640c"); break; } } foreach (LDAPProperty PrincipalObject in Principals) { Logger.Write_Verbose($@"[Add-DomainObjectAcl] Granting principal {PrincipalObject.distinguishedname} '{args.Rights}' on {TargetObject.Properties["distinguishedname"][0]}"); try { var Identity = new System.Security.Principal.SecurityIdentifier(PrincipalObject.objectsid[0]); if (GUIDs != null) { foreach (var GUID in GUIDs) { var NewGUID = new Guid(GUID); var ADRights = System.DirectoryServices.ActiveDirectoryRights.ExtendedRight; ACEs.Add(new System.DirectoryServices.ActiveDirectoryAccessRule(Identity, ADRights, ControlType, NewGUID, InheritanceType)); } } else { // deault to GenericAll rights var ADRights = System.DirectoryServices.ActiveDirectoryRights.GenericAll; ACEs.Add(new System.DirectoryServices.ActiveDirectoryAccessRule(Identity, ADRights, ControlType, InheritanceType)); } // add all the new ACEs to the specified object directory entry foreach (var ACE in ACEs) { Logger.Write_Verbose($@"[Add-DomainObjectAcl] Granting principal {PrincipalObject.distinguishedname} rights GUID '{ACE.ObjectType}' on {TargetObject.Properties["distinguishedname"][0]}"); var TargetEntry = TargetObject.GetDirectoryEntry(); TargetEntry.Options.SecurityMasks = SecurityMasks.Dacl; TargetEntry.ObjectSecurity.AddAccessRule(ACE); TargetEntry.CommitChanges(); } } catch (Exception e) { Logger.Write_Verbose($@"[Add-DomainObjectAcl] Error granting principal {PrincipalObject.distinguishedname} '{args.Rights}' on {TargetObject.Properties["distinguishedname"][0]}: {e}"); } } } }
public static IEnumerable <ACL> Find_InterestingDomainAcl(Args_Find_InterestingDomainAcl args = null) { if (args == null) { args = new Args_Find_InterestingDomainAcl(); } var ACLArguments = new Args_Get_DomainObjectAcl { ResolveGUIDs = args.ResolveGUIDs, RightsFilter = args.RightsFilter, 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 ObjectSearcherArguments = new Args_Get_DomainObject { Properties = new[] { "samaccountname", "objectclass" }, Raw = true, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var ADNameArguments = new Args_Convert_ADName { Server = args.Server, Credential = args.Credential }; // ongoing list of built-up SIDs var ResolvedSIDs = new Dictionary <string, ResolvedSID>(); if (args.Domain != null) { ACLArguments.Domain = args.Domain; ADNameArguments.Domain = args.Domain; } var InterestingACLs = new List <ACL>(); var acls = GetDomainObjectAcl.Get_DomainObjectAcl(ACLArguments); foreach (var acl in acls) { if ((acl.ActiveDirectoryRights.ToString().IsRegexMatch(@"GenericAll|Write|Create|Delete")) || ((acl.ActiveDirectoryRights == ActiveDirectoryRights.ExtendedRight) && (acl.Ace is QualifiedAce) && (acl.Ace as QualifiedAce).AceQualifier == AceQualifier.AccessAllowed)) { // only process SIDs > 1000 var ace = acl.Ace as QualifiedAce; if (ace != null && ace.SecurityIdentifier.Value.IsRegexMatch(@"^S-1-5-.*-[1-9]\d{3,}$")) { if (ResolvedSIDs.ContainsKey(ace.SecurityIdentifier.Value) && ResolvedSIDs[ace.SecurityIdentifier.Value] != null) { var ResolvedSID = ResolvedSIDs[(acl.Ace as KnownAce).SecurityIdentifier.Value]; var InterestingACL = new ACL { ObjectDN = acl.ObjectDN, Ace = ace, ActiveDirectoryRights = acl.ActiveDirectoryRights, IdentityReferenceName = ResolvedSID.IdentityReferenceName, IdentityReferenceDomain = ResolvedSID.IdentityReferenceDomain, IdentityReferenceDN = ResolvedSID.IdentityReferenceDN, IdentityReferenceClass = ResolvedSID.IdentityReferenceClass }; InterestingACLs.Add(InterestingACL); } else { ADNameArguments.Identity = new string[] { ace.SecurityIdentifier.Value }; ADNameArguments.OutputType = ADSNameType.DN; var IdentityReferenceDN = ConvertADName.Convert_ADName(ADNameArguments)?.FirstOrDefault(); // "IdentityReferenceDN: $IdentityReferenceDN" if (IdentityReferenceDN != null) { var IdentityReferenceDomain = IdentityReferenceDN.Substring(IdentityReferenceDN.IndexOf("DC=")).Replace(@"DC=", "").Replace(",", "."); // "IdentityReferenceDomain: $IdentityReferenceDomain" ObjectSearcherArguments.Domain = IdentityReferenceDomain; ObjectSearcherArguments.Identity = new[] { IdentityReferenceDN }; // "IdentityReferenceDN: $IdentityReferenceDN" var Object = GetDomainObject.Get_DomainObject(ObjectSearcherArguments)?.FirstOrDefault() as SearchResult; if (Object != null) { var IdentityReferenceName = Object.Properties["samaccountname"][0].ToString(); string IdentityReferenceClass; if (Object.Properties["objectclass"][0].ToString().IsRegexMatch(@"computer")) { IdentityReferenceClass = "computer"; } else if (Object.Properties["objectclass"][0].ToString().IsRegexMatch(@"group")) { IdentityReferenceClass = "group"; } else if (Object.Properties["objectclass"][0].ToString().IsRegexMatch(@"user")) { IdentityReferenceClass = "user"; } else { IdentityReferenceClass = null; } // save so we don't look up more than once ResolvedSIDs[ace.SecurityIdentifier.Value] = new ResolvedSID { IdentityReferenceName = IdentityReferenceName, IdentityReferenceDomain = IdentityReferenceDomain, IdentityReferenceDN = IdentityReferenceDN, IdentityReferenceClass = IdentityReferenceClass }; var InterestingACL = new ACL { ObjectDN = acl.ObjectDN, Ace = ace, ActiveDirectoryRights = acl.ActiveDirectoryRights, IdentityReferenceName = IdentityReferenceName, IdentityReferenceDomain = IdentityReferenceDomain, IdentityReferenceDN = IdentityReferenceDN, IdentityReferenceClass = IdentityReferenceClass }; InterestingACLs.Add(InterestingACL); } } else { Logger.Write_Warning($@"[Find-InterestingDomainAcl] Unable to convert SID '{ace.SecurityIdentifier.Value}' to a distinguishedname with Convert-ADName"); } } } } } return(InterestingACLs); }
public static IEnumerable <GroupMember> Get_DomainGroupMember(Args_Get_DomainGroupMember args = null) { if (args == null) { args = new Args_Get_DomainGroupMember(); } var SearcherArguments = new Args_Get_DomainSearcher() { Properties = new string[] { @"member", @"samaccountname", @"distinguishedname" }, 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 ADNameArguments = new Args_Convert_ADName { Domain = args.Domain, Server = args.Server, Credential = args.Credential }; var GroupMembers = new List <GroupMember>(); var GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (GroupSearcher != null) { string GroupFoundDomain = null; string GroupFoundName = null; string GroupFoundDN = null; List <string> Members = null; if (args.RecurseUsingMatchingRule) { var GroupArguments = new Args_Get_DomainGroup() { Properties = SearcherArguments.Properties, Domain = SearcherArguments.Domain, LDAPFilter = SearcherArguments.LDAPFilter, SearchBase = SearcherArguments.SearchBase, Server = SearcherArguments.Server, SearchScope = SearcherArguments.SearchScope, ResultPageSize = SearcherArguments.ResultPageSize, ServerTimeLimit = SearcherArguments.ServerTimeLimit, Tombstone = SearcherArguments.Tombstone, Credential = SearcherArguments.Credential, Identity = args.Identity, Raw = true }; var Groups = GetDomainGroup.Get_DomainGroup(GroupArguments); if (Groups == null) { Logger.Write_Warning($@"[Get-DomainGroupMember] Error searching for group with identity: {args.Identity}"); } else { var Group = Groups.First() as SearchResult; GroupFoundName = Group.Properties[@"samaccountname"][0] as string; GroupFoundDN = Group.Properties[@"distinguishedname"][0] as string; if (args.Domain.IsNotNullOrEmpty()) { GroupFoundDomain = args.Domain; } else { // if a domain isn't passed, try to extract it from the found group distinguished name if (GroupFoundDN.IsNotNullOrEmpty()) { GroupFoundDomain = GroupFoundDN.Substring(GroupFoundDN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @"."); } } Logger.Write_Verbose($@"[Get-DomainGroupMember] Using LDAP matching rule to recurse on '{GroupFoundDN}', only user accounts will be returned."); GroupSearcher.Filter = $@"(&(samAccountType=805306368)(memberof:1.2.840.113556.1.4.1941:={GroupFoundDN}))"; GroupSearcher.PropertiesToLoad.AddRange(new string[] { @"distinguishedName" }); var Results = GroupSearcher.FindAll(); if (Results != null) { Members = new List <string>(); foreach (SearchResult result in Results) { Members.Add(result.Properties[@"distinguishedname"][0] as string); } } } } else { var IdentityFilter = @""; var Filter = @""; if (args.Identity != null) { foreach (var item in args.Identity) { var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29"); if (new Regex(@"^S-1-").Match(IdentityInstance).Success) { IdentityFilter += $@"(objectsid={IdentityInstance})"; } else if (new Regex(@"^CN=").Match(IdentityInstance).Success) { 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-DomainGroupMember] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (GroupSearcher == null) { Logger.Write_Warning($@"[Get-DomainGroupMember] Unable to retrieve domain searcher for '{IdentityDomain}'"); } } } else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success) { var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2"))); IdentityFilter += $@"(objectguid={GuidByteString})"; } else if (IdentityInstance.Contains(@"\")) { var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName { OutputType = ADSNameType.Canonical, Identity = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") } }); if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any()) { var GroupDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/')); var GroupName = IdentityInstance.Split(new char[] { '\\' })[1]; IdentityFilter += $@"(samAccountName={GroupName})"; SearcherArguments.Domain = GroupDomain; Logger.Write_Verbose($@"[Get-DomainGroupMember] Extracted domain '{GroupDomain}' from '{IdentityInstance}'"); GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); } } else { IdentityFilter += $@"(samAccountName={IdentityInstance})"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != @"") { Filter += $@"(|{IdentityFilter})"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainGroupMember] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } GroupSearcher.Filter = $@"(&(objectCategory=group){Filter})"; Logger.Write_Verbose($@"[Get-DomainGroupMember] Get-DomainGroupMember filter string: {GroupSearcher.Filter}"); SearchResult Result = null; try { Result = GroupSearcher.FindOne(); } catch (Exception e) { Logger.Write_Warning($@"[Get-DomainGroupMember] Error searching for group with identity '{args.Identity}': {e}"); Members = new List <string>(); } GroupFoundName = @""; GroupFoundDN = @""; if (Result != null) { var tmpProperty = Result.Properties[@"member"]; var tmpValues = new string[tmpProperty.Count]; tmpProperty.CopyTo(tmpValues, 0); Members = tmpValues.ToList(); string RangedProperty = ""; if (Members.Count == 0) { // ranged searching, thanks @meatballs__ ! var Finished = false; var Bottom = 0; var Top = 0; while (!Finished) { Top = Bottom + 1499; var MemberRange = $@"member;range={Bottom}-{Top}"; Bottom += 1500; GroupSearcher.PropertiesToLoad.Clear(); GroupSearcher.PropertiesToLoad.Add($@"{MemberRange}"); GroupSearcher.PropertiesToLoad.Add(@"samaccountname"); GroupSearcher.PropertiesToLoad.Add(@"distinguishedname"); try { Result = GroupSearcher.FindOne(); RangedProperty = Result.Properties.PropertyNames.GetFirstMatch(@"member;range=*"); tmpProperty = Result.Properties[RangedProperty]; tmpValues = new string[tmpProperty.Count]; tmpProperty.CopyTo(tmpValues, 0); Members.AddRange(tmpValues.ToList()); GroupFoundName = Result.Properties[@"samaccountname"][0] as string; GroupFoundDN = Result.Properties[@"distinguishedname"][0] as string; if (Members.Count == 0) { Finished = true; } } catch { Finished = true; } } } else { GroupFoundName = Result.Properties[@"samaccountname"][0] as string; GroupFoundDN = Result.Properties[@"distinguishedname"][0] as string; tmpProperty = Result.Properties[RangedProperty]; tmpValues = new string[tmpProperty.Count]; tmpProperty.CopyTo(tmpValues, 0); Members.AddRange(tmpValues.ToList()); } if (args.Domain.IsNotNullOrEmpty()) { GroupFoundDomain = args.Domain; } else { // if a domain isn't passed, try to extract it from the found group distinguished name if (GroupFoundDN.IsNotNullOrEmpty()) { GroupFoundDomain = GroupFoundDN.Substring(GroupFoundDN.IndexOf(@"DC=")).Replace(@"DC=", @"".Replace(@",", @".")); } } } var UseMatchingRule = false; string MemberDomain = null; foreach (var Member in Members) { ResultPropertyCollection Properties = null; if (args.Recurse && UseMatchingRule) { //$Properties = $_.Properties } else { var ObjectSearcherArguments = new Args_Get_DomainObject { ADSPath = SearcherArguments.ADSPath, Credential = SearcherArguments.Credential, Domain = SearcherArguments.Domain, DomainController = SearcherArguments.DomainController, Filter = SearcherArguments.Filter, LDAPFilter = SearcherArguments.LDAPFilter, Properties = SearcherArguments.Properties, ResultPageSize = SearcherArguments.ResultPageSize, SearchBase = SearcherArguments.SearchBase, SearchScope = SearcherArguments.SearchScope, SecurityMasks = SearcherArguments.SecurityMasks, Server = SearcherArguments.Server, ServerTimeLimit = SearcherArguments.ServerTimeLimit, Tombstone = SearcherArguments.Tombstone }; ObjectSearcherArguments.Identity = new string[] { Member }; ObjectSearcherArguments.Raw = true; ObjectSearcherArguments.Properties = new string[] { @"distinguishedname", @"cn", @"samaccountname", @"objectsid", @"objectclass" }; var Object = GetDomainObject.Get_DomainObject(ObjectSearcherArguments)?.FirstOrDefault() as SearchResult; Properties = Object.Properties; } if (Properties != null) { var GroupMember = new GroupMember { GroupDomain = GroupFoundDomain, GroupName = GroupFoundName, GroupDistinguishedName = GroupFoundDN }; string MemberSID = null; if (Properties["objectsid"] != null) { MemberSID = new System.Security.Principal.SecurityIdentifier(Properties["objectsid"][0] as byte[], 0).Value; } else { MemberSID = null; } string MemberDN = null; try { MemberDN = Properties["distinguishedname"][0].ToString(); if (MemberDN.IsRegexMatch(@"ForeignSecurityPrincipals|S-1-5-21")) { try { if (MemberSID.IsNullOrEmpty()) { MemberSID = Properties["cn"][0].ToString(); } ADNameArguments.Identity = new string[] { MemberSID }; ADNameArguments.OutputType = ADSNameType.DomainSimple; var MemberSimpleName = ConvertADName.Convert_ADName(ADNameArguments); if (MemberSimpleName != null && MemberSimpleName.Any()) { MemberDomain = MemberSimpleName.First().Split('@')[1]; } else { Logger.Write_Warning($@"[Get-DomainGroupMember] Error converting {MemberDN}"); MemberDomain = null; } } catch { Logger.Write_Warning($@"[Get-DomainGroupMember] Error converting {MemberDN}"); MemberDomain = null; } } else { // extract the FQDN from the Distinguished Name MemberDomain = MemberDN.Substring(MemberDN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @"."); } } catch { MemberDN = null; MemberDomain = null; } string MemberName = null; if (Properties["samaccountname"] != null) { // forest users have the samAccountName set MemberName = Properties["samaccountname"][0].ToString(); } else { // external trust users have a SID, so convert it try { MemberName = ConvertFromSID.ConvertFrom_SID(new Args_ConvertFrom_SID { ObjectSID = new string[] { Properties["cn"][0].ToString() }, Domain = ADNameArguments.Domain, Server = ADNameArguments.Server, Credential = ADNameArguments.Credential }).First(); } catch { // if there's a problem contacting the domain to resolve the SID MemberName = Properties["cn"][0].ToString(); } } string MemberObjectClass = null; if (Properties["objectclass"].RegexContains(@"computer")) { MemberObjectClass = @"computer"; } else if (Properties["objectclass"].RegexContains(@"group")) { MemberObjectClass = @"group"; } else if (Properties["objectclass"].RegexContains(@"user")) { MemberObjectClass = @"user"; } else { MemberObjectClass = null; } GroupMember.MemberDomain = MemberDomain; GroupMember.MemberName = MemberName; GroupMember.MemberDistinguishedName = MemberDN; GroupMember.MemberObjectClass = MemberObjectClass; GroupMember.MemberSID = MemberSID; GroupMembers.Add(GroupMember); // if we're doing manual recursion if (args.Recurse && MemberDN.IsNotNullOrEmpty() && MemberObjectClass.IsRegexMatch(@"group")) { Logger.Write_Verbose($@"[Get-DomainGroupMember] Manually recursing on group: {MemberDN}"); var GroupArguments = new Args_Get_DomainGroupMember() { Domain = SearcherArguments.Domain, LDAPFilter = SearcherArguments.LDAPFilter, SearchBase = SearcherArguments.SearchBase, Server = SearcherArguments.Server, SearchScope = SearcherArguments.SearchScope, ResultPageSize = SearcherArguments.ResultPageSize, ServerTimeLimit = SearcherArguments.ServerTimeLimit, Tombstone = SearcherArguments.Tombstone, Credential = SearcherArguments.Credential, Identity = new string[] { MemberDN } }; GroupMembers.AddRange(Get_DomainGroupMember(GroupArguments)); } } } } GroupSearcher.Dispose(); } return(GroupMembers); }
public static IEnumerable <string> ConvertTo_SID(Args_ConvertTo_SID args = null) { if (args == null) { args = new Args_ConvertTo_SID(); } var DomainSearcherArguments = new Args_Get_DomainObject { Domain = args.Domain, Server = args.Server, Credential = args.Credential }; var SIDs = new List <string>(); foreach (var item in args.ObjectName) { var name = item.Replace(@"/", @"\"); if (args.Credential != null) { var DN = ConvertADName.Convert_ADName(new Args_Convert_ADName { Identity = new[] { name }, OutputType = ADSNameType.DN, Domain = DomainSearcherArguments.Domain, Server = DomainSearcherArguments.Server, Credential = DomainSearcherArguments.Credential }); if (DN != null) { var UserDomain = DN.First().Substring(DN.First().IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @"."); var UserName = DN.First().Split(',')[0].Split('=')[1]; DomainSearcherArguments.Identity = new[] { UserName }; DomainSearcherArguments.Domain = UserDomain; DomainSearcherArguments.Properties = new[] { @"objectsid" }; var obj = GetDomainObject.Get_DomainObject(DomainSearcherArguments); foreach (LDAPProperty ldapProperty in obj) { SIDs.AddRange(ldapProperty.objectsid); } } } else { try { if (name.Contains(@"\")) { args.Domain = name.Split('\\')[0]; name = name.Split('\\')[1]; } else if (args.Domain.IsNullOrEmpty()) { args.Domain = GetDomain.Get_Domain().Name; } var obj = new System.Security.Principal.NTAccount(args.Domain, name); SIDs.Add(obj.Translate(typeof(System.Security.Principal.SecurityIdentifier)).Value); } catch (Exception e) { Logger.Write_Verbose($@"[ConvertTo-SID] Error converting {args.Domain}\{name} : {e}"); } } } return(SIDs); }