Exemple #1
0
        /// <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));
        }
Exemple #2
0
        /// <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));
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        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);
        }