From 353159615e3ed9b2b260a1d2bbb5cbb212f40fe9 Mon Sep 17 00:00:00 2001 From: Shirofune-Security <43838376+Shirofune-Security@users.noreply.github.com> Date: Tue, 22 Sep 2026 12:06:07 +0900 Subject: [PATCH] fix: preserve omitted notification selection and document native OneSettings acceptance --- .gitattributes | 3 +++ .github/workflows/release.yml | 2 +- CHANGELOG-Japanese.md | 2 ++ CHANGELOG.md | 2 ++ WELA.ps1 | 6 ++++- docs/audit-notifications.md | 2 ++ docs/native-onesettings-acceptance.md | 30 ++++++++++++++++++++++++ tests/OneSettingsConfigure.Cli.Tests.ps1 | 7 ++++++ website/docs/resources/changelog.ja.md | 2 ++ website/docs/resources/changelog.md | 2 ++ 10 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 docs/native-onesettings-acceptance.md diff --git a/.gitattributes b/.gitattributes index 7f4524b7..7820df92 100644 --- a/.gitattributes +++ b/.gitattributes @@ -96,3 +96,6 @@ tests/NativeProviderConfigure.Windows.Tests.ps1 text eol=lf /modules/WecSubscriptionInventory.cs text eol=lf /tests/WecCollectorObservation* text eol=lf /tests/WecSubscriptionInventory* text eol=lf + +# Disposable public OneSettings fixture source identity. +/tests/OneSettingsConfigure*.ps1 text eol=lf diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52989c99..90a3d657 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: Copy-Item -Recurse -Path ./scripts -Destination release-binaries/ Copy-Item -Recurse -Path ./modules -Destination release-binaries/ New-Item -ItemType Directory -Path release-binaries/docs -Force | Out-Null - Copy-Item -Path ./docs/gpo-audit-packages.md, ./docs/gpo-package-deployment.md, ./docs/gpo-creation.md, ./docs/wmi-probe.md, ./docs/firewall-logging.md, ./docs/firewall-logging-recovery.md, ./docs/ipsec-prerequisites.md, ./docs/wec-state.md, ./docs/wec-update.md, ./docs/wec-runtime.md, ./docs/wef-deployment.md, ./docs/native-channel-access.md, ./docs/eventlog-settings.md, ./docs/channel-read.md, ./docs/native-rule-eligibility.md, ./docs/native-validation.md, ./docs/wef-arrival.md, ./docs/smb-runtime-activation.md, ./docs/smb-auditing.md, ./docs/wec-ingress.md, ./docs/capi2-probe.md, ./docs/powershell-transcription.md, ./docs/transcription-recovery.md, ./docs/eventlog-recovery.md, ./docs/failed-logon-probe.md, ./docs/wec-listener.md, ./docs/file-access-probe.md, ./docs/applocker-script-probe.md, ./docs/applocker-probe.md, ./docs/selected-sacl-configuration.md, ./docs/registry-sacl-recovery.md, ./docs/targeted-sacl-planning.md, ./docs/native-registry-sacl-validation.md, ./docs/wec-authorization.md, ./docs/channel-recovery.md, ./docs/outgoing-ntlm.md, ./docs/wec-collector-observation.md, ./docs/native-provider-packs.md, ./docs/native-provider-acceptance.md -Destination release-binaries/docs/ + Copy-Item -Path ./docs/gpo-audit-packages.md, ./docs/gpo-package-deployment.md, ./docs/gpo-creation.md, ./docs/wmi-probe.md, ./docs/firewall-logging.md, ./docs/firewall-logging-recovery.md, ./docs/ipsec-prerequisites.md, ./docs/wec-state.md, ./docs/wec-update.md, ./docs/wec-runtime.md, ./docs/wef-deployment.md, ./docs/native-channel-access.md, ./docs/eventlog-settings.md, ./docs/channel-read.md, ./docs/native-rule-eligibility.md, ./docs/native-validation.md, ./docs/wef-arrival.md, ./docs/smb-runtime-activation.md, ./docs/smb-auditing.md, ./docs/wec-ingress.md, ./docs/capi2-probe.md, ./docs/powershell-transcription.md, ./docs/transcription-recovery.md, ./docs/eventlog-recovery.md, ./docs/failed-logon-probe.md, ./docs/wec-listener.md, ./docs/file-access-probe.md, ./docs/applocker-script-probe.md, ./docs/applocker-probe.md, ./docs/selected-sacl-configuration.md, ./docs/registry-sacl-recovery.md, ./docs/targeted-sacl-planning.md, ./docs/native-registry-sacl-validation.md, ./docs/wec-authorization.md, ./docs/channel-recovery.md, ./docs/outgoing-ntlm.md, ./docs/wec-collector-observation.md, ./docs/native-provider-packs.md, ./docs/native-provider-acceptance.md, ./docs/audit-notifications.md, ./docs/native-onesettings-acceptance.md -Destination release-binaries/docs/ - name: Set Artifact Name if: contains(matrix.info.os, 'windows') == true diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index 3b6874eb..3e041be3 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -4,6 +4,8 @@ **改善:** +- OneSettingsポリシーと明示的なPrivacyチャネル設定の公開CLIを実機検証します。Server 2022で実際の適用、型付き復元記録と再読取、冪等性、不正値の拒否を確認し、Server 2025の既存の拒否を維持します。両PowerShellで厳密な後処理を検証し、イベント生成やSigma対応は主張しません。通知コントロール省略時の引数渡しを修正し、既定のAuditは両項目を読み取り、項目未選択のConfigureは非ゼロで失敗します。(関連 #378) (@Shirofune-Security) + - 明示的な `registry-sacl-recovery` を追加しました。整合する4つの元記録、レビュー済み計画のハッシュ、過去・現在ともに空の子キー観測、監査縮小と継承への個別同意を必須とし、追加が証明されたレジストリルートの明示的な監査ACEを1つだけ削除します。SACLのみのネイティブ書き込みで他の記述子フィールドとACEの順序を保持し、部分的な書き込みの証跡と元の記述子バイトとの一致を別々に報告します。過去のキー・操作者の同一性認証、ツリー全体の原子性、イベント生成、Sigmaの準備完了は保証しません。 (Related #373) (@Shirofune-Security) - Server 2022/2025とPowerShell 5.1/7でSMBポリシー設定の公開CLIを検証します。対応ホストで6項目の適用・再読取・再実行、非対応ホストのスキップ、元の型付き記録、無関係な設定の維持と完全な復元を確認します。イベント生成と実行時の有効化は別途検証します。(関連 #377) (@Shirofune-Security) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7129758..afee261b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ **Improvements:** +- Add native public OneSettings policy and explicit Privacy-channel configuration acceptance: actual apply, typed journals/readback, idempotence and invalid-value refusals on Server 2022; preserve the existing Server 2025 refusal. Both PowerShell engines verify exact fixture cleanup without event or Sigma claims. Fix omitted notification-control dispatch so default Audit reads both controls and Configure without a selection fails with a nonzero exit. (Related #378) (@Shirofune-Security) + - Added opt-in `registry-sacl-recovery` for one proven explicit registry-root audit ACE, requiring four matching original records, a reviewed plan hash, empty historical/current descendants and separate audit-reduction/inheritance consent. Native SACL-only removal preserves unrelated descriptor fields and ACE order, retains partial-write evidence and reports original-byte equality separately; no authenticated historical key/operator identity, atomic-tree, event or Sigma claim. (Related #373) (@Shirofune-Security) - Add native public SMB policy configuration acceptance on Server 2022/2025 and PowerShell 5.1/7: six-policy apply/readback and idempotence on supported hosts, unsupported-host skips, typed original journals, unrelated-state preservation and exact cleanup. Event generation and runtime activation remain separate. (Related #377) (@Shirofune-Security) diff --git a/WELA.ps1 b/WELA.ps1 index 9aad3df0..fad00372 100644 --- a/WELA.ps1 +++ b/WELA.ps1 @@ -2579,7 +2579,11 @@ switch ($Cmd.ToLower()) { if ($Help) { Write-Host 'Usage: ./WELA.ps1 audit-notifications [-NotificationAction Audit|Plan|Configure] [-NotificationControl OneSettings,SecurityWarning] [-WarningPercent 1..90] [-EnablePrivacyChannel] [-Auto] [-DryRun] [-BackupPath new-directory] [-ResultsPath report.json]. See docs/audit-notifications.md.'; return } if ($Profile -or $Baseline -or $Role -or $Build -or $HtmlPath) { throw 'audit-notifications uses actual host context and -ResultsPath; profile/role/build overrides and HTML are unsupported.' } if ($NotificationAction -eq 'Configure' -and -not (TestAdministrator)) { throw 'Notification Configure requires Administrator privileges.' } - $report=Invoke-WelaNotificationCommand -Action $NotificationAction -Control $NotificationControl -WarningPercent $WarningPercent -EnablePrivacyChannel:$EnablePrivacyChannel -Auto:$Auto -DryRun:$DryRun -BackupPath $BackupPath -ResultsPath $ResultsPath + $notificationArguments=@{Action=$NotificationAction;WarningPercent=$WarningPercent;EnablePrivacyChannel=$EnablePrivacyChannel;Auto=$Auto;DryRun=$DryRun;BackupPath=$BackupPath;ResultsPath=$ResultsPath} + # Omit an unspecified ValidateSet array: explicit null fails binding before default Audit + # selection or Configure's required-selection guard, and can leave a zero process exit. + if($PSBoundParameters.ContainsKey('NotificationControl')){$notificationArguments.Control=$NotificationControl} + $report=Invoke-WelaNotificationCommand @notificationArguments $report if ($report.ExitCode) { exit $report.ExitCode } } diff --git a/docs/audit-notifications.md b/docs/audit-notifications.md index 595521b7..230e5c9c 100644 --- a/docs/audit-notifications.md +++ b/docs/audit-notifications.md @@ -76,6 +76,8 @@ CrashOnAuditFail and all 59 audit masks. It never fills or clears a log, changes retention, tests warning generation, or supplies OneSettings/Windows 11/DC/AD CS acceptance. +A separate [native OneSettings acceptance fixture](native-onesettings-acceptance.md) exercises public policy and dependent-channel configuration on Server 2022 and the existing refusal on Server 2025, under both PowerShell engines. It verifies typed journals, idempotence, actual invalid-value refusals and exact cleanup. This remains settings evidence only. + Before closing issue #378, retain isolated Windows 11 and Server 2022 evidence of an authorized benign OneSettings attempt with exact build/patch, policy, channel, native event XML and collection result. Do not assume an EventID without inspecting diff --git a/docs/native-onesettings-acceptance.md b/docs/native-onesettings-acceptance.md new file mode 100644 index 00000000..acc2d93a --- /dev/null +++ b/docs/native-onesettings-acceptance.md @@ -0,0 +1,30 @@ +# Native public OneSettings configuration acceptance + +The disposable acceptance fixture invokes the actual `WELA.ps1 audit-notifications` command under Windows PowerShell 5.1 and PowerShell 7. It verifies local configuration and the explicit Privacy channel dependency. It does not generate a OneSettings event or claim effective producer behavior, policy persistence, forwarding or Sigma readiness. Sysmon is excluded. + +```powershell +./WELA.ps1 audit-notifications -NotificationAction Plan -NotificationControl OneSettings -EnablePrivacyChannel +./WELA.ps1 audit-notifications -NotificationAction Configure -NotificationControl OneSettings -EnablePrivacyChannel -DryRun +./WELA.ps1 audit-notifications -NotificationAction Configure -NotificationControl OneSettings -EnablePrivacyChannel -Auto -BackupPath C:\Evidence\onesettings-before -ResultsPath C:\Evidence\onesettings.json +``` + +Configure requires elevation and explicit control selection. Audit without a selection reads both notification controls. The CLI omits an unspecified control argument so these defaults and the required-selection error reach the command; passing an explicit null into the validated control parameter previously produced a binding error with a zero process exit. + +Server 2022 requires the real installed `DataCollection.admx` machine mapping for `EnableOneSettingsAuditing` DWORD1, its existing native registry key and readable `Microsoft-Windows-Privacy-Auditing/Operational` metadata. Server 2025 remains unverified by the reviewed source and must refuse configuration. Tests preserve this gate; installing an ADMX alone does not establish support. + +On Server 2022, `tests/OneSettingsConfigure.Windows.Tests.ps1 -AllowDisposableOneSettingsWrite` verifies: + +- Plan and DryRun against an actually absent value and disabled channel, with no write journal or mutation. +- Policy-only Configure creates exactly DWORD1 and leaves the disabled channel unchanged. +- Explicit `-EnablePrivacyChannel` enables the channel after the producer policy is verified, preserving its existing larger buffer, retention, complete descriptor and other native configuration. +- A combined call from DWORD0 and a disabled channel writes policy then channel, retaining exact typed original records and native readback. +- Repeated configuration produces only AlreadyCompliant results and no write journal. +- Actual string and unreviewed DWORD2 values are preserved; failed producer prerequisites prevent the dependent channel action. Unsupported preview arguments are rejected before dispatch. + +On Server 2025, Plan, Configure, DryRun and an explicit channel request exercise the existing unsupported-source refusal. They must not create the selected value, change a channel or write a pre-change journal. This is refusal evidence, not positive Server 2025 support. + +The fixture is restricted to explicitly opted-in disposable GitHub-hosted standalone servers. Only the fixture temporarily prepares the selected value and channel. It retains original and restored typed policy, full channel XML, unrelated DataCollection values/descendants and owner/group/DACL, Security/System/Application/CAPI2 settings, service status/start type, Security warning/CrashOnAuditFail and all59 audit masks. Each cleanup check runs independently and records errors. Event records produced during testing are not restored. The fixture never clears a log, requests GPO refresh, modifies diagnostic-data upload policy or invokes a OneSettings download. + +Owned public child processes have a three-minute deadline, bounded output, a bounded drain and confirmed termination before cleanup. The evidence manifest records commit, host/engine, source fingerprints and artifact hashes. These local hashes detect altered evidence; they are not signed attestation. Review the current four-way `Native public OneSettings configuration` workflow artifacts before relying on native acceptance. + +The broader [audit-notifications guide](audit-notifications.md) describes prerequisites and remaining Windows11, DC/AD CS, event-generation and intended-reader/collector evidence for issue #378. diff --git a/tests/OneSettingsConfigure.Cli.Tests.ps1 b/tests/OneSettingsConfigure.Cli.Tests.ps1 index 393a9fc3..883b139b 100644 --- a/tests/OneSettingsConfigure.Cli.Tests.ps1 +++ b/tests/OneSettingsConfigure.Cli.Tests.ps1 @@ -15,5 +15,12 @@ $cases=@( ) foreach($case in $cases){$old=$ErrorActionPreference;try{$ErrorActionPreference='Continue';$output=&$engine -NoLogo -NoProfile -NonInteractive -File "$repo/WELA.ps1" @($case.Args) 2>&1|Out-String;$code=$LASTEXITCODE}finally{$ErrorActionPreference=$old};if($code -ne $case.Code -or $output -notmatch $case.Pattern){throw "Public option case failed: $($case.Args -join ' ') [$code] $output"};$count++} if(Test-Path -LiteralPath $unused){throw 'Unsupported preview created a journal directory.'};$count++ +$defaultPath=$unused+'.json' +try{ + $old=$ErrorActionPreference;try{$ErrorActionPreference='Continue';$output=&$engine -NoLogo -NoProfile -NonInteractive -File "$repo/WELA.ps1" audit-notifications -ResultsPath $defaultPath 2>&1|Out-String;$code=$LASTEXITCODE}finally{$ErrorActionPreference=$old} + if(-not(Test-Path -LiteralPath $defaultPath)){throw ('Default public Audit failed to create its requested report: '+$output)} + $report=Get-Content -LiteralPath $defaultPath -Raw|ConvertFrom-Json + if($report.Action -cne 'Audit' -or $report.Current.Count -ne 2 -or (@($report.Current.Definition.Id|Sort-Object) -join ',') -cne 'OneSettings,SecurityWarning' -or $report.ExitCode -ne $code){throw 'Default Audit did not select both controls and preserve its truthful host-specific exit.'};$count++ +}finally{if(Test-Path -LiteralPath $defaultPath){Remove-Item -LiteralPath $defaultPath}} Write-Host "PASS: $count public OneSettings option guards." $global:LASTEXITCODE=0 diff --git a/website/docs/resources/changelog.ja.md b/website/docs/resources/changelog.ja.md index 854679ee..aceb06d4 100644 --- a/website/docs/resources/changelog.ja.md +++ b/website/docs/resources/changelog.ja.md @@ -7,6 +7,8 @@ **改善:** +- OneSettingsポリシーと明示的なPrivacyチャネル設定の公開CLIを実機検証します。Server 2022で実際の適用、型付き復元記録と再読取、冪等性、不正値の拒否を確認し、Server 2025の既存の拒否を維持します。両PowerShellで厳密な後処理を検証し、イベント生成やSigma対応は主張しません。通知コントロール省略時の引数渡しを修正し、既定のAuditは両項目を読み取り、項目未選択のConfigureは非ゼロで失敗します。(関連 #378) (@Shirofune-Security) + - 明示的な `registry-sacl-recovery` を追加しました。整合する4つの元記録、レビュー済み計画のハッシュ、過去・現在ともに空の子キー観測、監査縮小と継承への個別同意を必須とし、追加が証明されたレジストリルートの明示的な監査ACEを1つだけ削除します。SACLのみのネイティブ書き込みで他の記述子フィールドとACEの順序を保持し、部分的な書き込みの証跡と元の記述子バイトとの一致を別々に報告します。過去のキー・操作者の同一性認証、ツリー全体の原子性、イベント生成、Sigmaの準備完了は保証しません。 (Related #373) (@Shirofune-Security) - Server 2022/2025とPowerShell 5.1/7でSMBポリシー設定の公開CLIを検証します。対応ホストで6項目の適用・再読取・再実行、非対応ホストのスキップ、元の型付き記録、無関係な設定の維持と完全な復元を確認します。イベント生成と実行時の有効化は別途検証します。(関連 #377) (@Shirofune-Security) diff --git a/website/docs/resources/changelog.md b/website/docs/resources/changelog.md index 6b533916..926ab40c 100644 --- a/website/docs/resources/changelog.md +++ b/website/docs/resources/changelog.md @@ -7,6 +7,8 @@ **Improvements:** +- Add native public OneSettings policy and explicit Privacy-channel configuration acceptance: actual apply, typed journals/readback, idempotence and invalid-value refusals on Server 2022; preserve the existing Server 2025 refusal. Both PowerShell engines verify exact fixture cleanup without event or Sigma claims. Fix omitted notification-control dispatch so default Audit reads both controls and Configure without a selection fails with a nonzero exit. (Related #378) (@Shirofune-Security) + - Added opt-in `registry-sacl-recovery` for one proven explicit registry-root audit ACE, requiring four matching original records, a reviewed plan hash, empty historical/current descendants and separate audit-reduction/inheritance consent. Native SACL-only removal preserves unrelated descriptor fields and ACE order, retains partial-write evidence and reports original-byte equality separately; no authenticated historical key/operator identity, atomic-tree, event or Sigma claim. (Related #373) (@Shirofune-Security) - Add native public SMB policy configuration acceptance on Server 2022/2025 and PowerShell 5.1/7: six-policy apply/readback and idempotence on supported hosts, unsupported-host skips, typed original journals, unrelated-state preservation and exact cleanup. Event generation and runtime activation remain separate. (Related #377) (@Shirofune-Security)