using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Security.Principal; namespace Grabber { class Program { static IntPtr capturedToken = default(IntPtr); static WindowsIdentity identity; [DllImport("advapi32.dll", CharSet = CharSet.Auto, EntryPoint = "OpenProcessToken", SetLastError = true)] public static extern bool OpenProcessToken([In()] IntPtr ProcessToken, [In()] TokenAccessLevels DesiredAccess, [In()] ref IntPtr TokenHandle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, EntryPoint = "DuplicateTokenEx", SetLastError = true)] public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); [DllImport("kernel32", CharSet = CharSet.Auto, EntryPoint = "CloseHandle", SetLastError = true)] public static extern bool CloseHandle(IntPtr handle); [DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit); [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool CreateProcessWithTokenW( IntPtr hToken, LogonFlags dwLogonFlags, string lpApplicationName, string lpCommandLine, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); static void Main(string[] args) { Console.WriteLine("grabbing"); identity = GrabToken(); var info = new PROCESS_INFORMATION(); var startup = new STARTUPINFO(); Console.WriteLine("converting"); Console.ReadKey(); IntPtr lpEnvironment = IntPtr.Zero; bool envior = CreateEnvironmentBlock(out lpEnvironment, capturedToken, false); bool sucess = CreateProcessWithTokenW(capturedToken, LogonFlags.WithProfile, "", @"C:\Windows\system32\notepad.exe", CreationFlags.DefaultErrorMode, lpEnvironment, null, ref startup, out info); Console.WriteLine("we did it."); Console.ReadKey(); } static public WindowsIdentity GrabToken() { while (true) { Process currentProcess = Process.GetCurrentProcess(); //Bool to see if you have rights to view process token. if (OpenProcessToken(currentProcess.Handle, TokenAccessLevels.AllAccess, ref capturedToken)) //Grab the "impersonate token" before we convert to primary { var wi = new WindowsIdentity(capturedToken); return wi; } } } static public bool convertToken() { //Convert to primary IntPtr cloneToken = new IntPtr(0); bool finalToken; SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = true; sa.Length = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = (IntPtr)0; const uint GENERIC_ALL = 0x10000000; const int SecurityImpersonation = 2; const int accessLevel = 1; try { finalToken = DuplicateTokenEx(capturedToken, GENERIC_ALL, ref sa, SecurityImpersonation, accessLevel, ref cloneToken); } catch (Exception e) { throw e; } return finalToken; } } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public Int32 Length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } public enum LogonFlags { WithProfile = 1, NetCredentialsOnly } public enum CreationFlags { DefaultErrorMode = 0x04000000, NewConsole = 0x00000010, NewProcessGroup = 0x00000200, SeparateWOWVDM = 0x00000800, Suspended = 0x00000004, UnicodeEnvironment = 0x00000400, ExtendedStartupInfoPresent = 0x00080000 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct STARTUPINFO { public Int32 cb; public string lpReserved; public string lpDesktop; public string lpTitle; public Int32 dwX; public Int32 dwY; public Int32 dwXSize; public Int32 dwYSize; public Int32 dwXCountChars; public Int32 dwYCountChars; public Int32 dwFillAttribute; public Int32 dwFlags; public Int16 wShowWindow; public Int16 cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } }