mirror of
https://github.com/NexusOne23/noid-privacy.git
synced 2026-02-07 04:01:52 +01:00
302 lines
9.9 KiB
PowerShell
302 lines
9.9 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Parse Microsoft Edge Security Baseline GPO files to JSON (DEVELOPER TOOL ONLY)
|
|
|
|
.DESCRIPTION
|
|
**NOTE: This is a DEVELOPER/MAINTENANCE tool - NOT needed for production use!**
|
|
|
|
Parses GPO backups from Microsoft Edge Security Baseline:
|
|
- Registry.pol (Computer policies for Microsoft Edge)
|
|
|
|
Outputs structured JSON files for Edge hardening settings.
|
|
|
|
.PARAMETER BaselinePath
|
|
Path to Microsoft Edge Security Baseline folder
|
|
|
|
.PARAMETER OutputPath
|
|
Path where JSON output files will be saved
|
|
|
|
.NOTES
|
|
Author: NexusOne23
|
|
Version: 2.2.2
|
|
Requires: PowerShell 5.1+
|
|
|
|
.EXAMPLE
|
|
.\Parse-EdgeBaseline.ps1 -BaselinePath "C:\Edge Baseline" -OutputPath ".\Modules\EdgeHardening\ParsedSettings"
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$BaselinePath,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$OutputPath = (Join-Path $PSScriptRoot "..\Modules\EdgeHardening\ParsedSettings")
|
|
)
|
|
|
|
#region Helper Functions
|
|
|
|
function Read-PolFile {
|
|
<#
|
|
.SYNOPSIS
|
|
Parse binary Registry.pol file
|
|
|
|
.DESCRIPTION
|
|
Based on Microsoft GPRegistryPolicyParser format
|
|
Registry.pol binary format:
|
|
- Signature: PReg (4 bytes)
|
|
- Version: 1 (4 bytes)
|
|
- Entries: [KeyName;ValueName;Type;Size;Data]
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Path
|
|
)
|
|
|
|
if (-not (Test-Path $Path)) {
|
|
Write-Warning "Registry.pol not found: $Path"
|
|
return @()
|
|
}
|
|
|
|
try {
|
|
$entries = @()
|
|
$bytes = [System.IO.File]::ReadAllBytes($Path)
|
|
|
|
# Check signature (PReg)
|
|
$signature = [System.Text.Encoding]::ASCII.GetString($bytes[0..3])
|
|
if ($signature -ne 'PReg') {
|
|
Write-Warning "Invalid Registry.pol signature: $signature"
|
|
return @()
|
|
}
|
|
|
|
# Check version
|
|
$version = [BitConverter]::ToInt32($bytes, 4)
|
|
if ($version -ne 1) {
|
|
Write-Warning "Unsupported Registry.pol version: $version"
|
|
return @()
|
|
}
|
|
|
|
$index = 8 # Start after signature and version
|
|
|
|
while ($index -lt $bytes.Length) {
|
|
# Read entry: [KeyName;ValueName;Type;Size;Data]
|
|
|
|
# Read KeyName (Unicode null-terminated string)
|
|
$keyNameBytes = @()
|
|
while ($index -lt ($bytes.Length - 1)) {
|
|
$b1 = $bytes[$index]
|
|
$b2 = $bytes[$index + 1]
|
|
$index += 2
|
|
|
|
if ($b1 -eq 0 -and $b2 -eq 0) {
|
|
break
|
|
}
|
|
|
|
$keyNameBytes += $b1, $b2
|
|
}
|
|
|
|
$keyName = [System.Text.Encoding]::Unicode.GetString($keyNameBytes)
|
|
|
|
# Skip semicolon
|
|
$index += 2
|
|
|
|
# Read ValueName (Unicode null-terminated string)
|
|
$valueNameBytes = @()
|
|
while ($index -lt ($bytes.Length - 1)) {
|
|
$b1 = $bytes[$index]
|
|
$b2 = $bytes[$index + 1]
|
|
$index += 2
|
|
|
|
if ($b1 -eq 0 -and $b2 -eq 0) {
|
|
break
|
|
}
|
|
|
|
$valueNameBytes += $b1, $b2
|
|
}
|
|
|
|
$valueName = [System.Text.Encoding]::Unicode.GetString($valueNameBytes)
|
|
|
|
# Skip semicolon
|
|
$index += 2
|
|
|
|
# Read Type (DWORD - 4 bytes)
|
|
if ($index + 4 -gt $bytes.Length) { break }
|
|
$type = [BitConverter]::ToInt32($bytes, $index)
|
|
$index += 4
|
|
|
|
# Skip semicolon
|
|
$index += 2
|
|
|
|
# Read Size (DWORD - 4 bytes)
|
|
if ($index + 4 -gt $bytes.Length) { break }
|
|
$size = [BitConverter]::ToInt32($bytes, $index)
|
|
$index += 4
|
|
|
|
# Skip semicolon
|
|
$index += 2
|
|
|
|
# Read Data
|
|
$data = $null
|
|
if ($size -gt 0 -and ($index + $size) -le $bytes.Length) {
|
|
$dataBytes = $bytes[$index..($index + $size - 1)]
|
|
|
|
# Parse based on type
|
|
switch ($type) {
|
|
1 { # REG_SZ (String)
|
|
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
|
|
}
|
|
2 { # REG_EXPAND_SZ
|
|
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
|
|
}
|
|
3 { # REG_BINARY
|
|
$data = $dataBytes
|
|
}
|
|
4 { # REG_DWORD
|
|
if ($dataBytes.Length -ge 4) {
|
|
$data = [BitConverter]::ToInt32($dataBytes, 0)
|
|
}
|
|
}
|
|
7 { # REG_MULTI_SZ
|
|
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) -split '\x00'
|
|
}
|
|
default {
|
|
$data = $dataBytes
|
|
}
|
|
}
|
|
|
|
$index += $size
|
|
}
|
|
|
|
# Skip closing bracket
|
|
$index += 2
|
|
|
|
# Add entry
|
|
$entries += [PSCustomObject]@{
|
|
KeyName = $keyName
|
|
ValueName = $valueName
|
|
Type = switch ($type) {
|
|
1 { "REG_SZ" }
|
|
2 { "REG_EXPAND_SZ" }
|
|
3 { "REG_BINARY" }
|
|
4 { "REG_DWORD" }
|
|
7 { "REG_MULTI_SZ" }
|
|
11 { "REG_QWORD" }
|
|
default { "Unknown($type)" }
|
|
}
|
|
Data = $data
|
|
}
|
|
}
|
|
|
|
return $entries
|
|
}
|
|
catch {
|
|
Write-Error "Failed to parse Registry.pol: $Path - $_"
|
|
return @()
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Main Parsing Logic
|
|
|
|
Write-Host ""
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host " Microsoft Edge Security Baseline Parser" -ForegroundColor Cyan
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# Validate baseline path
|
|
if (-not (Test-Path $BaselinePath)) {
|
|
Write-Error "Baseline path not found: $BaselinePath"
|
|
exit 1
|
|
}
|
|
|
|
# Ensure output directory exists
|
|
if (-not (Test-Path $OutputPath)) {
|
|
New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
|
|
Write-Host "Created output directory: $OutputPath" -ForegroundColor Green
|
|
}
|
|
|
|
# Find GPO folder (should be only one GPO in Edge Baseline)
|
|
$gpoFolders = Get-ChildItem -Path (Join-Path $BaselinePath "GPOs") -Directory
|
|
|
|
if ($gpoFolders.Count -eq 0) {
|
|
Write-Error "No GPO folders found in $BaselinePath\GPOs"
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Found $($gpoFolders.Count) GPO folder(s)" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
$allComputerPolicies = @()
|
|
|
|
foreach ($gpoFolder in $gpoFolders) {
|
|
$gpoName = $gpoFolder.Name
|
|
Write-Host "Processing GPO: $gpoName" -ForegroundColor Yellow
|
|
|
|
# Parse Computer Registry policies
|
|
$computerPolPath = Join-Path $gpoFolder.FullName "DomainSysvol\GPO\Machine\registry.pol"
|
|
|
|
if (Test-Path $computerPolPath) {
|
|
Write-Host " Parsing Computer registry policies..." -ForegroundColor Gray
|
|
$computerPolicies = Read-PolFile -Path $computerPolPath
|
|
|
|
if ($computerPolicies.Count -gt 0) {
|
|
$allComputerPolicies += $computerPolicies
|
|
Write-Host " Found $($computerPolicies.Count) Computer registry policies" -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Warning " No Computer registry policies found"
|
|
}
|
|
}
|
|
else {
|
|
Write-Warning " Computer registry.pol not found"
|
|
}
|
|
|
|
# Check for User policies (Edge baseline typically doesn't have user policies)
|
|
$userPolPath = Join-Path $gpoFolder.FullName "DomainSysvol\GPO\User\registry.pol"
|
|
|
|
if (Test-Path $userPolPath) {
|
|
Write-Host " User registry.pol found (unexpected for Edge baseline)" -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
}
|
|
|
|
# Save Computer Registry Policies
|
|
if ($allComputerPolicies.Count -gt 0) {
|
|
$computerPoliciesFile = Join-Path $OutputPath "EdgePolicies.json"
|
|
$allComputerPolicies | ConvertTo-Json -Depth 10 | Out-File -FilePath $computerPoliciesFile -Encoding UTF8 -Force
|
|
Write-Host "Saved $($allComputerPolicies.Count) policies to: EdgePolicies.json" -ForegroundColor Green
|
|
}
|
|
|
|
# Create summary
|
|
$summary = [PSCustomObject]@{
|
|
TotalEdgePolicies = $allComputerPolicies.Count
|
|
ParsedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
BaselineVersion = "Edge v139"
|
|
RegistryPaths = ($allComputerPolicies | Select-Object -ExpandProperty KeyName -Unique | Sort-Object)
|
|
}
|
|
|
|
$summaryFile = Join-Path $OutputPath "Summary.json"
|
|
$summary | ConvertTo-Json -Depth 10 | Out-File -FilePath $summaryFile -Encoding UTF8 -Force
|
|
|
|
Write-Host ""
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host " Parsing Complete" -ForegroundColor Cyan
|
|
Write-Host "================================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host "Total Edge Policies: $($allComputerPolicies.Count)" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "Output files:" -ForegroundColor White
|
|
Write-Host " - EdgePolicies.json" -ForegroundColor Gray
|
|
Write-Host " - Summary.json" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host "Next steps:" -ForegroundColor Yellow
|
|
Write-Host " 1. Review parsed policies in EdgePolicies.json" -ForegroundColor Gray
|
|
Write-Host " 2. Implement Set-EdgePolicies.ps1 (native PowerShell)" -ForegroundColor Gray
|
|
Write-Host " 3. Implement Test-EdgePolicies.ps1 (compliance check)" -ForegroundColor Gray
|
|
Write-Host " 4. Implement Invoke-EdgeHardening.ps1 (main entry point)" -ForegroundColor Gray
|
|
Write-Host ""
|
|
|
|
#endregion
|