From 878917767351ed14bbdb0bca83dab207e4c6d6f4 Mon Sep 17 00:00:00 2001 From: Ashwini Karke Date: Mon, 29 Dec 2025 15:06:33 +0530 Subject: [PATCH 1/3] added test files for 25537 --- src/powershell/tests/Test-Assessment.25537.md | 7 + .../tests/Test-Assessment.25537.ps1 | 130 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/powershell/tests/Test-Assessment.25537.md create mode 100644 src/powershell/tests/Test-Assessment.25537.ps1 diff --git a/src/powershell/tests/Test-Assessment.25537.md b/src/powershell/tests/Test-Assessment.25537.md new file mode 100644 index 000000000..8c0f748d8 --- /dev/null +++ b/src/powershell/tests/Test-Assessment.25537.md @@ -0,0 +1,7 @@ +Azure Firewall Threat intelligence-based filtering alerts and denies traffic from/to known malicious IP addresses, FQDNs, and URLs. The IP addresses, domains, and URLs are sourced from the Microsoft Threat Intelligence feed, which includes multiple sources including the Microsoft Cyber Security team. When threat intelligence-based filtering is enabled, Azure Firewall evaluates traffic against the threat intelligence rules before applying NAT, network, or application rules. This check verifies that Threat Intelligence feature is enabled in “Alert and Deny” mode in the Azure Firewall policy configuration. The check will fail if Threat Intelligence is either “Disabled” or if it is not configured in “Alert and Deny” mode, in the firewall policy attached to the firewall. + +**Remediation action** + +- [Please check this article for guidance on how to enable Threat Intelligence in “Alert and Deny” mode in the Azure Firewall Policy.](https://learn.microsoft.com/en-us/azure/firewall-manager/threat-intelligence-settings) + +%TestResult% diff --git a/src/powershell/tests/Test-Assessment.25537.ps1 b/src/powershell/tests/Test-Assessment.25537.ps1 new file mode 100644 index 000000000..593cea082 --- /dev/null +++ b/src/powershell/tests/Test-Assessment.25537.ps1 @@ -0,0 +1,130 @@ +<# +.SYNOPSIS + Validates Threat intelligence is Enabled in Deny Mode on Azure Firewall. +.DESCRIPTION + This test validates that Azure Firewall Policies have Threat Intelligence enabled in Deny mode. + Checks all firewall policies in the subscription and reports their threat intelligence status. +.NOTES + Test ID: 25537 + Category: Internet Access Control + Required API: Azure Firewall Policies +#> + +function Test-Assessment-25537 { + [ZtTest( + Category = 'Internet Access Control', + ImplementationCost = 'Low', + MinimumLicense = ('Azure_Firewall_Standard','Azure_Firewall_Premium'), + Pillar = 'Network', + RiskLevel = 'High', + SfiPillar = 'Protect networks', + TenantType = ('Workforce'), + TestId = 25537, + Title = 'Threat intelligence is Enabled in Deny Mode on Azure Firewall', + UserImpact = 'Low' + )] + [CmdletBinding()] + param() + + Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose + + #region Authentication Check + try { + $accessToken = Get-AzAccessToken -AsSecureString -ErrorAction SilentlyContinue -WarningAction SilentlyContinue + } + catch { + Write-PSFMessage $_.Exception.Message -Tag Test -Level Error + } + + if (!$accessToken) { + Write-PSFMessage "Azure authentication token not found." -Level Warning + Add-ZtTestResultDetail -SkippedBecause NotConnectedAzure + return + } + #endregion Authentication Check + + #region Data Collection + Write-ZtProgress ` + -Activity 'Azure Firewall Threat Intelligence' ` + -Status 'Enumerating Firewall Policies' + + try { + $policies = Get-AzResource -ResourceType "Microsoft.Network/firewallPolicies" -ErrorAction Stop + } + catch { + Write-PSFMessage $_.Exception.Message -Tag Test -Level Error + Add-ZtTestResultDetail -SkippedBecause NoAzureAccess + return + } + #endregion Data Collection + + #region Assessment Logic + $passed = $false + $testResultMarkdown = "" + $results = @() + + if (-not $policies) { + $testResultMarkdown = "No Azure Firewall Policies were found in this subscription." + Add-ZtTestResultDetail ` + -TestId '25537' ` + -Title 'Threat intelligence is Enabled in Deny Mode on Azure Firewall' ` + -Status $false ` + -Result $testResultMarkdown + return + } + + $results = @() + + foreach ($policyResource in $policies) { + $policy = Get-AzFirewallPolicy ` + -Name $policyResource.Name ` + -ResourceGroupName $policyResource.ResourceGroupName ` + -ErrorAction SilentlyContinue + + $mode = $policy.ThreatIntelMode + + $result = switch ($mode) { + 'Deny' { '✅ Enabled (Alert and Deny)' } + 'Alert' { '❌ Alert only' } + 'Off' { '❌ Disabled' } + default { '❌ Not configured' } + } + + $results += [PSCustomObject]@{ + PolicyName = $policy.Name + ResourceGroup = $policy.ResourceGroupName + ThreatIntelMode = $mode + Result = $result + } + } + #endregion Data Collection + + #region Assessment Logic Evaluation + $failedPolicies = $results | Where-Object { $_.ThreatIntelMode -ne 'Deny' } + $passed = ($failedPolicies.Count -eq 0) + + if ($passed) { + $testResultMarkdown = "Threat Intelligence is enabled in **Alert and Deny** mode for all Azure Firewall Policies.`n`n%TestResult%" + } else { + $testResultMarkdown = "One or more Azure Firewall Policies do **not** have Threat Intelligence enabled in **Alert and Deny** mode.`n`n%TestResult%" + } + #endregion Assessment Logic Evaluation + + #region Report Generation + $mdInfo = "## Azure Firewall Threat Intelligence Status`n`n" + $mdInfo += "Policy Name | Resource Group | Threat Intel Mode | Result |`n" + $mdInfo += "| :--- | :--- | :--- | :---: |`n" + + foreach ($item in $results | Sort-Object PolicyName) { + $mdInfo += "| $($item.PolicyName) | $($item.ResourceGroup) | $($item.ThreatIntelMode) | $($item.Result) |`n" + } + + $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $mdInfo + + # --- Final result (NO AppliesTo) --- + Add-ZtTestResultDetail ` + -TestId '25537' ` + -Title 'Azure Firewall Threat Intelligence is enabled in Alert and Deny mode' ` + -Status $passed ` + -Result $testResultMarkdown +} From e64a01eaf3832e3168ed99ae5a10209275018ecd Mon Sep 17 00:00:00 2001 From: Ashwini Karke Date: Wed, 31 Dec 2025 15:54:18 +0530 Subject: [PATCH 2/3] updated code --- .../tests/Test-Assessment.25537.ps1 | 176 +++++++++--------- 1 file changed, 93 insertions(+), 83 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25537.ps1 b/src/powershell/tests/Test-Assessment.25537.ps1 index 593cea082..3882025a0 100644 --- a/src/powershell/tests/Test-Assessment.25537.ps1 +++ b/src/powershell/tests/Test-Assessment.25537.ps1 @@ -6,15 +6,15 @@ Checks all firewall policies in the subscription and reports their threat intelligence status. .NOTES Test ID: 25537 - Category: Internet Access Control + Category: Azure Network Security Required API: Azure Firewall Policies #> function Test-Assessment-25537 { [ZtTest( - Category = 'Internet Access Control', + Category = 'Azure Network Security', ImplementationCost = 'Low', - MinimumLicense = ('Azure_Firewall_Standard','Azure_Firewall_Premium'), + MinimumLicense = ('Azure_Firewall_Standard', 'Azure_Firewall_Premium'), Pillar = 'Network', RiskLevel = 'High', SfiPillar = 'Protect networks', @@ -28,103 +28,113 @@ function Test-Assessment-25537 { Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose - #region Authentication Check - try { - $accessToken = Get-AzAccessToken -AsSecureString -ErrorAction SilentlyContinue -WarningAction SilentlyContinue - } - catch { - Write-PSFMessage $_.Exception.Message -Tag Test -Level Error - } - - if (!$accessToken) { - Write-PSFMessage "Azure authentication token not found." -Level Warning - Add-ZtTestResultDetail -SkippedBecause NotConnectedAzure - return - } - #endregion Authentication Check - #region Data Collection Write-ZtProgress ` -Activity 'Azure Firewall Threat Intelligence' ` -Status 'Enumerating Firewall Policies' - try { - $policies = Get-AzResource -ResourceType "Microsoft.Network/firewallPolicies" -ErrorAction Stop - } - catch { - Write-PSFMessage $_.Exception.Message -Tag Test -Level Error - Add-ZtTestResultDetail -SkippedBecause NoAzureAccess - return - } - #endregion Data Collection - - #region Assessment Logic - $passed = $false - $testResultMarkdown = "" + $subscriptions = Get-AzSubscription $results = @() + foreach ($sub in $subscriptions) { + Set-AzContext -SubscriptionId $sub.Id | Out-Null + # Get all firewall policies in the subscription + $policies = Get-AzResource -ResourceType 'Microsoft.Network/firewallPolicies' -ErrorAction Stop - if (-not $policies) { - $testResultMarkdown = "No Azure Firewall Policies were found in this subscription." - Add-ZtTestResultDetail ` - -TestId '25537' ` - -Title 'Threat intelligence is Enabled in Deny Mode on Azure Firewall' ` - -Status $false ` - -Result $testResultMarkdown - return + if (-not $policies) { + continue + } + + #endregion Data Collection + #region Assessment Logic + + foreach ($policyResource in $policies) { + $policy = Get-AzFirewallPolicy ` + -Name $policyResource.Name ` + -ResourceGroupName $policyResource.ResourceGroupName ` + -ErrorAction SilentlyContinue + + if (-not $policy) { + continue + } + + $subContext = Get-AzContext + $status = if ($policy.ThreatIntelMode -eq 'Deny') { + 'Pass' + } + else { + 'Fail' + } + + $results += [PSCustomObject]@{ + CheckName = 'Threat intelligence is Enabled in Deny Mode on Azure Firewall' + PolicyName = $policy.Name + ResourceGroup = $policy.ResourceGroupName + SubscriptionName = $subContext.Subscription.Name + SubscriptionId = $subContext.Subscription.Id + ThreatIntelMode = $policy.ThreatIntelMode + Status = $status + } + } } + #endregion Assessment Logic - $results = @() + #region Assessment Logic Evaluation + if (-not $results) { + Write-PSFMessage 'No Azure Firewall policies found. Skipping test.' -Tag Firewall -Level Verbose + return + } + else { + $allModes = $results.ThreatIntelMode + $uniqueModes = $allModes | Select-Object -Unique - foreach ($policyResource in $policies) { - $policy = Get-AzFirewallPolicy ` - -Name $policyResource.Name ` - -ResourceGroupName $policyResource.ResourceGroupName ` - -ErrorAction SilentlyContinue + if ($uniqueModes.Count -eq 1 -and $uniqueModes -eq 'Deny') { - $mode = $policy.ThreatIntelMode + $passed = $true + $testResultMarkdown = 'Threat Intel is enabled in **Alert and Deny** mode.' - $result = switch ($mode) { - 'Deny' { '✅ Enabled (Alert and Deny)' } - 'Alert' { '❌ Alert only' } - 'Off' { '❌ Disabled' } - default { '❌ Not configured' } } - - $results += [PSCustomObject]@{ - PolicyName = $policy.Name - ResourceGroup = $policy.ResourceGroupName - ThreatIntelMode = $mode - Result = $result + else { + + $passed = $false + + if ($uniqueModes.Count -eq 1) { + + switch ($uniqueModes) { + 'Alert' { + $testResultMarkdown = 'Threat Intel is enabled in **Alert** mode.' + } + 'Off' { + $testResultMarkdown = 'Threat Intel is **disabled**.' + } + default { + $testResultMarkdown = 'Threat Intel is not enabled in **Alert and Deny** mode for all Firewall policies.' + } + } + } + else { + $testResultMarkdown = 'Threat Intel is not enabled in **Alert and Deny** mode for all Firewall policies.' + } } - } - #endregion Data Collection - - #region Assessment Logic Evaluation - $failedPolicies = $results | Where-Object { $_.ThreatIntelMode -ne 'Deny' } - $passed = ($failedPolicies.Count -eq 0) - if ($passed) { - $testResultMarkdown = "Threat Intelligence is enabled in **Alert and Deny** mode for all Azure Firewall Policies.`n`n%TestResult%" - } else { - $testResultMarkdown = "One or more Azure Firewall Policies do **not** have Threat Intelligence enabled in **Alert and Deny** mode.`n`n%TestResult%" - } - #endregion Assessment Logic Evaluation + # --- Markdown Table --- + $mdInfo = "`n`n## Firewall Policies`n`n" + $mdInfo += "| Check name | Policy name | Subscription name | Subscription id | Threat Intel Mode |`n" + $mdInfo += "| :--- | :--- | :--- | :--- | :---: |`n" - #region Report Generation - $mdInfo = "## Azure Firewall Threat Intelligence Status`n`n" - $mdInfo += "Policy Name | Resource Group | Threat Intel Mode | Result |`n" - $mdInfo += "| :--- | :--- | :--- | :---: |`n" + foreach ($item in $results | Sort-Object PolicyName) { + $mdInfo += "| $($item.CheckName) | $($item.PolicyName) | $($item.SubscriptionName) | $($item.SubscriptionId) | $($item.ThreatIntelMode) |`n" + } - foreach ($item in $results | Sort-Object PolicyName) { - $mdInfo += "| $($item.PolicyName) | $($item.ResourceGroup) | $($item.ThreatIntelMode) | $($item.Result) |`n" - } + $testResultMarkdown += $mdInfo - $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $mdInfo + #endregion Assessment Logic Evaluation - # --- Final result (NO AppliesTo) --- - Add-ZtTestResultDetail ` - -TestId '25537' ` - -Title 'Azure Firewall Threat Intelligence is enabled in Alert and Deny mode' ` - -Status $passed ` - -Result $testResultMarkdown + #region Report Generation + Add-ZtTestResultDetail ` + -TestId '25537' ` + -Title 'Azure Firewall Threat Intelligence is enabled in Alert and Deny mode' ` + -Status $passed ` + -Result $testResultMarkdown + #endregion Report Generation + } } From 52c4a4853859c50d026b95beec38112620b91e1e Mon Sep 17 00:00:00 2001 From: Ashwini Karke Date: Wed, 31 Dec 2025 15:59:40 +0530 Subject: [PATCH 3/3] updated code --- src/powershell/tests/Test-Assessment.25537.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.25537.md b/src/powershell/tests/Test-Assessment.25537.md index 8c0f748d8..3e260acf2 100644 --- a/src/powershell/tests/Test-Assessment.25537.md +++ b/src/powershell/tests/Test-Assessment.25537.md @@ -1,7 +1,11 @@ -Azure Firewall Threat intelligence-based filtering alerts and denies traffic from/to known malicious IP addresses, FQDNs, and URLs. The IP addresses, domains, and URLs are sourced from the Microsoft Threat Intelligence feed, which includes multiple sources including the Microsoft Cyber Security team. When threat intelligence-based filtering is enabled, Azure Firewall evaluates traffic against the threat intelligence rules before applying NAT, network, or application rules. This check verifies that Threat Intelligence feature is enabled in “Alert and Deny” mode in the Azure Firewall policy configuration. The check will fail if Threat Intelligence is either “Disabled” or if it is not configured in “Alert and Deny” mode, in the firewall policy attached to the firewall. +Azure Firewall Threat intelligence-based filtering alerts and denies traffic from/to known malicious IP addresses, FQDNs, and URLs. The IP addresses, domains, and URLs are sourced from the Microsoft Threat Intelligence feed, which includes multiple sources including the Microsoft Cyber Security team. When threat intelligence-based filtering is enabled, Azure Firewall evaluates traffic against the threat intelligence rules before applying NAT, network, or application rules. + +This check verifies that Threat Intelligence feature is enabled in “Alert and Deny” mode in the Azure Firewall policy configuration. The check will fail if Threat Intelligence is either “Disabled” or if it is not configured in “Alert and Deny” mode, in the firewall policy attached to the firewall. **Remediation action** -- [Please check this article for guidance on how to enable Threat Intelligence in “Alert and Deny” mode in the Azure Firewall Policy.](https://learn.microsoft.com/en-us/azure/firewall-manager/threat-intelligence-settings) +Please check this article for guidance on how to enable Threat Intelligence in “Alert and Deny” mode in the Azure Firewall Policy: +- [Azure Firewall threat intelligence configuration | Microsoft Learn](https://learn.microsoft.com/en-us/azure/firewall-manager/threat-intelligence-settings) + %TestResult%