Last active
January 24, 2020 02:07
-
-
Save Luiz-Monad/3eaa4a6147d92e38802bce99b4c33e12 to your computer and use it in GitHub Desktop.
windows privilege descalation
This file contains hidden or 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; | |
public static class MainClazz { | |
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
static extern bool OpenProcessToken( | |
IntPtr ProcessHandle, | |
UInt32 DesiredAccess, | |
out IntPtr TokenHandle | |
); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
static extern bool ImpersonateLoggedOnUser( | |
IntPtr hToken | |
); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
static extern bool RevertToSelf(); | |
[StructLayout(LayoutKind.Sequential)] | |
public struct SECURITY_ATTRIBUTES | |
{ | |
public int nLength; | |
public IntPtr lpSecurityDescriptor; | |
public int bInheritHandle; | |
} | |
public enum TOKEN_TYPE | |
{ | |
TokenPrimary = 1, | |
TokenImpersonation | |
} | |
public enum SECURITY_IMPERSONATION_LEVEL | |
{ | |
SecurityAnonymous, | |
SecurityIdentification, | |
SecurityImpersonation, | |
SecurityDelegation | |
} | |
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] | |
static extern bool DuplicateTokenEx( | |
IntPtr hExistingToken, | |
uint dwDesiredAccess, | |
ref SECURITY_ATTRIBUTES lpTokenAttributes, | |
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, | |
TOKEN_TYPE TokenType, | |
out IntPtr phNewToken ); | |
[StructLayout(LayoutKind.Sequential)] | |
public struct ParentProcessUtilities | |
{ | |
// These members must match PROCESS_BASIC_INFORMATION | |
internal IntPtr Reserved1; | |
internal IntPtr PebBaseAddress; | |
internal IntPtr Reserved2_0; | |
internal IntPtr Reserved2_1; | |
internal IntPtr UniqueProcessId; | |
internal IntPtr InheritedFromUniqueProcessId; | |
} | |
[DllImport("ntdll.dll")] | |
private static extern int NtQueryInformationProcess( | |
IntPtr processHandle, | |
int processInformationClass, | |
ref ParentProcessUtilities processInformation, | |
int processInformationLength, | |
out int returnLength); | |
public static Process GetParentProcess(IntPtr handle) | |
{ | |
var pbi = new ParentProcessUtilities(); | |
int returnLength; | |
var status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); | |
Debug.Assert(status == 0); | |
try | |
{ | |
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); | |
} | |
catch (ArgumentException) | |
{ | |
// not found | |
return null; | |
} | |
} | |
public const uint TOKEN_ALL_ACCESS = 983551; | |
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)] | |
struct PROCESS_INFORMATION | |
{ | |
public IntPtr hProcess; | |
public IntPtr hThread; | |
public int dwProcessId; | |
public int dwThreadId; | |
} | |
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] | |
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 Test(string cmd, IntPtr token) { | |
var si = new STARTUPINFO(); | |
var pi = new PROCESS_INFORMATION(); | |
si.lpTitle = token.ToString(); | |
var r = CreateProcessWithTokenW( | |
token, | |
LogonFlags.WithProfile, | |
null, | |
"cmd.exe /k " + cmd, /*k is for kontinue*/ | |
CreationFlags.NewConsole, | |
IntPtr.Zero, | |
null, | |
ref si, | |
out pi | |
); | |
token.Dump(); | |
pi.Dump(); | |
} | |
public static void Main() | |
{ | |
var pid = Process.GetCurrentProcess(); | |
var ppid = GetParentProcess(pid.Handle); | |
var pppid = GetParentProcess(ppid.Handle); | |
{ | |
var ownToken = IntPtr.Zero; | |
var hasOwnToken = OpenProcessToken(pid.Handle, TOKEN_ALL_ACCESS, out ownToken); | |
Debug.Assert(hasOwnToken); | |
var dtoken = IntPtr.Zero; | |
var oattr = new SECURITY_ATTRIBUTES(); | |
var duped = DuplicateTokenEx(ownToken, TOKEN_ALL_ACCESS, ref oattr, | |
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, | |
TOKEN_TYPE.TokenPrimary, | |
out dtoken); | |
Debug.Assert(duped); | |
Test("net session", dtoken); | |
Test("whoami /priv", dtoken); | |
} | |
{ | |
var token = IntPtr.Zero; | |
var hasToken = OpenProcessToken(pppid.Handle, TOKEN_ALL_ACCESS, out token); | |
Debug.Assert(hasToken); | |
var dtoken = IntPtr.Zero; | |
var attr = new SECURITY_ATTRIBUTES(); | |
var duped = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, ref attr, | |
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, | |
TOKEN_TYPE.TokenPrimary, | |
out dtoken); | |
Debug.Assert(duped); | |
//var done = ImpersonateLoggedOnUser(dtoken); | |
//Debug.Assert(done); | |
Test("net session", dtoken); | |
Test("whoami /priv", dtoken); | |
//RevertToSelf(); //usefull if the main process does more things after | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment