/// <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); } }
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); }