我正在尝试允许通过 winrs 远程访问服务器。在互联网上的某个地方,我发现这需要修改 winrm 服务的 RootSDDL,并且可以像这样获取它的值:
(Get-Item WSMAN:\localhost\Service\RootSDDL).Value
O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;S-1-5-21-3231263931-1371906242-1889625497-1141)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)
现在的问题是:当我知道我想要允许远程访问的用户的 SID 时,如何添加到这个 SDDL ACE,如
(A;;GA;;;S-1-5-21-The-rest-of-my-user-SID)
?
是否有任何代码片段可以将SDDL解析为ACE数组,修改它并解析回来?
使用 Trewor Sullivan 的答案中的信息,我设法使用以下代码添加此内容:
function add_sid_with_A_GA($sddl, $sid) {
$security_descriptor = New-Object -TypeName System.Security.AccessControl.CommonSecurityDescriptor -ArgumentList @($false, $false, $sddl);
$security_descriptor.DiscretionaryAcl.AddAccess("Allow", $sid, 268435456,"None","None")
# Convert the Security Descriptor back into SDDL
$security_descriptor.GetSddlForm([System.Security.AccessControl.AccessControlSections]::All);
}
268435456
是 GA 权限的 AccessMask。
此代码并不完全有效,但如果您修复
$ArgumentList
对象的构造函数参数(在 ObjectAce
变量中),您应该能够使其正常工作。我会尝试稍后再回到这个问题并完成它。
此示例展示了如何使用
RawSecurityDescriptor
类“导入”SDDL,然后调用 GetSDDLForm()
方法将其“导出”回 SDDL。我们需要弄清楚的是如何正确构造 ObjectAce
对象,并在将其导出到 SDDL 之前调用 InsertAce()
将其添加到 RawSecurityDescriptor
对象。
# Create a Security Descriptor from SDDL
$SD = New-Object -TypeName System.Security.AccessControl.RawSecurityDescriptor -ArgumentList 'O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;S-1-5-21-3231263931-1371906242-1889625497-1141)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)';
# Add a new Access Control Entry
# ObjectACE constructor docs: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.objectace.objectace(v=vs.110).aspx
$ArgumentList = @(
[System.Security.AccessControl.AceFlags]::None,
[System.Security.AccessControl.AceQualifier]::AccessAllowed,
1,
[System.Security.AccessControl.ObjectAceFlags]::None,
)
$ObjectACE = New-Object -TypeName System.Security.AccessControl.ObjectAce -ArgumentList $ArgumentList;
$SD.DiscretionaryAcl.InsertAce($ObjectACE);
# Convert the Security Descriptor back into SDDL
$SD.GetSddlForm([System.Security.AccessControl.AccessControlSections]::All);
要使用
SDDL
(安全描述符定义语言),您首先需要了解其结构。
格式是一个以 null 结尾的字符串,带有标记来指示安全描述符的四个主要组成部分中的每一个:
- 主人(O:),
- 初级组(G:),
- DACL(D:),
- 和 SACL (S:)
DACL(自主访问控制列表)
DACL 是访问控制条目 (ACE) 的列表,它规定谁可以访问特定对象以及他们可以使用该对象执行哪些操作。
“自由裁量”一词意味着对象的所有者可以控制授予访问权限和定义访问级别。
SACL(系统访问控制列表)
SACL 是一组访问控制条目 (ACE),它指定要对尝试访问对象的用户或系统进程进行审核的安全事件。这些对象可以包括文件、注册表项或其他系统资源。
SDDL 的结构
这是安全描述符字符串的简单示例
SDDL
"O:LAG:BUD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-5-32-545)"
分配权限时,您使用的是
DACL
的 SDDL
部分。SDDL
中的每个条目称为 ACE
(访问控制条目)。
这个特定示例没有 SACL(缺少 S:)。 使用常量
LA
(本地管理员)和 BU
(内置用户)代替 O: 和 G: 的 SID:s。
ConvertFrom-SddlString "O:AOG:AOD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-5-32-545)"
Owner : EXAMPLEHOST\Administrator
Group : BUILTIN\Users
DiscretionaryAcl : {BUILTIN\Users: AccessAllowed (ChangePermissions, CreateDirectories,
ExecuteKey, GenericAll, GenericExecute, GenericWrite, ListDirectory,
ReadExtendedAttributes, ReadPermissions, TakeOwnership, Traverse,
WriteData, WriteExtendedAttributes, WriteKey)}
SystemAcl : {}
ACE-string
中的每个DACL
都遵循的结构
ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)
构建 ACE
因此,我们想在
ACE-strings
中添加额外的 DACL
(或更改、删除或替换)。SDDL
来完成。但我不知道如何以这种方式将 SDDL
集成回 .Net 对象中。
将 ACE 添加到 DACL 的相关字段是:
这些字段的顺序很重要。
用于向特定用户授予读取访问权限的示例 ACE 字符串:
(A;;GA;;;S-1-5-32-545)
现在,当基础知识设置完毕后,上面的答案就可以使用一些 .Net 魔法进行输入了。
RawDescriptor
已可从 ConvertFrom-SddlString
cmdlet 获得。
$sddl = ConvertFrom-SddlString "O:LAG:BUD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-5-32-545)"
$sddl.RawDescriptor
IsContainer : False
IsDS : False
ControlFlags : DiscretionaryAclPresent, SelfRelative
Owner : S-1-5-21-XXXXXXX-500
Group : S-1-5-32-545
SystemAcl :
DiscretionaryAcl : {System.Security.AccessControl.CommonAce}
IsSystemAclCanonical : True
IsDiscretionaryAclCanonical : True
BinaryLength : 96
$sddl.RawDescriptor.DiscretionaryAcl
BinaryLength : 24
AceQualifier : AccessAllowed
IsCallback : False
OpaqueLength : 0
AccessMask : 269353023
SecurityIdentifier : S-1-5-32-545
AceType : AccessAllowed
AceFlags : None
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
AuditFlags : None
可以按照上面的方法构建一个裸的
ACE
对象。但它并不完整,而且我对 .Net 的了解不允许我找出缺少的内容:/
上面提供的另一个选项是使用
SecurityDescriptor
对象。已经为我们提供了:)
$sddl.RawDescriptor.DiscretionaryAcl.AddAccess("Allow", "S-1-5-32-546", 268435456,"None","None")
$sddl.RawDescriptor.GetSddlForm([System.Security.AccessControl.AccessControlSections]::All)
O:LAG:BUD:(A;;CCDCLCSWRPWPRCWDWOGA;;;BU)(A;;GA;;;BG)
请参阅 MS Learn - DiscretionaryAcl.AddAccess 方法
此答案中目前缺少的“唯一”内容是如何构造隐藏在 MS Learn - ObjectAccessRule Class
中的掩码如果我学会了如何...
,我会重新讨论这个问题
(未完待续)