mirror of
https://github.com/Yamato-Security/WELA.git
synced 2026-09-29 02:24:53 +02:00
74 lines
4.8 KiB
PowerShell
74 lines
4.8 KiB
PowerShell
# Exercise the real audit renderer/CSV exports with injected observations and rules.
|
|
# Only a temporary directory is written; no Windows policy is read or changed.
|
|
$ErrorActionPreference = 'Stop'
|
|
Import-Module (Join-Path $PSScriptRoot '../modules/RuleEligibility.psm1') -Force
|
|
$tokens = $null; $parseErrors = $null
|
|
$ast = [System.Management.Automation.Language.Parser]::ParseFile((Join-Path $PSScriptRoot '../WELA.ps1'), [ref]$tokens, [ref]$parseErrors)
|
|
if ($parseErrors.Count) { throw ($parseErrors | Out-String) }
|
|
$class = $ast.Find({ param($node) $node -is [System.Management.Automation.Language.TypeDefinitionAst] -and $node.Name -eq 'WELA' }, $true)
|
|
. ([scriptblock]::Create($class.Extent.Text))
|
|
$definition = $ast.Find({ param($node) $node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -eq 'AuditLogSetting' }, $true)
|
|
. ([scriptblock]::Create($definition.Extent.Text))
|
|
|
|
$script:assertions = 0
|
|
function Assert-Equal($Actual, $Expected, [string]$Message) {
|
|
if ($Actual -cne $Expected) { throw "$Message. Expected '$Expected', got '$Actual'." }
|
|
$script:assertions++
|
|
}
|
|
function TestAdministrator { return $true }
|
|
function CollectAuditpol { param([switch]$UseCached) return $true }
|
|
function GetAuditpol { return @{} }
|
|
function Get-WelaOutgoingNtlmState {
|
|
return [pscustomobject]@{ Description = 'Audit all (1)'; PolicySource = 'Mocked policy source' }
|
|
}
|
|
function Get-WelaDomainNtlmState { return [pscustomobject]@{ Description = $script:description } }
|
|
function Export-MitreHeatmap { param($sigmaRules, $OutputPath, $UseIdealCount) }
|
|
function BuildAuditResult {
|
|
param($all_rules, $Baseline, $enabledguid)
|
|
$all_rules[0].applicable = $true
|
|
@(
|
|
[WELA]::new('Fixture rules', 'Available', 'Success', @($all_rules[0]))
|
|
[WELA]::new('Fixture rules', 'Unavailable', 'No Auditing', @($all_rules[1]))
|
|
)
|
|
}
|
|
|
|
$script:ScriptRoot = Join-Path ([IO.Path]::GetTempPath()) ('wela-domain-output-' + [guid]::NewGuid().ToString('N'))
|
|
$null = New-Item -ItemType Directory -Path $script:ScriptRoot
|
|
$script:SecurityRulesPath = Join-Path $script:ScriptRoot 'rules.json'
|
|
try {
|
|
@(
|
|
@{ id = 'available-rule'; title = 'Available fixture'; level = 'high'; subcategory_guids = @() }
|
|
@{ id = 'unavailable-rule'; title = 'Unavailable fixture'; level = 'medium'; subcategory_guids = @() }
|
|
) | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $script:SecurityRulesPath -Encoding UTF8
|
|
foreach ($observed in @(
|
|
'Enable all (7)',
|
|
'Disabled (0)',
|
|
'Not configured',
|
|
'Value 2 (not interpreted as Enable all)',
|
|
'Not applicable (Windows client)',
|
|
'Not applicable (member or standalone server, including non-DC AD CS)',
|
|
'Unknown (computer role could not be determined)',
|
|
'Unknown (domain NTLM registry read failed: Access denied)'
|
|
)) {
|
|
$script:description = $observed
|
|
$output = (AuditLogSetting -outType std -Baseline YamatoSecurity 6>&1 | Out-String)
|
|
$expectedHeading = 'NTLM Authentication: Audit all (1); ' + $observed
|
|
Assert-Equal ($output -match ('(?m)^' + [regex]::Escape($expectedHeading) + '\r?$')) $true "Console heading retains '$observed'"
|
|
Assert-Equal ($output -match 'NTLM Authentication: Partially Enabled') $false 'An empty rule array does not imply partial enablement'
|
|
Assert-Equal ($output -match 'Fixture rules: Partially Enabled') $true 'Ordinary rule coverage aggregation is preserved'
|
|
$row = @(Import-Csv -LiteralPath (Join-Path $script:ScriptRoot 'WELA-Audit-Result.csv') | Where-Object SubCategory -eq 'Domain NTLM auditing')
|
|
Assert-Equal $row.Count 1 'CSV contains one domain NTLM setting row'
|
|
Assert-Equal $row[0].CurrentSetting $observed 'CSV retains the observed configuration state'
|
|
Assert-Equal $row[0].RuleCount '0' 'Configuration row claims no detection rules'
|
|
$outgoingRow = @(Import-Csv -LiteralPath (Join-Path $script:ScriptRoot 'WELA-Audit-Result.csv') | Where-Object SubCategory -eq 'Outgoing NTLM policy')
|
|
Assert-Equal $outgoingRow.Count 1 'CSV contains one outgoing NTLM setting row'
|
|
Assert-Equal $outgoingRow[0].CurrentSetting 'Audit all (1)' 'CSV retains the independent outgoing NTLM state'
|
|
Assert-Equal $outgoingRow[0].RuleCount '0' 'Outgoing configuration row claims no detection rules'
|
|
Assert-Equal @(Import-Csv -LiteralPath (Join-Path $script:ScriptRoot 'UsableRules.csv')).Count 0 'Configuration rows do not supply missing detection evidence'
|
|
Assert-Equal @(Import-Csv -LiteralPath (Join-Path $script:ScriptRoot 'UnusableRules.csv')).Count 2 'Both rules retain their missing-evidence gap'
|
|
}
|
|
Write-Host "PASS: $script:assertions domain NTLM output assertions (mocked observations; temporary CSV files only)."
|
|
} finally {
|
|
Remove-Item -LiteralPath $script:ScriptRoot -Recurse -Force
|
|
}
|