Skip to content

Instantly share code, notes, and snippets.

@mkht
Created July 3, 2019 15:59
Show Gist options
  • Save mkht/382911c344dff7b7cd2fe72417491e70 to your computer and use it in GitHub Desktop.
Save mkht/382911c344dff7b7cd2fe72417491e70 to your computer and use it in GitHub Desktop.
$CSCode = @'
using System;
using System.Runtime.InteropServices;
public static class Security
{
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct SID_IDENTIFIER_AUTHORITY
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
public byte[] Value;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct TOKEN_PRIVILEGES
{
public uint PrivilegeCount;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 1, ArraySubType = UnmanagedType.Struct)]
public LUID_AND_ATTRIBUTES[] Privileges;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public uint Attributes;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct LUID
{
public uint LowPart;
public int HighPart;
}
public enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY
}
[Flags]
private enum SECURITY_INFORMATION : uint
{
OWNER_SECURITY_INFORMATION = 0x00000001,
DACL_SECURITY_INFORMATION = 0x00000004,
}
private const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
private static SID_IDENTIFIER_AUTHORITY SECURITY_NT_AUTHORITY =
new SID_IDENTIFIER_AUTHORITY() { Value = new byte[] { 0, 0, 0, 0, 0, 5 } };
private const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
private const int SECURITY_BUILTIN_DOMAIN_RID = 0x00000020;
private const int DOMAIN_ALIAS_RID_ADMINS = 0x00000220;
private const int TOKEN_QUERY = 8;
private const int SE_PRIVILEGE_ENABLED = 2;
[DllImportAttribute("advapi32.dll", EntryPoint = "OpenProcessToken")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool OpenProcessToken(
[InAttribute]
IntPtr ProcessHandle,
uint DesiredAccess,
out IntPtr TokenHandle);
[DllImportAttribute("advapi32.dll", EntryPoint = "AllocateAndInitializeSid")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool AllocateAndInitializeSid(
[InAttribute] ref SID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
byte nSubAuthorityCount,
uint nSubAuthority0,
uint nSubAuthority1,
uint nSubAuthority2,
uint nSubAuthority3,
uint nSubAuthority4,
uint nSubAuthority5,
uint nSubAuthority6,
uint nSubAuthority7,
ref IntPtr pSid);
[DllImportAttribute("kernel32.dll", EntryPoint = "CloseHandle")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool CloseHandle([InAttribute] IntPtr hObject);
[DllImportAttribute("kernel32.dll", EntryPoint = "GetCurrentProcess")]
private static extern IntPtr GetCurrentProcess();
[DllImportAttribute("advapi32.dll", EntryPoint = "FreeSid")]
private static extern IntPtr FreeSid([InAttribute] IntPtr pSid);
[DllImportAttribute("kernel32.dll", EntryPoint = "LocalFree")]
private static extern IntPtr LocalFree(IntPtr hMem);
[DllImportAttribute("advapi32.dll", EntryPoint = "LookupPrivilegeValueA")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool LookupPrivilegeValueA(
[InAttribute]
[MarshalAsAttribute(UnmanagedType.LPStr)]
string lpSystemName,
[InAttribute]
[MarshalAsAttribute(UnmanagedType.LPStr)]
string lpName,
[OutAttribute]
out LUID lpLuid);
[DllImportAttribute("advapi32.dll", EntryPoint = "AdjustTokenPrivileges")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool AdjustTokenPrivileges(
[InAttribute()]
IntPtr TokenHandle,
[MarshalAsAttribute(UnmanagedType.Bool)]
bool DisableAllPrivileges,
[InAttribute()]
ref TOKEN_PRIVILEGES NewState,
uint BufferLength,
IntPtr PreviousState,
IntPtr ReturnLength);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int SetNamedSecurityInfo(
string pObjectName,
SE_OBJECT_TYPE ObjectType,
SECURITY_INFORMATION SecurityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
IntPtr pDacl,
IntPtr pSacl);
public static void GrantAdministratorsAccess(string name, SE_OBJECT_TYPE type)
{
SID_IDENTIFIER_AUTHORITY sidNTAuthority = SECURITY_NT_AUTHORITY;
// Create a SID for the BUILTIN\Administrators group.
IntPtr sidAdmin = IntPtr.Zero;
AllocateAndInitializeSid(ref sidNTAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
ref sidAdmin);
Action<string, bool> setPrivilege = (privilege, allow) =>
{
IntPtr token = IntPtr.Zero;
TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out token);
if (allow)
{
LUID luid;
LookupPrivilegeValueA(null, privilege, out luid);
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges = new LUID_AND_ATTRIBUTES[1];
tokenPrivileges.Privileges[0].Luid = luid;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
AdjustTokenPrivileges(token, false, ref tokenPrivileges, 0,
IntPtr.Zero, IntPtr.Zero);
CloseHandle(token);
};
// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
setPrivilege(SE_TAKE_OWNERSHIP_NAME, true);
// Set the owner in the object's security descriptor.
SetNamedSecurityInfo(
name,
type,
SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION,
sidAdmin,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
setPrivilege(SE_TAKE_OWNERSHIP_NAME, false);
FreeSid(sidAdmin);
}
}
'@
Add-Type $CSCode -Language CSharp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment