Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 从Windows Server 2019上以IIS APPPOOL帐户运行的进程调用OpenProcess时,访问被拒绝_Winapi_Iis_Permissions_Openprocess - Fatal编程技术网

Winapi 从Windows Server 2019上以IIS APPPOOL帐户运行的进程调用OpenProcess时,访问被拒绝

Winapi 从Windows Server 2019上以IIS APPPOOL帐户运行的进程调用OpenProcess时,访问被拒绝,winapi,iis,permissions,openprocess,Winapi,Iis,Permissions,Openprocess,在IIS APPPOOL\Content Server帐户下运行的用于收集诊断信息的工具正在尝试进行以下调用: hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, <process id>); 使用SysInternals显示以下用户权限分配: SeCreateTokenPrivilege (Create a token object): SeAssignPrimaryTokenPrivilege (Replac

在IIS APPPOOL\Content Server帐户下运行的用于收集诊断信息的工具正在尝试进行以下调用:

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, <process id>);
使用SysInternals显示以下用户权限分配:

  SeCreateTokenPrivilege (Create a token object):
  SeAssignPrimaryTokenPrivilege (Replace a process level token):
    IIS APPPOOL\DefaultAppPool
    IIS APPPOOL\Content Server
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
  SeLockMemoryPrivilege (Lock pages in memory):
  SeIncreaseQuotaPrivilege (Adjust memory quotas for a process):
    IIS APPPOOL\DefaultAppPool
    IIS APPPOOL\Content Server
    BUILTIN\Administrators
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
  SeMachineAccountPrivilege (Add workstations to domain):
  SeTcbPrivilege (Act as part of the operating system):
  SeSecurityPrivilege (Manage auditing and security log):
    BUILTIN\Administrators
  SeTakeOwnershipPrivilege (Take ownership of files or other objects):
    BUILTIN\Administrators
  SeLoadDriverPrivilege (Load and unload device drivers):
    BUILTIN\Administrators
  SeSystemProfilePrivilege (Profile system performance):
    NT SERVICE\WdiServiceHost
    BUILTIN\Administrators
  SeSystemtimePrivilege (Change the system time):
    BUILTIN\Administrators
    NT AUTHORITY\LOCAL SERVICE
  SeProfileSingleProcessPrivilege (Profile single process):
    BUILTIN\Administrators
  SeIncreaseBasePriorityPrivilege (Increase scheduling priority):
    Window Manager\Window Manager Group
    BUILTIN\Administrators
  SeCreatePagefilePrivilege (Create a pagefile):
    BUILTIN\Administrators
  SeCreatePermanentPrivilege (Create permanent shared objects):
  SeBackupPrivilege (Back up files and directories):
    BUILTIN\Backup Operators
    BUILTIN\Administrators
  SeRestorePrivilege (Restore files and directories):
    BUILTIN\Backup Operators
    BUILTIN\Administrators
  SeShutdownPrivilege (Shut down the system):
    BUILTIN\Backup Operators
    BUILTIN\Administrators
  SeDebugPrivilege (Debug programs):
    BUILTIN\Administrators
  SeAuditPrivilege (Generate security audits):
    IIS APPPOOL\DefaultAppPool
    IIS APPPOOL\Content Server
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
  SeSystemEnvironmentPrivilege (Modify firmware environment values):
    BUILTIN\Administrators
  SeChangeNotifyPrivilege (Bypass traverse checking):
    BUILTIN\Backup Operators
    BUILTIN\Users
    BUILTIN\Administrators
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
    Everyone
  SeRemoteShutdownPrivilege (Force shutdown from a remote system):
    BUILTIN\Administrators
  SeUndockPrivilege (Remove computer from docking station):
    BUILTIN\Administrators
  SeSyncAgentPrivilege (Synchronize directory service data):
  SeEnableDelegationPrivilege (Enable computer and user accounts to be trusted for delegation):
  SeManageVolumePrivilege (Perform volume maintenance tasks):
    BUILTIN\Administrators
  SeImpersonatePrivilege (Impersonate a client after authentication):
    NT AUTHORITY\SERVICE
    BUILTIN\IIS_IUSRS
    BUILTIN\Administrators
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
  SeCreateGlobalPrivilege (Create global objects):
    NT AUTHORITY\SERVICE
    BUILTIN\Administrators
    NT AUTHORITY\NETWORK SERVICE
    NT AUTHORITY\LOCAL SERVICE
  SeTrustedCredManAccessPrivilege (Access Credential Manager as a trusted caller):
  SeRelabelPrivilege (Modify an object label):
  SeIncreaseWorkingSetPrivilege (Increase a process working set):
    BUILTIN\Users
  SeTimeZonePrivilege (Change the time zone):
    BUILTIN\Administrators
    NT AUTHORITY\LOCAL SERVICE
  SeCreateSymbolicLinkPrivilege (Create symbolic links):
    BUILTIN\Administrators
  SeDelegateSessionUserImpersonatePrivilege (Obtain an impersonation token for another user in the same session):
    BUILTIN\Administrators
  SeBatchLogonRight:
    BUILTIN\IIS_IUSRS
    BUILTIN\Performance Log Users
    BUILTIN\Backup Operators
    BUILTIN\Administrators
  SeInteractiveLogonRight:
    BUILTIN\Backup Operators
    BUILTIN\Users
    BUILTIN\Administrators
  SeNetworkLogonRight:
    BUILTIN\Backup Operators
    BUILTIN\Users
    BUILTIN\Administrators
    Everyone
  SeServiceLogonRight:
    IIS APPPOOL\DefaultAppPool
    IIS APPPOOL\Content Server
    NT SERVICE\ALL SERVICES
  SeDenyBatchLogonRight:
  SeDenyInteractiveLogonRight:
  SeDenyNetworkLogonRight:
  SeDenyServiceLogonRight:
  SeRemoteInteractiveLogonRight:
    BUILTIN\Remote Desktop Users
    BUILTIN\Administrators
  SeDenyRemoteInteractiveLogonRight:
通过流程检查显示以下内容:

在一个实验中,我试图通过SecPol.msc(非加入域的计算机)授予应用程序SeDebugPrivilege,但出于安全原因,我不想永久应用该设置,但未能解决问题。应用此策略并重新启动计算机后,在Process Explorer中,进程现在显示SeDebugPrivilege,但被列为“已禁用”

最后,我使用以下XML配置文件启用了“进程访问”日志记录:

