Public/Compare-OffsetThreatResult.ps1
|
function Compare-OffsetThreatResult { <# .SYNOPSIS Compares two threat-scan results and classifies how detection changed between them. .DESCRIPTION Diffs a reference result against a difference result (for example the same file scanned before and after a Defender signature-definition update, or two variants of a payload) and reports which fields changed, the boundary delta, and an overall classification: NewlyDetected, NoLongerDetected, BoundaryEarlier, BoundaryLater, BoundaryUnchanged, or BothClean. Operates on result objects only, so it runs on every platform. .PARAMETER Reference The baseline OffsetInspect.ThreatScanResult. .PARAMETER Difference The result to compare against the baseline. .EXAMPLE $before = Invoke-OffsetThreatScan .\sample.ps1 -Engine Defender -PassThru # ... update signature definitions ... $after = Invoke-OffsetThreatScan .\sample.ps1 -Engine Defender -PassThru Compare-OffsetThreatResult -Reference $before -Difference $after #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [pscustomobject]$Reference, [Parameter(Mandatory = $true, Position = 1)] [pscustomobject]$Difference ) $comparedFields = @( 'InitialStatus', 'DetectionPrefixLength', 'DetectionBoundaryOffset', 'DetectionBoundaryHex', 'Stable', 'Confidence', 'SignatureName' ) $changes = New-Object 'System.Collections.Generic.List[object]' foreach ($field in $comparedFields) { $referenceValue = Get-OIResultProperty -InputObject $Reference -Name $field $differenceValue = Get-OIResultProperty -InputObject $Difference -Name $field if ([string]$referenceValue -ne [string]$differenceValue) { $changes.Add([pscustomobject]@{ Field = $field Reference = $referenceValue Difference = $differenceValue }) } } $referencePrefix = Get-OIResultProperty -InputObject $Reference -Name 'DetectionPrefixLength' $differencePrefix = Get-OIResultProperty -InputObject $Difference -Name 'DetectionPrefixLength' $referenceDetected = $null -ne $referencePrefix $differenceDetected = $null -ne $differencePrefix $classification = if (-not $referenceDetected -and $differenceDetected) { 'NewlyDetected' } elseif ($referenceDetected -and -not $differenceDetected) { 'NoLongerDetected' } elseif (-not $referenceDetected -and -not $differenceDetected) { 'BothClean' } elseif ([int64]$differencePrefix -lt [int64]$referencePrefix) { 'BoundaryEarlier' } elseif ([int64]$differencePrefix -gt [int64]$referencePrefix) { 'BoundaryLater' } else { 'BoundaryUnchanged' } $boundaryDelta = if ($referenceDetected -and $differenceDetected) { [int64]$differencePrefix - [int64]$referencePrefix } else { $null } $result = [pscustomobject]@{ ReferenceFile = Get-OIResultProperty -InputObject $Reference -Name 'File' DifferenceFile = Get-OIResultProperty -InputObject $Difference -Name 'File' Classification = $classification BoundaryDelta = $boundaryDelta SignatureChanged = [string](Get-OIResultProperty -InputObject $Reference -Name 'SignatureName') -ne [string](Get-OIResultProperty -InputObject $Difference -Name 'SignatureName') ReferenceProbeCount = @(Get-OIResultProperty -InputObject $Reference -Name 'ProbeLog' -Default @()).Count DifferenceProbeCount = @(Get-OIResultProperty -InputObject $Difference -Name 'ProbeLog' -Default @()).Count Unchanged = ($changes.Count -eq 0) Changes = $changes.ToArray() } $result.PSObject.TypeNames.Insert(0, 'OffsetInspect.ThreatScanDiff') return $result } |