-
Notifications
You must be signed in to change notification settings - Fork 3
/
ConvertFrom-SDDLString.ps1
152 lines (129 loc) · 5.14 KB
/
ConvertFrom-SDDLString.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function ConvertFrom-SDDLString {
<#
.SYNOPSIS
ConvertFrom-SDDLString function converted for use in PowerShell 2.0
.DESCRIPTION
Function taken from Microsoft.PowerShell.Utility module and adapted to PowerShell 2.0, removed ordered hash tables and adapted parameter blocks to be compatible with PowerShell 2.0.
.NOTES
ModifiedBy: Jaap Brasser
DateUpdated: 2016-03-01
Blog: http://www.jaapbrasser.com
#>
[CmdletBinding()]
param(
## The string representing the security descriptor in SDDL syntax
[Parameter(Mandatory=$true, Position = 0)]
[String] $Sddl,
## The type of rights that this SDDL string represents, if any.
[Parameter()]
[ValidateSet(
'FileSystemRights', 'RegistryRights', 'ActiveDirectoryRights',
'MutexRights', 'SemaphoreRights', 'CryptoKeyRights',
'EventWaitHandleRights')]
$Type
)
## Translates a SID into a NT Account
function ConvertTo-NtAccount
{
param($Sid)
if($Sid)
{
$securityIdentifier = [System.Security.Principal.SecurityIdentifier] $Sid
try
{
$ntAccount = $securityIdentifier.Translate([System.Security.Principal.NTAccount]).ToString()
}
catch{}
$ntAccount
}
}
## Gets the access rights that apply to an access mask, preferring right types
## of 'Type' if specified.
function Get-AccessRights
{
param($AccessMask, $Type)
## All the types of access rights understood by .NET
$rightTypes = @{
'FileSystemRights' = [System.Security.AccessControl.FileSystemRights]
'RegistryRights' = [System.Security.AccessControl.RegistryRights]
'ActiveDirectoryRights' = [System.DirectoryServices.ActiveDirectoryRights]
'MutexRights' = [System.Security.AccessControl.MutexRights]
'SemaphoreRights' = [System.Security.AccessControl.SemaphoreRights]
'CryptoKeyRights' = [System.Security.AccessControl.CryptoKeyRights]
'EventWaitHandleRights' = [System.Security.AccessControl.EventWaitHandleRights]
}
$typesToExamine = $rightTypes.Values
## If they know the access mask represents a certain type, prefer its names
## (i.e.: CreateLink for the registry over CreateDirectories for the filesystem)
if($Type)
{
$typesToExamine = @($rightTypes[$Type]) + $typesToExamine
}
## Stores the access types we've found that apply
$foundAccess = @()
## Store the access types we've already seen, so that we don't report access
## flags that are essentially duplicate. Many of the access values in the different
## enumerations have the same value but with different names.
$foundValues = @{}
## Go through the entries in the different right types, and see if they apply to the
## provided access mask. If they do, then add that to the result.
foreach($rightType in $typesToExamine)
{
foreach($accessFlag in [Enum]::GetNames($rightType))
{
$longKeyValue = [long] $rightType::$accessFlag
if(-not $foundValues.ContainsKey($longKeyValue))
{
$foundValues[$longKeyValue] = $true
if(($AccessMask -band $longKeyValue) -eq ($longKeyValue))
{
$foundAccess += $accessFlag
}
}
}
}
$foundAccess | Sort-Object
}
## Converts an ACE into a string representation
function ConvertTo-AceString
{
param(
[Parameter(ValueFromPipeline=$true)]
$Ace,
$Type
)
process
{
foreach($aceEntry in $Ace)
{
$AceString = (ConvertTo-NtAccount $aceEntry.SecurityIdentifier) + ': ' + $aceEntry.AceQualifier
if($aceEntry.AceFlags -ne 'None')
{
$AceString += ' ' + $aceEntry.AceFlags
}
if($aceEntry.AccessMask)
{
$foundAccess = Get-AccessRights $aceEntry.AccessMask $Type
if($foundAccess)
{
$AceString += ' ({0})' -f ($foundAccess -join ', ')
}
}
$AceString
}
}
}
$arguments = $false,$false,$Sddl
$rawSecurityDescriptor = New-Object Security.AccessControl.CommonSecurityDescriptor $arguments
$owner = ConvertTo-NtAccount $rawSecurityDescriptor.Owner
$group = ConvertTo-NtAccount $rawSecurityDescriptor.Group
$discretionaryAcl = ConvertTo-AceString $rawSecurityDescriptor.DiscretionaryAcl $Type
$systemAcl = ConvertTo-AceString $rawSecurityDescriptor.SystemAcl $Type
[PSCustomObject] @{
Owner = $owner
Group = $group
DiscretionaryAcl = @($discretionaryAcl)
SystemAcl = @($systemAcl)
RawDescriptor = $rawSecurityDescriptor
}
}