public static IEnumerable <DFSShare> Get_DomainDFSShare(Args_Get_DomainDFSShare args = null) { if (args == null) { args = new Args_Get_DomainDFSShare(); } var SearcherArguments = new Args_Get_DomainSearcher { SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var DFSShares = new List <DFSShare>(); if (args.Domain != null) { foreach (var TargetDomain in args.Domain) { SearcherArguments.Domain = TargetDomain; if (args.Version == Enums.Version.All || args.Version == Enums.Version.V1) { DFSShares.AddRange(Get_DomainDFSShareV1(SearcherArguments)); } if (args.Version == Enums.Version.All || args.Version == Enums.Version.V2) { DFSShares.AddRange(Get_DomainDFSShareV2(SearcherArguments)); } } } else { if (args.Version == Enums.Version.All || args.Version == Enums.Version.V1) { DFSShares.AddRange(Get_DomainDFSShareV1(SearcherArguments)); } if (args.Version == Enums.Version.All || args.Version == Enums.Version.V2) { DFSShares.AddRange(Get_DomainDFSShareV2(SearcherArguments)); } } return(DFSShares); }
public static IEnumerable <object> Get_DomainObject(Args_Get_DomainObject args = null) { if (args == null) { args = new Args_Get_DomainObject(); } 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 ObjectSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var Objects = new List <object>(); if (ObjectSearcher != null) { 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|OU|DC)=").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-DomainObject] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; ObjectSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (ObjectSearcher == null) { Logger.Write_Warning($@"[Get-DomainObject] 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 ObjectDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/')); var ObjectName = IdentityInstance.Split(new char[] { '\\' })[1]; IdentityFilter += $@"(samAccountName={ObjectName})"; SearcherArguments.Domain = ObjectDomain; Logger.Write_Verbose($@"[Get-DomainObject] Extracted domain '{ObjectDomain}' from '{IdentityInstance}'"); ObjectSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); } } else if (IdentityInstance.Contains(@".")) { IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(dnshostname={IdentityInstance}))"; } else { IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(displayname={IdentityInstance}))"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != "") { Filter += $@"(|{IdentityFilter})"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainObject] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } // build the LDAP filter for the dynamic UAC filter value var uacs = args.UACFilter.ExtractValues(); foreach (var uac in uacs) { if (uac.IsNot()) { Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))"; } else { Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})"; } } if (Filter != null && Filter != "") { ObjectSearcher.Filter = $@"(&{Filter})"; } Logger.Write_Verbose($@"[Get-DomainObject] Get-DomainComputer filter string: {ObjectSearcher.Filter}"); if (args.FindOne) { var result = ObjectSearcher.FindOne(); if (args.Raw) { // return raw result objects Objects.Add(result); } else { Objects.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } else { var Results = ObjectSearcher.FindAll(); foreach (SearchResult result in Results) { if (args.Raw) { // return raw result objects Objects.Add(result); } else { Objects.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } if (Results != null) { try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainObject] Error disposing of the Results object: {e}"); } } } ObjectSearcher.Dispose(); } return(Objects); }
public static Dictionary <string, string> Get_DomainGUIDMap(Args_Get_DomainGUIDMap args = null) { if (args == null) { args = new Args_Get_DomainGUIDMap(); } var GUIDs = new Dictionary <string, string> { { @"00000000-0000-0000-0000-000000000000", @"All" } }; var ForestArguments = new Args_Get_Forest() { Credential = args.Credential }; string SchemaPath = null; try { SchemaPath = GetForest.Get_Forest(ForestArguments).Forest.Schema.Name; } catch { throw new Exception(@"[Get-DomainGUIDMap] Error in retrieving forest schema path from Get-Forest"); } if (SchemaPath.IsNullOrEmpty()) { throw new Exception(@"[Get-DomainGUIDMap] Error in retrieving forest schema path from Get-Forest"); } var SearcherArguments = new Args_Get_DomainSearcher { SearchBase = SchemaPath, LDAPFilter = @"(schemaIDGUID=*)", Domain = args.Domain, Server = args.Server, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Credential = args.Credential }; var SchemaSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (SchemaSearcher != null) { try { var Results = SchemaSearcher.FindAll(); if (Results != null) { foreach (SearchResult result in Results) { GUIDs[(new Guid(result.Properties["schemaidguid"][0] as byte[])).ToString()] = result.Properties["name"][0].ToString(); } try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error disposing of the Results object: {e}"); } } SchemaSearcher.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error in building GUID map: {e}"); } } SearcherArguments.SearchBase = SchemaPath.Replace(@"Schema", @"Extended-Rights"); SearcherArguments.LDAPFilter = @"(objectClass=controlAccessRight)"; var RightsSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (RightsSearcher != null) { try { var Results = RightsSearcher.FindAll(); if (Results != null) { foreach (SearchResult result in Results) { GUIDs[(new Guid(result.Properties["rightsguid"][0] as byte[])).ToString()] = result.Properties["name"][0].ToString(); } try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error disposing of the Results object: {e}"); } } RightsSearcher.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error in building GUID map: {e}"); } } return(GUIDs); }
public static IEnumerable <ACL> Get_DomainObjectAcl(Args_Get_DomainObjectAcl args = null) { if (args == null) { args = new Args_Get_DomainObjectAcl(); } var SearcherArguments = new Args_Get_DomainSearcher { Properties = new[] { "samaccountname", "ntsecuritydescriptor", "distinguishedname", "objectsid" }, SecurityMasks = args.Sacl ? SecurityMasks.Sacl : SecurityMasks.Dacl, Domain = args.Domain, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var Searcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var DomainGUIDMapArguments = new Args_Get_DomainGUIDMap { Domain = args.Domain, Server = args.Server, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Credential = args.Credential }; // get a GUID -> name mapping IDictionary <string, string> GUIDs = null; if (args.ResolveGUIDs) { GUIDs = GetDomainGUIDMap.Get_DomainGUIDMap(DomainGUIDMapArguments); } var ACLs = new List <ACL>(); if (Searcher != null) { var IdentityFilter = ""; var Filter = ""; if (args.Identity != null) { foreach (var item in args.Identity) { var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29"); if (IdentityInstance.IsRegexMatch(@"^S-1-.*")) { IdentityFilter += $@"(objectsid={IdentityInstance})"; } else if (IdentityInstance.IsRegexMatch(@"^(CN|OU|DC)=.*")) { 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-DomainObjectAcl] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; Searcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (Searcher == null) { Logger.Write_Warning($@"[Get-DomainObjectAcl] Unable to retrieve domain searcher for '{IdentityDomain}'"); } } } else if (IdentityInstance.IsRegexMatch(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$")) { var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2"))); IdentityFilter += $@"(objectguid={GuidByteString})"; } else if (IdentityInstance.Contains('.')) { IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(dnshostname={IdentityInstance}))"; } else { IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(displayname={IdentityInstance}))"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != "") { Filter += $@"(|{IdentityFilter})"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainObjectAcl] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } if (Filter.IsNotNullOrEmpty()) { Searcher.Filter = $@"(&{Filter})"; } Logger.Write_Verbose($@"[Get-DomainObjectAcl] Get-DomainObjectAcl filter string: {Searcher.Filter}"); var Results = Searcher.FindAll(); foreach (SearchResult result in Results) { var Object = result.Properties; string ObjectSid = null; if (Object["objectsid"] != null && Object["objectsid"].Count > 0 && Object["objectsid"][0] != null) { ObjectSid = new System.Security.Principal.SecurityIdentifier(Object["objectsid"][0] as byte[], 0).Value; } else { ObjectSid = null; } try { var rsd = new System.Security.AccessControl.RawSecurityDescriptor(Object["ntsecuritydescriptor"][0] as byte[], 0); var rawAcl = args.Sacl ? rsd.SystemAcl : rsd.DiscretionaryAcl; foreach (var ace in rawAcl) { var acl = new ACL { Ace = ace }; bool Continue = false; if (args.RightsFilter != null) { string GuidFilter = null; switch (args.RightsFilter.Value) { case Rights.ResetPassword: GuidFilter = "00299570-246d-11d0-a768-00aa006e0529"; break; case Rights.WriteMembers: GuidFilter = "bf9679c0-0de6-11d0-a285-00aa003049e2"; break; default: GuidFilter = "00000000-0000-0000-0000-000000000000"; break; } if (ace is System.Security.AccessControl.ObjectAccessRule) { if (string.Compare(((object)ace as System.Security.AccessControl.ObjectAccessRule).ObjectType.ToString(), GuidFilter, StringComparison.OrdinalIgnoreCase) == 0) { acl.ObjectDN = Object["distinguishedname"][0] as string; acl.ObjectSID = ObjectSid; Continue = true; } } } else { acl.ObjectDN = Object["distinguishedname"][0] as string; acl.ObjectSID = ObjectSid; Continue = true; } if (Continue) { if (ace is System.Security.AccessControl.KnownAce) { acl.ActiveDirectoryRights = (System.DirectoryServices.ActiveDirectoryRights)(ace as System.Security.AccessControl.KnownAce).AccessMask; } if (GUIDs != null) { // if we're resolving GUIDs, map them them to the resolved hash table if (ace is ObjectAce) { try { (acl.Ace as ObjectAce).ObjectAceType = new Guid(GUIDs[(ace as ObjectAce).ObjectAceType.ToString()]); } catch { } try { (acl.Ace as ObjectAce).InheritedObjectAceType = new Guid(GUIDs[(ace as ObjectAce).InheritedObjectAceType.ToString()]); } catch { } } else if (ace is ObjectAccessRule) { /*try { (acl.Ace as ObjectAccessRule).ObjectType = new Guid(GUIDs[(ace as ObjectAccessRule).ObjectType.ToString()]); } * catch { } * try { (acl.Ace as ObjectAccessRule).InheritedObjectType = new Guid(GUIDs[(ace as ObjectAccessRule).InheritedObjectType.ToString()]); } * catch { }*/ } } ACLs.Add(acl); } } } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainObjectAcl] Error: {e}"); } } } return(ACLs); }
private static IEnumerable <DFSShare> Get_DomainDFSShareV1(Args_Get_DomainSearcher args = null) { if (args == null) { args = new Args_Get_DomainSearcher(); } var DFSSearcher = GetDomainSearcher.Get_DomainSearcher(args); if (DFSSearcher != null) { var DFSShares = new List <DFSShare>(); ResultPropertyCollection Properties = null; DFSSearcher.Filter = @"(&(objectClass=fTDfs))"; try { ResultPropertyValueCollection Pkt = null; var Results = DFSSearcher.FindAll(); if (Results != null) { foreach (SearchResult result in Results) { Properties = result.Properties; var RemoteNames = Properties[@"remoteservername"]; Pkt = Properties[@"pkt"]; if (RemoteNames != null) { foreach (string name in RemoteNames) { try { if (name.Contains(@"\")) { DFSShares.Add(new DFSShare { Name = Properties[@"name"][0] as string, RemoteServerName = name.Split(new char[] { '\\' })[2] }); } } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error in parsing DFS share : {e}"); } } } try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error disposing of the Results object: {e}"); } } DFSSearcher.Dispose(); if (Pkt != null && Pkt[0] != null) { var servers = Parse_Pkt(Pkt[0] as byte[]); if (servers != null) { foreach (var server in servers) { // If a folder doesn't have a redirection it will have a target like // \\null\TestNameSpace\folder\.DFSFolderLink so we do actually want to match // on 'null' rather than $Null if (server != null && server != @"null" && DFSShares.Any(x => x.RemoteServerName == server)) { DFSShares.Add(new DFSShare { Name = Properties[@"name"][0] as string, RemoteServerName = server }); } } } } } } catch (Exception e) { Logger.Write_Warning($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error : {e}"); } return(DFSShares); } return(null); }
private static IEnumerable <DFSShare> Get_DomainDFSShareV2(Args_Get_DomainSearcher args = null) { if (args == null) { args = new Args_Get_DomainSearcher(); } var DFSSearcher = GetDomainSearcher.Get_DomainSearcher(args); if (DFSSearcher != null) { var DFSShares = new List <DFSShare>(); ResultPropertyCollection Properties = null; DFSSearcher.Filter = @"(&(objectClass=msDFS-Linkv2))"; DFSSearcher.PropertiesToLoad.AddRange(new string[] { @"msdfs-linkpathv2", @"msDFS-TargetListv2" }); try { var Results = DFSSearcher.FindAll(); if (Results != null) { foreach (SearchResult result in Results) { Properties = result.Properties; var target_list = Properties[@"msdfs-targetlistv2"][0] as byte[]; var xml = new XmlDocument(); xml.LoadXml(System.Text.Encoding.Unicode.GetString(target_list.Skip(2).Take(target_list.Length - 1 + 1 - 2).ToArray())); if (xml.FirstChild != null) { foreach (XmlNode node in xml.FirstChild.ChildNodes) { try { var Target = node.InnerText; if (Target.Contains(@"\")) { var DFSroot = Target.Split('\\')[3]; var ShareName = Properties[@"msdfs-linkpathv2"][0] as string; DFSShares.Add(new DFSShare { Name = $@"{DFSroot}{ShareName}", RemoteServerName = Target.Split('\\')[2] }); } } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV2 error in parsing target : {e}"); } } } } try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainDFSShare] Error disposing of the Results object: {e}"); } } DFSSearcher.Dispose(); } catch (Exception e) { Logger.Write_Warning($@"[Get-DomainDFSShare] Get-DomainDFSShareV2 error : {e}"); } return(DFSShares); } return(null); }
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); }
/* connect ldap server & create an searcher object */ public static System.DirectoryServices.DirectorySearcher Get_DomainSearcher(Args_Get_DomainSearcher args = null) { if (args == null) { args = new Args_Get_DomainSearcher(); } string TargetDomain = null; string BindServer = null; var userDnsDomain = Environment.GetEnvironmentVariable("USERDNSDOMAIN"); if (args.Domain.IsNotNullOrEmpty()) { TargetDomain = args.Domain; if (userDnsDomain != null && userDnsDomain.Trim() != "") { // see if we can grab the user DNS logon domain from environment variables var UserDomain = userDnsDomain; var logonServer = Environment.GetEnvironmentVariable("LOGONSERVER"); if (logonServer != null && logonServer.Trim() != "" && UserDomain.IsNotNullOrEmpty()) { BindServer = $"{logonServer.Replace(@"\\", "")}.{UserDomain}"; } } } else if (args.Credential != null) { // if not -Domain is specified, but -Credential is, try to retrieve the current domain name with Get-Domain var DomainObject = GetDomain.Get_Domain(new Args_Get_Domain { Credential = args.Credential }); BindServer = DomainObject.PdcRoleOwner.Name; TargetDomain = DomainObject.Name; } else if (userDnsDomain != null && userDnsDomain.Trim() != "") { // see if we can grab the user DNS logon domain from environment variables TargetDomain = userDnsDomain; var logonServer = Environment.GetEnvironmentVariable("LOGONSERVER"); if (logonServer != null && logonServer.Trim() != "" && TargetDomain.IsNotNullOrEmpty()) { BindServer = $"{logonServer.Replace(@"\\", "")}.{TargetDomain}"; } } else { // otherwise, resort to Get-Domain to retrieve the current domain object var DomainObject = GetDomain.Get_Domain(); if (DomainObject == null) { System.Environment.Exit(0); } BindServer = DomainObject.PdcRoleOwner.Name; TargetDomain = DomainObject.Name; } if (args.Server.IsNotNullOrEmpty()) { // if there's not a specified server to bind to, try to pull a logon server from ENV variables BindServer = args.Server; } var SearchString = "LDAP://"; if (BindServer != null && BindServer.Trim() != "") { SearchString += BindServer; if (TargetDomain.IsNotNullOrEmpty()) { SearchString += '/'; } } if (args.SearchBasePrefix.IsNotNullOrEmpty()) { SearchString += args.SearchBasePrefix + @","; } var DN = string.Empty; if (args.SearchBase.IsNotNullOrEmpty()) { if (new Regex(@"^GC://").Match(args.SearchBase).Success) { // if we're searching the global catalog, get the path in the right format DN = args.SearchBase.ToUpper().Trim('/'); SearchString = string.Empty; } else { if (new Regex(@"^LDAP://").Match(args.SearchBase).Success) { if (new Regex(@"LDAP://.+/.+").Match(args.SearchBase).Success) { SearchString = string.Empty; DN = args.SearchBase; } else { DN = args.SearchBase.Substring(7); } } else { DN = args.SearchBase; } } } else { // transform the target domain name into a distinguishedName if an ADS search base is not specified if (TargetDomain != null && TargetDomain.Trim() != "") { DN = $"DC={TargetDomain.Replace(".", ",DC=")}"; } } SearchString += DN; Logger.Write_Verbose($@"[Get-DomainSearcher] search base: {SearchString}"); System.DirectoryServices.DirectorySearcher Searcher = null; if (args.Credential != null) { Logger.Write_Verbose(@"[Get-DomainSearcher] Using alternate credentials for LDAP connection"); // bind to the inital search object using alternate credentials var DomainObject = new System.DirectoryServices.DirectoryEntry(SearchString, args.Credential.UserName, args.Credential.Password); Searcher = new System.DirectoryServices.DirectorySearcher(DomainObject); } else { // bind to the inital object using the current credentials //Searcher = new System.DirectoryServices.DirectorySearcher([ADSI]$SearchString) var DomainObject = new System.DirectoryServices.DirectoryEntry(SearchString); Searcher = new System.DirectoryServices.DirectorySearcher(DomainObject); } Searcher.PageSize = args.ResultPageSize; Searcher.SearchScope = args.SearchScope; Searcher.CacheResults = false; Searcher.ReferralChasing = System.DirectoryServices.ReferralChasingOption.All; if (args.ServerTimeLimit != null) { Searcher.ServerTimeLimit = new TimeSpan(0, 0, args.ServerTimeLimit.Value); } if (args.Tombstone) { Searcher.Tombstone = true; } if (args.LDAPFilter.IsNotNullOrWhiteSpace()) { Searcher.Filter = args.LDAPFilter; } if (args.SecurityMasks != null) { Searcher.SecurityMasks = args.SecurityMasks.Value; } if (args.Properties != null) { // handle an array of properties to load w/ the possibility of comma-separated strings var PropertiesToLoad = new List <string>(); foreach (var item in args.Properties) { PropertiesToLoad.AddRange(item.Split(',')); } Searcher.PropertiesToLoad.AddRange(PropertiesToLoad.ToArray()); } return(Searcher); }
public static IEnumerable <object> Get_DomainSite(Args_Get_DomainSite args = null) { if (args == null) { args = new Args_Get_DomainSite(); } var SearcherArguments = new Args_Get_DomainSearcher { SearchBasePrefix = @"CN=Sites,CN=Configuration", 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 SiteSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var Sites = new List <object>(); if (SiteSearcher != null) { var IdentityFilter = @""; var Filter = @""; if (args.Identity != null) { foreach (var item in args.Identity) { var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29"); if (IdentityInstance.IsRegexMatch(@"^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-DomainSite] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; SiteSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (SiteSearcher == null) { Logger.Write_Warning($@"[Get-DomainSite] Unable to retrieve domain searcher for '{IdentityDomain}'"); } } } else { try { var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2"))); IdentityFilter += $@"(objectguid={GuidByteString})"; } catch { IdentityFilter += $@"(name={IdentityInstance})"; } } } } if (IdentityFilter != null && IdentityFilter.Trim() != @"") { Filter += $@"(|{IdentityFilter})"; } if (args.GPLink.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainSite] Searching for sites with {args.GPLink} set in the gpLink property"); Filter += $@"(gplink=*{args.GPLink}*)"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainSite] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } SiteSearcher.Filter = $@"(&(objectCategory=site){Filter})"; Logger.Write_Verbose($@"[Get-DomainSite] Get-DomainSite filter string: {SiteSearcher.Filter}"); SearchResult[] Results = null; if (args.FindOne) { Results = new SearchResult[] { SiteSearcher.FindOne() }; } else { var items = SiteSearcher.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 Sites.Add(result); } else { var Site = ConvertLDAPProperty.Convert_LDAPProperty(result.Properties); Sites.Add(Site); } } } SiteSearcher.Dispose(); } return(Sites); }
public static IEnumerable <DNSZone> Get_DomainDNSZone(Args_Get_DomainDNSZone args = null) { if (args == null) { args = new Args_Get_DomainDNSZone(); } var SearcherArguments = new Args_Get_DomainSearcher { LDAPFilter = @"(objectClass=dnsZone)", Domain = args.Domain, Server = args.Server, Properties = args.Properties, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Credential = args.Credential }; var DNSSearcher1 = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); SearchResult[] Results = null; List <DNSZone> Outs = null; if (DNSSearcher1 != null) { if (args.FindOne) { Results = new SearchResult[] { DNSSearcher1.FindOne() }; } else { var items = DNSSearcher1.FindAll(); if (items != null) { Results = new SearchResult[items.Count]; items.CopyTo(Results, 0); } } if (Results != null) { foreach (var result in Results) { var Out = new DNSZone(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); Outs.Add(Out); } } DNSSearcher1.Dispose(); } SearcherArguments.SearchBasePrefix = @"CN=MicrosoftDNS,DC=DomainDnsZones"; var DNSSearcher2 = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (DNSSearcher2 != null) { try { if (args.FindOne) { Results = new SearchResult[] { DNSSearcher2.FindOne() }; } else { var items = DNSSearcher2.FindAll(); if (items != null) { Results = new SearchResult[items.Count]; items.CopyTo(Results, 0); } } if (Results != null) { foreach (var result in Results) { var Out = new DNSZone(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); Outs.Add(Out); } } } catch { Logger.Write_Verbose(@"[Get-DomainDNSZone] Error accessing 'CN=MicrosoftDNS,DC=DomainDnsZones'"); } DNSSearcher2.Dispose(); } return(Outs); }
public static IEnumerable <object> Get_DomainComputer(Args_Get_DomainComputer args = null) { if (args == null) { args = new Args_Get_DomainComputer(); } 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 CompSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var Computers = new List <object>(); if (CompSearcher != null) { 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-DomainComputer] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; CompSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (CompSearcher == null) { Logger.Write_Warning($@"[Get-DomainComputer] Unable to retrieve domain searcher for '{IdentityDomain}'"); } } } else if (IdentityInstance.Contains(@".")) { IdentityFilter += $@"(|(name={IdentityInstance})(dnshostname={IdentityInstance}))"; } 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 { IdentityFilter += $@"(name={IdentityInstance})"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != "") { Filter += $@"(|{IdentityFilter})"; } if (args.Unconstrained) { Logger.Write_Verbose(@"[Get-DomainComputer] Searching for computers with for unconstrained delegation"); Filter += @"(userAccountControl:1.2.840.113556.1.4.803:=524288)"; } if (args.TrustedToAuth) { Logger.Write_Verbose(@"[Get-DomainComputer] Searching for computers that are trusted to authenticate for other principals"); Filter += @"(msds-allowedtodelegateto=*)"; } if (args.Printers) { Logger.Write_Verbose("[Get-DomainComputer] Searching for printers"); Filter += @"(objectCategory=printQueue)"; } if (args.SPN.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with SPN: {args.SPN}"); Filter += $@"(servicePrincipalName={args.SPN})"; } if (args.OperatingSystem.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with operating system: {args.OperatingSystem}"); Filter += $@"(operatingsystem={args.OperatingSystem})"; } if (args.ServicePack.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with service pack: {args.ServicePack}"); Filter += $@"(operatingsystemservicepack={args.ServicePack})"; } if (args.SiteName.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with site name: {args.SiteName}"); Filter += $@"(serverreferencebl={args.SiteName})"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainComputer] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } // build the LDAP filter for the dynamic UAC filter value var uacs = args.UACFilter.ExtractValues(); foreach (var uac in uacs) { if (uac.IsNot()) { Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))"; } else { Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})"; } } CompSearcher.Filter = $@"(&(samAccountType=805306369){Filter})"; Logger.Write_Verbose($@"[Get-DomainComputer] Get-DomainComputer filter string: {CompSearcher.Filter}"); if (args.FindOne) { var result = CompSearcher.FindOne(); var Up = true; if (args.Ping) { Up = TestConnection.Ping(result.Properties["dnshostname"][0] as string, 1); } if (Up) { if (args.Raw) { // return raw result objects Computers.Add(result); } else { Computers.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } } else { var Results = CompSearcher.FindAll(); foreach (SearchResult result in Results) { var Up = true; if (args.Ping) { Up = TestConnection.Ping(result.Properties["dnshostname"][0] as string, 1); } if (Up) { if (args.Raw) { // return raw result objects Computers.Add(result); } else { Computers.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } } if (Results != null) { try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainComputer] Error disposing of the Results object: {e}"); } } } CompSearcher.Dispose(); } return(Computers); }
public static string[] Get_DomainFileServer(Args_Get_DomainFileServer args = null) { if (args == null) { args = new Args_Get_DomainFileServer(); } var SearcherArguments = new Args_Get_DomainSearcher { LDAPFilter = "(&(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(homedirectory=*)(scriptpath=*)(profilepath=*)))", Properties = new string[] { "homedirectory", "scriptpath", "profilepath" }, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var retValues = new List <string>(); if (args.Domain != null) { foreach (var TargetDomain in args.Domain) { SearcherArguments.Domain = TargetDomain; var UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); // get all results w/o the pipeline and uniquify them (I know it's not pretty) foreach (SearchResult UserResult in UserSearcher.FindAll()) { if (UserResult.Properties["homedirectory"] != null) { var val = Split_Path(UserResult.Properties["homedirectory"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } if (UserResult.Properties["scriptpath"] != null) { var val = Split_Path(UserResult.Properties["scriptpath"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } if (UserResult.Properties["profilepath"] != null) { var val = Split_Path(UserResult.Properties["profilepath"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } } } } else { var UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); // get all results w/o the pipeline and uniquify them (I know it's not pretty) foreach (SearchResult UserResult in UserSearcher.FindAll()) { if (UserResult.Properties["homedirectory"] != null) { var val = Split_Path(UserResult.Properties["homedirectory"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } if (UserResult.Properties["scriptpath"] != null) { var val = Split_Path(UserResult.Properties["scriptpath"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } if (UserResult.Properties["profilepath"] != null) { var val = Split_Path(UserResult.Properties["profilepath"][0] as string); if (!retValues.Any(x => x == val)) { retValues.Add(val); } } } } return(retValues.ToArray()); }
public static IEnumerable <object> Get_DomainUser(Args_Get_DomainUser args = null) { if (args == null) { args = new Args_Get_DomainUser(); } 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 UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); var Users = new List <object>(); if (UserSearcher != null) { 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-DomainUser] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'"); SearcherArguments.Domain = IdentityDomain; UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); if (UserSearcher == null) { Logger.Write_Warning($@"[Get-DomainUser] 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 UserDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/')); var UserName = IdentityInstance.Split(new char[] { '\\' })[1]; IdentityFilter += $@"(samAccountName={UserName})"; SearcherArguments.Domain = UserDomain; Logger.Write_Verbose($@"[Get-DomainUser] Extracted domain '{UserDomain}' from '{IdentityInstance}'"); UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); } } else { IdentityFilter += $@"(samAccountName={IdentityInstance})"; } } } if (IdentityFilter != null && IdentityFilter.Trim() != "") { Filter += $@"(|{IdentityFilter})"; } if (args.SPN) { Logger.Write_Verbose(@"[Get-DomainUser] Searching for non-null service principal names"); Filter += "(servicePrincipalName=*)"; } if (args.AllowDelegation) { Logger.Write_Verbose(@"[Get-DomainUser] Searching for users who can be delegated"); // negation of "Accounts that are sensitive and not trusted for delegation" Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=1048574))"; } if (args.DisallowDelegation) { Logger.Write_Verbose(@"[Get-DomainUser] Searching for users who are sensitive and not trusted for delegation"); Filter += "(userAccountControl:1.2.840.113556.1.4.803:=1048574)"; } if (args.AdminCount) { Logger.Write_Verbose(@"[Get-DomainUser] Searching for adminCount=1"); Filter += "(admincount=1)"; } if (args.TrustedToAuth) { Logger.Write_Verbose("[Get-DomainUser] Searching for users that are trusted to authenticate for other principals"); Filter += "(msds-allowedtodelegateto=*)"; } if (args.PreauthNotRequired) { Logger.Write_Verbose("[Get-DomainUser] Searching for user accounts that do not require kerberos preauthenticate"); Filter += "(userAccountControl:1.2.840.113556.1.4.803:=4194304)"; } if (args.LDAPFilter.IsNotNullOrEmpty()) { Logger.Write_Verbose($@"[Get-DomainUser] Using additional LDAP filter: {args.LDAPFilter}"); Filter += $@"{args.LDAPFilter}"; } // build the LDAP filter for the dynamic UAC filter value var uacs = args.UACFilter.ExtractValues(); foreach (var uac in uacs) { if (uac.IsNot()) { Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))"; } else { Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})"; } } UserSearcher.Filter = $@"(&(samAccountType=805306368){Filter})"; Logger.Write_Verbose($@"[Get-DomainUser] filter string: {UserSearcher.Filter}"); if (args.FindOne) { var result = UserSearcher.FindOne(); if (args.Raw) { // return raw result objects Users.Add(result); } else { Users.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } else { var Results = UserSearcher.FindAll(); foreach (SearchResult result in Results) { if (args.Raw) { // return raw result objects Users.Add(result); } else { Users.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties)); } } if (Results != null) { try { Results.Dispose(); } catch (Exception e) { Logger.Write_Verbose($@"[Get-DomainUser] Error disposing of the Results object: {e}"); } } } UserSearcher.Dispose(); } return(Users); }
public static IEnumerable <DNSRecord> Get_DomainDNSRecord(Args_Get_DomainDNSRecord args = null) { if (args == null) { args = new Args_Get_DomainDNSRecord(); } var SearcherArguments = new Args_Get_DomainSearcher { LDAPFilter = @"(objectClass=dnsNode)", SearchBasePrefix = $@"DC={args.ZoneName},CN=MicrosoftDNS,DC=DomainDnsZones", Domain = args.Domain, Server = args.Server, Properties = args.Properties, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Credential = args.Credential }; var DNSSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments); SearchResult[] Results = null; List <DNSRecord> Outs = null; if (DNSSearcher != null) { if (args.FindOne) { Results = new SearchResult[] { DNSSearcher.FindOne() }; } else { var items = DNSSearcher.FindAll(); if (items != null) { Results = new SearchResult[items.Count]; items.CopyTo(Results, 0); } } if (Results != null) { foreach (var result in Results) { DNSRecord Out = null; try { var ldapProperty = ConvertLDAPProperty.Convert_LDAPProperty(result.Properties); Out = new DNSRecord { name = ldapProperty.name, distinguishedname = ldapProperty.distinguishedname, dnsrecord = ldapProperty.dnsrecord, whencreated = ldapProperty.whencreated, whenchanged = ldapProperty.whenchanged, ZoneName = args.ZoneName }; // convert the record and extract the properties DNSRecord Record = null; if (Out.dnsrecord is System.DirectoryServices.ResultPropertyValueCollection) { // TODO: handle multiple nested records properly? Record = Convert_DNSRecord((Out.dnsrecord as System.DirectoryServices.ResultPropertyValueCollection)[0] as byte[]); } else { Record = Convert_DNSRecord(Out.dnsrecord as byte[]); } if (Record != null) { if (Record.RecordType != null) { Out.RecordType = Record.RecordType; } else if (Record.UpdatedAtSerial != null) { Out.UpdatedAtSerial = Record.UpdatedAtSerial; } else if (Record.TTL != null) { Out.TTL = Record.TTL; } else if (Record.Age != null) { Out.Age = Record.Age; } else if (Record.TimeStamp != null) { Out.TimeStamp = Record.TimeStamp; } else if (Record.Data.IsNotNullOrEmpty()) { Out.Data = Record.Data; } else if (Record.ZoneName.IsNotNullOrEmpty()) { Out.ZoneName = Record.ZoneName; } else if (Record.name.IsNotNullOrEmpty()) { Out.name = Record.name; } else if (Record.distinguishedname.IsNotNullOrEmpty()) { Out.distinguishedname = Record.distinguishedname; } else if (Record.dnsrecord != null) { Out.dnsrecord = Record.dnsrecord; } else if (Record.whencreated != null) { Out.whencreated = Record.whencreated; } else if (Record.whenchanged != null) { Out.whenchanged = Record.whenchanged; } } } catch (Exception e) { Logger.Write_Warning($@"[Get-DomainDNSRecord] Error: {e}"); } if (Outs == null) { Outs = new List <DNSRecord>(); } Outs.Add(Out); } } DNSSearcher.Dispose(); } return(Outs); }
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 <IDomainTrust> Get_DomainTrust(Args_Get_DomainTrust args = null) { if (args == null) { args = new Args_Get_DomainTrust(); } var LdapSearcherArguments = new Args_Get_DomainSearcher { Domain = args.Domain, LDAPFilter = args.LDAPFilter, Properties = args.Properties, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; Args_Get_DomainSID NetSearcherArguments = null; string SourceDomain = null; if (!args.API) { NetSearcherArguments = new Args_Get_DomainSID(); if (args.Domain.IsNotNullOrEmpty() && args.Domain.Trim() != "") { SourceDomain = args.Domain; } else { if (args.Credential != null) { SourceDomain = GetDomain.Get_Domain(new Args_Get_Domain { Credential = args.Credential }).Name; } else { SourceDomain = GetDomain.Get_Domain().Name; } } } else if (!args.NET) { if (args.Domain != null && args.Domain.Trim() != "") { SourceDomain = args.Domain; } else { SourceDomain = Environment.GetEnvironmentVariable("USERDNSDOMAIN"); } } var DomainTrusts = new List <IDomainTrust>(); if (!args.API && !args.NET) { // if we're searching for domain trusts through LDAP/ADSI var TrustSearcher = GetDomainSearcher.Get_DomainSearcher(LdapSearcherArguments); var SourceSID = GetDomainSID.Get_DomainSID(NetSearcherArguments); if (TrustSearcher != null) { TrustSearcher.Filter = @"(objectClass=trustedDomain)"; SearchResult[] Results = null; if (args.FindOne) { Results = new SearchResult[] { TrustSearcher.FindOne() }; } else { var items = TrustSearcher.FindAll(); if (items != null) { Results = new SearchResult[items.Count]; items.CopyTo(Results, 0); } } if (Results != null) { foreach (var result in Results) { var Props = result.Properties; var DomainTrust = new LdapDomainTrust(); var TrustAttrib = (TrustAttribute)Props[@"trustattributes"][0]; var Direction = (TrustDirection)Props[@"trustdirection"][0]; var TrustType = (TrustType)Props[@"trusttype"][0]; var Distinguishedname = Props[@"distinguishedname"][0] as string; var SourceNameIndex = Distinguishedname.IndexOf(@"DC="); if (SourceNameIndex != 0) { SourceDomain = Distinguishedname.Substring(SourceNameIndex).Replace(@"DC=", @"").Replace(@",", @"."); } else { SourceDomain = @""; } var TargetNameIndex = Distinguishedname.IndexOf(@",CN=System"); string TargetDomain = null; if (SourceNameIndex != 0) { TargetDomain = Distinguishedname.Substring(3, TargetNameIndex - 3); } else { TargetDomain = @""; } var ObjectGuid = new Guid(Props[@"objectguid"][0] as byte[]); var TargetSID = (new System.Security.Principal.SecurityIdentifier(Props[@"securityidentifier"][0] as byte[], 0)).Value; DomainTrust = new LdapDomainTrust { SourceName = SourceDomain, TargetName = Props[@"name"][0] as string, TrustType = TrustType, TrustAttributes = TrustAttrib, TrustDirection = Direction, WhenCreated = Props[@"whencreated"][0], WhenChanged = Props[@"whenchanged"][0] }; DomainTrusts.Add(DomainTrust); } } TrustSearcher.Dispose(); } } else if (args.API) { // if we're searching for domain trusts through Win32 API functions string TargetDC = null; if (args.Server.IsNotNullOrEmpty()) { TargetDC = args.Server; } else if (args.Domain != null && args.Domain.Trim() != @"") { TargetDC = args.Domain; } else { // see https://msdn.microsoft.com/en-us/library/ms675976(v=vs.85).aspx for default NULL behavior TargetDC = null; } // arguments for DsEnumerateDomainTrusts var PtrInfo = IntPtr.Zero; // 63 = DS_DOMAIN_IN_FOREST + DS_DOMAIN_DIRECT_OUTBOUND + DS_DOMAIN_TREE_ROOT + DS_DOMAIN_PRIMARY + DS_DOMAIN_NATIVE_MODE + DS_DOMAIN_DIRECT_INBOUND uint Flags = 63; uint DomainCount = 0; // get the trust information from the target server var Result = NativeMethods.DsEnumerateDomainTrusts(TargetDC, Flags, out PtrInfo, out DomainCount); // Locate the offset of the initial intPtr var Offset = PtrInfo.ToInt64(); // 0 = success if (Result == 0 && Offset > 0) { // Work out how much to increment the pointer by finding out the size of the structure var Increment = Marshal.SizeOf(typeof(NativeMethods.DS_DOMAIN_TRUSTS)); // parse all the result structures for (var i = 0; i < DomainCount; i++) { // create a new int ptr at the given offset and cast the pointer as our result structure var NewIntPtr = new IntPtr(Offset); var Info = (NativeMethods.DS_DOMAIN_TRUSTS)Marshal.PtrToStructure(NewIntPtr, typeof(NativeMethods.DS_DOMAIN_TRUSTS)); Offset = NewIntPtr.ToInt64(); Offset += Increment; var SidString = @""; bool ret = NativeMethods.ConvertSidToStringSid(Info.DomainSid, out SidString); var LastError = Marshal.GetLastWin32Error(); if (ret == false) { Logger.Write_Verbose($@"[Get-DomainTrust] Error: {new System.ComponentModel.Win32Exception(LastError).Message}"); } else { var DomainTrust = new ApiDomainTrust { SourceName = SourceDomain, TargetName = Info.DnsDomainName, TargetNetbiosName = Info.NetbiosDomainName, Flags = Info.Flags, ParentIndex = Info.ParentIndex, TrustType = (NativeMethods.DS_DOMAIN_TRUST_TYPE)Info.TrustType, TrustAttributes = Info.TrustAttributes, TargetSid = SidString, TargetGuid = Info.DomainGuid }; DomainTrusts.Add(DomainTrust); } } // free up the result buffer NativeMethods.NetApiBufferFree(PtrInfo); } else { Logger.Write_Verbose($@"[Get-DomainTrust] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}"); } } else { // if we're searching for domain trusts through .NET methods var FoundDomain = GetDomain.Get_Domain(new Args_Get_Domain { Domain = NetSearcherArguments.Domain, Credential = NetSearcherArguments.Credential }); if (FoundDomain != null) { var items = FoundDomain.GetAllTrustRelationships(); foreach (TrustRelationshipInformation item in items) { DomainTrusts.Add(new NetDomainTrust { SourceName = item.SourceName, TargetName = item.TargetName, TrustDirection = item.TrustDirection, TrustType = item.TrustType }); } } } return(DomainTrusts); }
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); }