Separate SMB policy verification from runtime activation

This commit is contained in:
Shirofune-Security committed 2026-09-19 04:39:55 +09:00
1 parent 374b931676
commit be3a354f18
9 files changed
+89 -24

No files matched your search

+11 -7
View File
@@ -11,7 +11,7 @@ Run in elevated **64-bit** Windows PowerShell 5.1 or PowerShell 7:
.\WELA.ps1 smb-auditing -SmbAction Configure -Auto -BackupPath .\smb-before -ResultsPath smb-results.json
```
`-Profile` and `-Baseline` are rejected for this command: their advanced Security audit-policy semantics do not include these SMB policies. Audit and Plan both read the current host and show desired DWORD values; the plan is evidence, not an offline authorization file. They write only the explicitly requested results JSON. Configure dry run performs no policy/key writes and creates no recovery directory. Unknown observations fail with exit code 1; known unsupported controls are skipped explicitly. A readable assessment with `ChangeRequired` has exit code 0 because the assessment completed.
`-Profile` and `-Baseline` are rejected for this command: their advanced Security audit-policy semantics do not include these SMB policies. Audit and Plan both read the current host and show desired DWORD values; the plan is evidence, not an offline authorization file. They write only the explicitly requested results JSON. Configure dry run performs no policy/key writes and creates no recovery directory. Unknown read failures give exit code 1; known unsupported controls are skipped explicitly. Audit/Plan uses `PolicyConfigured` for the desired registry DWORD, with runtime state reported separately. A readable assessment with `ChangeRequired` has exit code 0 because the assessment completed. `Applied` and `AlreadyCompliant` rows verify the requested policy-registry DWORD. Exit code 0 means there are no failed/overridden controls; dry-run, declined and unsupported/skipped controls do not establish configuration. None of these results proves runtime auditing or event generation.
## Exact controls and capability gates
@@ -32,11 +32,13 @@ Microsoft's Policy CSP pages list **26100.3613** as the availability floor for t
Reports keep `Policy` (the actual policy-registry value/type) separate from `Runtime` (the corresponding property of `Get-SmbServerConfiguration` or `Get-SmbClientConfiguration`). WELA never substitutes the policy DWORD for a runtime observation:
- `Observed`: the getter exposes an actual Boolean. True supports effective configuration; False means the requested auditing is not yet observed. A write that leaves an exposed property False fails verification even when the DWORD was written successfully. Review policy application and repeat the audit; WELA does not restart a service or weaken security to make verification pass.
- `NotExposed`: the getter or property is unavailable. With the exact local ADMX mapping, WELA can verify the registry policy only. The snapshot explicitly says **effective auditing not established**. A successful registry result is not proof of runtime activation or event generation.
- `Observed`: the getter exposes an actual Boolean. `RuntimeState=Active` means that Boolean was True, not that representative events were generated. False is `NotActive` before the desired policy exists, or `PendingVerification` when the policy registry contains DWORD 1. A correctly written/read-back policy therefore succeeds even when the runtime Boolean remains False. Pending verification does **not** assert propagation delay, a future activation deadline, or that a policy refresh/restart will fix the discrepancy. Its cause and activation timing are unknown; investigate and repeat Audit independently. WELA performs no refresh/restart and never weakens security to make a Boolean change.
- `NotExposed`: the getter or property is unavailable. `RuntimeState=Unknown` distinguishes this from an observed False. With the exact local ADMX mapping, WELA can verify the registry policy only. The snapshot explicitly says **effective auditing not established**. A successful registry result is not proof of runtime activation or event generation.
- `Unknown`: a runtime read fails or returns an unexpected type. Configuration fails closed without treating the state as a default.
Configure uses the common recovery journal and result runner. It rechecks capabilities/current values before writing, verifies the DWORD and available runtime property afterward, and reads them again at completion. Changed previously compliant controls become `Overridden`. Read/write failures are reported per control and give a nonzero exit code while other controls continue. A prompt-time policy change is refused so recovery evidence does not silently describe a stale value.
Configure uses the common recovery journal and result runner. It rechecks capabilities/current values before writing, verifies the DWORD afterward, and reads policy/runtime again at completion. Registry value/type drift becomes `Overridden`; actual read/write failures remain failures and give a nonzero exit code while other controls continue. A runtime Boolean that remains or becomes False is reported separately as pending verification, rather than a registry write failure. An existing DWORD 1 is not rewritten merely to try to make the runtime Boolean change. A later audit can observe `Active` without any additional writes. A prompt-time policy change is refused so recovery evidence does not silently describe a stale value.
Configure JSON includes an explicit `VerificationScope` and `RuntimeVerification` counts for Active, PendingVerification, NotActive, Unknown and NotApplicable, alongside each actual before/after observation. Failed controls count as Unknown in that summary so an older snapshot cannot be mistaken for a successful final runtime read. Console output scopes success to policy-registry verification and prints the runtime counts. None of these statuses proves event generation or central collection.
The registry policy is a current observation, not proof of GPO/MDM ownership or long-term persistence. Future policy refresh can replace it. A direct local policy write also is not an edit to the domain GPO or its authoritative registry.pol source.
@@ -57,12 +59,14 @@ if ($old.ValueExists) {
}
```
Review concurrent administrator changes and GPO/MDM ownership first; a failed write may have left the original state unchanged. Restore controls individually and rerun Audit. Keep newly created parent policy keys unless separately reviewed as empty and safe to remove; never delete the entire LanmanServer/Workstation policy key. Service runtime can lag a registry change, so recovery also requires a later runtime check. This command has not changed guest access, signing/encryption requirements, shares or service state.
Review concurrent administrator changes and GPO/MDM ownership first; a failed write may have left the original state unchanged. Restore controls individually and rerun Audit. Keep newly created parent policy keys unless separately reviewed as empty and safe to remove; never delete the entire LanmanServer/Workstation policy key. Registry and runtime observations can differ, and this implementation has not established why or when they converge; recovery also requires a later runtime check. This command has not changed guest access, signing/encryption requirements, shares or service state.
## Evidence still needed before closing issue #377
Mocked tests exercise OS/build and per-policy ADMX gating, all six exact policy targets, DWORD types, supported/unsupported/unknown states, runtime read errors and unavailable properties, dry run, recovery ordering, idempotence, ineffective runtime state and final drift. Windows CI adds read-only registry/local-ADMX/native-runtime observations and dry-run checks under PowerShell 5.1 and 7. It does not generate SMB traffic or alter runner policy.
Mocked tests exercise OS/build and per-policy ADMX gating, all six exact policy targets, DWORD types, supported/unsupported/unknown states, runtime read errors and unavailable properties, dry run, recovery ordering, idempotence, pending runtime verification despite successful DWORD writes, later runtime activation without rewriting, actual runtime read failures and final registry drift. Windows CI adds read-only registry/local-ADMX/native-runtime observations and dry-run checks under PowerShell 5.1 and 7. It does not generate SMB traffic or alter runner policy.
On isolated supported client/server snapshots, retain OS build/revision, PowerShell version, WELA commit, ADMX hashes and before/after reports. Confirm a policy refresh does not unexpectedly override the requested setting. Capture representative native SMB audit events under the existing security requirements and verify collector delivery. Microsoft's signing/encryption guide identifies SMBClient/Audit 31998/31999 and SMBServer/Audit 3021/3022; validate the event actually corresponds to the test condition. Inspect guest-audit behavior without enabling guest access or weakening signing/encryption. If the existing secure configuration prevents a guest-session event, record that limitation rather than changing the security posture merely to obtain a test event. Also verify manual recovery. These traffic and ingestion tests remain pending; keep the issue open until the required evidence exists.
Sources: [LanmanServer Policy CSP mappings](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-lanmanserver), [LanmanWorkstation Policy CSP mappings](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-lanmanworkstation), [SMB signing and encryption auditing](https://learn.microsoft.com/en-us/windows-server/storage/file-server/smb-signing-overview), [SMB feature availability](https://learn.microsoft.com/en-us/windows-server/storage/file-server/file-server-smb-overview), [SMB server audit parameters](https://learn.microsoft.com/en-us/powershell/module/smbshare/set-smbserverconfiguration?view=windowsserver2025-ps), and [issue #377](https://github.com/Yamato-Security/WELA/issues/377).
Microsoft documents the policy-to-registry mappings and the SMB configuration cmdlets, but the cited pages do not establish synchronous propagation of a direct policy-registry write into the getter or promise that refreshing Group Policy resolves any discrepancy. WELA makes neither assumption.
Sources: [LanmanServer Policy CSP mappings](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-lanmanserver), [LanmanWorkstation Policy CSP mappings](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-lanmanworkstation), [SMB signing and encryption auditing](https://learn.microsoft.com/en-us/windows-server/storage/file-server/smb-signing-overview), [SMB feature availability](https://learn.microsoft.com/en-us/windows-server/storage/file-server/file-server-smb-overview), [SMB configuration getter](https://learn.microsoft.com/en-us/powershell/module/smbshare/get-smbclientconfiguration?view=windowsserver2025-ps), [SMB server audit parameters](https://learn.microsoft.com/en-us/powershell/module/smbshare/set-smbserverconfiguration?view=windowsserver2025-ps), and [issue #377](https://github.com/Yamato-Security/WELA/issues/377).