Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds ntSecurityDescriptor parser framework #5

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from
2 changes: 1 addition & 1 deletion ActiveDirectoryCore/ActiveDirectoryCore.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''

}
}
9 changes: 9 additions & 0 deletions ActiveDirectoryCore/Classes/00 - Enums/00 - Enums.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Enums - These are added to the PSM1 first during build
enum ActiveDirectoryCoreLogLevel {
Information
Warning
Error
Debug
Verbose
Quiet
}
10 changes: 10 additions & 0 deletions ActiveDirectoryCore/Classes/00 - Enums/Security/00 - AceFlags.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Flags()]
enum AceFlags : byte {
ObjectInherit = 0x01
ContainerInherit = 0x02
NoPropagateInherit = 0x04
InheritOnly = 0x08
Inherited = 0x10
SuccessfulAccess = 0x40
FailedAccess = 0x80
}
20 changes: 20 additions & 0 deletions ActiveDirectoryCore/Classes/00 - Enums/Security/00 - AceType.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
enum AceType : byte {
Allow
Deny
Audit
Alarm
AllowCompound
AllowObject
DenyObject
AuditObject
AlarmObject
AllowCallback
AllowCallbackObject
AuditCallback
AlarmCallback
AuditCallbackObject
AlarmCallbackObject
MandatoryLabel
ResourceAttribute
ScopedPolicyID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[Flags()]
enum DSSDControl : ushort {
SelfRelative = 0x0000
RMControlValid = 0x0001
SaclProtected = 0x0002
DaclProtected = 0x0004
SaclAutoInherited = 0x0008
DaclAutoInherited = 0x0010
SaclComputedInheritanceRequired = 0x0020
DaclComputedInheritanceRequired = 0x0040
ServerSecurity = 0x0080
DaclTrusted = 0x0100
SaclDefaulted = 0x0200
SaclPresent = 0x0400
DaclDefaulted = 0x0800
DaclPresent = 0x1000
GroupDefaulted = 0x2000
OwnerDefaulted = 0x4000
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[Flags()]
enum ObjectAceFlags : uint {
None
ObjectTypePresent
InheritedObjectTypePresent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
enum WellKnownSid : ulong {
CREATORGROUP = 0x0100000000
DIALUP = 0x0100000000
CONSOLELOGON = 0x0100000000
NETWORK = 0x0200000000
CREATOROWNERSERVER = 0x0200000000
BATCH = 0x0300000000
CREATORGROUPSERVER = 0x0300000000
OWNERRIGHTS = 0x0400000000
INTERACTIVE = 0x0400000000
SERVICE = 0x0600000000
ANONYMOUSLOGON = 0x0700000000
PROXY = 0x0800000000
ENTERPRISEDOMAINCONTROLLERS = 0x0900000000
SELF = 0x0A00000000
AuthenticatedUsers = 0x0B00000000
RESTRICTED = 0x0C00000000
TERMINALSERVERUSER = 0x0D00000000
ThisOrganization = 0x0F00000000
SYSTEM = 0x1200000000
LOCALSERVICE = 0x1300000000
NETWORKSERVICE = 0x1400000000
Wellknown = 0x1500000000 # Check name
Administrators = 0x2000000220
Users = 0x2000000221
Guests = 0x2000000222
PowerUsers = 0x2000000223
AccountOperators = 0x2000000224 # Check name
ServerOperators = 0x2000000225 # Check name
PrintOperators = 0x2000000226 # Check name
BackupOperators = 0x2000000227
Replicator = 0x2000000228
PreWindows2000CompatibleAccess = 0x200000022A # Check name
RemoteDesktopUsers = 0x200000022B
NetworkConfigurationOperators = 0x200000022C
IncomingForestTrustBuilders = 0x200000022D # Check name
PerformanceMonitorUsers = 0x200000022E
PerformanceLogUsers = 0x200000022F
WindowsAuthorizationAccessGroup = 0x2000000230 # Check name
TerminalServerLicenseServers = 0x2000000231 # Check name
DistributedCOMUsers = 0x2000000232
CryptographicOperators = 0x2000000239
EventLogReaders = 0x200000023D
CertificateServiceDCOMAccess = 0x200000023E # Check name
RDSRemoteAccessServers = 0x200000023F # Check name
RDSEndpointServers = 0x2000000240 # Check name
RDSManagementServers = 0x2000000241 # Check name
HyperVAdministrators = 0x2000000242
AccessControlAssistanceOperators = 0x2000000243
RemoteManagementUsers = 0x2000000244
StorageReplicaAdministrators = 0x2000000246 # Check name
ALLSERVICES = 0x5000000000
NTService = 0x5000000000 # Check name
VirtualMachines = 0x5300000000 # Check name
WindowManagerGroup = 0x5A00000000
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class EndianBinaryReader : System.IO.BinaryReader {
EndianBinaryReader([System.IO.Stream]$BaseStream) : base($BaseStream) { }

[ushort] ReadUInt16([bool] $isBigEndian) {
if ($isBigEndian) {
return [ushort](([ushort]$this.ReadByte() -shl 8) -bor $this.ReadByte())
} else {
return $this.ReadUInt16()
}
}

[uint] ReadUInt32([bool] $isBigEndian) {
if ($isBigEndian) {
return [UInt32](
([UInt32]$this.ReadByte() -shl 24) -bor
([UInt32]$this.ReadByte() -shl 16) -bor
([UInt32]$this.ReadByte() -shl 8) -bor
$this.ReadByte())
} else {
return $this.ReadUInt32()
}
}

[Byte] PeekByte() {
$value = $this.ReadByte()
$this.BaseStream.Seek(-1, 'Current')
return $value
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ class ADObject {
}
}
}
'NTSecDesc' {
$converted.Value = [SecurityDescriptor]::new($attribute.ByteValue)
return $true
}
{ $_ -in 'Unicode', 'OID' } {
$converted.Value = foreach ($string in $attribute.StringValueArray) {
$string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class SecurityPrincipal {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ADSecurityPrincipal : SecurityPrincipal {
[string] $DomainName
[string] $SamAccountName
[string] $UserPrincipalName
[Sid] $Sid


[string] ToString() {
return '{0}\{1}' -f $this.DomainName, $this.SamAccountName
}
}
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
class SID : IEquatable[Object] {
class Sid : SecurityPrincipal, IEquatable[Object] {
[int] $BinaryLength
[string] $AccountDomainSid
[string] $Value

hidden [byte] $revisionLevel
hidden [byte] $revisionLevel
hidden [IdentifierAuthority] $identifierAuthority
hidden [uint[]] $subAuthorities
hidden [uint[]] $subAuthorities

# Create an instance of SID from a string
SID([string] $sidString) {
$this.ConvertFromString($sidString)
# Create an instance of Sid from a string
Sid([string] $SidString) {
$this.ConvertFromString($SidString)
}

# Create an instance of SID from the SecurityIdentifier class
SID([System.Security.Principal.SecurityIdentifier]$securityIdentifier) {
# Create an instance of Sid from the SecurityIdentifier class
Sid([System.Security.Principal.SecurityIdentifier]$securityIdentifier) {
$this.ConvertFromString($securityIdentifier.ToString())
}

SID([byte[]] $sidBytes) {
$this.BinaryLength = $sidBytes.Count
Sid([byte[]] $SidBytes) {
$this.ConvertFromByte([EndianBinaryReader][System.IO.MemoryStream]$SidBytes)
}

Sid([EndianBinaryReader] $binaryReader) {
$this.ConvertFromByte($binaryReader)
}

$this.revisionLevel = $sidBytes[0]
$subAuthorityCount = $sidBytes[1]
hidden [void] ConvertFromByte([EndianBinaryReader] $binaryReader) {
$this.revisionLevel = $binaryReader.ReadByte()
$subAuthorityCount = $binaryReader.ReadByte()

$identifierAuthorityBytes = [byte[]]::new(8)
[Array]::Copy(
$sidBytes,
2,
$binaryReader.ReadBytes(6),
0,
$identifierAuthorityBytes,
2,
6
)
[Array]::Reverse($identifierAuthorityBytes)
$this.identifierAuthority = [BitConverter]::ToUInt64($identifierAuthorityBytes)

$this.subAuthorities = for ($i = 8; $i -lt 8 + ($subAuthorityCount * 4); $i += 4) {
[BitConverter]::ToUInt32([byte[]](
$sidBytes[$i],
$sidBytes[$i + 1],
$sidBytes[$i + 2],
$sidBytes[$i + 3]
))
$this.BinaryLength = 8 + ($subAuthorityCount * 4)
$this.subAuthorities = for ($i = 0; $i -lt $subAuthorityCount; $i++) {
[BitConverter]::ToUInt32($binaryReader.ReadBytes(4))
}

$this.Value = $this.ToString()
Expand All @@ -49,43 +51,36 @@ class SID : IEquatable[Object] {
$this.AccountDomainSid = $this
}
elseif ($this.subAuthorities.Count -gt 4) {
$accountDomainSidBytes = [byte[]]::new($this.BinaryLength - 4)
[Array]::Copy(
$sidBytes,
$accountDomainSidBytes,
$accountDomainSidBytes.Count
)
$accountDomainSidBytes[1] = $this.subAuthorities.Count - 1
$this.AccountDomainSid = [Sid]::new($accountDomainSidBytes)
$this.AccountDomainSid = [Sid]::new($this.Value -replace '-\d+$')
}
}

hidden ConvertFromString([string] $sidString) {
$null, $this.RevisionLevel, $this.identifierAuthority, $this.subAuthorities = $sidString -split '-'
hidden ConvertFromString([string] $SidString) {
$null, $this.RevisionLevel, $this.identifierAuthority, $this.subAuthorities = $SidString -split '-'
$this.BinaryLength = 8 + ($this.subAuthorities.Count * 4)
$this.Value = $this.ToString()

if ($this.subAuthorities.Count -eq 4) {
$this.AccountDomainSid = $sidString
$this.AccountDomainSid = $SidString
}
elseif ($this.subAuthorities.Count -gt 4) {
$this.AccountDomainSid = $sidString -replace '-\d+$'
$this.AccountDomainSid = $SidString -replace '-\d+$'
}
}

# Return the security identifier as a byte array.
[byte[]] ToBinary() {
$sidBytes = [byte[]]::new($this.BinaryLength)
$sidBytes[0] = $this.revisionLevel
$sidBytes[1] = $this.subAuthorities.Count
[byte[]] GetBytes() {
$SidBytes = [byte[]]::new($this.BinaryLength)
$SidBytes[0] = $this.revisionLevel
$SidBytes[1] = $this.subAuthorities.Count

$identifierAuthorityBytes = [BitConverter]::GetBytes([ulong]$this.identifierAuthority)
[Array]::Reverse($identifierAuthorityBytes)

[Array]::Copy(
$identifierAuthorityBytes,
2,
$sidBytes,
$SidBytes,
2,
6
)
Expand All @@ -95,13 +90,13 @@ class SID : IEquatable[Object] {
[Array]::Copy(
$subAuthorityBytes,
0,
$sidBytes,
$SidBytes,
(8 + ($i * 4)),
4
)
}

return $sidBytes
return $SidBytes
}

[string] ToString() {
Expand All @@ -118,7 +113,7 @@ class SID : IEquatable[Object] {
return $this.ToString() -eq $object.ToString()
}

hidden static [System.Security.Principal.SecurityIdentifier] op_Implicit([SID] $sid) {
return [System.Security.Principal.SecurityIdentifier]$sid.ToString()
hidden static [System.Security.Principal.SecurityIdentifier] op_Implicit([Sid] $Sid) {
return [System.Security.Principal.SecurityIdentifier]$Sid.ToString()
}
}
Loading