<Sysmon schemaversion="4.22">
<EventFiltering>
    <RuleGroup name="ProcessAccess" groupRelation="or">
        <ProcessAccess onmatch="include">
            <SourceImage condition="contains">TargetProcess.exe</SourceImage>
        </ProcessAccess>
    </RuleGroup>
</EventFiltering>
</Sysmon>
以IIS APPPOOL\Content Server运行

RuleName: ProcessAccess
UtcTime: 2020-06-16 08:21:41.015
SourceProcessGUID: {4cfe3c55-8100-5ee8-0000-0010a5107500}
SourceProcessId: 3740
SourceThreadId: 1532
SourceImage: c:\TEST\source.exe
TargetProcessGUID: {4cfe3c55-8114-5ee8-0000-0010e1a87500}
TargetProcessId: 3992
TargetImage: c:\TEST\target.exe
GrantedAccess: 0x12367B
虽然0x1400是预期的过程查询信息+过程查询有限信息返回授权访问0x12367B的结果似乎与记录的访问权限不完全匹配

缺乏什么特权阻止了这种访问?OpenProcess的文档似乎没有指定所需的任何特定权限,除非请求PROCESS\u ALL\u访问。目标进程不是“受保护”的进程


是否有任何选项可将此帐户配置为在目标进程上打开进程

原因是缺少对目标进程的权限。要测试所需的权限,可通过右键单击目标进程并选择属性,然后选择安全性选项卡并选择权限按钮来查看,您可以为调用OpenProcess的进程正在运行的用户帐户添加所需的权限进程查询信息允许。权限也可能因进程而被拒绝,即中级完整性进程无法访问高完整性进程。即使用户帐户添加了正确的权限,但由于强制完整性控制,您没有访问权限,您也将被拒绝访问

在代码中,这可以通过修改对象的ACL来实现

下面是我为测试不同场景编写的PowerShell脚本,例如添加所需的权限

$code = @'
using System;
using System.Security;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Principal;
namespace CSharp
{
    public class ProcessSecurity : NativeObjectSecurity
    {
        public ProcessSecurity(SafeHandle processHandle)
            : base(false, ResourceType.KernelObject, processHandle, AccessControlSections.Access)
        {

        }

        public void AddAccessRule(ProcessAccessRule rule)
        {
            base.AddAccessRule(rule);
        }

        // this is not a full impl- it only supports writing DACL changes
        public void SaveChanges(SafeHandle processHandle)
        {
            Persist(processHandle, AccessControlSections.Access);
        }

        public override Type AccessRightType
        {
            get { return typeof(ProcessAccessRights); }
        }

