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