Private/M365Monitor/Detections/Test-M365ForwardingRule.ps1
|
# PSGuerrilla - Jim Tyler, Microsoft MVP - CC BY 4.0 # https://github.com/jimrtyler/PSGuerrilla | https://creativecommons.org/licenses/by/4.0/ # AI/LLM use: see AI-USAGE.md for required attribution function Test-M365ForwardingRule { [CmdletBinding()] param( [PSCustomObject[]]$Events = @() ) $results = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($event in $Events) { $operationType = $event.OperationType ?? $event.Activity ?? '' $targetMailbox = $event.TargetName ?? '' $forwardingDest = '' $isServerSide = $false $isClientSide = $false $ruleName = '' # Analyze modified properties for forwarding configuration foreach ($prop in $event.ModifiedProps) { $propName = $prop.Name ?? '' $newVal = $prop.NewValue ?? '' # Server-side forwarding (Set-Mailbox) if ($propName -match 'ForwardingSmtpAddress|ForwardingAddress') { $isServerSide = $true if ($newVal -and $newVal -ne '' -and $newVal -ne '""' -and $newVal -ne 'null') { $forwardingDest = $newVal -replace '"', '' } } if ($propName -eq 'DeliverToMailboxAndForward' -and $newVal -match 'True|true') { $isServerSide = $true } # Client-side inbox rules (ForwardTo, RedirectTo) if ($propName -match 'ForwardTo|ForwardAsAttachmentTo|RedirectTo') { $isClientSide = $true if ($newVal -and $newVal -ne '' -and $newVal -ne '""') { $forwardingDest = $newVal -replace '"', '' } } if ($propName -eq 'Name' -or $propName -eq 'RuleName') { $ruleName = $newVal -replace '"', '' } } # Determine forwarding type from operation if not already classified if (-not $isServerSide -and -not $isClientSide) { if ($operationType -match 'New-InboxRule|Set-InboxRule') { $isClientSide = $true } elseif ($operationType -match 'Set-Mailbox' -and $event.Activity -match 'Forward') { $isServerSide = $true } elseif ($event.Activity -match 'forwarding|forward|redirect|inbox rule') { $isClientSide = $true } } # Determine if forwarding is to an external domain $isExternal = $false if ($forwardingDest -match '@(.+)$') { $destDomain = $Matches[1] if ($targetMailbox -match '@(.+)$') { $sourceDomain = $Matches[1] if ($destDomain -ne $sourceDomain) { $isExternal = $true } } } # Severity assessment $severity = if ($isExternal) { 'Critical' } elseif ($forwardingDest) { 'High' } elseif ($isServerSide) { 'High' } else { 'Medium' } $typeLabel = if ($isServerSide) { 'Server-side' } elseif ($isClientSide) { 'Client-side' } else { 'Unknown' } $description = if ($forwardingDest) { "$typeLabel forwarding rule on '$targetMailbox' to '$forwardingDest' by $($event.Actor)" } else { "$typeLabel forwarding rule modified on '$targetMailbox' by $($event.Actor)" } $results.Add([PSCustomObject]@{ Timestamp = $event.Timestamp Actor = $event.Actor DetectionType = 'm365ForwardingRule' Description = $description Details = @{ ForwardingDestination = $forwardingDest TargetMailbox = $targetMailbox RuleName = $ruleName IsServerSide = $isServerSide IsClientSide = $isClientSide IsExternal = $isExternal OperationType = $operationType ModifiedProps = $event.ModifiedProps } Severity = $severity }) } return @($results) } |