        public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
        {
            return new ProcessAccessRule(identityReference, (ProcessAccessRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type);
        }

        public override Type AccessRuleType
        {
            get { return typeof(ProcessAccessRule); }
        }

        public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
        {
            throw new NotImplementedException();
        }

        public override Type AuditRuleType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class ProcessAccessRule : AccessRule
    {
        public ProcessAccessRule(IdentityReference identityReference, ProcessAccessRights accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
            : base(identityReference, (int)accessMask, isInherited, inheritanceFlags, propagationFlags, type)
        {
        }

        public ProcessAccessRights ProcessAccessRights { get { return (ProcessAccessRights)AccessMask; } }
    }

    [Flags]
    public enum ProcessAccessRights
    {
        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
        DELETE = (0x00010000), // Required to delete the object. 
        READ_CONTROL = (0x00020000), // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
        WRITE_DAC = (0x00040000), // Required to modify the DACL in the security descriptor for the object. 
        WRITE_OWNER = (0x00080000), // Required to change the owner in the security descriptor for the object. 

        PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, //All possible access rights for a process object.
        PROCESS_CREATE_PROCESS = (0x0080), // Required to create a process. 
        PROCESS_CREATE_THREAD = (0x0002), // Required to create a thread. 
        PROCESS_DUP_HANDLE = (0x0040), // Required to duplicate a handle using DuplicateHandle. 
        PROCESS_QUERY_INFORMATION = (0x0400), // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
        PROCESS_QUERY_LIMITED_INFORMATION = (0x1000),
        PROCESS_SET_INFORMATION = (0x0200), // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
        PROCESS_SET_QUOTA = (0x0100), // Required to set memory limits using SetProcessWorkingSetSize. 
        PROCESS_SUSPEND_RESUME = (0x0800), // Required to suspend or resume a process. 
        PROCESS_TERMINATE = (0x0001), // Required to terminate a process using TerminateProcess. 
        PROCESS_VM_OPERATION = (0x0008), // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
        PROCESS_VM_READ = (0x0010), // Required to read memory in a process using ReadProcessMemory. 
        PROCESS_VM_WRITE = (0x0020), // Required to write to memory in a process using WriteProcessMemory. 
        SYNCHRONIZE = (0x00100000), // Required to wait for the process to terminate using the wait functions. 
    }

    public static class NativeMethods
    {
        private const Int32 ANYSIZE_ARRAY        = 0x00000001;
        public const int SE_PRIVILEGE_ENABLED    = 0x00000002;

        //Use these for DesiredAccess
        public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
        public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const UInt32 TOKEN_DUPLICATE = 0x0002;
        public const UInt32 TOKEN_IMPERSONATE = 0x0004;
        public const UInt32 TOKEN_QUERY = 0x0008;
        public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
        public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
        public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
        public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
        public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
            TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
            TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
            TOKEN_ADJUST_SESSIONID);

       public enum SecurityEntity
       {
          SE_CREATE_TOKEN_NAME,
          SE_ASSIGNPRIMARYTOKEN_NAME,
          SE_LOCK_MEMORY_NAME,
          SE_INCREASE_QUOTA_NAME,
          SE_UNSOLICITED_INPUT_NAME,
          SE_MACHINE_ACCOUNT_NAME,
          SE_TCB_NAME,
          SE_SECURITY_NAME,
          SE_TAKE_OWNERSHIP_NAME,
          SE_LOAD_DRIVER_NAME,
          SE_SYSTEM_PROFILE_NAME,
          SE_SYSTEMTIME_NAME,
          SE_PROF_SINGLE_PROCESS_NAME,
          SE_INC_BASE_PRIORITY_NAME,
          SE_CREATE_PAGEFILE_NAME,
          SE_CREATE_PERMANENT_NAME,
          SE_BACKUP_NAME,
          SE_RESTORE_NAME,
          SE_SHUTDOWN_NAME,
          SE_DEBUG_NAME,
          SE_AUDIT_NAME,
          SE_SYSTEM_ENVIRONMENT_NAME,
          SE_CHANGE_NOTIFY_NAME,
          SE_REMOTE_SHUTDOWN_NAME,
          SE_UNDOCK_NAME,
          SE_SYNC_AGENT_NAME,
          SE_ENABLE_DELEGATION_NAME,
          SE_MANAGE_VOLUME_NAME,
          SE_IMPERSONATE_NAME,
          SE_CREATE_GLOBAL_NAME,
          SE_CREATE_SYMBOLIC_LINK_NAME,
          SE_INC_WORKING_SET_NAME,
          SE_RELABEL_NAME,
          SE_TIME_ZONE_NAME,
          SE_TRUSTED_CREDMAN_ACCESS_NAME
       }

      public static string GetSecurityEntityValue(SecurityEntity securityEntity)
      {
         switch (securityEntity)
         {
            case SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME:
               return "SeAssignPrimaryTokenPrivilege";
            case SecurityEntity.SE_AUDIT_NAME:
               return "SeAuditPrivilege";
            case SecurityEntity.SE_BACKUP_NAME:
               return "SeBackupPrivilege";
            case SecurityEntity.SE_CHANGE_NOTIFY_NAME:
               return "SeChangeNotifyPrivilege";
            case SecurityEntity.SE_CREATE_GLOBAL_NAME:
               return "SeCreateGlobalPrivilege";
            case SecurityEntity.SE_CREATE_PAGEFILE_NAME:
               return "SeCreatePagefilePrivilege";
            case SecurityEntity.SE_CREATE_PERMANENT_NAME:
               return "SeCreatePermanentPrivilege";
            case SecurityEntity.SE_CREATE_SYMBOLIC_LINK_NAME:
               return "SeCreateSymbolicLinkPrivilege";
            case SecurityEntity.SE_CREATE_TOKEN_NAME:
               return "SeCreateTokenPrivilege";
            case SecurityEntity.SE_DEBUG_NAME:
               return "SeDebugPrivilege";
            case SecurityEntity.SE_ENABLE_DELEGATION_NAME:
               return "SeEnableDelegationPrivilege";
            case SecurityEntity.SE_IMPERSONATE_NAME:
               return "SeImpersonatePrivilege";
            case SecurityEntity.SE_INC_BASE_PRIORITY_NAME:
               return "SeIncreaseBasePriorityPrivilege";
            case SecurityEntity.SE_INCREASE_QUOTA_NAME:
               return "SeIncreaseQuotaPrivilege";
            case SecurityEntity.SE_INC_WORKING_SET_NAME:
               return "SeIncreaseWorkingSetPrivilege";
            case SecurityEntity.SE_LOAD_DRIVER_NAME:
               return "SeLoadDriverPrivilege";
            case SecurityEntity.SE_LOCK_MEMORY_NAME:
               return "SeLockMemoryPrivilege";
            case SecurityEntity.SE_MACHINE_ACCOUNT_NAME:
               return "SeMachineAccountPrivilege";
            case SecurityEntity.SE_MANAGE_VOLUME_NAME:
               return "SeManageVolumePrivilege";
            case SecurityEntity.SE_PROF_SINGLE_PROCESS_NAME:
               return "SeProfileSingleProcessPrivilege";
            case SecurityEntity.SE_RELABEL_NAME:
               return "SeRelabelPrivilege";
            case SecurityEntity.SE_REMOTE_SHUTDOWN_NAME:
               return "SeRemoteShutdownPrivilege";
            case SecurityEntity.SE_RESTORE_NAME:
               return "SeRestorePrivilege";
            case SecurityEntity.SE_SECURITY_NAME:
               return "SeSecurityPrivilege";
            case SecurityEntity.SE_SHUTDOWN_NAME:
               return "SeShutdownPrivilege";
            case SecurityEntity.SE_SYNC_AGENT_NAME:
               return "SeSyncAgentPrivilege";
            case SecurityEntity.SE_SYSTEM_ENVIRONMENT_NAME:
               return "SeSystemEnvironmentPrivilege";
            case SecurityEntity.SE_SYSTEM_PROFILE_NAME:
               return "SeSystemProfilePrivilege";
            case SecurityEntity.SE_SYSTEMTIME_NAME:
               return "SeSystemtimePrivilege";
            case SecurityEntity.SE_TAKE_OWNERSHIP_NAME:
               return "SeTakeOwnershipPrivilege";
            case SecurityEntity.SE_TCB_NAME:
               return "SeTcbPrivilege";
            case SecurityEntity.SE_TIME_ZONE_NAME:
               return "SeTimeZonePrivilege";
            case SecurityEntity.SE_TRUSTED_CREDMAN_ACCESS_NAME:
               return "SeTrustedCredManAccessPrivilege";
            case SecurityEntity.SE_UNDOCK_NAME:
               return "SeUndockPrivilege";
            default:
               throw new ArgumentOutOfRangeException(typeof(SecurityEntity).Name);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID {
           public UInt32 LowPart;
           public Int32 HighPart;
        }

        public struct TOKEN_PRIVILEGES {
           public int PrivilegeCount;
           [MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
           public LUID_AND_ATTRIBUTES [] Privileges;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct LUID_AND_ATTRIBUTES {
           public LUID Luid;
           public UInt32 Attributes;
        }

        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }

        [DllImport("kernel32.dll", SetLastError=true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseHandle(IntPtr hObject);

        // Use this signature if you want the previous state information returned
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 BufferLengthInBytes,
           ref TOKEN_PRIVILEGES PreviousState,
           out UInt32 ReturnLengthInBytes);

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 Zero,
           IntPtr Null1,
           IntPtr Null2);

        [DllImport("advapi32.dll")]
        public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
           ref LUID lpLuid);

        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(
            ProcessAccessFlags processAccess,
            bool bInheritHandle,
            int processId
        );

        public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess(flags, false, proc.Id);
        }
    }
}
'@

Add-Type -TypeDefinition $code -IgnoreWarnings 

Function Enable-DebugPrivilege
{
    $hToken = New-Object System.IntPtr
    $luidSEDebugNameValue = New-Object CSharp.NativeMethods+LUID
    $tkpPrivileges = New-Object CSharp.NativeMethods+TOKEN_PRIVILEGES

    if (![CSharp.NativeMethods]::OpenProcessToken([System.Diagnostics.Process]::GetCurrentProcess().Handle, [CSharp.NativeMethods]::TOKEN_ADJUST_PRIVILEGES -bor [CSharp.NativeMethods]::TOKEN_QUERY, [ref]$hToken))
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "OpenProcessToken Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
    }
    else
    {
        "OpenProcessToken SUCCESS!"
    }

    if (![CSharp.NativeMethods]::LookupPrivilegeValue($null, [CSharp.NativeMethods]::GetSecurityEntityValue([CSharp.NativeMethods+SecurityEntity]::SE_DEBUG_NAME), [ref]$luidSEDebugNameValue))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "LookupPrivilegeValue Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return
    }
    else
    {
       "LookupPrivilegeValue() SUCCESS!"
    }


