【windows 访问控制】十一、C# 实操 对象 System.Security.AccessControl 命名空间
AccessControl 命名空间 结构图
解说:
DirectorySecurity=目录ACL
FileSecurity=文件ACL
FileSystemAuditRule=目录和文件中SACL中的ACE
FileSystemAccessRule=目录和文件中DACL中的ACE
GetAccessControl=ACL(AccessControlList)The security descriptors of all the access control sections of the directory.
DirectorySecurity类和FileSecurity类是对基础Microsoft Windows文件安全系统的抽象。----注:本文部分内容改编自《.NET安全揭秘》
FileSystemAccessRule和FileSystemAuditRule 类是对组成DACL和SACL的访问控制项(ACE)的抽象----注:本文部分内容改编自《.NET安全揭秘》
案例1、window平台的ACL、 ACE操作实例
給文件夹添加访问控制项(ACE:), 要以管理员的方式运行vs2022,这样才能正确的添加sACE,特权。
新建一个ACL
第一方式,新建一个ACL,然后赋值给文件,这种方式会覆盖原来ACL的列表。并且对文件的sACE,dACE经行增删改
using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal; //把桌面设置未当前目录
Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop ));
//用n #region 添加ACE //新建ACE ,ACE FileSystemAuditRule SACE = new("TestAccount", FileSystemRights.FullControl, AuditFlags.Success);
FileSystemAuditRule SACE2 = new(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read, AuditFlags.Failure);
FileSystemAuditRule SACE3 = new("TestAccount", FileSystemRights.Modify, AuditFlags.Failure); FileSystemAccessRule DACE = new("TestAccount" ,FileSystemRights.FullControl,AccessControlType.Deny);
FileSystemAccessRule DACE2 = new(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read|FileSystemRights.Write,InheritanceFlags.None,PropagationFlags.None, AccessControlType.Allow);
FileSystemAccessRule DACE3 = new("TestAccount", FileSystemRights.Read , AccessControlType.Allow); //关联桌面的已经存在的CSD文件夹
DirectoryInfo dir = new ("CSD"); //获取文件的ACL
DirectorySecurity ACL=dir.GetAccessControl(); //将sACEs、dACLs加入ACL
ACL.AddAccessRule(DACE);
ACL.AddAccessRule(DACE2);
ACL.AddAccessRule(DACE3); ACL.AddAuditRule(SACE);
ACL.AddAuditRule(SACE2);
ACL.AddAuditRule(SACE3); dir.SetAccessControl(ACL); //获取文件夹SACL权限
DirectorySecurity AClwithAudit = dir.GetAccessControl(AccessControlSections.Audit); foreach (FileSystemAuditRule item in AClwithAudit.GetAuditRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(item.AuditFlags); }
Console.Read(); //获取文件夹DACL权限
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAccessRule item in AClwithAccess.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(item.AccessControlType );
}
#endregion //removeDACE("TestAccount","CSD",AccessControlType.Deny);
RemoveAllDACE("TestAccount","CSD");
/// <summary>
/// 删除指定用户的文件夹dACE
/// </summary>
static void RemovedDACE(string username,string fielname, AccessControlType Type)
{ DirectoryInfo dir = new (fielname);
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAccessRule dace in AClwithAccess.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(dace.IdentityReference.Value); if (dace.AccessControlType == Type && dace.IdentityReference.Value == @$"{Environment.UserDomainName}\{username}")
{ AClwithAccess.ModifyAccessRule(AccessControlModification.Remove, dace, out bool ivalue);
if (ivalue == true)
{ dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功"); } }
} } /// <summary>
/// 删除指定用户在指定文件夹的所有D-ACE权限
/// </summary>
static void RemoveAllDACE(string username,string filename)
{ DirectoryInfo dir = new (filename);
DirectorySecurity AClwithAccess = dir.GetAccessControl(); AClwithAccess.PurgeAccessRules(new NTAccount(@$"{Environment.UserDomainName}\{username}"));
dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功");
} /// <summary>
/// 删除指定用户的文件夹sACE
/// </summary> static void RemovedSACE(string username, string fielname, AuditFlags Type)
{ DirectoryInfo dir = new(fielname);
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAuditRule sace in AClwithAccess.GetAuditRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(sace.IdentityReference.Value); if (sace.AuditFlags == Type && sace.IdentityReference.Value == @$"{Environment.UserDomainName}\{username}")
{ AClwithAccess.ModifyAuditRule(AccessControlModification.Remove, sace, out bool ivalue);
if (ivalue == true)
{ dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功"); } }
} } /// <summary>
/// 删除指定用户在指定文件夹的所有S-ACE权限
/// </summary>
static void RemovedALLSACE(string username, string filename)
{ DirectoryInfo dir = new(filename);
DirectorySecurity AClwithAudit = dir.GetAccessControl(); AClwithAudit.PurgeAuditRules(new NTAccount(@$"{Environment.UserDomainName}\{username}"));
dir.SetAccessControl(AClwithAudit);
Console.WriteLine("移除成功");
}
下面详细的介绍一下比较重要的几个方法,第一个:
一、 public FileSystemAccessRule( string identity, FileSystemRights fileSystemRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
定义访问规则,参数如下:

identity
Type: System.String
The name of a user account. (账户名)
fileSystemRights
Type: System.Security.AccessControl.FileSystemRights
One of the FileSystemRights values that specifies the type of operation associated with the access rule. (与访问规则相关联的操作类型)
inheritanceFlags
Type: System.Security.AccessControl.InheritanceFlags
One of the InheritanceFlags values that specifies how access masks are propagated to child objects.
(CSDN上解释的是“该值指示如何将访问掩码传播到子对象”,我的理解是 该值规定是将继承规则作用在文件夹上还是文件上)
propagationFlags
Type: System.Security.AccessControl.PropagationFlags
One of the PropagationFlags values that specifies how Access Control Entries (ACEs) are propagated to child objects.
(CSDN上解释的是“该值指定如何将访问控制项 (Ace) 传播到子对象”,propagationFlags能起作用的前提是inheritanceFlags不为None)
type
Type: System.Security.AccessControl.AccessControlType
One of the AccessControlType values that specifies whether to allow or deny the operation.(允许还是拒绝)

第一个参数是账户名,第二个是操作类型,操作类型对应的有以下:

("AppendData", "附加数据");
("ChangePermissions", "更改权限");
("CreateDirectories", "创建文件夹/附加数据");
("CreateFiles", "创建文件/写入数据");
("Delete", "删除");
("DeleteSubdirectoriesAndFiles", "删除子文件夹及文件");
("ExecuteFile", "执行文件");
("FullControl", "完全控制");
("ListDirectory", "列出文件夹/读取数据");
("Modify", "修改");
("Read", "读取");
("ReadAndExecute", "读取和执行");
("ReadAttributes", "读取属性");
("ReadData", "读取数据");
("ReadExtendedAttributes", "读取扩展属性");
("ReadPermissions", "读取权限");
("Synchronize", "同步");
("TakeOwnership", "更改文件(夹)所有者");
("Traverse", "执行程序");
("Write", "写入");
("WriteAttributes", "写入属性");
("WriteData", "写入数据");
("WriteExtendedAttributes", "写入扩展属性");

第三四个参数比较难懂,并且他两个应该组合起来应用。一个是inheritanceFlags(ContainerInherit,None,ObjectInherit),另一个是propagationFlags(InheritOnly,None,NoPropagateInherit),这两枚举都有三个值,都具有允许其成员值的按位组合的 FlagsAttribute 特性,propagationFlags能起作用的前提是inheritanceFlags不为None。
下面是我总结的常用的枚举组合:
对应到windows界面操作上后,如下图所示:
第五个参数规定该访问规则的类型是 允许还是拒绝。
现有的ACL上添加ACE
using System.Security.AccessControl;
using System.Security.Principal;
//把桌面设置未当前目录
Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop )); //新建ACE ,ACE的拥有者设置成当前 操作系统用
FileSystemAuditRule SACE=new FileSystemAuditRule(WindowsIdentity.GetCurrent().Name,FileSystemRights.FullControl,AuditFlags.Success);
FileSystemAccessRule DACE = new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name,FileSystemRights.FullControl,AccessControlType.Deny);
FileSystemAccessRule DACE2 = new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read|FileSystemRights.Write,InheritanceFlags.None,PropagationFlags.None, AccessControlType.Allow); //新建文件,并且ACL把文件添加到目录上。会和原来的ACL列表合并
DirectoryInfo dir = new DirectoryInfo("CSD");
DirectorySecurity sd=dir.GetAccessControl();
sd.AddAccessRule(DACE);
sd.AddAccessRule(DACE2); dir.SetAccessControl(sd);
遍历ACL中的ACE
遍历ACL中的ACE AuthorizationRuleCollection rules = fileAcl.GetAccessRules(true, true, typeof(NTAccount));
// AuthorizationRule Rule = rules[0];
foreach (FileSystemAccessRule rule in rules)
{
if(rule.IdentityReference.Value.CompareTo("Users")==0)
{
fileAcl.RemoveAccessRule(rule);
}
}
文件夹权限继承控制
DirectorySecurity ss = di.GetAccessControl(); ss.SetAccessRuleProtection(true,true);//这个是保护acl,防止继承,true为启用保护,这样就不会继承父类了,第二项是否保留已经继承的。
获取ACE的掩码
using System.Security.AccessControl;
using System.IO;
using System.Security.Principal;
using System.Reflection; Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
DirectoryInfo di = new("CSD"); DirectorySecurity ss = di.GetAccessControl(); Console.WriteLine(ss.GetGroup(typeof(NTAccount)));
foreach (FileSystemAccessRule ace in ss.GetAccessRules(true,true,typeof(NTAccount)))
{
Type getMask = typeof(FileSystemAccessRule);
PropertyInfo propertyInfo = getMask.GetProperty("AccessMask", BindingFlags.Instance|BindingFlags.NonPublic | BindingFlags.GetProperty);
int Mask =int.Parse( propertyInfo.GetValue(ace, null).ToString()); Console.WriteLine($"AccessControltype:{ace.FileSystemRights} AcessMask:{ Convert.ToString(Mask, 2).PadLeft(32,'0') }"); }
案例2、通用平台的ACL ACE操作实例
这些方式是操作SD类型的通用方式(与底层的Windows资源的类型无关),.NET提供了如下类型:
- System.Security.AccessControl.GenericSecurityDescriptor
- System.Security.AccessControl.CommonSecurityDescriptor
- System.Security.AccessControl.RawSecurityDescriptor
- System.Security.AccessControl.GenericAcl
- System.Security.AccessControl.CommonAcl
- System.Security.AccessControl.DescretionaryAcl
- System.Security.AccessControl.SystemAcl
- System.Security.AccessControl.RawAcl
- System.Security.AccessControl.GenericAce
- System.Security.AccessControl.CustomAce
- System.Security.AccessControl.KnownAce
- System.Security.AccessControl.CompoundAce
- System.Security.AccessControl.QualifiedAce
- System.Security.AccessControl.CommonAce
- System.Security.AccessControl.ObjectAce
示例:创建一个SD,向其DACL中添加ACE并将其转化为一个代表Windows资源的特殊SD(此处为互斥体)。
using System;
using System.Security.AccessControl;
using System.Security.Principal;
class Program {
static void Main() {
//创建一个新的SD
CommonSecurityDescriptor csd = new CommonSecurityDescriptor(false, false, string.Empty);
DiscretionaryAcl dacl = csd.DiscretionaryAcl;
//向DACL中添加ACE
dacl.AddAccess(
AccessControlType.Allow, // 枚举Allow、Deny.
WindowsIdentity.GetCurrent().Owner,
(int)MutexRights.TakeOwnership | (int)MutexRights.Synchronize,
InheritanceFlags.None, // 禁用ACE继承
PropagationFlags.None); string sSDDL = csd.GetSddlForm( AccessControlSections.Owner ); MutexSecurity mutexSec = new MutexSecurity();
mutexSec.SetSecurityDescriptorSddlForm( sSDDL );
AuthorizationRuleCollection aces = mutexSec.GetAccessRules(true, true, typeof(NTAccount));
foreach ( AuthorizationRule ace in aces ) {
if (ace is MutexAccessRule) {
MutexAccessRule mutexAce = (MutexAccessRule)ace;
Console.WriteLine( "-->SID : " + mutexAce.IdentityReference.Value );
Console.WriteLine( "访问权限类型:" + mutexAce.AccessControlType.ToString());
if (0xffffffff == (uint) mutexAce.MutexRights)
Console.WriteLine( "拥有所有权限" );
else
Console.WriteLine( "权限: " + mutexAce.MutexRights.ToString());
}
}
}
}
【windows 访问控制】十一、C# 实操 对象 System.Security.AccessControl 命名空间的更多相关文章
- 【windows 访问控制】十二、C#实操 主体 System.Security.Principal 案例
案例1.主体(包含用户和组)和标识(用户名)的使用. PrincipalPolicy枚举:主体类型 分为window主体.未认证的主体和未分配主体GenericPrincipal.GenericIde ...
- net中System.Security.Cryptography 命名空间 下的加密算法
.net中System.Security.Cryptography命名空间 在.NETFramework出现之前,如果我们需要进行加密的话,我们只有各种较底层的技术可以选择,如 Microsoft C ...
- 【windows 访问控制】六、安全标识符(SID Security Identifiers)
安全标识符(SID Security Identifiers) SID是用来标识安全主体.就是给安全主体一个唯一的ID.用户层面通过用户账户名识别,程序和资源之间通过SID识别. 什么是安全标识符? ...
- 【windows 访问控制】二、安全描述符(Security Descriptors,SD)
安全描述符(Security Descriptors,SD) 定义 安全描述符是与安全对象的安全信息,它含有这个对象所有者的SID,以及一个访问控制列表(ACL,Access Control List ...
- .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数
.Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...
- 高并发分布式系统中生成全局唯一(订单号)Id js返回上一页并刷新、返回上一页、自动刷新页面 父页面操作嵌套iframe子页面的HTML标签元素 .net判断System.Data.DataRow中是否包含某列 .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数
高并发分布式系统中生成全局唯一(订单号)Id 1.GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么通过组合的方式,保留GUID的10个字节,用另6个字节表示GUID生成的时间(D ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- 72 个网络应用安全实操要点,全方位保护 Web 应用的安全
原文地址:Web Application Security Checklist 原文作者:Teo Selenius(已授权) 译者 & 校正:HelloGitHub-小熊熊 & 卤蛋 ...
- CS内网横向移动 模拟渗透实操 超详细
@Webkio 前言: 最近在跟朋友搞一些项目玩,所以最近没怎么更新内容接下来我将在虚拟中模拟内网多层靶场,进行内网渗透实验,超详细,适合小白.本文仅供网安学习,不可利用于未授权渗透工作中,否则后果自 ...
随机推荐
- unity3d百度语音合成mp3流转换byte[]失败
using (Stream stream = response.GetResponseStream()) { buffer2 = new byte[stream ...
- Docker环境安装,基本命令集合
一.docker安装 1).卸载旧的安装包 centos7默认安装的docker版本是1.13.1,卸载它,安装新的版本. root用户下,一次把这坨命令复制进去 yum remove docker ...
- java内部类概述和修饰符
1 package face_09; 2 /* 3 * 内部类访问特点: 4 * 1,内部类可以直接访问外部类的成员. 5 * 2,外部类要访问内部类,必须建立内部类的对象. 6 * 7 * 一把用于 ...
- Python 使用 Windows10 桌面通知
前言 Win10 没有提供简单命令行方式来触发桌面通知,所以使用 Python 来写通知脚本. 一番搜索,找到 win10toast .但这开源仓库已无人维护,通过 github fork 的关系图, ...
- Device or resource busy
格式化磁盘显示忙碌,如何解决呢? [root@jp33e503-11-8 ~]# mkfs.xfs /dev/sdc mkfs.xfs: cannot open /dev/sdc: Device or ...
- Java中的wait方法 简单介绍。
一 wait方法怎么用? package com.aaa.threaddemo; /* * 多线程中的wait方法? public final void wait() throws Interrupt ...
- 如何在pyqt中使用 QGraphicsView 实现图片查看器
前言 在 PyQt 中可以使用很多方式实现照片查看器,最朴素的做法就是重写 QWidget 的 paintEvent().mouseMoveEvent 等事件,但是如果要在图像上多添加一些形状,那么在 ...
- 计算机电子书 2019 BiliDrive 备份
下载方式 pip install BiliDriveEx bdex download <link> 链接 文档 链接 传智播客轻松搞定系列 C.C++.Linux.设计模式.7z (33. ...
- 有向图子图 DAG 数量
考虑 \(\tt DP\),朴素的想法是令 \(f_S\) 表示 \(S\) 这个导出子图将边定向集合构成 \(\tt DAG\) 的方案数. 转移可以考虑剥去所有入度为 \(0\) 的点,那么我们就 ...
- Sleep_Yield_Join
名称解释 Sleep:意思就是睡眠,当前线程暂停一段时间让给别的线程去运行;Sleep是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活. Yield:就是当前线程正在执行的时候停止下来进入 ...