mirror of
https://github.com/Yamato-Security/WELA.git
synced 2026-10-01 12:04:46 +02:00
46 lines
3.7 KiB
PowerShell
46 lines
3.7 KiB
PowerShell
# Fixed native5.1 worker. Automatic policy is the sole transcription producer.
|
|
param([Parameter(Mandatory)][ValidatePattern('^[a-f0-9]{32}$')][string]$Nonce)
|
|
$ErrorActionPreference='Stop'
|
|
[Console]::OutputEncoding=[Text.UTF8Encoding]::new($false)
|
|
if($PSVersionTable.PSEdition -cne 'Desktop' -or $PSVersionTable.PSVersion.Major -ne 5 -or $PSVersionTable.PSVersion.Minor -ne 1 -or -not [Environment]::Is64BitProcess){throw 'Native Windows PowerShell5.1 is required.'}
|
|
# A PowerShell7 parent can pass a PSModulePath without the native5.1 modules.
|
|
# Load only the fixed installed native modules, independent of caller module search paths.
|
|
foreach($module in @('Microsoft.PowerShell.Utility','Microsoft.PowerShell.Management')){
|
|
Import-Module ([IO.Path]::Combine($PSHOME,'Modules',$module,($module+'.psd1'))) -ErrorAction Stop
|
|
}
|
|
$script:ScriptRoot=Split-Path $PSScriptRoot -Parent
|
|
. (Join-Path $PSScriptRoot 'WmiProbe.ps1')
|
|
. (Join-Path $PSScriptRoot 'PowerShellTranscription.ps1')
|
|
Initialize-WelaWmiProbeNative
|
|
$assembly=[psobject].Assembly
|
|
$types=@($assembly.GetTypes()|Where-Object Name -eq 'InternalHostUserInterfaceStrings')
|
|
if($types.Count -ne 1){throw 'Native transcript resource type is unknown.'}
|
|
$resources=[ordered]@{}
|
|
foreach($name in @('TranscriptPrologue','TranscriptEpilogue')){
|
|
$property=$types[0].GetProperty($name,[Reflection.BindingFlags]'Public,NonPublic,Static')
|
|
if(-not $property){throw 'Native transcript resource is unavailable.'}
|
|
$value=$property.GetValue($null,$null)
|
|
if($value -isnot [string] -or $value.Length -gt 8192 -or -not $value.Contains('{0:yyyyMMddHHmmss}')){throw 'Unrecognized native transcript resource.'}
|
|
$resources[$name]=$value
|
|
}
|
|
$assemblyPath=$assembly.Location;$assemblyHash=(Get-FileHash -LiteralPath $assemblyPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
$policyBefore=@(Get-WelaTranscriptPolicy @('Registry64','Registry32'));Test-WelaTranscriptSharedPolicy $policyBefore
|
|
$before=[Wela.WmiProbe.Native]::Snapshot();$start=[DateTimeOffset]::Now
|
|
Microsoft.PowerShell.Utility\Write-Output ('WELA-TRANSCRIPT-BEGIN:'+${Nonce}+':'+$PID)
|
|
$policyAfter=@(Get-WelaTranscriptPolicy @('Registry64','Registry32'))
|
|
if(($policyBefore|ConvertTo-Json -Depth 12 -Compress) -cne ($policyAfter|ConvertTo-Json -Depth 12 -Compress)){throw 'Worker policy changed.'}
|
|
if((Get-FileHash -LiteralPath $assemblyPath -Algorithm SHA256).Hash.ToLowerInvariant() -cne $assemblyHash){throw 'Worker engine assembly changed.'}
|
|
$after=[Wela.WmiProbe.Native]::Snapshot()
|
|
if((Get-WelaWmiProbeTokenKey $before) -cne (Get-WelaWmiProbeTokenKey $after)){throw 'Worker token changed.'}
|
|
Microsoft.PowerShell.Utility\Write-Output ('WELA-TRANSCRIPT-END:'+${Nonce}+':'+$PID)
|
|
$end=[DateTimeOffset]::Now
|
|
$operation=[pscustomobject][ordered]@{
|
|
Nonce=$Nonce;ProcessId=$PID;Engine=(Get-Process -Id $PID).Path;EngineVersion=$PSVersionTable.PSVersion.ToString();Edition=$PSVersionTable.PSEdition
|
|
StartedUtc=$start.UtcDateTime.ToString('o');CompletedUtc=$end.UtcDateTime.ToString('o');StartOffsetMinutes=$start.Offset.TotalMinutes;EndOffsetMinutes=$end.Offset.TotalMinutes
|
|
BeforeToken=$before;AfterToken=$after;PolicyBefore=$policyBefore;PolicyAfter=$policyAfter
|
|
Computer=[Environment]::MachineName;HeaderUser=([Environment]::UserDomainName+'\'+[Environment]::UserName);OsVersion=[Environment]::OSVersion.VersionString
|
|
CommandLine=[Environment]::CommandLine;HeaderCommandLine=([Environment]::GetCommandLineArgs() -join ' ');Arguments=@([Environment]::GetCommandLineArgs());UiCulture=[Globalization.CultureInfo]::CurrentUICulture.Name
|
|
Assembly=[pscustomobject]@{Path=$assemblyPath;FullName=$assembly.FullName;Sha256=$assemblyHash};Resources=[pscustomobject]$resources
|
|
}
|
|
[Console]::WriteLine('WELA-WORKER-JSON:'+($operation|ConvertTo-Json -Depth 16 -Compress))
|