    $tkpPrivileges.PrivilegeCount = 1

    $luid = New-Object CSharp.NativeMethods+LUID_AND_ATTRIBUTES
    $luid.Luid = $luidSEDebugNameValue
    $luid.Attributes =  [CSharp.NativeMEthods]::SE_PRIVILEGE_ENABLED
    $tkpPrivileges.Privileges = @($luid)

    if (![CSharp.NativeMethods]::AdjustTokenPrivileges($hToken,$false,[ref]$tkpPrivileges, 0,[IntPtr]::Zero,[IntPtr]::Zero))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "AdjustTokenPriviles Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return

    }
    else
    {
        "SeDebugPrivilege is now available!";
    }

    [CSharp.NativeMethods]::CloseHandle($hToken);


}

Function Open-Process($Process)
{
    $hProcess = [CSharp.NativeMethods]::OpenProcess($Process,[CSharp.NativeMethods+ProcessAccessFlags]::QueryInformation)

    if ($hProcess -eq 0 )
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
    }
    else
    {
        "Handle to process $hProcess opened ok!"
    }
}


Function Add-ProcessQueryInfoPermission($Process,$IdentityReference)
{
    $procSec = New-Object CSharp.ProcessSecurity($Process.SafeHandle)
    $accessRule = New-Object CSharp.ProcessAccessRule($IdentityReference, [CSharp.ProcessAccessRights]::PROCESS_QUERY_INFORMATION, $true, [System.Security.AccessControl.InheritanceFlags]::None, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow)
    $procSec.AddAccessRule($accessRule)
    $procSec.SaveChanges($Process.SafeHandle)
}


# change to hold your target process
$targetProcess = (Get-process | Where-Object { $_.Id -eq 3700  })

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

