如何在 C# 中编辑 DACL?



SetFileSecurity函数的模拟吗?

我需要从 Python 重写一些测试,但我被困在这一部分。在Python中,我可以自由地编辑带有pywin32的DACL(具有C++实现的模块,以与Windows API一起使用(。 我可以用win32security编辑任何 ACE.

将所有者更改为Everyone?好。

win32security.SetNamedSecurityInfo("somefile.txt", win32security.SE_FILE_OBJECT,
win32security.OWNER_SECURITY_INFORMATION,
win32security.ConvertStringSidToSid("S-1-1-0"))
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)

删除继承的 ACE?容易。

sd = win32security.GetFileSecurity("", win32security.DACL_SECURITY_INFORMATION)
dacl = SECURITY_DESCRIPTOR.GetSecurityDescriptorDacl()
dacl.DeleteAce(0)
sd.SetSecurityDescriptorDacl(1, dacl, 0)  # may not be necessary
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)

以及所有没有特殊权限的人。

但是,如果我想在 C# 中做这样的事情。 我发现的一种方法是使用纯 SDDL 更改安全描述符,但如果在没有SeSecurityPrivilege权限的情况下调用SetSecurityDescriptorSddlFormSystem.Security.File.SetAccessControl()FileSecurity一起使用不起作用。此外,即使使用具有几乎所有权限的管理员令牌,如果我想以"错误"的方式更改某些内容(删除一些继承的 ACE(,则安全描述符不适用。如果我尝试做一些"非常错误"的事情,比如将所有者设置为Everyone,则会抛出异常。

var sddl_everyone_owner = @"O:S-1-1-0G:DUD:P";
var path = @"C:Userssomeusertest.txt";
FileSecurity fs_edit = new FileSecurity();
fs_edit.SetSecurityDescriptorSddlForm(sddl_everyone_owner);
File.SetAccessControl(path, fs_edit);

使用管理员令牌运行:

Unhandled Exception: System.InvalidOperationException: The security identifier is not 
allowed to be the owner of this object.
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle 
handle, 
AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, 
AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, 
AccessControlSections includeSections)
at System.Security.AccessControl.FileSystemSecurity.Persist(String fullPath)
at System.IO.File.SetAccessControl(String path, FileSecurity fileSecurity)
at rtest.Program.Main(String[] args) in C:somepathProgram.cs:line 52

经过 11 个小时的谷歌搜索,然后尝试编写一些 woking 代码,我有这个:

// changes SDDL of file:
using System;
using System.Runtime.InteropServices; // DllImport
public class SomeClass
{
[DllImport("Advapi32.dll", SetLastError = true)]
static extern void SetFileSecurity(string path, int type_of_sd, IntPtr sd);
[DllImport("Advapi32.dll", SetLastError = true)]
static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, out UIntPtr SecurityDescriptorSize);
private static void Main()
{
string path = @"C:Somepathtofile";
string sddl = "D:AI(A;ID;FA;;;S-1-1-0)"; // set only one ACE: inherited full access to Everyone
uint sd_revision = 1;  // the only revision of SECURITY_DESCRIPTOR
int DACL_SECURITY_INFORMATION = 4; // can be changed to change other properties, not DACL, relying on SECURITY_DESCRIPTOR_CONTROL parameters https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa379566%28v=vs.85%29.aspx
IntPtr sd_ptr = new IntPtr();
UIntPtr sd_size_ptr = new UIntPtr();
ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, sd_revision, out sd_ptr, out sd_size_ptr);
SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd_ptr);
}
}

此代码将函数从 Advapi32.dll直接导入到 C# 代码。 特别感谢 PInvoke.net! 将此代码添加到代码示例中。

您可以使用 powershell 命令获取文件或文件夹(symlink/junction(的 sddl:get-acl -path "c:\some\file_or_folder" | fl。

将输出管道传输到 fl 会将 ACL 转换为详细列表和 ssdl 形式。

对于文件夹"C:\Users\someuser\Application Data",sddl 为

O:SYG:SYD:AI(D;;抄送;;;WD((A;OICIID;FA;;;SY((A;OICIID;FA;;;文学士((A;OICIID;FA;;;S-1-5-21-2614944367-2017529714-1376493066-1XXX(

O:SY 所有者:NT 权限/系统 G:SY 集团:NT 权威/系统 D:AI(D;;抄送;;;WD((A;OICIID;FA;;;SY((A;OICIID;FA;;;文学士((A;OICIID;FA;;;S-1-5-21-2614944367-2017529714-1376493066-1XXX(

"D:"表示 DACL "AI"的意思是允许继承

括号中的每个子字符串都是一个访问控制项 (ACE(。每个 ACE 包含六个字段,这些字段由指示实际权限的分号分隔。第一个 ACE,(D;;抄送;;;WD(,对应于详细列表行:每个人都拒绝读取数据。也就是说,D 表示拒绝,CC 表示 ReadData,WD 表示每个人。请注意,Microsoft文档中显示的 CC 代码与 Sddl.h 中的 SDDL_CREATE_CHILD 和访问权限值ADS_RIGHT_DS_CREATE_CHILD同义。CC如何解释为"ReadData"尚不清楚。另请注意,指定"每个人"是使用代码 WD(可能派生自"世界"(完成的,而不是使用 SID 完成的。

对于那些希望深入研究的人,请参阅 https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format

https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language-for-conditional-aces-

https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings

祝你好运!

相关内容

  • 没有找到相关文章

最新更新