Security/DefenderAntiMalwareChecks.ps1

# -------------------------------------------------------------------
# Defender -- Anti-Malware & Comprehensive Attachment Filter Checks
# Extracted from Get-DefenderSecurityConfig.ps1 (#257)
# Runs in shared scope: $settings, $checkIdCounter, Add-Setting,
# Test-PresetPolicy, $script:presetPolicyNames
# -------------------------------------------------------------------
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
param()

# ------------------------------------------------------------------
# 3. Anti-Malware Policies
# ------------------------------------------------------------------
try {
    Write-Verbose "Checking anti-malware policies..."
    $malwarePolicies = Get-MalwareFilterPolicy -ErrorAction Stop

    foreach ($policy in @($malwarePolicies)) {
        $policyLabel = if ($policy.IsDefault) { 'Default' } else { $policy.Name }
        $presetTier = Test-PresetPolicy -PolicyName $policy.Name
        if ($presetTier) {
            $settingParams = @{
                Category         = 'Anti-Malware'
                Setting          = "Policy ($policyLabel)"
                CurrentValue     = "Managed by $presetTier preset security policy"
                RecommendedValue = 'Preset security policy active'
                Status           = 'Pass'
                CheckId          = 'DEFENDER-MALWARE-001'
                Remediation      = 'No action needed -- settings enforced by preset security policy.'
            }
            Add-Setting @settingParams
            continue
        }

        # Common attachment type filter
        $commonFilter = $policy.EnableFileFilter
        $settingParams = @{
            Category         = 'Anti-Malware'
            Setting          = "Common Attachment Filter ($policyLabel)"
            CurrentValue     = "$commonFilter"
            RecommendedValue = 'True'
            Status           = if ($commonFilter) { 'Pass' } else { 'Fail' }
            CheckId          = 'DEFENDER-ANTIMALWARE-001'
            Remediation      = 'Run: Set-MalwareFilterPolicy -Identity <PolicyName> -EnableFileFilter $true. Security admin center > Anti-malware > Default policy > Common attachments filter > Enable.'
        }
        Add-Setting @settingParams

        # ZAP for malware
        if ($null -ne $policy.ZapEnabled) {
            $malwareZap = $policy.ZapEnabled
            $settingParams = @{
                Category         = 'Anti-Malware'
                Setting          = "Malware ZAP ($policyLabel)"
                CurrentValue     = "$malwareZap"
                RecommendedValue = 'True'
                Status           = if ($malwareZap) { 'Pass' } else { 'Fail' }
                CheckId          = 'DEFENDER-ANTIMALWARE-001'
                Remediation      = 'Run: Set-MalwareFilterPolicy -Identity <PolicyName> -ZapEnabled $true. Security admin center > Anti-malware > Default policy > Zero-hour auto purge for malware > Enabled.'
            }
            Add-Setting @settingParams
        }

        # Admin notification
        $adminNotify = $policy.EnableInternalSenderAdminNotifications
        $settingParams = @{
            Category         = 'Anti-Malware'
            Setting          = "Internal Sender Admin Notifications ($policyLabel)"
            CurrentValue     = "$adminNotify"
            RecommendedValue = 'True'
            Status           = if ($adminNotify) { 'Pass' } else { 'Warning' }
            CheckId          = 'DEFENDER-ANTIMALWARE-002'
            Remediation      = 'Run: Set-MalwareFilterPolicy -Identity <PolicyName> -EnableInternalSenderAdminNotifications $true -InternalSenderAdminAddress admin@domain.com. Security admin center > Anti-malware > Default policy > Admin notifications > Notify admin about undelivered messages from internal senders.'
        }
        Add-Setting @settingParams

        # Only assess default policy in detail
        if (-not $policy.IsDefault) { continue }
    }
}
catch {
    Write-Warning "Could not retrieve anti-malware policies: $_"
}

# ------------------------------------------------------------------
# 7. Comprehensive Attachment Filter (CIS 2.1.11)
# ------------------------------------------------------------------
try {
    Write-Verbose "Checking comprehensive attachment filter file types..."
    # Reuse $malwarePolicies from section 3 if available
    if ($malwarePolicies) {
        $defaultMalware = $malwarePolicies | Where-Object { $_.IsDefault }
        if ($defaultMalware) {
            $fileTypes = @($defaultMalware.FileTypes)
            # CIS 2.1.11 L2 requires comprehensive coverage of dangerous extensions
            $requiredTypes = @('ace','ani','apk','app','cab','cmd','com','deb','dmg','exe',
                'hta','img','iso','jar','js','jse','lnk','msi','pif','ps1','reg','rgs',
                'scr','sct','vb','vbe','vbs','vhd','vxd','wsc','wsf','wsh')
            $missing = @($requiredTypes | Where-Object { $fileTypes -notcontains $_ })

            if ($fileTypes.Count -ge 30 -and $missing.Count -eq 0) {
                $settingParams = @{
                    Category         = 'Anti-Malware'
                    Setting          = 'Comprehensive Attachment Filter (Default)'
                    CurrentValue     = "$($fileTypes.Count) file types blocked"
                    RecommendedValue = '30+ dangerous types blocked'
                    Status           = 'Pass'
                    CheckId          = 'DEFENDER-MALWARE-002'
                    Remediation      = 'No action needed.'
                }
                Add-Setting @settingParams
            }
            else {
                $missingStr = if ($missing.Count -gt 0) { " Missing: $($missing -join ', ')" } else { '' }
                $settingParams = @{
                    Category         = 'Anti-Malware'
                    Setting          = 'Comprehensive Attachment Filter (Default)'
                    CurrentValue     = "$($fileTypes.Count) types blocked.$missingStr"
                    RecommendedValue = '30+ dangerous types blocked'
                    Status           = 'Fail'
                    CheckId          = 'DEFENDER-MALWARE-002'
                    Remediation      = "Add missing file types via: Set-MalwareFilterPolicy -Identity Default -FileTypes @{Add='ext1','ext2'}. Security admin center > Anti-malware > Default policy > Common attachments filter > Customize file types."
                }
                Add-Setting @settingParams
            }
        }
    }
}
catch {
    Write-Warning "Could not check comprehensive attachment filter: $_"
}