//////////////////////////////////////////////////////////////////////////////// // Finds a process per user discovered // ToDo: check if token is a primary token //////////////////////////////////////////////////////////////////////////////// public static Dictionary <string, uint> EnumerateTokens(bool findElevation) { Dictionary <string, uint> users = new Dictionary <string, uint>(); foreach (Process p in Process.GetProcesses()) { IntPtr hProcess = kernel32.OpenProcess(ProcessThreadsApi.ProcessSecurityRights.PROCESS_QUERY_LIMITED_INFORMATION, true, (uint)p.Id); if (IntPtr.Zero == hProcess) { continue; } IntPtr hToken; if (!kernel32.OpenProcessToken(hProcess, (uint)Winnt.ACCESS_MASK.MAXIMUM_ALLOWED, out hToken)) { continue; } kernel32.CloseHandle(hProcess); if (findElevation) { if (!TokenInformation.CheckElevation(hToken)) { continue; } } uint dwLength = 0; Winnt._TOKEN_STATISTICS tokenStatistics = new Winnt._TOKEN_STATISTICS(); //Split up impersonation and primary tokens if (Winnt._TOKEN_TYPE.TokenImpersonation == tokenStatistics.TokenType) { continue; } if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) { if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) { Console.WriteLine("GetTokenInformation: {0}", Marshal.GetLastWin32Error()); continue; } } kernel32.CloseHandle(hToken); string userName = string.Empty; if (!ConvertTokenStatisticsToUsername(tokenStatistics, ref userName)) { continue; } if (!users.ContainsKey(userName)) { users.Add(userName, (uint)p.Id); } } return(users); }
//////////////////////////////////////////////////////////////////////////////// // Converts a TokenStatistics Pointer array to User Name //////////////////////////////////////////////////////////////////////////////// private static bool ConvertTokenStatisticsToUsername(Winnt._TOKEN_STATISTICS tokenStatistics, ref string userName) { IntPtr lpLuid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Winnt._LUID))); Marshal.StructureToPtr(tokenStatistics.AuthenticationId, lpLuid, false); if (IntPtr.Zero == lpLuid) { return(false); } IntPtr ppLogonSessionData = new IntPtr(); if (0 != secur32.LsaGetLogonSessionData(lpLuid, out ppLogonSessionData)) { Misc.GetWin32Error("LsaGetLogonSessionData"); return(false); } if (IntPtr.Zero == ppLogonSessionData) { return(false); } ntsecapi._SECURITY_LOGON_SESSION_DATA securityLogonSessionData = (ntsecapi._SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(ppLogonSessionData, typeof(ntsecapi._SECURITY_LOGON_SESSION_DATA)); if (IntPtr.Zero == securityLogonSessionData.Sid || IntPtr.Zero == securityLogonSessionData.UserName.Buffer || IntPtr.Zero == securityLogonSessionData.LogonDomain.Buffer) { return(false); } string usernameBuffer = Marshal.PtrToStringUni(securityLogonSessionData.UserName.Buffer); if (Environment.MachineName + "$" == usernameBuffer && ConvertSidToName(securityLogonSessionData.Sid, out userName)) { return(true); } userName = string.Format("{0}\\{1}", Marshal.PtrToStringUni(securityLogonSessionData.LogonDomain.Buffer), usernameBuffer); return(true); }
public static extern bool GetTokenInformation(IntPtr TokenHandle, Winnt._TOKEN_INFORMATION_CLASS TokenInformationClass, ref Winnt._TOKEN_STATISTICS TokenInformation, uint TokenInformationLength, out uint ReturnLength);
//////////////////////////////////////////////////////////////////////////////// // Find processes for a user via Tokens //////////////////////////////////////////////////////////////////////////////// public static Dictionary <uint, string> EnumerateUserProcesses(bool findElevation, string targetAccount) { Dictionary <uint, string> users = new Dictionary <uint, string>(); Process[] pids = Process.GetProcesses(); Console.WriteLine("[*] Examining {0} processes", pids.Length); foreach (Process p in pids) { IntPtr hProcess = kernel32.OpenProcess(ProcessThreadsApi.ProcessSecurityRights.PROCESS_QUERY_LIMITED_INFORMATION, true, (uint)p.Id); if (IntPtr.Zero == hProcess) { continue; } IntPtr hToken; if (!kernel32.OpenProcessToken(hProcess, (uint)Winnt.ACCESS_MASK.MAXIMUM_ALLOWED, out hToken)) { continue; } kernel32.CloseHandle(hProcess); if (findElevation && !TokenInformation.CheckElevation(hToken)) { continue; } uint dwLength = 0; Winnt._TOKEN_STATISTICS tokenStatistics = new Winnt._TOKEN_STATISTICS(); if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) { if (!advapi32.GetTokenInformation(hToken, Winnt._TOKEN_INFORMATION_CLASS.TokenStatistics, ref tokenStatistics, dwLength, out dwLength)) { continue; } } kernel32.CloseHandle(hToken); if (Winnt._TOKEN_TYPE.TokenImpersonation == tokenStatistics.TokenType) { continue; } string userName = string.Empty; if (!ConvertTokenStatisticsToUsername(tokenStatistics, ref userName)) { continue; } if (userName.Contains(targetAccount, StringComparison.OrdinalIgnoreCase)) { users.Add((uint)p.Id, p.ProcessName); if (findElevation) { return(users); } } } Console.WriteLine("[*] Discovered {0} processes", users.Count); Dictionary <uint, string> sorted = new Dictionary <uint, string>(); foreach (var user in users.OrderBy(u => u.Value)) { sorted.Add(user.Key, user.Value); } return(sorted); }
public static extern Boolean GetTokenInformation(IntPtr TokenHandle, Winnt._TOKEN_INFORMATION_CLASS TokenInformationClass, ref Winnt._TOKEN_STATISTICS TokenInformation, UInt32 TokenInformationLength, out UInt32 ReturnLength);