mirror of
https://github.com/Yamato-Security/WELA.git
synced 2026-10-24 15:08:08 +02:00
Recheck outgoing NTLM enforcement after confirmation
This commit is contained in:
1 parent
ca54b5cf74
commit
bc9e098c81
2 files changed
+52
-1
No files matched your search
@@ -1136,6 +1136,24 @@ function Set-WelaOutgoingNtlmPolicy {
|
||||
}
|
||||
}
|
||||
try {
|
||||
# A prompt or ShouldProcess confirmation may outlive a Group Policy refresh.
|
||||
# Recheck immediately before mutation so default audit setup cannot undo new enforcement.
|
||||
$freshState = Get-WelaOutgoingNtlmState
|
||||
if (-not $freshState.Readable) {
|
||||
throw 'Outgoing NTLM was not changed because its current state became unreadable.'
|
||||
}
|
||||
if ($Mode -eq 'PreserveOrAudit' -and $freshState.Value -eq 2) {
|
||||
Write-Host '[PRESERVED] Deny all enforcement appeared before the write. Select explicit Audit mode to replace it.' -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
if ($Mode -eq 'PreserveOrAudit' -and $null -ne $freshState.Value -and $freshState.Value -notin @(0, 1, 2)) {
|
||||
Write-Warning "Outgoing NTLM changed to an unknown value ($($freshState.Value)); it was preserved."
|
||||
return
|
||||
}
|
||||
if ($freshState.Value -eq $desired) {
|
||||
Write-Host "[SKIPPED] Outgoing NTLM is now already $description." -ForegroundColor Yellow
|
||||
return
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $path -ErrorAction Stop)) {
|
||||
New-Item -Path $path -Force -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
@@ -29,10 +29,15 @@ function Reset-Policy($Value) {
|
||||
$script:ignoreWrite = $false
|
||||
$script:response = 'Y'
|
||||
$script:rsop = @()
|
||||
$script:onPrompt = $null
|
||||
$script:onRead = $null
|
||||
$script:reads = 0
|
||||
}
|
||||
function Test-Path { param($LiteralPath, $ErrorAction) return $script:keyExists }
|
||||
function Get-ItemProperty {
|
||||
param($LiteralPath, $ErrorAction)
|
||||
$script:reads++
|
||||
if ($script:onRead) { & $script:onRead }
|
||||
if ($script:readFails) { throw 'Access denied' }
|
||||
if ($null -eq $script:value) { return [pscustomobject]@{} }
|
||||
return [pscustomobject]@{ RestrictSendingNTLMTraffic = $script:value }
|
||||
@@ -45,7 +50,7 @@ function Set-ItemProperty {
|
||||
if (-not $script:ignoreWrite) { $script:value = $Value }
|
||||
}
|
||||
function Get-CimInstance { param($Namespace, $ClassName, $ErrorAction) if ($ClassName -eq 'RSOP_RegistryPolicySetting') { return $script:rsop } }
|
||||
function Read-Host { param($Prompt) $script:prompts++; return $script:response }
|
||||
function Read-Host { param($Prompt) $script:prompts++; if ($script:onPrompt) { & $script:onPrompt }; return $script:response }
|
||||
|
||||
$script:assertions = 0
|
||||
foreach ($initial in @($null, 0, 1)) {
|
||||
@@ -88,6 +93,34 @@ Assert-Equal $script:writes 0 'Declining preserves deny'
|
||||
$script:response = ''
|
||||
Set-WelaOutgoingNtlmPolicy -Mode Audit
|
||||
Assert-Equal $script:value 1 'Confirmed explicit override succeeds'
|
||||
# A user confirmation must not authorize replacing enforcement that appeared during the prompt.
|
||||
foreach ($changed in @(2, 42)) {
|
||||
Reset-Policy 0
|
||||
$script:changedDuringPrompt = $changed
|
||||
$script:onPrompt = { $script:value = $script:changedDuringPrompt }
|
||||
Set-WelaOutgoingNtlmPolicy
|
||||
Assert-Equal $script:prompts 1 'State changes while the user is confirming'
|
||||
Assert-Equal $script:value $changed 'Default mode preserves newly applied deny or unknown policy'
|
||||
Assert-Equal $script:writes 0 'A stale initial read never authorizes replacing new enforcement'
|
||||
}
|
||||
Reset-Policy 0
|
||||
$script:onPrompt = { $script:readFails = $true }
|
||||
Assert-Throws { Set-WelaOutgoingNtlmPolicy } 'State becoming unreadable during confirmation aborts'
|
||||
Assert-Equal $script:writes 0 'Unreadable refreshed state is not overwritten'
|
||||
Reset-Policy 0
|
||||
$script:onPrompt = { $script:value = 2 }
|
||||
Set-WelaOutgoingNtlmPolicy -Mode Audit
|
||||
Assert-Equal $script:value 1 'Explicit Audit still authorizes replacing deny introduced during confirmation'
|
||||
Assert-Equal $script:writes 1 'Explicit override writes once after a fresh readable state'
|
||||
Reset-Policy 0
|
||||
$script:onPrompt = { $script:value = 1 }
|
||||
Set-WelaOutgoingNtlmPolicy
|
||||
Assert-Equal $script:writes 0 'A concurrently applied audit setting is not redundantly rewritten'
|
||||
Reset-Policy 0
|
||||
$script:onRead = { if ($script:reads -eq 2) { $script:value = 2 } }
|
||||
Set-WelaOutgoingNtlmPolicy -Auto
|
||||
Assert-Equal $script:value 2 'Auto also preserves deny introduced after the initial read'
|
||||
Assert-Equal $script:writes 0 'Auto rechecks immediately before writing'
|
||||
Reset-Policy 0
|
||||
$script:writeFails = $true
|
||||
Assert-Throws { Set-WelaOutgoingNtlmPolicy -Auto } 'Write failure propagates'
|
||||
|
||||
Reference in new issue
Block a user