【问题标题】:Is there a way to modify a process DACL in C#有没有办法在 C# 中修改进程 DACL
【发布时间】:2023-03-17 01:00:02
【问题描述】:

我有更改进程 DACL 的旧版 C++ 代码,并且正在尝试使用 .NET 3.5 中的托管代码类。我在网上找到了代码,其中有人创建了一个 SetAclOnServices 类,该类扩展了服务的 NativeObjectSecurity 类。我认为我可以实现这一点,只需将 ResourceType.Service 更改为 ResourceType.KernelObject 但是当我调用 GetAccessControl 时它失败并出现 File Not Found 错误。

【问题讨论】:

    标签: c# security dacl


    【解决方案1】:

    圣诞快乐。

    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. 
    }
    

    【讨论】:

    • 谢谢你,也祝你圣诞快乐!我已经实现了这一点,添加了一个 SafeHandle 类,并且可以修改我的进程安全描述符,但它似乎没有做我想要它做的事情。我试图否认程序终止权。我在添加拒绝规则之前和之后获得了安全描述符,它看起来应该可以工作,但我仍然可以终止程序。是否需要对进程安全描述符设置访问控制?
    • 这可能与您是所有者这一事实有关 - 可能有一些未记录的特殊情况围绕进程 ACL 的自动权限扩展。拒绝 ACE应该始终优先于允许。也许尝试更改所有者,看看是否有任何效果。
    • 抱歉,是的,您需要添加对受保护的 Persist 方法的调用才能将 ACL 实际写入进程。我对 NativeObjectSecurity 的研究不够仔细。我添加了一个“SaveChanges”方法,将进程句柄传递给 Persist,并且成功了。
    • 感谢您的努力,非常感谢您的帮助。不幸的是,我仍然无法让它工作,因为我可以通过 TaskManager 终止这个过程。这是为 PROCESS_TERMINATE D 设置拒绝访问权限之前的 SDDL:(A;;0x1f0fff;;;SY)(A;;0x1f0fff;;;S-1-5-213...-我的 ID 的其余部分) 这是调用 AddAccessRule 和 SaveChanges 后的 SDDL D:(D;;CC;;;S-1-5-21-213S-1-5-213...我的 ID 的其余部分)(A;;0x1f0fff;;; SY)(A;;0x1f0fff;;;S-1-5-21-213S-1-5-213...我的 ID 的其余部分)
    • 看起来 DACL 已正确修改。你说你有一个可以工作的非托管版本的代码——它会产生相同的 ACL 吗?我无法阻止自己在我自己的机器上终止一个进程作为它的所有者,但是 ACL 代码工作正常(例如,我可以添加其他人终止的权利,等等,这很有效)。我仍然认为这是所有权问题。
    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    相关资源
    最近更新 更多