/// <summary> /// Gets the primary token of the first found active user session. /// </summary> /// <returns>A <see cref="TokenHelper"/> or null if no valid sessions was found.</returns> /// <exception cref="Win32Exception"></exception> public static SafeAccessTokenHandle GetPrimaryTokenOfFirstActiveSession() { //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!! // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019 uint activeSessionId = Wtsapi32.InvalidSessionId; IntPtr sessionInfos = IntPtr.Zero; var sessionCount = 0; try { //Get a handle to the user access token for the current active session. if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount)) { int arrayElementSize = Marshal.SizeOf <Wtsapi32.WtsSessionInfo>(); IntPtr current = sessionInfos; for (var i = 0; i < sessionCount; i++) { var sessionInfo = Marshal.PtrToStructure <Wtsapi32.WtsSessionInfo>(current); current += arrayElementSize; if (sessionInfo.State == Wtsapi32.WtsConnectstateClass.WTSActive) { activeSessionId = (uint)sessionInfo.SessionID; break; } } } } finally { if (sessionInfos != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(sessionInfos); } } //If enumerating not working use the fall back method if (activeSessionId == Wtsapi32.InvalidSessionId) { activeSessionId = Kernel32.WTSGetActiveConsoleSessionId(); if (activeSessionId == Wtsapi32.InvalidSessionId) { return(null); } } return(GetPrimaryTokenFromSessionId(activeSessionId)); }
/// <summary> /// Gets the primary token from an first active user session with the given username. /// </summary> /// <param name="username">The username.</param> /// <returns>A <see cref="SafeAccessTokenHandle"/> or null if no valid sessions was found.</returns> /// <exception cref="Win32Exception"> /// </exception> public static SafeAccessTokenHandle GetPrimaryTokenByUsername(string username) { //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!! // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019 uint activeSessionId = Wtsapi32.InvalidSessionId; IntPtr sessionInfos = IntPtr.Zero; var sessionCount = 0; try { //Get a handle to the user access token for the current active session. if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount)) { int arrayElementSize = Marshal.SizeOf <Wtsapi32.WtsSessionInfo>(); IntPtr current = sessionInfos; for (var i = 0; i < sessionCount; i++) { IntPtr usernamePtr = IntPtr.Zero; IntPtr domainPtr = IntPtr.Zero; try { var sessionInfo = Marshal.PtrToStructure <Wtsapi32.WtsSessionInfo>(current); current += arrayElementSize; //If the session is not active, go to the next if (sessionInfo.State != Wtsapi32.WtsConnectstateClass.WTSActive) { continue; } //Get the username if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsUserName, out usernamePtr, out uint bytesReturnedUsername)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //continue when no bytes returned if (bytesReturnedUsername <= 0) { continue; } string sessionUsername = Marshal.PtrToStringUni(usernamePtr); //Get the domain name if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsDomainName, out domainPtr, out uint bytesReturnedDomainName)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //continue when no bytes returned if (bytesReturnedDomainName <= 0) { continue; } string sessionDomainName = Marshal.PtrToStringUni(domainPtr); //If the username is not the same, go to the next string sessionFullUsername = sessionDomainName.ConvertNullTerminatedStringToString() + "\\" + sessionUsername.ConvertNullTerminatedStringToString(); //If the session is found break the for if (!string.IsNullOrWhiteSpace(sessionFullUsername) && sessionFullUsername.Equals(username.Trim(), StringComparison.OrdinalIgnoreCase)) { activeSessionId = (uint)sessionInfo.SessionID; break; } } finally { if (usernamePtr != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(usernamePtr); } if (domainPtr != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(domainPtr); } } } } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (sessionInfos != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(sessionInfos); } } //If enumerating not working throw an exception if (activeSessionId == Wtsapi32.InvalidSessionId) { return(null); } return(GetPrimaryTokenFromSessionId(activeSessionId)); }
/// <summary> /// Gets the session token by the username. /// </summary> /// <param name="username">The username.</param> /// <returns></returns> /// <exception cref="Exception">No valid session found.</exception> /// <exception cref="Win32Exception"> /// </exception> public static TokenHandle GetSessionTokenByUsername(string username) { //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!! // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019 var primTokenHandle = new TokenHandle(); uint activeSessionId = Wtsapi32.InvalidSessionId; IntPtr sessionInfos = IntPtr.Zero; IntPtr usernamePtr = IntPtr.Zero; IntPtr domainPtr = IntPtr.Zero; var sessionCount = 0; try { //Get a handle to the user access token for the current active session. if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount)) { int arrayElementSize = Marshal.SizeOf(typeof(Wtsapi32.WtsSessionInfo)); IntPtr current = sessionInfos; for (var i = 0; i < sessionCount; i++) { var sessionInfo = (Wtsapi32.WtsSessionInfo)Marshal.PtrToStructure(current, typeof(Wtsapi32.WtsSessionInfo)); current += arrayElementSize; //If the session is not active, go to the next if (sessionInfo.State != Wtsapi32.WtsConnectstateClass.WTSActive) { continue; } //Get the username if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsUserName, out usernamePtr, out uint bytesReturnedUsername)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //continue when no bytes returned if (bytesReturnedUsername <= 0) { continue; } string sessionUsername = Marshal.PtrToStringUni(usernamePtr); //Get the domain name if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsDomainName, out domainPtr, out uint bytesReturnedDomainName)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //continue when no bytes returned if (bytesReturnedDomainName <= 0) { continue; } string sessionDomainName = Marshal.PtrToStringUni(domainPtr); //If the username is not the same, go to the next string sessionFullUsername = sessionDomainName.ConvertNullTerminatedStringToString() + "\\" + sessionUsername.ConvertNullTerminatedStringToString(); if (sessionUsername == null || !string.Equals(username.Trim(), sessionFullUsername, StringComparison.CurrentCultureIgnoreCase)) { continue; } //If the session is found break the for activeSessionId = (uint)sessionInfo.SessionID; break; } } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (usernamePtr != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(usernamePtr); } if (domainPtr != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(domainPtr); } if (sessionInfos != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(sessionInfos); } } //If enumerating not working throw an exception if (activeSessionId == Wtsapi32.InvalidSessionId) { throw new Exception("No valid session found."); } var impersonationToken = new TokenHandle(); try { //Get token if (!Wtsapi32.WTSQueryUserToken(activeSessionId, out impersonationToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //Convert the impersonation token to a primary token if (!Advapi32.DuplicateTokenEx(impersonationToken, 0, IntPtr.Zero, (int)Advapi32.SecurityImpersonationLevel.SecurityImpersonation, (int)Advapi32.TokenType.TokenPrimary, ref primTokenHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { impersonationToken.Close(); } return(primTokenHandle); }
/// <summary> /// Gets the active session user token. /// </summary> /// <param name="userToken">The user token.</param> /// <returns></returns> /// <exception cref="Win32Exception"></exception> public static TokenHandle GetActiveSessionUserToken() { //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!! // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019 var primTokenHandle = new TokenHandle(); uint activeSessionId = Wtsapi32.InvalidSessionId; IntPtr sessionInfos = IntPtr.Zero; var sessionCount = 0; try { //Get a handle to the user access token for the current active session. if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount)) { int arrayElementSize = Marshal.SizeOf(typeof(Wtsapi32.WtsSessionInfo)); IntPtr current = sessionInfos; for (var i = 0; i < sessionCount; i++) { var sessionInfo = (Wtsapi32.WtsSessionInfo)Marshal.PtrToStructure(current, typeof(Wtsapi32.WtsSessionInfo)); current += arrayElementSize; if (sessionInfo.State == Wtsapi32.WtsConnectstateClass.WTSActive) { activeSessionId = (uint)sessionInfo.SessionID; } } } } finally { if (sessionInfos != IntPtr.Zero) { Wtsapi32.WTSFreeMemory(sessionInfos); } } //If enumerating not working use the fall back method if (activeSessionId == Wtsapi32.InvalidSessionId) { activeSessionId = Kernel32.WTSGetActiveConsoleSessionId(); if (activeSessionId == Wtsapi32.InvalidSessionId) { throw new Exception("No valid session found."); } } var impersonationToken = new TokenHandle(); try { //Get token if (!Wtsapi32.WTSQueryUserToken(activeSessionId, out impersonationToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } //Convert the impersonation token to a primary token if (!Advapi32.DuplicateTokenEx(impersonationToken, 0, IntPtr.Zero, (int)Advapi32.SecurityImpersonationLevel.SecurityImpersonation, (int)Advapi32.TokenType.TokenPrimary, ref primTokenHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { impersonationToken.Close(); } return(primTokenHandle); }
public static List <Dictionary <string, string> > GetRDPSessions() { List <Dictionary <string, string> > results = new List <Dictionary <string, string> >(); // adapted from http://www.pinvoke.net/default.aspx/wtsapi32.wtsenumeratesessions IntPtr server = IntPtr.Zero; List <String> ret = new List <string>(); server = OpenServer("localhost"); try { IntPtr ppSessionInfo = IntPtr.Zero; Int32 count = 0; Int32 level = 1; Int32 retval = Wtsapi32.WTSEnumerateSessionsEx(server, ref level, 0, ref ppSessionInfo, ref count); Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO_1)); Int64 current = (Int64)ppSessionInfo; if (retval != 0) { for (int i = 0; i < count; i++) { Dictionary <string, string> rdp_session = new Dictionary <string, string>(); WTS_SESSION_INFO_1 si = (WTS_SESSION_INFO_1)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO_1)); current += dataSize; if (si.pUserName == null || si.pUserName == "") { continue; } rdp_session["SessionID"] = string.Format("{0}", si.SessionID); rdp_session["pSessionName"] = string.Format("{0}", si.pSessionName); rdp_session["pUserName"] = string.Format("{0}", si.pUserName); rdp_session["pDomainName"] = string.Format("{0}", si.pDomainName); rdp_session["State"] = string.Format("{0}", si.State); rdp_session["SourceIP"] = ""; // Now use WTSQuerySessionInformation to get the remote IP (if any) for the connection IntPtr addressPtr = IntPtr.Zero; uint bytes = 0; Wtsapi32.WTSQuerySessionInformation(server, (uint)si.SessionID, WTS_INFO_CLASS.WTSClientAddress, out addressPtr, out bytes); WTS_CLIENT_ADDRESS address = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure((System.IntPtr)addressPtr, typeof(WTS_CLIENT_ADDRESS)); if (address.Address[2] != 0) { string sourceIP = string.Format("{0}.{1}.{2}.{3}", address.Address[2], address.Address[3], address.Address[4], address.Address[5]); rdp_session["SourceIP"] = string.Format("{0}", sourceIP); } results.Add(rdp_session); } Wtsapi32.WTSFreeMemory(ppSessionInfo); } } catch (Exception ex) { Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex)); } finally { CloseServer(server); } return(results); }