mirror of
https://github.com/Yamato-Security/WELA.git
synced 2026-10-08 07:15:25 +02:00
Document bounded WMI tree guarantees and record native protection behavior
This commit is contained in:
1 parent
036f51886a
commit
ddcdd8e2b8
11 files changed
+71
-8
No files matched your search
@@ -110,3 +110,8 @@ tests/NativeProviderConfigure.Windows.Tests.ps1 text eol=lf
|
||||
# Public filesystem-SACL disposable lifecycle evidence.
|
||||
tests/FileSaclProfileFixture.cs text eol=lf
|
||||
tests/FileSaclLifecycle.Windows.Tests.ps1 text eol=lf
|
||||
|
||||
# Native WMI tree evidence binds source bytes across checkouts.
|
||||
/scripts/WmiNamespaceAuditing.ps1 text eol=lf
|
||||
/scripts/WmiNamespaceDescendants.ps1 text eol=lf
|
||||
/tests/WmiNamespaceDescendants* text eol=lf
|
||||
@@ -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, ./docs/audit-catalog-mappings.md, ./docs/native-token-right-attribution.md, ./docs/audit-notifications.md, ./docs/native-onesettings-acceptance.md, ./docs/ntlm-auditing.md, ./docs/wef-query.md, ./docs/native-filesystem-sacl-validation.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-catalog-mappings.md, ./docs/native-token-right-attribution.md, ./docs/audit-notifications.md, ./docs/native-onesettings-acceptance.md, ./docs/ntlm-auditing.md, ./docs/wef-query.md, ./docs/native-filesystem-sacl-validation.md, ./docs/wmi-namespace-auditing.md, ./docs/wmi-descendants.md -Destination release-binaries/docs/
|
||||
|
||||
- name: Set Artifact Name
|
||||
if: contains(matrix.info.os, 'windows') == true
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
**改善:**
|
||||
|
||||
- WMI の明示的な継承設定に、既存の子名前空間の上限付き調査、完全な変更前記録、ツリー変更の拒否を追加しました。親の SACL のみを書き込み、継承・保護状態と最終状態を確認します。不完全な伝播は失敗として扱い、子への直接書き込み、自動復元、イベントや Sigma 対応を保証しません。(Related #372) (@Shirofune-Security)
|
||||
|
||||
- Server2022/2025 と PowerShell5.1/7 で、Token Right Adjusted の正規GUIDに対する Security4703 の実機検証を追加しました。所有する子プロセスの既存権限を固定手順で無効化・復元し、候補となる2つの監査マスクを比較して、実イベント・実行条件・ハッシュとポリシー/トークンの復元を記録します。過去の候補は条件付きのまま維持し、製品用プローブ・全OS共通の対応関係・Sigma加点は追加しません。(関連 #380) (@Shirofune-Security)
|
||||
|
||||
- OneSettingsポリシーと明示的なPrivacyチャネル設定の公開CLIを実機検証します。Server 2022で実際の適用、型付き復元記録と再読取、冪等性、不正値の拒否を確認し、Server 2025の既存の拒否を維持します。両PowerShellで厳密な後処理を検証し、イベント生成やSigma対応は主張しません。通知コントロール省略時の引数渡しを修正し、既定のAuditは両項目を読み取り、項目未選択のConfigureは非ゼロで失敗します。(関連 #378) (@Shirofune-Security)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
**Improvements:**
|
||||
|
||||
- Added bounded existing-descendant snapshots, full recovery evidence and stale-tree guards for explicit WMI inheritance. Parent-only SACL writes now require native inherited/protected readbacks and final drift checks; incomplete propagation fails without child setters, rollback ownership, event or Sigma credit. (Related #372) (@Shirofune-Security)
|
||||
|
||||
- Added disposable native Security4703 attribution for the canonical Token Right Adjusted GUID on Server2022/2025 and PowerShell5.1/7. A fixed owned-child privilege disable/restore compares the two historical audit-mask candidates, retains exact event/context/hash evidence and verifies policy/token cleanup. Historical candidates remain conditional; no production probe, universal mapping or Sigma credit. (Related #380) (@Shirofune-Security)
|
||||
|
||||
- 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)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Reviewed WMI namespace descendants
|
||||
|
||||
`wmi-auditing -WmiIncludeChildren` now inventories existing descendants before an inheritable parent SACL write. It still accepts only the five reviewed local catalog namespaces. The CIMV2 definitions use parent-only flags even when this option is selected; the four reference definitions with flag66 receive the extra safeguards. No descendant is passed to a setter.
|
||||
|
||||
```powershell
|
||||
./WELA.ps1 wmi-auditing -WmiAction Plan -WmiNamespace 'root\default' -WmiIncludeChildren -ResultsPath tree-plan.json
|
||||
./WELA.ps1 wmi-auditing -WmiAction Configure -WmiNamespace 'root\default' -WmiIncludeChildren -DryRun -ResultsPath tree-dry-run.json
|
||||
./WELA.ps1 wmi-auditing -WmiAction Configure -WmiNamespace 'root\default' -WmiIncludeChildren -BackupPath C:\Evidence\new-wmi-backup -ResultsPath tree-result.json
|
||||
```
|
||||
|
||||
Review `Controls[].Descendants` and the full descriptor strings before configuration. Configure builds a fresh in-memory plan, shows the descendant count in its confirmation, and checks that same tree again before writing. The earlier Plan export is documentation of its observation, not a persisted authorization token consumed by Configure. `-Auto` skips the confirmation only; it does not skip the tree checks.
|
||||
|
||||
The inventory records every existing child and grandchild within 64 descendants, eight levels and two MiB of descriptor evidence. Two complete passes must agree on names, parent relationships and every full descriptor. Unknown names, duplicates, access failures, caps, incomplete reads and drift fail closed. The scan checks a 30-second budget between namespaces, and native enumeration requests a ten-second timeout. Individual synchronous provider calls cannot be forcibly cancelled, so this is not a hard total runtime limit. Winmgmt must already be running. Host, implementation fingerprints and the full observed caller SID, logon, groups and privilege attributes must remain unchanged.
|
||||
|
||||
`before.jsonl` retains the existing parent `DescriptorJson` and `DescriptorMof` fields and adds complete descendant descriptor strings. After confirmation and journaling, another stable inventory must match before the parent-only SACL setter is reached. A journal or guard failure prevents that setter. Original parent ACEs and owner/group/DACL continue to use the existing preservation contract.
|
||||
|
||||
After a write, the command requires the same existing descendants, preserves every unrelated descriptor field and original ACE multiplicity, and accepts only the exact requested inherited success ACEs. A returned `SE_SACL_PROTECTED` bit is treated conservatively as a preservation barrier for that namespace and its descendants: the entire observed descriptor must stay unchanged. This does not establish that every WMI provider enforces that bit. Missing inherited entries, an unexpected ACE, changed protection or a new/disappearing namespace is unverified and causes a nonzero result. A final full tree read checks for later drift. Results include the individual descendant observations and diagnostics.
|
||||
|
||||
Microsoft documents [namespace inheritance when a child is created](https://learn.microsoft.com/en-us/windows/win32/wmisdk/establishing-inheritance-of-namespace-security) and the [inherited ACE flag](https://learn.microsoft.com/en-us/windows/win32/wmisdk/namespace-ace-flag-constants). This does not establish that adding an inheritable ACE retroactively updates every existing child. A successful parent setter can therefore be followed by a failed descendant verification. The parent addition may remain in place; the command does not retry child writes or claim subtree success. A repeat also fails when the parent is already compliant but existing descendants lack the requested inherited entry. Inspect the recorded native outcomes before choosing a separately reviewed child configuration or recovery procedure.
|
||||
|
||||
There is no transaction across the tree. A concurrent change between the final pre-write observations and the provider call remains possible. Namespace names do not establish durable identity across deletion/recreation. No automatic rollback, descendant ACE ownership, future-child behavior, event generation, remote WMI, forwarding or Sigma readiness is inferred. [SetSecurityDescriptor's SACL-only contract](https://learn.microsoft.com/en-us/windows/win32/wmisdk/setsecuritydescriptor-method-in-class---systemsecurity) preserves owner, group and DACL by omitting those fields from the request.
|
||||
|
||||
Native acceptance uses generated `root\WelaInheritance_<GUID>` namespaces on disposable Server2022/2025 hosts, runs the production inventory/configuration functions, records exact provider outcomes and removes only owned instances in reverse creation order. It does not redirect the production catalog or write existing production namespaces. Synthetic tests separately exercise caps, stale descriptors, protected subtrees, missing inheritance, unexpected child changes and final failure propagation. Windows11, production target writes, DC/ADCS role behavior and forwarding remain unverified.
|
||||
@@ -29,7 +29,7 @@ The entries come from the [ASD WMI script pinned at 59041b5](https://github.com/
|
||||
| `root\subscription` | Everyone | `0x4001E` (262174) | Execute Methods, Full Write, Partial Write, Provider Write, Edit Security | 66 |
|
||||
| `root\default` | Everyone | `0x4001F` (262175) | Read plus all preceding rights | 66 |
|
||||
|
||||
The numeric subscription mask includes Execute Methods even though the reference script's comment omits it. WELA uses the actual numeric mask. Flags 64 mean success on this namespace; 66 add container inheritance. **By default WELA uses 64 for every selection**, limiting new entries to that namespace. `-WmiIncludeChildren` enables the reference's flag 66 for the four applicable namespaces. This may propagate audit ACEs to inheriting descendants, including existing and future child namespaces; it does not grant access. Child ACL propagation is not enumerated, backed up or verified by this command, and is an explicit additional scope requiring a lab review. Existing inherited entries are retained in either mode. SecurityCenter namespaces are commonly absent on servers; absence is reported rather than treated as successful configuration.
|
||||
The numeric subscription mask includes Execute Methods even though the reference script's comment omits it. WELA uses the actual numeric mask. Flags 64 mean success on this namespace; 66 add container inheritance. **By default WELA uses 64 for every selection**, limiting new entries to that namespace. `-WmiIncludeChildren` enables the reference's flag 66 for the four applicable namespaces. This may propagate audit ACEs to inheriting descendants, including existing and future child namespaces; it does not grant access. Existing descendants are now enumerated, journaled and checked before and after the parent-only setter; incomplete inventories or unverified inheritance fail the operation. Review the [bounded descendant safeguards](wmi-descendants.md), including provider limitations and possible parent-only partial outcomes. Existing inherited entries are retained in either mode. SecurityCenter namespaces are commonly absent on servers; absence is reported rather than treated as successful configuration.
|
||||
|
||||
## Privileges, preservation and results
|
||||
|
||||
@@ -51,9 +51,9 @@ WELA separately observes the effective **Other Object Access Events** audit poli
|
||||
|
||||
## Recovery and remaining lab verification
|
||||
|
||||
Keep the new backup directory and result JSON outside temporary folders. `before.jsonl` contains each selected namespace's original `DescriptorJson` and `DescriptorMof`, namespace name and proposed entries. Compare these with a fresh Audit export before making any recovery change. In an elevated WMI Control (`wmimgmt.msc`), select the exact namespace, Security > Advanced > Auditing, and remove only entries that this run added after confirming they were absent from the original descriptor. Restore changed audit flags/masks from the original export if necessary; retain unrelated owner/group/DACL and newer administrative changes. WELA deliberately provides no blind whole-descriptor restore. An existing matching ACE was not created by this run and must not be removed. If descendant inheritance was enabled, inspect affected child namespaces independently and use a pre-change machine snapshot if a complete rollback is needed.
|
||||
Keep the new backup directory and result JSON outside temporary folders. `before.jsonl` contains each selected namespace's original `DescriptorJson` and `DescriptorMof`, namespace name and proposed entries. Compare these with a fresh Audit export before making any recovery change. In an elevated WMI Control (`wmimgmt.msc`), select the exact namespace, Security > Advanced > Auditing, and remove only entries that this run added after confirming they were absent from the original descriptor. Restore changed audit flags/masks from the original export if necessary; retain unrelated owner/group/DACL and newer administrative changes. WELA deliberately provides no blind whole-descriptor restore. An existing matching ACE was not created by this run and must not be removed. If descendant inheritance was enabled, retain the descendant snapshots and inspect each reported outcome; these observations confer no descendant ACE ownership or automatic rollback authority. Use a pre-change machine snapshot if a complete rollback is needed.
|
||||
|
||||
CI uses synthetic descriptors, a real privileged read of root\cimv2, an in-memory native writer adapter and a read-only dry-run on Windows PowerShell 5.1/7. A separate integration job performs real SACL writes only on uniquely created temporary namespaces on disposable Server 2022/2025 runners, verifies read-back/idempotence and deletes its own namespaces. It never changes the SACL of an existing namespace. **Writes to the five production target namespaces, Windows 11 behavior, benign local/remote event generation, child propagation and forwarding have not been verified by these tests.** Before deployment, use isolated patched snapshots of Windows 11, member server, domain controller and AD CS hosts; record descriptors/effective audit policy before and after, repeat configuration for idempotence, issue benign local and remote calls with known tokens, capture Security 4662 XML, and test the chosen WEF subscription and collector receipt. Validate namespace `ObjectName` and access masks, not EventID alone. These are pending acceptance labs, not claimed Sigma uplift.
|
||||
CI uses synthetic descriptors, a real privileged read of root\cimv2, an in-memory native writer adapter and a read-only dry-run on Windows PowerShell 5.1/7. A separate integration job performs real SACL writes only on uniquely created temporary namespaces on disposable Server 2022/2025 runners, verifies read-back/idempotence and deletes its own namespaces. It never changes the SACL of an existing namespace. **Writes to the five production target namespaces, Windows 11 behavior, benign local/remote event generation and forwarding have not been verified by these tests.** A separate [descendant acceptance fixture](wmi-descendants.md) records native existing-child outcomes and owned new-child inheritance without extrapolating production-tree behavior. Before deployment, use isolated patched snapshots of Windows 11, member server, domain controller and AD CS hosts; record descriptors/effective audit policy before and after, repeat configuration for idempotence, issue benign local and remote calls with known tokens, capture Security 4662 XML, and test the chosen WEF subscription and collector receipt. Validate namespace `ObjectName` and access masks, not EventID alone. These are pending acceptance labs, not claimed Sigma uplift.
|
||||
|
||||
Additional primary references: [SetSecurityDescriptor and preservation flags](https://learn.microsoft.com/en-us/windows/win32/wmisdk/setsecuritydescriptor-method-in-class---systemsecurity), [namespace access masks](https://learn.microsoft.com/en-us/windows/win32/wmisdk/namespace-access-rights-constants), [namespace inheritance flags](https://learn.microsoft.com/en-us/windows/win32/wmisdk/namespace-ace-flag-constants).
|
||||
|
||||
|
||||
@@ -264,7 +264,12 @@ function Get-WelaWmiAuditPlan {
|
||||
} else {$snapshot = Get-WelaWmiNamespaceSnapshot $name}
|
||||
$descriptor = $snapshot.DescriptorJson | ConvertFrom-Json
|
||||
$missing = @(Get-WelaWmiMissingAces $descriptor $selected)
|
||||
[pscustomobject]@{ Namespace = $name; Status = $(if ($missing.Count) { 'ChangeRequired' } else { 'AlreadyCompliant' }); Before = $snapshot; Definitions = $selected; Missing = $missing; Descendants=$tree; Diagnostic = '' }
|
||||
$status=if($missing.Count){'ChangeRequired'}else{'AlreadyCompliant'};$diagnostic=''
|
||||
if($tree -and -not $missing.Count){
|
||||
$outcomes=Test-WelaWmiDescendantOutcomes $tree $tree $selected
|
||||
if($outcomes.Status -cne 'Observed'){$status='Unknown';$diagnostic='Parent entry exists but descendants are unverified: '+($outcomes.Diagnostics -join '; ')}
|
||||
}
|
||||
[pscustomobject]@{ Namespace = $name; Status = $status; Before = $snapshot; Definitions = $selected; Missing = $missing; Descendants=$tree; Diagnostic = $diagnostic }
|
||||
} catch { [pscustomobject]@{ Namespace = $name; Status = 'Unknown'; Before = $null; Definitions = $selected; Missing = @(); Diagnostic = $_.Exception.Message } }
|
||||
}
|
||||
}
|
||||
@@ -282,6 +287,7 @@ function Set-WelaWmiAuditControls {
|
||||
if((Get-WelaWmiDescendantKey $tree) -cne (Get-WelaWmiDescendantKey $state.PlannedTree)){throw 'WMI descendant tree changed after planning; no SACL was written.'}
|
||||
$state.OriginalTree=$tree
|
||||
}
|
||||
if($tree.Context -cne $state.OriginalTree.Context){throw 'Caller token, host, source or service context changed since descendant planning.'}
|
||||
$snapshot=$tree.Root|Select-Object *
|
||||
$snapshot|Add-Member NoteProperty Descendants $tree -Force
|
||||
} else {$snapshot = Get-WelaWmiNamespaceSnapshot $state.Namespace}
|
||||
|
||||
@@ -4,7 +4,7 @@ function Get-WelaWmiDescendantContext {
|
||||
Initialize-WelaWmiProbeNative
|
||||
if((Get-Service Winmgmt -ErrorAction Stop).Status -ne 'Running'){throw 'Winmgmt must already be running before descendant observation.'}
|
||||
$sources=[ordered]@{}
|
||||
foreach($name in @('WmiNamespaceAuditing.ps1','WmiNamespaceDescendants.ps1','WmiProbeNative.cs')){$sources[$name]=(Get-FileHash -LiteralPath (Join-Path $PSScriptRoot $name) -Algorithm SHA256 -ErrorAction Stop).Hash}
|
||||
foreach($name in @('WmiNamespaceAuditing.ps1','WmiNamespaceDescendants.ps1','WmiProbeNative.cs','WmiProbe.ps1','Configuration.ps1')){$sources[$name]=(Get-FileHash -LiteralPath (Join-Path $PSScriptRoot $name) -Algorithm SHA256 -ErrorAction Stop).Hash}
|
||||
[ordered]@{Computer=[Environment]::MachineName;Version=[Environment]::OSVersion.VersionString;Token=(Get-WelaWmiProbeTokenKey ([Wela.WmiProbe.Native]::Snapshot()));Sources=$sources}|ConvertTo-Json -Compress -Depth 5
|
||||
}
|
||||
function Get-WelaWmiChildNames {
|
||||
|
||||
@@ -32,6 +32,21 @@ function Configure($Entry,[string]$Name,[switch]$DryRun){
|
||||
Set-WelaWmiAuditControls -Context $c -Plan @($Entry)
|
||||
Complete-WelaConfiguration -Context $c -Scope wmi-namespace-sacl-only
|
||||
}
|
||||
function Observe-OwnedProtection([string]$Namespace){
|
||||
$before=Get-WelaWmiNamespaceSnapshot $Namespace
|
||||
$privilege=New-Object Wela.WmiSecurityPrivilege;$connection=$null;$response=$null
|
||||
try{
|
||||
$connection=New-WelaWmiConnection $Namespace;$descriptor=Get-WelaWmiNativeDescriptor $connection
|
||||
$request=$descriptor.Clone();$request.DACL=$null;$request.Owner=$null;$request.Group=$null
|
||||
$request.ControlFlags=([uint32]$descriptor.ControlFlags -band [uint32]4294967291) -bor [uint32]8208
|
||||
$parameters=$connection.GetMethodParameters('SetSecurityDescriptor');$parameters.Descriptor=$request
|
||||
$response=$connection.InvokeMethod('SetSecurityDescriptor',$parameters,$null)
|
||||
}finally{try{if($connection){$connection.Dispose()}}finally{$privilege.Dispose()}}
|
||||
$after=Get-WelaWmiNamespaceSnapshot $Namespace;$a=$before.DescriptorJson|ConvertFrom-Json;$b=$after.DescriptorJson|ConvertFrom-Json
|
||||
foreach($property in $a.PSObject.Properties){if($property.Name -ne 'ControlFlags'){Assert ((ConvertTo-WelaWmiJson $property.Value) -ceq (ConvertTo-WelaWmiJson $b.($property.Name))) 'Protection fixture changed an unrelated descriptor field.'}}
|
||||
Assert (([uint32]$a.ControlFlags -band (-bnot 8192)) -eq ([uint32]$b.ControlFlags -band (-bnot 8192))) 'Protection fixture changed unrelated controls.'
|
||||
[pscustomobject]@{Namespace=$Namespace;ReturnValue=$response.ReturnValue;Before=$before;After=$after;ProtectionObserved=(([uint32]$b.ControlFlags -band 8192) -ne 0)}
|
||||
}
|
||||
$backup=Join-Path ([IO.Path]::GetTempPath()) ('wela-wmi-tree-'+[guid]::NewGuid().ToString('N'))
|
||||
$e=[ordered]@{SchemaVersion=1;Host=$env:COMPUTERNAME;Version=[Environment]::OSVersion.VersionString;PowerShell=$PSVersionTable.PSVersion.ToString();Head=$env:GITHUB_SHA;Cases=@();Before=$null;After=$null;Sources=@();Cleanup=@();Complete=$false;Failure=$null}
|
||||
$failure=$null
|
||||
@@ -45,8 +60,14 @@ try{
|
||||
$s=Get-WelaWmiNamespaceSnapshot $special
|
||||
$specialDef=[pscustomobject]@{Sid='S-1-5-18';AccessMask=[uint32]1;AceFlags=[uint32]128}
|
||||
$null=Set-WelaWmiNamespaceDescriptor $special $s.DescriptorJson @($specialDef)
|
||||
$protected=New-OwnedNamespace $root Protected
|
||||
$s=Get-WelaWmiNamespaceSnapshot $protected
|
||||
$null=Set-WelaWmiNamespaceDescriptor $protected $s.DescriptorJson @($specialDef)
|
||||
$protection=Observe-OwnedProtection $protected
|
||||
$protectedGrand=New-OwnedNamespace $protected Grandchild
|
||||
$e.Cases+=@{Name='NativeProtectionObservation';Observation=$protection}
|
||||
$p=Entry $root
|
||||
Assert ($p.Descendants.Entries.Count -eq 3) 'All existing children and the grandchild are captured.'
|
||||
Assert ($p.Descendants.Entries.Count -eq 5) 'All existing children and grandchildren are captured.'
|
||||
$dry=Configure $p dry -DryRun
|
||||
Assert ($dry.ExitCode -eq 0 -and $dry.Results[0].Status -eq 'Skipped' -and -not (Test-Path $backup)) 'Tree dry-run wrote state or backup.'
|
||||
Assert ((Get-WelaWmiDescendantKey (Get-WelaWmiStableDescendants $root)) -ceq (Get-WelaWmiDescendantKey $p.Descendants)) 'Dry-run changed tree.'
|
||||
@@ -63,7 +84,7 @@ try{
|
||||
$outcome=Test-WelaWmiDescendantOutcomes $p.Descendants $after $p.Definitions
|
||||
Assert (($outcome.Status -eq 'Observed' -and $result.ExitCode -eq 0) -or ($outcome.Status -eq 'Unverified' -and $result.ExitCode -eq 1)) 'Configuration status misrepresents actual child observations.'
|
||||
$journal=@(Get-Content (Join-Path $backup 'apply/before.jsonl')|ConvertFrom-Json)
|
||||
Assert ($journal.Count -eq 1 -and $journal[0].Before.Descendants.Entries.Count -eq 4) 'Original complete subtree missing from journal.'
|
||||
Assert ($journal.Count -eq 1 -and $journal[0].Before.Descendants.Entries.Count -eq 6) 'Original complete subtree missing from journal.'
|
||||
Assert ((Get-WelaWmiDescendantKey $journal[0].Before.Descendants) -ceq (Get-WelaWmiDescendantKey $p.Descendants)) 'Journal tree differs from pre-write snapshots.'
|
||||
$e.Cases+=@{Name='ExistingTree';Plan=$p;Result=$result;After=$after;Outcomes=$outcome;Journal=$journal}
|
||||
# A genuinely newly created namespace independently demonstrates provider inheritance.
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
**改善:**
|
||||
|
||||
- WMI の明示的な継承設定に、既存の子名前空間の上限付き調査、完全な変更前記録、ツリー変更の拒否を追加しました。親の SACL のみを書き込み、継承・保護状態と最終状態を確認します。不完全な伝播は失敗として扱い、子への直接書き込み、自動復元、イベントや Sigma 対応を保証しません。(Related #372) (@Shirofune-Security)
|
||||
|
||||
- Server2022/2025 と PowerShell5.1/7 で、Token Right Adjusted の正規GUIDに対する Security4703 の実機検証を追加しました。所有する子プロセスの既存権限を固定手順で無効化・復元し、候補となる2つの監査マスクを比較して、実イベント・実行条件・ハッシュとポリシー/トークンの復元を記録します。過去の候補は条件付きのまま維持し、製品用プローブ・全OS共通の対応関係・Sigma加点は追加しません。(関連 #380) (@Shirofune-Security)
|
||||
|
||||
- OneSettingsポリシーと明示的なPrivacyチャネル設定の公開CLIを実機検証します。Server 2022で実際の適用、型付き復元記録と再読取、冪等性、不正値の拒否を確認し、Server 2025の既存の拒否を維持します。両PowerShellで厳密な後処理を検証し、イベント生成やSigma対応は主張しません。通知コントロール省略時の引数渡しを修正し、既定のAuditは両項目を読み取り、項目未選択のConfigureは非ゼロで失敗します。(関連 #378) (@Shirofune-Security)
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
**Improvements:**
|
||||
|
||||
- Added bounded existing-descendant snapshots, full recovery evidence and stale-tree guards for explicit WMI inheritance. Parent-only SACL writes now require native inherited/protected readbacks and final drift checks; incomplete propagation fails without child setters, rollback ownership, event or Sigma credit. (Related #372) (@Shirofune-Security)
|
||||
|
||||
- Added disposable native Security4703 attribution for the canonical Token Right Adjusted GUID on Server2022/2025 and PowerShell5.1/7. A fixed owned-child privilege disable/restore compares the two historical audit-mask candidates, retains exact event/context/hash evidence and verifies policy/token cleanup. Historical candidates remain conditional; no production probe, universal mapping or Sigma credit. (Related #380) (@Shirofune-Security)
|
||||
|
||||
- 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)
|
||||
|
||||
Reference in new issue
Block a user