// the host enumeration block we're using to enumerate all servers private static IEnumerable <object> _Find_DomainLocalGroupMember(string[] ComputerName, string GroupName, MethodType Method, IntPtr TokenHandle) { // Add check if user defaults to/selects "Administrators" if (GroupName == "Administrators") { var AdminSecurityIdentifier = new System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.BuiltinAdministratorsSid, null); GroupName = AdminSecurityIdentifier.Translate(typeof(System.Security.Principal.NTAccount)).Value.Split('\\').LastOrDefault(); } var LogonToken = IntPtr.Zero; if (TokenHandle != IntPtr.Zero) { // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation { TokenHandle = TokenHandle, Quiet = true }); } var Members = new List <object>(); foreach (var TargetComputer in ComputerName) { var Up = TestConnection.Ping(TargetComputer, 1); if (Up) { var NetLocalGroupMemberArguments = new Args_Get_NetLocalGroupMember { ComputerName = new[] { TargetComputer }, Method = Method, GroupName = GroupName }; var ret = GetNetLocalGroupMember.Get_NetLocalGroupMember(NetLocalGroupMemberArguments); if (ret != null) { Members.AddRange(ret); } } } if (TokenHandle != IntPtr.Zero) { InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken); } return(Members); }
public static IEnumerable <object> Get_NetLocalGroupMember(Args_Get_NetLocalGroupMember args = null) { if (args == null) { args = new Args_Get_NetLocalGroupMember(); } var LogonToken = IntPtr.Zero; if (args.Credential != null) { LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation { Credential = args.Credential }); } var LocalGroupMembers = new List <object>(); foreach (var Computer in args.ComputerName) { if (args.Method == MethodType.API) { // if we're using the Netapi32 NetLocalGroupGetMembers API call to get the local group information // arguments for NetLocalGroupGetMembers var QueryLevel = 2; var PtrInfo = IntPtr.Zero; var EntriesRead = 0; var TotalRead = 0; var ResumeHandle = IntPtr.Zero; // get the local user information var Result = NativeMethods.NetLocalGroupGetMembers(Computer, args.GroupName, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ResumeHandle); // locate the offset of the initial intPtr var Offset = PtrInfo.ToInt64(); var Members = new List <object>(); // 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(LOCALGROUP_MEMBERS_INFO_2)); // parse all the result structures for (var i = 0; (i < EntriesRead); i++) { // create a new int ptr at the given offset and cast the pointer as our result structure var NewIntPtr = new System.IntPtr(Offset); var Info = (LOCALGROUP_MEMBERS_INFO_2)Marshal.PtrToStructure(NewIntPtr, typeof(LOCALGROUP_MEMBERS_INFO_2)); Offset = NewIntPtr.ToInt64(); Offset += Increment; var SidString = ""; var Result2 = NativeMethods.ConvertSidToStringSid(Info.lgrmi2_sid, out SidString); var LastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); if (!Result2) { Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}"); } else { var Member = new LocalGroupMemberAPI { ComputerName = Computer, GroupName = args.GroupName, MemberName = Info.lgrmi2_domainandname, SID = SidString, IsGroup = Info.lgrmi2_sidusage == SID_NAME_USE.SidTypeGroup }; Members.Add(Member); } } // free up the result buffer NativeMethods.NetApiBufferFree(PtrInfo); // try to extract out the machine SID by using the -500 account as a reference var MachineSid = (Members.FirstOrDefault(x => (x as LocalGroupMemberAPI).SID.IsRegexMatch(".*-500") || (x as LocalGroupMemberAPI).SID.IsRegexMatch(".*-501")) as LocalGroupMemberAPI).SID; if (MachineSid != null) { MachineSid = MachineSid.Substring(0, MachineSid.LastIndexOf('-')); foreach (LocalGroupMemberAPI member in Members) { if (member.SID.IsRegexMatch(MachineSid)) { member.IsDomain = "false"; } else { member.IsDomain = "true"; } } } else { foreach (LocalGroupMemberAPI member in Members) { if (!member.SID.IsRegexMatch("S-1-5-21")) { member.IsDomain = "false"; } else { member.IsDomain = "UNKNOWN"; } } } LocalGroupMembers.AddRange(Members); } else { Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}"); } } else { // otherwise we're using the WinNT service provider try { var GroupProvider = new System.DirectoryServices.DirectoryEntry($@"WinNT://{Computer}/{args.GroupName},group"); IEnumerable Members = (IEnumerable)GroupProvider.Invoke("Members"); foreach (var obj in Members) { var LocalUser = new System.DirectoryServices.DirectoryEntry(obj); var Member = new LocalGroupMemberWinNT { ComputerName = Computer, GroupName = args.GroupName }; var AdsPath = LocalUser.InvokeGet("AdsPath").ToString().Replace("WinNT://", ""); var IsGroup = LocalUser.SchemaClassName.IsLikeMatch("group"); bool MemberIsDomain; string Name; if (Regex.Matches(AdsPath, "/").Count == 1) { // DOMAIN\user MemberIsDomain = true; Name = AdsPath.Replace(@"/", @"\"); } else { // DOMAIN\machine\user MemberIsDomain = false; Name = AdsPath.Substring(AdsPath.IndexOf('/') + 1).Replace(@"/", @"\"); } Member.AccountName = Name; Member.SID = new System.Security.Principal.SecurityIdentifier((byte[])LocalUser.InvokeGet("ObjectSID"), 0).Value; Member.IsGroup = IsGroup; Member.IsDomain = MemberIsDomain; LocalGroupMembers.Add(Member); } } catch (Exception e) { Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error for {Computer} : {e}"); } } } if (LogonToken != IntPtr.Zero) { InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken); } return(LocalGroupMembers); }
public static IEnumerable <object> Get_NetLocalGroupMember(Args_Get_NetLocalGroupMember args = null) { return(GetNetLocalGroupMember.Get_NetLocalGroupMember(args)); }