# change for appropriate account to add
$ctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)  
$usr = [ System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($ctx,[System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName,"test")  

# add process query information (This may need to be run elevated / run from different acct then open-process line depending on target process)
Add-ProcessQueryInfoPermission -Process $targetProcess -IdentityReference $usr.Sid

# test open process
Open-Process -Process  $targetProcess

原因是缺少对目标进程的权限。要测试所需的权限,可通过右键单击目标进程并选择属性,然后选择安全性选项卡并选择权限按钮来查看,您可以为调用OpenProcess的进程正在运行的用户帐户添加所需的权限进程查询信息允许。权限也可能因进程而被拒绝,即中级完整性进程无法访问高完整性进程。即使用户帐户添加了正确的权限,但由于强制完整性控制,您没有访问权限,您也将被拒绝访问

在代码中,这可以通过修改对象的ACL来实现

下面是我为测试不同场景编写的PowerShell脚本,例如添加所需的权限

$code = @'
using System;
using System.Security;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Principal;
namespace CSharp
{
    public class ProcessSecurity : NativeObjectSecurity
    {
        public ProcessSecurity(SafeHandle processHandle)
            : base(false, ResourceType.KernelObject, processHandle, AccessControlSections.Access)
        {

        }

        public void AddAccessRule(ProcessAccessRule rule)
        {
            base.AddAccessRule(rule);
        }

        // this is not a full impl- it only supports writing DACL changes
        public void SaveChanges(SafeHandle processHandle)
        {
            Persist(processHandle, AccessControlSections.Access);
        }

        public override Type AccessRightType
        {
            get { return typeof(ProcessAccessRights); }
        }

        public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
        {
            return new ProcessAccessRule(identityReference, (ProcessAccessRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type);
        }

        public override Type AccessRuleType
        {
            get { return typeof(ProcessAccessRule); }
        }

        public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
        {
            throw new NotImplementedException();
        }

        public override Type AuditRuleType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class ProcessAccessRule : AccessRule
    {
        public ProcessAccessRule(IdentityReference identityReference, ProcessAccessRights accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
            : base(identityReference, (int)accessMask, isInherited, inheritanceFlags, propagationFlags, type)
        {
        }

        public ProcessAccessRights ProcessAccessRights { get { return (ProcessAccessRights)AccessMask; } }
    }

    [Flags]
    public enum ProcessAccessRights
    {
        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
        DELETE = (0x00010000), // Required to delete the object. 
        READ_CONTROL = (0x00020000), // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
        WRITE_DAC = (0x00040000), // Required to modify the DACL in the security descriptor for the object. 
        WRITE_OWNER = (0x00080000), // Required to change the owner in the security descriptor for the object. 

        PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, //All possible access rights for a process object.
        PROCESS_CREATE_PROCESS = (0x0080), // Required to create a process. 
        PROCESS_CREATE_THREAD = (0x0002), // Required to create a thread. 
        PROCESS_DUP_HANDLE = (0x0040), // Required to duplicate a handle using DuplicateHandle. 
        PROCESS_QUERY_INFORMATION = (0x0400), // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
        PROCESS_QUERY_LIMITED_INFORMATION = (0x1000),
        PROCESS_SET_INFORMATION = (0x0200), // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
        PROCESS_SET_QUOTA = (0x0100), // Required to set memory limits using SetProcessWorkingSetSize. 
        PROCESS_SUSPEND_RESUME = (0x0800), // Required to suspend or resume a process. 
        PROCESS_TERMINATE = (0x0001), // Required to terminate a process using TerminateProcess. 
        PROCESS_VM_OPERATION = (0x0008), // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
        PROCESS_VM_READ = (0x0010), // Required to read memory in a process using ReadProcessMemory. 
        PROCESS_VM_WRITE = (0x0020), // Required to write to memory in a process using WriteProcessMemory. 
        SYNCHRONIZE = (0x00100000), // Required to wait for the process to terminate using the wait functions. 
    }

    public static class NativeMethods
    {
        private const Int32 ANYSIZE_ARRAY        = 0x00000001;
        public const int SE_PRIVILEGE_ENABLED    = 0x00000002;

        //Use these for DesiredAccess
        public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
        public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const UInt32 TOKEN_DUPLICATE = 0x0002;
        public const UInt32 TOKEN_IMPERSONATE = 0x0004;
        public const UInt32 TOKEN_QUERY = 0x0008;
        public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
        public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
        public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
        public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
        public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
            TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
            TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
            TOKEN_ADJUST_SESSIONID);

       public enum SecurityEntity
       {
          SE_CREATE_TOKEN_NAME,
          SE_ASSIGNPRIMARYTOKEN_NAME,
          SE_LOCK_MEMORY_NAME,
          SE_INCREASE_QUOTA_NAME,
          SE_UNSOLICITED_INPUT_NAME,
          SE_MACHINE_ACCOUNT_NAME,
          SE_TCB_NAME,
          SE_SECURITY_NAME,
          SE_TAKE_OWNERSHIP_NAME,
          SE_LOAD_DRIVER_NAME,
          SE_SYSTEM_PROFILE_NAME,
          SE_SYSTEMTIME_NAME,
          SE_PROF_SINGLE_PROCESS_NAME,
          SE_INC_BASE_PRIORITY_NAME,
          SE_CREATE_PAGEFILE_NAME,
          SE_CREATE_PERMANENT_NAME,
          SE_BACKUP_NAME,
          SE_RESTORE_NAME,
          SE_SHUTDOWN_NAME,
          SE_DEBUG_NAME,
          SE_AUDIT_NAME,
          SE_SYSTEM_ENVIRONMENT_NAME,
          SE_CHANGE_NOTIFY_NAME,
          SE_REMOTE_SHUTDOWN_NAME,
          SE_UNDOCK_NAME,
          SE_SYNC_AGENT_NAME,
          SE_ENABLE_DELEGATION_NAME,
          SE_MANAGE_VOLUME_NAME,
          SE_IMPERSONATE_NAME,
          SE_CREATE_GLOBAL_NAME,
          SE_CREATE_SYMBOLIC_LINK_NAME,
          SE_INC_WORKING_SET_NAME,
          SE_RELABEL_NAME,
          SE_TIME_ZONE_NAME,
          SE_TRUSTED_CREDMAN_ACCESS_NAME
       }

      public static string GetSecurityEntityValue(SecurityEntity securityEntity)
      {
         switch (securityEntity)
         {
            case SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME:
               return "SeAssignPrimaryTokenPrivilege";
            case SecurityEntity.SE_AUDIT_NAME:
               return "SeAuditPrivilege";
            case SecurityEntity.SE_BACKUP_NAME:
               return "SeBackupPrivilege";
            case SecurityEntity.SE_CHANGE_NOTIFY_NAME:
               return "SeChangeNotifyPrivilege";
            case SecurityEntity.SE_CREATE_GLOBAL_NAME:
               return "SeCreateGlobalPrivilege";
            case SecurityEntity.SE_CREATE_PAGEFILE_NAME:
               return "SeCreatePagefilePrivilege";
            case SecurityEntity.SE_CREATE_PERMANENT_NAME:
               return "SeCreatePermanentPrivilege";
            case SecurityEntity.SE_CREATE_SYMBOLIC_LINK_NAME:
               return "SeCreateSymbolicLinkPrivilege";
            case SecurityEntity.SE_CREATE_TOKEN_NAME:
               return "SeCreateTokenPrivilege";
            case SecurityEntity.SE_DEBUG_NAME:
               return "SeDebugPrivilege";
            case SecurityEntity.SE_ENABLE_DELEGATION_NAME:
               return "SeEnableDelegationPrivilege";
            case SecurityEntity.SE_IMPERSONATE_NAME:
               return "SeImpersonatePrivilege";
            case SecurityEntity.SE_INC_BASE_PRIORITY_NAME:
               return "SeIncreaseBasePriorityPrivilege";
            case SecurityEntity.SE_INCREASE_QUOTA_NAME:
               return "SeIncreaseQuotaPrivilege";
            case SecurityEntity.SE_INC_WORKING_SET_NAME:
               return "SeIncreaseWorkingSetPrivilege";
            case SecurityEntity.SE_LOAD_DRIVER_NAME:
               return "SeLoadDriverPrivilege";
            case SecurityEntity.SE_LOCK_MEMORY_NAME:
               return "SeLockMemoryPrivilege";
            case SecurityEntity.SE_MACHINE_ACCOUNT_NAME:
               return "SeMachineAccountPrivilege";
            case SecurityEntity.SE_MANAGE_VOLUME_NAME:
               return "SeManageVolumePrivilege";
            case SecurityEntity.SE_PROF_SINGLE_PROCESS_NAME:
               return "SeProfileSingleProcessPrivilege";
            case SecurityEntity.SE_RELABEL_NAME:
               return "SeRelabelPrivilege";
            case SecurityEntity.SE_REMOTE_SHUTDOWN_NAME:
               return "SeRemoteShutdownPrivilege";
            case SecurityEntity.SE_RESTORE_NAME:
               return "SeRestorePrivilege";
            case SecurityEntity.SE_SECURITY_NAME:
               return "SeSecurityPrivilege";
            case SecurityEntity.SE_SHUTDOWN_NAME:
               return "SeShutdownPrivilege";
            case SecurityEntity.SE_SYNC_AGENT_NAME:
               return "SeSyncAgentPrivilege";
            case SecurityEntity.SE_SYSTEM_ENVIRONMENT_NAME:
               return "SeSystemEnvironmentPrivilege";
            case SecurityEntity.SE_SYSTEM_PROFILE_NAME:
               return "SeSystemProfilePrivilege";
            case SecurityEntity.SE_SYSTEMTIME_NAME:
               return "SeSystemtimePrivilege";
            case SecurityEntity.SE_TAKE_OWNERSHIP_NAME:
               return "SeTakeOwnershipPrivilege";
            case SecurityEntity.SE_TCB_NAME:
               return "SeTcbPrivilege";
            case SecurityEntity.SE_TIME_ZONE_NAME:
               return "SeTimeZonePrivilege";
            case SecurityEntity.SE_TRUSTED_CREDMAN_ACCESS_NAME:
               return "SeTrustedCredManAccessPrivilege";
            case SecurityEntity.SE_UNDOCK_NAME:
               return "SeUndockPrivilege";
            default:
               throw new ArgumentOutOfRangeException(typeof(SecurityEntity).Name);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID {
           public UInt32 LowPart;
           public Int32 HighPart;
        }

        public struct TOKEN_PRIVILEGES {
           public int PrivilegeCount;
           [MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
           public LUID_AND_ATTRIBUTES [] Privileges;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct LUID_AND_ATTRIBUTES {
           public LUID Luid;
           public UInt32 Attributes;
        }

        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }

        [DllImport("kernel32.dll", SetLastError=true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseHandle(IntPtr hObject);

        // Use this signature if you want the previous state information returned
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 BufferLengthInBytes,
           ref TOKEN_PRIVILEGES PreviousState,
           out UInt32 ReturnLengthInBytes);

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 Zero,
           IntPtr Null1,
           IntPtr Null2);

        [DllImport("advapi32.dll")]
        public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
           ref LUID lpLuid);

        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(
            ProcessAccessFlags processAccess,
            bool bInheritHandle,
            int processId
        );

        public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess(flags, false, proc.Id);
        }
    }
}
'@

Add-Type -TypeDefinition $code -IgnoreWarnings 

Function Enable-DebugPrivilege
{
    $hToken = New-Object System.IntPtr
    $luidSEDebugNameValue = New-Object CSharp.NativeMethods+LUID
    $tkpPrivileges = New-Object CSharp.NativeMethods+TOKEN_PRIVILEGES

    if (![CSharp.NativeMethods]::OpenProcessToken([System.Diagnostics.Process]::GetCurrentProcess().Handle, [CSharp.NativeMethods]::TOKEN_ADJUST_PRIVILEGES -bor [CSharp.NativeMethods]::TOKEN_QUERY, [ref]$hToken))
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "OpenProcessToken Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
    }
    else
    {
        "OpenProcessToken SUCCESS!"
    }

    if (![CSharp.NativeMethods]::LookupPrivilegeValue($null, [CSharp.NativeMethods]::GetSecurityEntityValue([CSharp.NativeMethods+SecurityEntity]::SE_DEBUG_NAME), [ref]$luidSEDebugNameValue))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "LookupPrivilegeValue Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return
    }
    else
    {
       "LookupPrivilegeValue() SUCCESS!"
    }


    $tkpPrivileges.PrivilegeCount = 1

    $luid = New-Object CSharp.NativeMethods+LUID_AND_ATTRIBUTES
    $luid.Luid = $luidSEDebugNameValue
    $luid.Attributes =  [CSharp.NativeMEthods]::SE_PRIVILEGE_ENABLED
    $tkpPrivileges.Privileges = @($luid)

    if (![CSharp.NativeMethods]::AdjustTokenPrivileges($hToken,$false,[ref]$tkpPrivileges, 0,[IntPtr]::Zero,[IntPtr]::Zero))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "AdjustTokenPriviles Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return

    }
    else
    {
        "SeDebugPrivilege is now available!";
    }

    [CSharp.NativeMethods]::CloseHandle($hToken);


}

Function Open-Process($Process)
{
    $hProcess = [CSharp.NativeMethods]::OpenProcess($Process,[CSharp.NativeMethods+ProcessAccessFlags]::QueryInformation)

    if ($hProcess -eq 0 )
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
    }
    else
    {
        "Handle to process $hProcess opened ok!"
    }
}


Function Add-ProcessQueryInfoPermission($Process,$IdentityReference)
{
    $procSec = New-Object CSharp.ProcessSecurity($Process.SafeHandle)
    $accessRule = New-Object CSharp.ProcessAccessRule($IdentityReference, [CSharp.ProcessAccessRights]::PROCESS_QUERY_INFORMATION, $true, [System.Security.AccessControl.InheritanceFlags]::None, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow)
    $procSec.AddAccessRule($accessRule)
    $procSec.SaveChanges($Process.SafeHandle)
}


# change to hold your target process
$targetProcess = (Get-process | Where-Object { $_.Id -eq 3700  })

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

# change for appropriate account to add
$ctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)  
$usr = [ System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($ctx,[System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName,"test")  

# add process query information (This may need to be run elevated / run from different acct then open-process line depending on target process)
Add-ProcessQueryInfoPermission -Process $targetProcess -IdentityReference $usr.Sid

# test open process
Open-Process -Process  $targetProcess

确保用户或组位于由对象所有者控制的目标进程的DACL中。请参阅,0x12367b似乎是
同步|读控制|进程|查询|有限|信息|进程|查询|信息|进程|集|信息|进程| VM |读|进程| VM |写|进程|重复|处理|进程|终止|进程|创建|线程|进程| VM |操作
确保用户或组处于目标位置由对象所有者控制的进程的DACL。请参阅,0x12367b似乎是
同步|读控制|进程|查询|有限|信息|进程|查询|信息|进程|集|信息|进程| VM |读|进程| VM |写|进程|重复|处理|进程|终止|进程|创建|线程|进程| VM |操作
$code = @'
using System;
using System.Security;
using System.Diagnostics;
using System.Security.AccessControl;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Principal;
namespace CSharp
{
    public class ProcessSecurity : NativeObjectSecurity
    {
        public ProcessSecurity(SafeHandle processHandle)
            : base(false, ResourceType.KernelObject, processHandle, AccessControlSections.Access)
        {

        }

        public void AddAccessRule(ProcessAccessRule rule)
        {
            base.AddAccessRule(rule);
        }

        // this is not a full impl- it only supports writing DACL changes
        public void SaveChanges(SafeHandle processHandle)
        {
            Persist(processHandle, AccessControlSections.Access);
        }

        public override Type AccessRightType
        {
            get { return typeof(ProcessAccessRights); }
        }

        public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
        {
            return new ProcessAccessRule(identityReference, (ProcessAccessRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type);
        }

        public override Type AccessRuleType
        {
            get { return typeof(ProcessAccessRule); }
        }

        public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
        {
            throw new NotImplementedException();
        }

        public override Type AuditRuleType
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class ProcessAccessRule : AccessRule
    {
        public ProcessAccessRule(IdentityReference identityReference, ProcessAccessRights accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
            : base(identityReference, (int)accessMask, isInherited, inheritanceFlags, propagationFlags, type)
        {
        }

        public ProcessAccessRights ProcessAccessRights { get { return (ProcessAccessRights)AccessMask; } }
    }

    [Flags]
    public enum ProcessAccessRights
    {
        STANDARD_RIGHTS_REQUIRED = (0x000F0000),
        DELETE = (0x00010000), // Required to delete the object. 
        READ_CONTROL = (0x00020000), // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
        WRITE_DAC = (0x00040000), // Required to modify the DACL in the security descriptor for the object. 
        WRITE_OWNER = (0x00080000), // Required to change the owner in the security descriptor for the object. 

        PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, //All possible access rights for a process object.
        PROCESS_CREATE_PROCESS = (0x0080), // Required to create a process. 
        PROCESS_CREATE_THREAD = (0x0002), // Required to create a thread. 
        PROCESS_DUP_HANDLE = (0x0040), // Required to duplicate a handle using DuplicateHandle. 
        PROCESS_QUERY_INFORMATION = (0x0400), // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
        PROCESS_QUERY_LIMITED_INFORMATION = (0x1000),
        PROCESS_SET_INFORMATION = (0x0200), // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
        PROCESS_SET_QUOTA = (0x0100), // Required to set memory limits using SetProcessWorkingSetSize. 
        PROCESS_SUSPEND_RESUME = (0x0800), // Required to suspend or resume a process. 
        PROCESS_TERMINATE = (0x0001), // Required to terminate a process using TerminateProcess. 
        PROCESS_VM_OPERATION = (0x0008), // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
        PROCESS_VM_READ = (0x0010), // Required to read memory in a process using ReadProcessMemory. 
        PROCESS_VM_WRITE = (0x0020), // Required to write to memory in a process using WriteProcessMemory. 
        SYNCHRONIZE = (0x00100000), // Required to wait for the process to terminate using the wait functions. 
    }

    public static class NativeMethods
    {
        private const Int32 ANYSIZE_ARRAY        = 0x00000001;
        public const int SE_PRIVILEGE_ENABLED    = 0x00000002;

        //Use these for DesiredAccess
        public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
        public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
        public const UInt32 TOKEN_DUPLICATE = 0x0002;
        public const UInt32 TOKEN_IMPERSONATE = 0x0004;
        public const UInt32 TOKEN_QUERY = 0x0008;
        public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
        public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
        public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
        public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
        public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
        public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
        public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
            TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
            TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
            TOKEN_ADJUST_SESSIONID);

       public enum SecurityEntity
       {
          SE_CREATE_TOKEN_NAME,
          SE_ASSIGNPRIMARYTOKEN_NAME,
          SE_LOCK_MEMORY_NAME,
          SE_INCREASE_QUOTA_NAME,
          SE_UNSOLICITED_INPUT_NAME,
          SE_MACHINE_ACCOUNT_NAME,
          SE_TCB_NAME,
          SE_SECURITY_NAME,
          SE_TAKE_OWNERSHIP_NAME,
          SE_LOAD_DRIVER_NAME,
          SE_SYSTEM_PROFILE_NAME,
          SE_SYSTEMTIME_NAME,
          SE_PROF_SINGLE_PROCESS_NAME,
          SE_INC_BASE_PRIORITY_NAME,
          SE_CREATE_PAGEFILE_NAME,
          SE_CREATE_PERMANENT_NAME,
          SE_BACKUP_NAME,
          SE_RESTORE_NAME,
          SE_SHUTDOWN_NAME,
          SE_DEBUG_NAME,
          SE_AUDIT_NAME,
          SE_SYSTEM_ENVIRONMENT_NAME,
          SE_CHANGE_NOTIFY_NAME,
          SE_REMOTE_SHUTDOWN_NAME,
          SE_UNDOCK_NAME,
          SE_SYNC_AGENT_NAME,
          SE_ENABLE_DELEGATION_NAME,
          SE_MANAGE_VOLUME_NAME,
          SE_IMPERSONATE_NAME,
          SE_CREATE_GLOBAL_NAME,
          SE_CREATE_SYMBOLIC_LINK_NAME,
          SE_INC_WORKING_SET_NAME,
          SE_RELABEL_NAME,
          SE_TIME_ZONE_NAME,
          SE_TRUSTED_CREDMAN_ACCESS_NAME
       }

      public static string GetSecurityEntityValue(SecurityEntity securityEntity)
      {
         switch (securityEntity)
         {
            case SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME:
               return "SeAssignPrimaryTokenPrivilege";
            case SecurityEntity.SE_AUDIT_NAME:
               return "SeAuditPrivilege";
            case SecurityEntity.SE_BACKUP_NAME:
               return "SeBackupPrivilege";
            case SecurityEntity.SE_CHANGE_NOTIFY_NAME:
               return "SeChangeNotifyPrivilege";
            case SecurityEntity.SE_CREATE_GLOBAL_NAME:
               return "SeCreateGlobalPrivilege";
            case SecurityEntity.SE_CREATE_PAGEFILE_NAME:
               return "SeCreatePagefilePrivilege";
            case SecurityEntity.SE_CREATE_PERMANENT_NAME:
               return "SeCreatePermanentPrivilege";
            case SecurityEntity.SE_CREATE_SYMBOLIC_LINK_NAME:
               return "SeCreateSymbolicLinkPrivilege";
            case SecurityEntity.SE_CREATE_TOKEN_NAME:
               return "SeCreateTokenPrivilege";
            case SecurityEntity.SE_DEBUG_NAME:
               return "SeDebugPrivilege";
            case SecurityEntity.SE_ENABLE_DELEGATION_NAME:
               return "SeEnableDelegationPrivilege";
            case SecurityEntity.SE_IMPERSONATE_NAME:
               return "SeImpersonatePrivilege";
            case SecurityEntity.SE_INC_BASE_PRIORITY_NAME:
               return "SeIncreaseBasePriorityPrivilege";
            case SecurityEntity.SE_INCREASE_QUOTA_NAME:
               return "SeIncreaseQuotaPrivilege";
            case SecurityEntity.SE_INC_WORKING_SET_NAME:
               return "SeIncreaseWorkingSetPrivilege";
            case SecurityEntity.SE_LOAD_DRIVER_NAME:
               return "SeLoadDriverPrivilege";
            case SecurityEntity.SE_LOCK_MEMORY_NAME:
               return "SeLockMemoryPrivilege";
            case SecurityEntity.SE_MACHINE_ACCOUNT_NAME:
               return "SeMachineAccountPrivilege";
            case SecurityEntity.SE_MANAGE_VOLUME_NAME:
               return "SeManageVolumePrivilege";
            case SecurityEntity.SE_PROF_SINGLE_PROCESS_NAME:
               return "SeProfileSingleProcessPrivilege";
            case SecurityEntity.SE_RELABEL_NAME:
               return "SeRelabelPrivilege";
            case SecurityEntity.SE_REMOTE_SHUTDOWN_NAME:
               return "SeRemoteShutdownPrivilege";
            case SecurityEntity.SE_RESTORE_NAME:
               return "SeRestorePrivilege";
            case SecurityEntity.SE_SECURITY_NAME:
               return "SeSecurityPrivilege";
            case SecurityEntity.SE_SHUTDOWN_NAME:
               return "SeShutdownPrivilege";
            case SecurityEntity.SE_SYNC_AGENT_NAME:
               return "SeSyncAgentPrivilege";
            case SecurityEntity.SE_SYSTEM_ENVIRONMENT_NAME:
               return "SeSystemEnvironmentPrivilege";
            case SecurityEntity.SE_SYSTEM_PROFILE_NAME:
               return "SeSystemProfilePrivilege";
            case SecurityEntity.SE_SYSTEMTIME_NAME:
               return "SeSystemtimePrivilege";
            case SecurityEntity.SE_TAKE_OWNERSHIP_NAME:
               return "SeTakeOwnershipPrivilege";
            case SecurityEntity.SE_TCB_NAME:
               return "SeTcbPrivilege";
            case SecurityEntity.SE_TIME_ZONE_NAME:
               return "SeTimeZonePrivilege";
            case SecurityEntity.SE_TRUSTED_CREDMAN_ACCESS_NAME:
               return "SeTrustedCredManAccessPrivilege";
            case SecurityEntity.SE_UNDOCK_NAME:
               return "SeUndockPrivilege";
            default:
               throw new ArgumentOutOfRangeException(typeof(SecurityEntity).Name);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID {
           public UInt32 LowPart;
           public Int32 HighPart;
        }

        public struct TOKEN_PRIVILEGES {
           public int PrivilegeCount;
           [MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
           public LUID_AND_ATTRIBUTES [] Privileges;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct LUID_AND_ATTRIBUTES {
           public LUID Luid;
           public UInt32 Attributes;
        }

        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }

        [DllImport("kernel32.dll", SetLastError=true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CloseHandle(IntPtr hObject);

        // Use this signature if you want the previous state information returned
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 BufferLengthInBytes,
           ref TOKEN_PRIVILEGES PreviousState,
           out UInt32 ReturnLengthInBytes);

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
           [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
           ref TOKEN_PRIVILEGES NewState,
           UInt32 Zero,
           IntPtr Null1,
           IntPtr Null2);

        [DllImport("advapi32.dll")]
        public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName,
           ref LUID lpLuid);

        [DllImport("advapi32.dll", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool OpenProcessToken(IntPtr ProcessHandle,
            UInt32 DesiredAccess, out IntPtr TokenHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr OpenProcess(
            ProcessAccessFlags processAccess,
            bool bInheritHandle,
            int processId
        );

        public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags)
        {
            return OpenProcess(flags, false, proc.Id);
        }
    }
}
'@

Add-Type -TypeDefinition $code -IgnoreWarnings 

Function Enable-DebugPrivilege
{
    $hToken = New-Object System.IntPtr
    $luidSEDebugNameValue = New-Object CSharp.NativeMethods+LUID
    $tkpPrivileges = New-Object CSharp.NativeMethods+TOKEN_PRIVILEGES

    if (![CSharp.NativeMethods]::OpenProcessToken([System.Diagnostics.Process]::GetCurrentProcess().Handle, [CSharp.NativeMethods]::TOKEN_ADJUST_PRIVILEGES -bor [CSharp.NativeMethods]::TOKEN_QUERY, [ref]$hToken))
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "OpenProcessToken Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
    }
    else
    {
        "OpenProcessToken SUCCESS!"
    }

    if (![CSharp.NativeMethods]::LookupPrivilegeValue($null, [CSharp.NativeMethods]::GetSecurityEntityValue([CSharp.NativeMethods+SecurityEntity]::SE_DEBUG_NAME), [ref]$luidSEDebugNameValue))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "LookupPrivilegeValue Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return
    }
    else
    {
       "LookupPrivilegeValue() SUCCESS!"
    }


    $tkpPrivileges.PrivilegeCount = 1

    $luid = New-Object CSharp.NativeMethods+LUID_AND_ATTRIBUTES
    $luid.Luid = $luidSEDebugNameValue
    $luid.Attributes =  [CSharp.NativeMEthods]::SE_PRIVILEGE_ENABLED
    $tkpPrivileges.Privileges = @($luid)

    if (![CSharp.NativeMethods]::AdjustTokenPrivileges($hToken,$false,[ref]$tkpPrivileges, 0,[IntPtr]::Zero,[IntPtr]::Zero))
    {
      $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "AdjustTokenPriviles Failed ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
        return
        [CSharp.NativeMethods]::CloseHandle($hToken)
        return

    }
    else
    {
        "SeDebugPrivilege is now available!";
    }

    [CSharp.NativeMethods]::CloseHandle($hToken);


}

Function Open-Process($Process)
{
    $hProcess = [CSharp.NativeMethods]::OpenProcess($Process,[CSharp.NativeMethods+ProcessAccessFlags]::QueryInformation)

    if ($hProcess -eq 0 )
    {
        $win32exception = New-Object System.ComponentModel.Win32Exception([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
        "ERROR #$($win32exception.NativeErrorCode) HRESULT: 0x{0:X8} Message: $($win32exception.Message) " -f $($win32exception.HResult)
    }
    else
    {
        "Handle to process $hProcess opened ok!"
    }
}


Function Add-ProcessQueryInfoPermission($Process,$IdentityReference)
{
    $procSec = New-Object CSharp.ProcessSecurity($Process.SafeHandle)
    $accessRule = New-Object CSharp.ProcessAccessRule($IdentityReference, [CSharp.ProcessAccessRights]::PROCESS_QUERY_INFORMATION, $true, [System.Security.AccessControl.InheritanceFlags]::None, [System.Security.AccessControl.PropagationFlags]::None, [System.Security.AccessControl.AccessControlType]::Allow)
    $procSec.AddAccessRule($accessRule)
    $procSec.SaveChanges($Process.SafeHandle)
}


# change to hold your target process
$targetProcess = (Get-process | Where-Object { $_.Id -eq 3700  })

Add-Type -AssemblyName System.DirectoryServices.AccountManagement

# change for appropriate account to add
$ctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)  
$usr = [ System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($ctx,[System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName,"test")  

# add process query information (This may need to be run elevated / run from different acct then open-process line depending on target process)
Add-ProcessQueryInfoPermission -Process $targetProcess -IdentityReference $usr.Sid

# test open process
Open-Process -Process  $targetProcess