mirror of
https://github.com/Yamato-Security/WELA.git
synced 2026-11-09 22:49:58 +01:00
Reserve registry probe capacity and isolate exact-value cleanup
This commit is contained in:
1 parent
9575c8204d
commit
d72bf939a7
4 files changed
+39
-3
No files matched your search
@@ -7,7 +7,7 @@ function Reject([scriptblock]$Action){$threw=$false;try{& $Action|Out-Null}catch
|
||||
function Copy-Value($Value){ConvertFrom-WelaArrivalJson (Get-WelaFileProbeKey $Value)}
|
||||
function Fixture {
|
||||
$script:token=[pscustomobject]@{Sid='S-1-5-21-1-2-3-1001';Name='FIXTURE\Reader';AuthenticationId='0x1234';AuthenticationType='Negotiate';ImpersonationLevel='None';TokenSource='Process';Groups=@([pscustomobject]@{Sid='S-1-1-0';Attributes=7});Privileges=@([pscustomobject]@{Luid='0x8';Attributes=0})}
|
||||
$script:state=[pscustomobject]@{Computer='FIXTURE';Host=[pscustomobject]@{ProductType=3;Build=20348;DomainJoined=$false;Domain='WORKGROUP'};Services=@([pscustomobject]@{Name='EventLog';Status='Running'},[pscustomobject]@{Name='RpcSs';Status='Running'},[pscustomobject]@{Name='Winmgmt';Status='Running'});Reader=[pscustomobject]@{UserSid=$script:token.Sid;ElevatedAdministrator=$true;TokenType='Primary';Impersonation='Absent'};Token=Copy-Value $script:token;Registry=[pscustomobject]@{Path=('HKEY_USERS\'+$script:token.Sid+'\Software\WELA\AuditProbe');Kind='Registry';IsDirectory=$false;Identity='fixed:123';DescriptorBase64='AA==';SecurityInformation=511;Values=@();Aces=@([pscustomobject]@{Ordinary=$true;Type=2;Flags=64;Mask=2;Sid='S-1-1-0';Binary='AA=='})};AuditPolicies=[pscustomobject]@{'0CCE921E-69AE-11D9-BED3-505054503030'=1};Precedence=[pscustomobject]@{ValueExists=$true;Type='DWord';Value=1};Channel=[pscustomobject]@{Name='Security';Enabled=$true;SecurityDescriptor='O:SYG:SYD:'};Engine='C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe';EngineHash=('b'*64);Sources=[pscustomobject]@{Source=('c'*64)}}
|
||||
$script:state=[pscustomobject]@{Computer='FIXTURE';Host=[pscustomobject]@{ProductType=3;Build=20348;DomainRole=2;DomainJoined=$false;Domain='WORKGROUP'};Services=@([pscustomobject]@{Name='EventLog';Status='Running'},[pscustomobject]@{Name='RpcSs';Status='Running'},[pscustomobject]@{Name='Winmgmt';Status='Running'});Reader=[pscustomobject]@{UserSid=$script:token.Sid;ElevatedAdministrator=$true;TokenType='Primary';Impersonation='Absent'};Token=Copy-Value $script:token;Registry=[pscustomobject]@{Path=('HKEY_USERS\'+$script:token.Sid+'\Software\WELA\AuditProbe');Kind='Registry';IsDirectory=$false;Identity='fixed:123';DescriptorBase64='AA==';SecurityInformation=511;Values=@();Aces=@([pscustomobject]@{Ordinary=$true;Type=2;Flags=64;Mask=2;Sid='S-1-1-0';Binary='AA=='})};AuditPolicies=[pscustomobject]@{'0CCE921E-69AE-11D9-BED3-505054503030'=1};Precedence=[pscustomobject]@{ValueExists=$true;Type='DWord';Value=1};Channel=[pscustomobject]@{Name='Security';Enabled=$true;SecurityDescriptor='O:SYG:SYD:'};Engine='C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe';EngineHash=('b'*64);Sources=[pscustomobject]@{Source=('c'*64)}}
|
||||
$n='d'*32;$script:operation=[pscustomobject]@{Kind='WelaOwnedRegistryValueModification';Nonce=$n;ProcessId=1234;Executable=$script:state.Engine;RecordIdBefore=10;BeforeToken=Copy-Value $script:token;AfterToken=Copy-Value $script:token;LaunchedUtc='2026-09-21T00:00:00.0000000Z';ObservedUtc='2026-09-21T00:00:01.0000000Z';Native=[pscustomobject]@{Succeeded=$true;CleanupComplete=$true;Nonce=$n;Name=('WELA_Probe_'+$n);BeforeValue=('WELA_BEFORE_'+$n);AfterValue=('WELA_AFTER_'+$n);HandleId='0x888';Before=Copy-Value $script:state.Registry;After=Copy-Value $script:state.Registry;StartedUtc='2026-09-21T00:00:00.0001000Z';WriteReturnedUtc='2026-09-21T00:00:00.0001600Z';CompletedUtc='2026-09-21T00:00:00.0002000Z';Diagnostic=''}}
|
||||
$script:stateReads=0;$script:attempts=0;$script:batchMode='match';$script:failArtifact=$null;$script:afterDrift=$false
|
||||
}
|
||||
@@ -22,6 +22,9 @@ foreach($bad in @('path','mask','precedence','channel','role','group','inherit-o
|
||||
switch($bad){'path'{$script:state.Registry.Path='HKEY_LOCAL_MACHINE\Software\WELA\AuditProbe'};'mask'{$script:state.AuditPolicies.'0CCE921E-69AE-11D9-BED3-505054503030'=0};'precedence'{$script:state.Precedence.Value=$true};'channel'{$script:state.Channel.Enabled='true'};'role'{$script:state.Host.ProductType=$true};'group'{$script:state.Token.Groups[0].Attributes=16};'inherit-only'{$script:state.Registry.Aces[0].Flags=72};'failure'{$script:state.Registry.Aces[0].Flags=128};'callback'{$script:state.Registry.Aces[0].Ordinary=$false};'right'{$script:state.Registry.Aces[0].Mask=1};'descriptor'{$script:state.Registry.DescriptorBase64=$null};'sources'{$script:state.Sources.Source='bad'};'token'{$script:state.Token.TokenSource='Thread'}}
|
||||
Reject {Get-WelaRegistryValueProbeStateKey $script:state}
|
||||
}
|
||||
foreach($badRole in @($null,$true,0,4)) {Fixture;$script:state.Host.DomainRole=$badRole;Reject {Get-WelaRegistryValueProbeStateKey $script:state}}
|
||||
Fixture;$script:state.Host.DomainJoined=$true;Reject {Get-WelaRegistryValueProbeStateKey $script:state}
|
||||
Fixture;$script:state.Host.Build=22631;Reject {Get-WelaRegistryValueProbeStateKey $script:state}
|
||||
foreach($bad in @('nonce','success','cleanup','key','values','before','after','reverse','handle','token')){
|
||||
Fixture
|
||||
switch($bad){'nonce'{$script:operation.Nonce='invalid'};'success'{$script:operation.Native.Succeeded='true'};'cleanup'{$script:operation.Native.CleanupComplete=$false};'key'{$script:operation.Native.After.Path='wrong'};'values'{$script:operation.Native.After.Values=@('new')};'before'{$script:operation.Native.StartedUtc='2026-09-20T00:00:00Z'};'after'{$script:operation.Native.CompletedUtc='2026-09-22T00:00:00Z'};'reverse'{$script:operation.Native.WriteReturnedUtc='2026-09-21T00:00:00Z'};'handle'{$script:operation.Native.HandleId='0x0'};'token'{$script:operation.AfterToken.Privileges[0].Attributes=2}}
|
||||
@@ -34,6 +37,17 @@ foreach($badXml in @($xml.Replace('</EventData>','<Data Name="OldValue">duplicat
|
||||
function Initialize-WelaWmiProbeNative {}
|
||||
Initialize-WelaRegistryValueProbe
|
||||
Assert ([Wela.RegistryValueProbe.Descriptor]::SourceSha256 -ceq (Get-FileHash (Join-Path $script:ScriptRoot 'scripts/RegistryValueProbeNative.cs')).Hash.ToLowerInvariant()) 'Exact native source hash is bound.'
|
||||
# The temporary value must fit the same inventory bounds used for final readback.
|
||||
$small=[Wela.RegistryValueProbe.Value]::new();$small.Name='small';$small.Type=3;$small.DataBase64='AA=='
|
||||
[Wela.RegistryValueProbe.Descriptor]::AssertProbeCapacity([Wela.RegistryValueProbe.Value[]]@((1..127|ForEach-Object{$small})))
|
||||
Assert $true '127 original values leave room for exactly one owned marker.'
|
||||
Reject {[Wela.RegistryValueProbe.Descriptor]::AssertProbeCapacity([Wela.RegistryValueProbe.Value[]]@((1..128|ForEach-Object{$small})))}
|
||||
$large=[Wela.RegistryValueProbe.Value]::new();$large.Type=3;$large.DataBase64=[Convert]::ToBase64String([byte[]]::new(65536))
|
||||
Reject {[Wela.RegistryValueProbe.Descriptor]::AssertProbeCapacity([Wela.RegistryValueProbe.Value[]]@((1..16|ForEach-Object{$large})))}
|
||||
$reserved=[Text.Encoding]::Unicode.GetByteCount('WELA_BEFORE_'+('0'*32)+[char]0)
|
||||
$tail=[Wela.RegistryValueProbe.Value]::new();$tail.Type=3;$tail.DataBase64=[Convert]::ToBase64String([byte[]]::new(65536-$reserved))
|
||||
[Wela.RegistryValueProbe.Descriptor]::AssertProbeCapacity([Wela.RegistryValueProbe.Value[]](@((1..15|ForEach-Object{$large}))+@($tail)))
|
||||
Assert $true 'Exactly reserved byte capacity is accepted.'
|
||||
$writer=(Get-Command Write-WelaFileProbeArtifact).ScriptBlock
|
||||
function Get-WelaFileProbeOutputKey {param($Path) 'private-fixture'}
|
||||
function Write-WelaFileProbeArtifact {param($Root,$OutputKey,$Name,$Text) if($Name -eq $script:failArtifact){throw 'Injected artifact failure'};& $script:writer $Root $OutputKey $Name $Text}
|
||||
|
||||
Reference in new issue
Block a user