ADCSTemplateParser.psm1
function Get-SidfromHex { param ( [string]$Sid ) $ByteSid = New-Object Byte[] 150 for ($i = 0; $i -lt $Sid.Length ; $i += 2) { $ByteSid.Set(($i/2),([Byte]::Parse($Sid.Substring($i, 2), [System.Globalization.NumberStyles]::HexNumber))) } New-Object System.Security.Principal.SecurityIdentifier($ByteSid,0) } function Get-NtSecurityDescriptor { param ( [string]$SecurityDescriptor ) $ntsecdesc = New-Object Byte[] ($SecurityDescriptor.Length) for ($i = 0; $i -lt $SecurityDescriptor.Length ; $i += 2) { $ntsecdesc.Set(($i/2),([Byte]::Parse($SecurityDescriptor.Substring($i, 2), [System.Globalization.NumberStyles]::HexNumber))) } [System.Security.AccessControl.RawSecurityDescriptor]::new($ntsecdesc,0) } function Get-ATPTemplate { param ( [String]$TemplateFile ) $Contents = Get-Content $TemplateFile -Raw $temp = @{} $templates = @{} [regex]::Matches($Contents,'\[(.+?)\]')| ForEach-Object {$templates[$_.Value.replace('[','').replace(']','')]=@()} foreach ($key in $($templates.Keys)) {$temp[$key] = [regex]::Match($Contents,'\[' + ($key) + '\]' + '(?>.+?|\n)+?\r\n\r\n\r\n')} foreach ($template in $($temp.Keys)) { $temp.$template.Value|Out-File "$env:TEMP\temptemplate.txt" -Force Switch -Regex -File ("$env:TEMP\temptemplate.txt") { '\s*(.+?)\s*=\s*"(.*?)"(?:,\s"?(.*?)")?.*?(.*)' { $name,$value1,$value2,$hex = $matches[1..4] if ($value2) {$Value = "$value1, $value2"} else {$Value = $value1} $templates[$template] += [pscustomobject]@{ 'Name' = $name 'Value' = $Value 'Second value' = $hex } } } Remove-Item -Path "$env:TEMP\temptemplate.txt" -Force $description = [regex]::Matches([regex]::Match($temp.$template.Value,'nTSecurityDescriptor\s=(.*?|\n)+05 0b 00 00 00').Value,'(?:[0-9a-fA-F]{2}\s[0-9a-fA-F]{2}\s)+')|% {$_.Value} if ($description) { $templates[$template] += [pscustomobject]@{ 'Name' = 'nTSecurityDescriptor' 'Value' = Get-NtSecurityDescriptor -SecurityDescriptor (-split($description) -join '') } } } $templates } |