非规范 ACL 的 .NET RegistrySecurity API 处理:处理方法

发布于 2024-08-21 02:58:27 字数 1882 浏览 8 评论 0原文

我正在尝试向 RegistryKey 添加访问规则,如下所示:

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = registry.GetAccessControl();
    security.AddAccessRule( new RegistryAccessRule(
        new SecurityIdentifier( WellKnownSidType.BuiltinUsersSid, null ),
        RegistryRights.WriteKey,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.None,
        AccessControlType.Allow ) );
    registry.SetAccessControl( security );
}

但是,如果注册表被损坏,AddAccessRule 会抛出异常(Reflector 显示 GetAccessControl 调用确定它们预先不规范,并且当您尝试在 RegistrySecurity 实例处于该状态时进行写入时,您会触发故障保护):

System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.

运行 regedt32 (并且可能是 regedit),然后显示一个弹出窗口,显示 的权限;顺序不正确,这可能会导致某些条目无效您想现在取消它们吗? Y/N

我在这个问题上见过的最权威的文章是 http://www.codeproject.com/KB/system/accessctrl3.aspx,上面写着:

但是,控制标志是作为属性实现的(谈论不一致!)。您可以从 AreAccessRulesProtected / AreAuditRulesProtected 检索自动继承设置(回想一下,如果 ACL 受保护,它不会自动继承)。如果您阅读第 2 部分,您就会知道某些 Windows API 不支持继承,因此可能会损坏您计算机的继承设置。好消息是.NET 完全支持继承机制,并将正确保留继承设置。如果您打开的安全描述符以某种方式获得了无序的 ACL(可能来自某些流氓 Win32 应用程序),则在尝试编辑它时将抛出 InvalidOperationException。

一般来说,此类非规范 ACL 是由于使用[已停用] NewSID 工具< /a> 和人们写知识库文章是为了说“那就别再这样做了”

但重要的是,这并不总是原因,有时代码只需要工作即可。有什么好的、干净、安全的方法来处理这个问题?

我将提供两个答案,人们可​​以投票、挑漏洞、投票、评论和挑剔。

I'm attempting to add in an access rule to a RegistryKey like so:

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = registry.GetAccessControl();
    security.AddAccessRule( new RegistryAccessRule(
        new SecurityIdentifier( WellKnownSidType.BuiltinUsersSid, null ),
        RegistryRights.WriteKey,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.None,
        AccessControlType.Allow ) );
    registry.SetAccessControl( security );
}

However, if the registry is mangled, AddAccessRule throws an exception (Reflector shows that the GetAccessControl call determines that they are not canonical up-front and you trip the fail-safe when you attempt to do a write when the RegistrySecurity instance is in that state):

System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.

Running regedt32 (and probably regedit) then shows a popup saying the permissions on <key> are incorrectly ordered, which may cause some entries to be ineffective <paraphrasing>Do you want to unmangle them now? Y/N</paraprasing>

The most authorative piece I've seen on this issue is http://www.codeproject.com/KB/system/accessctrl3.aspx, which says:

However, the control flags are implemented as properties (talk about inconsistency!). You can retrieve the auto inheritance settings from the AreAccessRulesProtected / AreAuditRulesProtected (recall if an ACL is protected, it does not auto-inherit). If you read part 2, you'll know that some of the Windows APIs did not support inheritance, hence could corrupt the inheritance settings of your machine. The good news is that .NET fully supports the inheritance mechanism and will properly preserve the inheritance settings. If you opened a security descriptor that somehow got a disordered ACL (maybe from some rogue Win32 app), an InvalidOperationException will be thrown if you tried to edit it.

Generally, such non canonical ACLs results from use of the [since retired] NewSID tool, and people write KB articles to say "well stop doing that then".

But, critically, this isn't always the reason, and sometimes the code just needs to work. What's a good clean safe way of handling this?

I'll provide two answers and people can vote and pick holes, vote, comment and nitpick.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟若柳尘 2024-08-28 02:58:27

方法 1 是忽略继承的权限并盲目地写入您想要的内容:-

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

问题是,我不知道潜在的负面影响是什么。我很高兴所有需要访问权限的人都能从我的规则中获得它。然而,它与操作系统基础设施的其余部分配合得很好吗?

Approach 1 is to ignore the inherited permissions and blindly write in what you wanted to anyway:-

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

Problem is, I have no idea what the potential negative impacts are. I'm happy that all people that need access will gain it from my rule. However, does it play nice with the rest of the OS infrastructure?

初见你 2024-08-28 02:58:27

方法 2 是尝试第一种方法,仅在必要时才回退到肮脏的方法: -

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    if ( !security.AreAccessRulesCanonical )
    {
        Log.WriteWarning( "Registry permissions (likely ones inherited from parent) are inconsistent (RegistrySecurity.AreAccessRulesCanonical is false), so using alternate permissioning algorithm, Has NewSID or another tool mangled permissions? regedt32 can be used to analyze the issue." );
         // Ignore parent ACLs and just blindly stuff in this ACL (which will continue to be inherited)
         security = new RegistrySecurity();
     }

    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

除了 方法 1,这具有不可预测的行为,但至少它在一定程度上与原始方法是错误兼容的。

Approach 2 is to try the first way and fall-back to the dirty way only if necessary:-

using ( RegistryKey registry = OpenOrCreateMyKey() )
{
    RegistrySecurity security = new RegistrySecurity();
    if ( !security.AreAccessRulesCanonical )
    {
        Log.WriteWarning( "Registry permissions (likely ones inherited from parent) are inconsistent (RegistrySecurity.AreAccessRulesCanonical is false), so using alternate permissioning algorithm, Has NewSID or another tool mangled permissions? regedt32 can be used to analyze the issue." );
         // Ignore parent ACLs and just blindly stuff in this ACL (which will continue to be inherited)
         security = new RegistrySecurity();
     }

    security.AddAccessRule( new RegistryAccessRule( ... ));
    registry.SetAccessControl( security );
}

In addition to the weaknesses in Approach 1, this has unpredictable behavior, but at least it's bug-compatible with the original approach to a degree.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文