/// <summary>
        /// Get SECURITY_LOGON_SESSION_DATA for a process or thread via a handle to its token and populate an InjectedThread object's Logon Session values
        /// </summary>
        /// <param name="hToken"></param>
        /// <param name="injectedThread"></param>
        static void GetLogonSessionData(IntPtr hToken, InjectedThread injectedThread)
        {
            int    tokenInformationLength = 0;
            bool   result           = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenOrigin, IntPtr.Zero, tokenInformationLength, out tokenInformationLength);
            IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInformationLength);

            result = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenOrigin, tokenInformation, tokenInformationLength, out tokenInformationLength);

            if (result)
            {
                // GetTokenInformation to retreive LUID struct
                TOKEN_ORIGIN tokenOrigin = (TOKEN_ORIGIN)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_ORIGIN));
                IntPtr       pLUID       = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LUID)));

                // Get pointer to LUID struct for LsaGetLogonSessionData
                Marshal.StructureToPtr(tokenOrigin.OriginatingLogonSession, pLUID, false);

                IntPtr pLogonSessionData = IntPtr.Zero;
                LsaGetLogonSessionData(pLUID, out pLogonSessionData);

                SECURITY_LOGON_SESSION_DATA logonSessionData = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(pLogonSessionData, typeof(SECURITY_LOGON_SESSION_DATA));

                // Check for a valid logon
                if (logonSessionData.PSiD != IntPtr.Zero)
                {
                    if (injectedThread.Username.Equals("NO OWNER"))
                    {
                        string domain   = Marshal.PtrToStringUni(logonSessionData.LoginDomain.buffer).Trim();
                        string username = Marshal.PtrToStringUni(logonSessionData.Username.buffer).Trim();
                        injectedThread.Username = $"{domain}\\{username}";
                    }

                    // Add logon session information to InjectedThread object
                    injectedThread.LogonSessionStartTime = DateTime.FromFileTime(logonSessionData.LoginTime);
                    injectedThread.LogonType             = Enum.GetName(typeof(SECURITY_LOGON_TYPES), logonSessionData.LogonType);
                    injectedThread.AuthenticationPackage = Marshal.PtrToStringAuto(logonSessionData.AuthenticationPackage.buffer);
                }

                LsaFreeReturnBuffer(pLogonSessionData);
            }
        }
Exemplo n.º 2
0
        public static void EnumerateLogonSessions(uint currentLUID)
        {
            UInt64   count;
            IntPtr   pLuid;
            IntPtr   pLuidList    = IntPtr.Zero;
            uint     AccessDenied = 0xc0000022;
            DateTime systime      = new DateTime(1601, 1, 1, 0, 0, 0, 0);

            if (LsaEnumerateLogonSessions(out count, out pLuidList) != 0)
            {
                Console.WriteLine("[!] Error running LsaEnumerateLogonSessions()");
                Console.ReadLine();

                return;
            }

            // Sets pLuid to the first LUID structure in the list
            pLuid = pLuidList;

            // count stores number of LUIDs in the list
            for (ulong idx = 0; idx < count; idx++)
            {
                IntPtr pSessionData;
                uint   result = LsaGetLogonSessionData(pLuid, out pSessionData);
                if (result != 0)
                {
                    if (result == AccessDenied)
                    {
                        Console.WriteLine("[!] Access denied enumerating LogonId {0:X2}", pLuid);
                    }
                    else
                    {
                        Console.WriteLine("[!] Unknown error accessing session data for LogonId {0:X2}: {1}", pLuid, result);
                    }
                    continue;
                }

                SECURITY_LOGON_SESSION_DATA sessionData = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(pSessionData, typeof(SECURITY_LOGON_SESSION_DATA));

                if (pSessionData == IntPtr.Zero)
                {
                    // Not a valid logon session
                    continue;
                }

                // Marshal our data
                String username = Marshal.PtrToStringUni(sessionData.Username.buffer).Trim();
                String domain   = Marshal.PtrToStringUni(sessionData.DnsDomainName.buffer).Trim();
                String sid      = new System.Security.Principal.SecurityIdentifier(sessionData.PSiD).Value;
                String package  = Marshal.PtrToStringUni(sessionData.AuthenticationPackage.buffer).Trim();
                SECURITY_LOGON_TYPE logonType = (SECURITY_LOGON_TYPE)sessionData.LogonType;
                DateTime            logonTime = systime.AddTicks((long)sessionData.LoginTime);

                if (domain == "")
                {
                    domain = Marshal.PtrToStringUni(sessionData.LoginDomain.buffer).Trim();
                }

                // Write our data
                Console.WriteLine();
                if (currentLUID == sessionData.LoginID.LowPart)
                {
                    Console.WriteLine("***********Current Session***********");
                }
                Console.WriteLine("LogonID (LUID):     {0}", sessionData.LoginID.LowPart);
                Console.WriteLine("User:               {0}\\{1}", domain, username);
                Console.WriteLine("SID:                {0}", sid);
                Console.WriteLine("Auth Package:       {0}", package);
                Console.WriteLine("Logon Type:         {0}", logonType);
                Console.WriteLine("Logon Time:         {0}", logonTime);
                if (currentLUID == sessionData.LoginID.LowPart)
                {
                    Console.WriteLine("*************************************");
                }
                Console.WriteLine();

                // Bunch of typecasts to essentially move our pointer to the next LUID in the list
                pLuid = (IntPtr)((int)pLuid + Marshal.SizeOf(typeof(LUID)));
                LsaFreeReturnBuffer(pSessionData);
            }
            LsaFreeReturnBuffer(pLuid);
        }