public static IEnumerable <ForeignUser> Get_DomainForeignUser(Args_Get_DomainForeignUser args = null) { if (args == null) { args = new Args_Get_DomainForeignUser(); } var SearcherArguments = new Args_Get_DomainUser { LDAPFilter = @"(memberof=*)", Domain = args.Domain, Properties = args.Properties, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, SecurityMasks = args.SecurityMasks, Tombstone = args.Tombstone, Credential = args.Credential }; var ForeignUsers = new List <ForeignUser>(); var Results = GetDomainUser.Get_DomainUser(SearcherArguments); foreach (LDAPProperty result in Results) { foreach (var Membership in result.memberof) { var Index = Membership.IndexOf(@"DC="); if (Index != 0) { var GroupDomain = Membership.Substring(Index).Replace(@"DC=", @"").Replace(@",", @"."); var UserDistinguishedName = result.distinguishedname; var UserIndex = UserDistinguishedName.IndexOf(@"DC="); var UserDomain = result.distinguishedname.Substring(UserIndex).Replace(@"DC=", @"").Replace(@",", @"."); if (GroupDomain != UserDomain) { // if the group domain doesn't match the user domain, display it var GroupName = Membership.Split(',')[0].Split('=')[1]; var ForeignUser = new ForeignUser { UserDomain = UserDomain, UserName = result.samaccountname, UserDistinguishedName = result.distinguishedname, GroupDomain = GroupDomain, GroupName = GroupName, GroupDistinguishedName = Membership }; } } } } return(ForeignUsers); }
public static ForestEx Get_Forest(Args_Get_Forest args = null) { if (args == null) { args = new Args_Get_Forest(); } var ForestObject = new ForestEx(); if (args.Credential != null) { Logger.Write_Verbose(@"[Get-Forest] Using alternate credentials for Get-Forest"); string TargetForest = null; if (args.Forest.IsNotNullOrEmpty()) { TargetForest = args.Forest; } else { // if no domain is supplied, extract the logon domain from the PSCredential passed TargetForest = args.Credential.Domain; Logger.Write_Verbose(@"[Get-Forest] Extracted domain '$Forest' from -Credential"); } var ForestContext = new System.DirectoryServices.ActiveDirectory.DirectoryContext(System.DirectoryServices.ActiveDirectory.DirectoryContextType.Forest, TargetForest, args.Credential.UserName, args.Credential.Password); try { ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetForest(ForestContext); } catch (Exception e) { Logger.Write_Verbose($@"[Get-Forest] The specified forest '{TargetForest}' does not exist, could not be contacted, there isn't an existing trust, or the specified credentials are invalid: {e}"); } } else if (args.Forest.IsNotNullOrEmpty()) { var ForestContext = new System.DirectoryServices.ActiveDirectory.DirectoryContext(System.DirectoryServices.ActiveDirectory.DirectoryContextType.Forest, args.Forest); try { ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetForest(ForestContext); } catch (Exception e) { Logger.Write_Verbose($@"[Get-Forest] The specified forest '{args.Forest}' does not exist, could not be contacted, or there isn't an existing trust: {e}"); } } else { // otherwise use the current forest ForestObject.Forest = System.DirectoryServices.ActiveDirectory.Forest.GetCurrentForest(); } if (ForestObject.Forest != null) { // get the SID of the forest root string ForestSid = null; if (args.Credential != null) { ForestSid = (GetDomainUser.Get_DomainUser(new Args_Get_DomainUser { Identity = new[] { @"krbtgt" }, Domain = ForestObject.Forest.RootDomain.Name, Credential = args.Credential }).First() as LDAPProperty).objectsid?.First(); } else { ForestSid = (GetDomainUser.Get_DomainUser(new Args_Get_DomainUser { Identity = new[] { @"krbtgt" }, Domain = ForestObject.Forest.RootDomain.Name }).First() as LDAPProperty).objectsid?.First(); } var Parts = ForestSid.Split('-'); ForestSid = string.Join(@"-", Parts.Take(Parts.Length - 2 + 1)); ForestObject.RootDomainSid = ForestSid; return(ForestObject); } return(null); }
public static IEnumerable <object> Find_DomainUserEvent(Args_Find_DomainUserEvent args = null) { if (args == null) { args = new Args_Find_DomainUserEvent(); } var UserSearcherArguments = new Args_Get_DomainUser { Properties = new[] { "samaccountname" }, Identity = args.UserIdentity, Domain = args.UserDomain, LDAPFilter = args.UserLDAPFilter, SearchBase = args.UserSearchBase, AdminCount = args.UserAdminCount, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; string[] TargetUsers = null; if (args.UserIdentity != null || !string.IsNullOrEmpty(args.UserLDAPFilter) || !string.IsNullOrEmpty(args.UserSearchBase) || args.UserAdminCount) { TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray(); } else if (args.UserGroupIdentity != null || (args.Filter == null)) { // otherwise we're querying a specific group var GroupSearcherArguments = new Args_Get_DomainGroupMember { Identity = args.UserGroupIdentity, Recurse = true, Domain = args.UserDomain, SearchBase = args.UserSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; Logger.Write_Verbose($@"UserGroupIdentity: {args.UserGroupIdentity.ToJoinedString()}"); TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray(); } // build the set of computers to enumerate string[] TargetComputers = null; if (args.ComputerName != null) { TargetComputers = args.ComputerName; } else { // if not -ComputerName is passed, query the current (or target) domain for domain controllers var DCSearcherArguments = new Args_Get_DomainController { LDAP = true, Domain = args.Domain, Server = args.Server, Credential = args.Credential }; Logger.Write_Verbose($@"[Find-DomainUserEvent] Querying for domain controllers in domain: {args.Domain}"); TargetComputers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray(); } Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers length: {TargetComputers.Count()}"); Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers {TargetComputers.ToJoinedString()}"); if (TargetComputers == null || TargetComputers.Length == 0) { throw new Exception("[Find-DomainUserEvent] No hosts found to enumerate"); } var rets = new List <IWinEvent>(); // only ignore threading if -Delay is passed if (args.Delay != 0 || args.StopOnSuccess) { Logger.Write_Verbose($@"[Find-DomainUserEvent] TargetComputers length: {TargetComputers.Length}"); Logger.Write_Verbose($@"[Find-DomainUserEvent] Delay: {args.Delay}, Jitter: {args.Jitter}"); var Counter = 0; var RandNo = new System.Random(); foreach (var TargetComputer in TargetComputers) { Counter = Counter + 1; // sleep for our semi-randomized interval System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000); Logger.Write_Verbose($@"[Find-DomainUserEvent] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})"); var Result = _Find_DomainUserEvent(new[] { TargetComputer }, args.StartTime, args.EndTime, args.MaxEvents, TargetUsers, args.Filter, args.Credential); if (Result != null) { rets.AddRange(Result); } if (Result != null && args.StopOnSuccess) { Logger.Write_Verbose("[Find-DomainUserEvent] Target user found, returning early"); return(rets); } } } else { Logger.Write_Verbose($@"[Find-DomainUserEvent] Using threading with threads: {args.Threads}"); // if we're using threading, kick off the script block with New-ThreadedFunction // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params System.Threading.Tasks.Parallel.ForEach( TargetComputers, TargetComputer => { var Result = _Find_DomainUserEvent(new[] { TargetComputer }, args.StartTime, args.EndTime, args.MaxEvents, TargetUsers, args.Filter, args.Credential); lock (rets) { if (Result != null) { rets.AddRange(Result); } } }); } return(rets); }
public static IEnumerable <UserProcess> Find_DomainProcess(Args_Find_DomainProcess args = null) { if (args == null) { args = new Args_Find_DomainProcess(); } var ComputerSearcherArguments = new Args_Get_DomainComputer { Properties = new[] { "dnshostname" }, Domain = args.Domain, LDAPFilter = args.ComputerLDAPFilter, SearchBase = args.ComputerSearchBase, Unconstrained = args.Unconstrained, OperatingSystem = args.OperatingSystem, ServicePack = args.ServicePack, SiteName = args.SiteName, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { ComputerSearcherArguments.Domain = args.ComputerDomain; } var UserSearcherArguments = new Args_Get_DomainUser { Properties = new[] { "samaccountname" }, Identity = args.UserIdentity, Domain = args.Domain, LDAPFilter = args.UserLDAPFilter, SearchBase = args.UserSearchBase, AdminCount = args.UserAdminCount, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.UserDomain)) { UserSearcherArguments.Domain = args.UserDomain; } // first, build the set of computers to enumerate string[] TargetComputers = null; if (args.ComputerName != null) { TargetComputers = args.ComputerName; } else { Logger.Write_Verbose(@"[Find-DomainProcess] Querying computers in the domain"); TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray(); } if (TargetComputers == null || TargetComputers.Length == 0) { throw new Exception("[Find-DomainProcess] No hosts found to enumerate"); } Logger.Write_Verbose($@"[Find-DomainProcess] TargetComputers length: {TargetComputers.Length}"); // now build the user target set List <string> TargetProcessName = null; string[] TargetUsers = null; if (args.ProcessName != null) { TargetProcessName = new List <string>(); foreach (var T in args.ProcessName) { TargetProcessName.AddRange(T.Split(',')); } } else if (args.UserIdentity != null || args.UserLDAPFilter != null || args.UserSearchBase != null || args.UserAdminCount /* || args.UserAllowDelegation*/) { TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray(); } else { var GroupSearcherArguments = new Args_Get_DomainGroupMember { Identity = args.UserGroupIdentity, Recurse = true, Domain = args.UserDomain, SearchBase = args.UserSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray(); } var rets = new List <UserProcess>(); // only ignore threading if -Delay is passed if (args.Delay != 0 || args.StopOnSuccess) { Logger.Write_Verbose($@"[Find-DomainProcess] Total number of hosts: {TargetComputers.Count()}"); Logger.Write_Verbose($@"[Find-DomainProcess] Delay: {args.Delay}, Jitter: {args.Jitter}"); var Counter = 0; var RandNo = new System.Random(); foreach (var TargetComputer in TargetComputers) { Counter = Counter + 1; // sleep for our semi-randomized interval System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000); Logger.Write_Verbose($@"[Find-DomainProcess] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})"); var Result = _Find_DomainProcess(new[] { TargetComputer }, TargetProcessName?.ToArray(), TargetUsers, args.Credential); if (Result != null) { rets.AddRange(Result); } if (Result != null && args.StopOnSuccess) { Logger.Write_Verbose("[Find-DomainProcess] Target user found, returning early"); return(rets); } } } else { Logger.Write_Verbose($@"[Find-DomainProcess] Using threading with threads: {args.Threads}"); // if we're using threading, kick off the script block with New-ThreadedFunction // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params System.Threading.Tasks.Parallel.ForEach( TargetComputers, TargetComputer => { var Result = _Find_DomainProcess(new[] { TargetComputer }, TargetProcessName?.ToArray(), TargetUsers, args.Credential); lock (rets) { if (Result != null) { rets.AddRange(Result); } } }); } return(rets); }
public static IEnumerable <PropertyOutlier> Find_DomainObjectPropertyOutlier(Args_Find_DomainObjectPropertyOutlier args = null) { if (args == null) { args = new Args_Find_DomainObjectPropertyOutlier(); } var UserReferencePropertySet = new[] { "admincount", "accountexpires", "badpasswordtime", "badpwdcount", "cn", "codepage", "countrycode", "description", "displayname", "distinguishedname", "dscorepropagationdata", "givenname", "instancetype", "iscriticalsystemobject", "lastlogoff", "lastlogon", "lastlogontimestamp", "lockouttime", "logoncount", "memberof", "msds-supportedencryptiontypes", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "primarygroupid", "pwdlastset", "samaccountname", "samaccounttype", "sn", "useraccountcontrol", "userprincipalname", "usnchanged", "usncreated", "whenchanged", "whencreated" }; var GroupReferencePropertySet = new[] { "admincount", "cn", "description", "distinguishedname", "dscorepropagationdata", "grouptype", "instancetype", "iscriticalsystemobject", "member", "memberof", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "samaccountname", "samaccounttype", "systemflags", "usnchanged", "usncreated", "whenchanged", "whencreated" }; var ComputerReferencePropertySet = new[] { "accountexpires", "badpasswordtime", "badpwdcount", "cn", "codepage", "countrycode", "distinguishedname", "dnshostname", "dscorepropagationdata", "instancetype", "iscriticalsystemobject", "lastlogoff", "lastlogon", "lastlogontimestamp", "localpolicyflags", "logoncount", "msds-supportedencryptiontypes", "name", "objectcategory", "objectclass", "objectguid", "objectsid", "operatingsystem", "operatingsystemservicepack", "operatingsystemversion", "primarygroupid", "pwdlastset", "samaccountname", "samaccounttype", "serviceprincipalname", "useraccountcontrol", "usnchanged", "usncreated", "whenchanged", "whencreated" }; var SearcherArgumentsForUser = new Args_Get_DomainUser { Domain = args.Domain, LDAPFilter = args.LDAPFilter, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var SearcherArgumentsForGroup = new Args_Get_DomainGroup { Domain = args.Domain, LDAPFilter = args.LDAPFilter, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; var SearcherArgumentsForComputer = new Args_Get_DomainComputer { Domain = args.Domain, LDAPFilter = args.LDAPFilter, SearchBase = args.SearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; // Domain / Credential var TargetForest = string.Empty; if (!args.Domain.IsNullOrEmpty()) { if (args.Credential != null) { TargetForest = GetDomain.Get_Domain(new Args_Get_Domain { Domain = args.Domain }).Forest.Name; } else { TargetForest = GetDomain.Get_Domain(new Args_Get_Domain { Domain = args.Domain, Credential = args.Credential }).Forest.Name; } Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Enumerated forest '{TargetForest}' for target domain '{args.Domain}'"); } var SchemaArguments = new { Credential = args.Credential, Forest = TargetForest }; string[] ReferenceObjectProperties = null; ClassType?ReferenceObjectClass = null; if (args.ReferencePropertySet != null) { Logger.Write_Verbose(@"[Find-DomainObjectPropertyOutlier] Using specified -ReferencePropertySet"); ReferenceObjectProperties = args.ReferencePropertySet; } else if (args.ReferenceObject != null) { Logger.Write_Verbose(@"[Find-DomainObjectPropertyOutlier] Extracting property names from -ReferenceObject to use as the reference property set"); ReferenceObjectProperties = args.ReferenceObject.GetType().GetProperties().Select(x => x.Name).ToArray(); ReferenceObjectClass = args.ReferenceObject.GetPropValue <ClassType>("objectclass"); Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Calculated ReferenceObjectClass : {ReferenceObjectClass}"); } else { Logger.Write_Verbose($@"[Find-DomainObjectPropertyOutlier] Using the default reference property set for the object class '{args.ClassName}'"); } IEnumerable <object> Objects; if ((args.ClassName == ClassType.User) || (ReferenceObjectClass == ClassType.User)) { Objects = GetDomainUser.Get_DomainUser(SearcherArgumentsForUser); if (ReferenceObjectProperties == null) { ReferenceObjectProperties = UserReferencePropertySet; } } else if ((args.ClassName == ClassType.Group) || (ReferenceObjectClass == ClassType.Group)) { Objects = GetDomainGroup.Get_DomainGroup(SearcherArgumentsForGroup); if (ReferenceObjectProperties == null) { ReferenceObjectProperties = GroupReferencePropertySet; } } else if ((args.ClassName == ClassType.Computer) || (ReferenceObjectClass == ClassType.Computer)) { Objects = GetDomainComputer.Get_DomainComputer(SearcherArgumentsForComputer); if (ReferenceObjectProperties == null) { ReferenceObjectProperties = ComputerReferencePropertySet; } } else { throw new Exception($@"[Find-DomainObjectPropertyOutlier] Invalid class: {args.ClassName}"); } var PropertyOutliers = new List <PropertyOutlier>(); foreach (LDAPProperty Object in Objects) { var ObjectProperties = Object.GetType().GetProperties().Select(x => x.Name).ToArray(); foreach (var ObjectProperty in ObjectProperties) { var val = Object.GetPropValue <object>(ObjectProperty); if (val is Dictionary <string, object> ) { var dic = val as Dictionary <string, object>; foreach (var ObjectProperty1 in dic.Keys) { if (!ReferenceObjectProperties.ContainsNoCase(ObjectProperty1)) { var Out = new PropertyOutlier { SamAccountName = Object.samaccountname, Property = ObjectProperty1, Value = dic[ObjectProperty1] }; PropertyOutliers.Add(Out); } } } else if (val != null && !ReferenceObjectProperties.ContainsNoCase(ObjectProperty)) { var Out = new PropertyOutlier { SamAccountName = Object.samaccountname, Property = ObjectProperty, Value = Object.GetPropValue <object>(ObjectProperty) }; PropertyOutliers.Add(Out); } } } return(PropertyOutliers); }
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 IEnumerable <object> Get_NetUser(Args_Get_DomainUser args = null) { return(GetDomainUser.Get_DomainUser(args)); }
public static IEnumerable <UserLocation> Find_DomainUserLocation(Args_Find_DomainUserLocation args = null) { if (args == null) { args = new Args_Find_DomainUserLocation(); } var ComputerSearcherArguments = new Args_Get_DomainComputer { Properties = new[] { "dnshostname" }, Domain = args.Domain, LDAPFilter = args.ComputerLDAPFilter, SearchBase = args.ComputerSearchBase, Unconstrained = args.Unconstrained, OperatingSystem = args.OperatingSystem, ServicePack = args.ServicePack, SiteName = args.SiteName, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { ComputerSearcherArguments.Domain = args.ComputerDomain; } var UserSearcherArguments = new Args_Get_DomainUser { Properties = new[] { "samaccountname" }, Identity = args.UserIdentity, Domain = args.Domain, LDAPFilter = args.UserLDAPFilter, SearchBase = args.UserSearchBase, AdminCount = args.UserAdminCount, AllowDelegation = args.AllowDelegation, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.UserDomain)) { UserSearcherArguments.Domain = args.UserDomain; } string[] TargetComputers = null; // first, build the set of computers to enumerate if (args.ComputerName != null) { TargetComputers = args.ComputerName; } else { if (args.Stealth) { Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}"); var TargetComputerArrayList = new System.Collections.ArrayList(); if (args.StealthSource.ToString().IsRegexMatch("File|All")) { Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers"); var FileServerSearcherArguments = new Args_Get_DomainFileServer { Domain = new[] { args.Domain }, SearchBase = args.ComputerSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { FileServerSearcherArguments.Domain = new[] { args.ComputerDomain } } ; var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments); TargetComputerArrayList.AddRange(FileServers); } if (args.StealthSource.ToString().IsRegexMatch("DFS|All")) { Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers"); // { TODO: fix the passed parameters to Get-DomainDFSShare // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName} } if (args.StealthSource.ToString().IsRegexMatch("DC|All")) { Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers"); var DCSearcherArguments = new Args_Get_DomainController { LDAP = true, Domain = args.Domain, Server = args.Server, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { DCSearcherArguments.Domain = args.ComputerDomain; } var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray(); TargetComputerArrayList.AddRange(DomainControllers); } TargetComputers = TargetComputerArrayList.ToArray() as string[]; } } if (args.ComputerName != null) { TargetComputers = args.ComputerName; } else { if (args.Stealth) { Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}"); var TargetComputerArrayList = new System.Collections.ArrayList(); if (args.StealthSource.ToString().IsRegexMatch("File|All")) { Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers"); var FileServerSearcherArguments = new Args_Get_DomainFileServer { Domain = new[] { args.Domain }, SearchBase = args.ComputerSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { FileServerSearcherArguments.Domain = new[] { args.ComputerDomain } } ; var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments); TargetComputerArrayList.AddRange(FileServers); } if (args.StealthSource.ToString().IsRegexMatch("DFS|All")) { Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers"); // { TODO: fix the passed parameters to Get-DomainDFSShare // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName} } if (args.StealthSource.ToString().IsRegexMatch("DC|All")) { Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers"); var DCSearcherArguments = new Args_Get_DomainController { LDAP = true, Domain = args.Domain, Server = args.Server, Credential = args.Credential }; if (!string.IsNullOrEmpty(args.ComputerDomain)) { DCSearcherArguments.Domain = args.ComputerDomain; } var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray(); TargetComputerArrayList.AddRange(DomainControllers); } TargetComputers = TargetComputerArrayList.ToArray() as string[]; } else { Logger.Write_Verbose("[Find-DomainUserLocation] Querying for all computers in the domain"); TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray(); } } Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}"); if (TargetComputers.Length == 0) { throw new Exception("[Find-DomainUserLocation] No hosts found to enumerate"); } // get the current user so we can ignore it in the results string CurrentUser; if (args.Credential != null) { CurrentUser = args.Credential.UserName; } else { CurrentUser = Environment.UserName.ToLower(); } // now build the user target set string[] TargetUsers = null; if (args.ShowAll) { TargetUsers = new string[] { }; } else if (args.UserIdentity != null || args.UserLDAPFilter != null || args.UserSearchBase != null || args.UserAdminCount || args.UserAllowDelegation) { TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray(); } else { var GroupSearcherArguments = new Args_Get_DomainGroupMember { Identity = args.UserGroupIdentity, Recurse = true, Domain = args.UserDomain, SearchBase = args.UserSearchBase, Server = args.Server, SearchScope = args.SearchScope, ResultPageSize = args.ResultPageSize, ServerTimeLimit = args.ServerTimeLimit, Tombstone = args.Tombstone, Credential = args.Credential }; TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray(); } Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetUsers length: {TargetUsers.Length}"); if ((!args.ShowAll) && (TargetUsers.Length == 0)) { throw new Exception("[Find-DomainUserLocation] No users found to target"); } var LogonToken = IntPtr.Zero; if (args.Credential != null) { if (args.Delay != 0 || args.StopOnSuccess) { LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation { Credential = args.Credential }); } else { LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation { Credential = args.Credential, Quiet = true }); } } var rets = new List <UserLocation>(); // only ignore threading if -Delay is passed if (args.Delay != 0 /* || args.StopOnSuccess*/) { Logger.Write_Verbose($@"[Find-DomainUserLocation] Total number of hosts: {TargetComputers.Count()}"); Logger.Write_Verbose($@"[Find-DomainUserLocation] Delay: {args.Delay}, Jitter: {args.Jitter}"); var Counter = 0; var RandNo = new System.Random(); foreach (var TargetComputer in TargetComputers) { Counter = Counter + 1; // sleep for our semi-randomized interval System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000); Logger.Write_Verbose($@"[Find-DomainUserLocation] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})"); var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken); if (Result != null) { rets.AddRange(Result); } if (Result != null && args.StopOnSuccess) { Logger.Write_Verbose("[Find-DomainUserLocation] Target user found, returning early"); return(rets); } } } else { Logger.Write_Verbose($@"[Find-DomainUserLocation] Using threading with threads: {args.Threads}"); Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}"); // if we're using threading, kick off the script block with New-ThreadedFunction // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params System.Threading.Tasks.Parallel.ForEach( TargetComputers, TargetComputer => { var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken); lock (rets) { if (Result != null) { rets.AddRange(Result); } } }); } if (LogonToken != IntPtr.Zero) { InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken); } return(rets); }