Skip to content

Commit

Permalink
Merge pull request #337 from Snozzberries/aadFix
Browse files Browse the repository at this point in the history
Fixes for #325
  • Loading branch information
f-bader authored Jul 14, 2024
2 parents 6bc5c8f + 7fe0a92 commit 65db165
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 61 deletions.
5 changes: 2 additions & 3 deletions powershell/internal/Get-GraphObjectMarkdown.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Function Get-GraphObjectMarkdown {
# The type of graph object, this will be used to show the right deeplink to the test results report.
[Parameter(Mandatory = $true)]
[ValidateSet('AuthenticationMethod', 'AuthorizationPolicy', 'ConditionalAccess', 'ConsentPolicy',
'Devices', 'DiagnosticSettings', 'Domains', 'Groups', 'IdentityProtection', 'Users', 'UserRole'
'Devices', 'Domains', 'Groups', 'IdentityProtection', 'Users', 'UserRole'
)]
[string] $GraphObjectType
)
Expand All @@ -33,8 +33,7 @@ Function Get-GraphObjectMarkdown {
AuthorizationPolicy = "https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserManagementMenuBlade/~/UserSettings/menuId/UserSettings"
ConditionalAccess = "https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/{0}"
ConsentPolicy = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/~/UserSettings"
Devices = "https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DeviceDetailsMenuBlade/~/Properties/objectId/{0}"
DiagnosticSettings = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/DiagnosticSettingsMenuBlade/~/General"
Devices = "https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DeviceDetailsMenuBlade/~/Properties/objectId/{0}"
Domains = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/DomainsManagementMenuBlade/~/CustomDomainNames"
Groups = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/{0}"
IdentityProtection = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/IdentityProtectionMenuBlade/~/UsersAtRiskAlerts/fromNav/Identity"
Expand Down
3 changes: 2 additions & 1 deletion powershell/internal/Get-MtSkippedReason.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ function Get-MtSkippedReason {
)

switch($SkippedBecause){
"NotConnectedAzure" { "Not connected to Azure. See [Connecting to Azure](https://maester.dev/docs/installation#optional-modules-and-permissions)" ; break}
"NotConnectedAzure" { "Not connected to Azure. See [Connecting to Azure](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedExchange" { "Not connected to Exchange Online. See [Connecting to Exchange Online](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedSecurityCompliance" { "Not connected to Security & Compliance. See [Connecting to Security & Compliance](https://maester.dev/docs/installation#optional-modules-and-permissions)"; break}
"NotConnectedGraph" { "Not connected to Graph. See [Connect-Maester](https://maester.dev/docs/commands/Connect-Maester#examples)"; break}
"NotDotGovDomain" { "This test is only for federal, executive branch, departments and agencies. To override use [Test-MtCisaDmarcAggregateCisa -Force](https://maester.dev/docs/commands/Test-MtCisaDmarcAggregateCisa)"; break}
"NotLicensedEntraIDP1" { "This test is for tenants that are licensed for Entra ID P1. See [Entra ID licensing](https://learn.microsoft.com/entra/fundamentals/licensing)"; break}
"NotLicensedEntraIDP2" { "This test is for tenants that are licensed for Entra ID P2. See [Entra ID licensing](https://learn.microsoft.com/entra/fundamentals/licensing)"; break}
Expand Down
4 changes: 2 additions & 2 deletions powershell/public/Add-MtTestResultDetail.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Function Add-MtTestResultDetail {

# The type of graph object, this will be used to show the right deeplink to the test results report.
[ValidateSet('AuthenticationMethod', 'AuthorizationPolicy', 'ConditionalAccess', 'ConsentPolicy',
'Devices', 'DiagnosticSettings', 'Domains', 'Groups', 'IdentityProtection', 'Users', 'UserRole'
'Devices', 'Domains', 'Groups', 'IdentityProtection', 'Users', 'UserRole'
)]
[string] $GraphObjectType,

Expand All @@ -62,7 +62,7 @@ Function Add-MtTestResultDetail {
[Parameter(Mandatory = $false)]
[string] $TestName = $____Pester.CurrentTest.ExpandedName,

[ValidateSet('NotConnectedAzure', 'NotConnectedExchange', 'NotDotGovDomain', 'NotLicensedEntraIDP1', 'NotConnectedSecurityCompliance',
[ValidateSet('NotConnectedAzure', 'NotConnectedExchange', 'NotConnectedGraph', 'NotDotGovDomain', 'NotLicensedEntraIDP1', 'NotConnectedSecurityCompliance',
'NotLicensedEntraIDP2', 'NotLicensedEntraIDGovernance', 'NotLicensedEntraWorkloadID', "LicensedEntraIDPremium", 'NotSupported'
)]
[string] $SkippedBecause
Expand Down
36 changes: 30 additions & 6 deletions powershell/public/cisa/entra/Test-MtCisaActivationNotification.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ Function Test-MtCisaActivationNotification {
[switch]$GlobalAdminOnly
)

$EntraIDPlan = Get-MtLicenseInformation -Product EntraID
$pim = $EntraIDPlan -eq "P2" -or $EntraIDPlan -eq "Governance"
if(-not $pim){
return $false
if(!(Test-MtConnection Graph)){
Add-MtTestResultDetail -SkippedBecause NotConnectedGraph
return $null
}else{
$EntraIDPlan = Get-MtLicenseInformation -Product EntraID
if($EntraIDPlan -ne "P2"){
Add-MtTestResultDetail -SkippedBecause NotLicensedEntraIDP2
}elseif($EntraIDPlan -ne "Governance"){
Add-MtTestResultDetail -SkippedBecause NotLicensedEntraIDGovernance
}
return $null
}

$roles = Get-MtRole -CisaHighlyPrivilegedRoles
Expand Down Expand Up @@ -74,11 +81,28 @@ Function Test-MtCisaActivationNotification {

$testResult = ($misconfigured|Measure-Object).Count -eq 0

$link = "https://entra.microsoft.com/#view/Microsoft_Azure_PIMCommon/ResourceMenuBlade/~/roles/resourceId//resourceType/tenant/provider/aadroles"
$resultFail = "❌ Fail"
$resultPass = "✅ Pass"

if ($testResult) {
$testResultMarkdown = "Well done. Your tenant has notifications for role activations:`n`n%TestResult%"
$testResultMarkdown = "Well done. Your tenant has notifications for [role activations]($link).`n`n%TestResult%"
} else {
$testResultMarkdown = "Your tenant does not have notifications on role activations."
$testResultMarkdown = "Your tenant does not have notifications on [role activations]($link).`n`n%TestResult%"
}

$result = "| Role Name | Result |`n"
$result += "| --- | --- |`n"

foreach ($item in $rolePolicies) {
$itemResult = $resultFail
if($item.activationNotify){
$itemResult = $resultPass
}
$result += "| $($item.role) | $($itemResult) |`n"
}
$testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result

Add-MtTestResultDetail -Result $testResultMarkdown

return $testResult
Expand Down
28 changes: 24 additions & 4 deletions powershell/public/cisa/entra/Test-MtCisaAuthenticatorContext.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ Function Test-MtCisaAuthenticatorContext {
[OutputType([bool])]
param()

if(!(Test-MtConnection Graph)){
Add-MtTestResultDetail -SkippedBecause NotConnectedGraph
return $null
}

$isMethodsMigrationComplete = Test-MtCisaMethodsMigration

$result = Get-MtAuthenticationMethodPolicyConfig

$policies = $result | Where-Object {`
Expand All @@ -29,14 +36,27 @@ Function Test-MtCisaAuthenticatorContext {
$_.featureSettings.displayLocationInformationRequiredState.state -eq "enabled" -and `
$_.featureSettings.displayLocationInformationRequiredState.includeTarget.id -contains "all_users" }

$testResult = ($policies|Measure-Object).Count -ge 1
$testResult = (($policies|Measure-Object).Count -ge 1) -and $isMethodsMigrationComplete

$link = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AdminAuthMethods/fromNav/Identity"

if ($testResult) {
$testResultMarkdown = "Well done. Your tenant has the Authentication Methods policy for Microsoft Authenticator set appropriately:`n`n%TestResult%"
$testResultMarkdown = "Well done. Your tenant has the [Authentication Methods]($link) policy for Microsoft Authenticator set appropriately.`n`n%TestResult%"
} else {
$testResultMarkdown = "Your tenant does not have the Authentication Methods policy for Microsoft Authenticator set appropriately."
$testResultMarkdown = "Your tenant does not have the [Authentication Methods]($link) policy for Microsoft Authenticator set appropriately or migration to Authentication Methods is not complete.`n`n%TestResult%"
}
Add-MtTestResultDetail -Result $testResultMarkdown -GraphObjectType AuthenticationMethod -GraphObjects $policies

$resultFail = "❌ Fail"
$resultPass = "✅ Pass"
if($isMethodsMigrationComplete){
$migrationResult = $resultPass
}else{
$migrationResult = $resultFail
}
$result = "[Authentication Methods]($link) Migration Complete: $migrationResult"
$testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result

Add-MtTestResultDetail -Result $testResultMarkdown

return $testResult
}
3 changes: 0 additions & 3 deletions powershell/public/cisa/entra/Test-MtCisaCloudGlobalAdmin.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,5 @@ Rationale: Many privileged administrative users do not need unfettered access to
* [CISA 7.3 Highly Privileged User Access - MS.AAD.7.3v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/aad.md#msaad73v1)
* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/AADConfig.rego#L833)

#### Note
Current test only captures active role assignments: https://github.com/maester365/maester/issues/195

<!--- Results --->
%TestResult%
35 changes: 32 additions & 3 deletions powershell/public/cisa/entra/Test-MtCisaDiagnosticSettings.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Function Test-MtCisaDiagnosticSettings {
[OutputType([bool])]
param()

if(!(Test-MtConnection Azure)){
Add-MtTestResultDetail -SkippedBecause NotConnectedAzure
return $null
}

$logs = Invoke-AzRestMethod -Path "/providers/microsoft.aadiam/diagnosticSettingsCategories?api-version=2017-04-01-preview"
$logs = ($logs.Content|ConvertFrom-Json).value
$logs = ($logs | Where-Object { `
Expand Down Expand Up @@ -53,14 +58,38 @@ Function Test-MtCisaDiagnosticSettings {
$actual["$_"] -eq $false
} | Sort-Object

$array = $actual.Keys | ForEach-Object { `
[pscustomobject]@{
Log = "$_"
Enabled = $($actual[$_])
}
}

$testResult = $unsetLogs.Count -eq 0

$link = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/DiagnosticSettingsMenuBlade/~/General"
$resultFail = "❌ Fail"
$resultPass = "✅ Pass"

if ($testResult) {
$testResultMarkdown = "Well done. Your tenant has diagnostic settings configured for all logs."
$testResultMarkdown = "Well done. Your tenant has [diagnostic settings]($link) configured for all logs."
} else {
$testResultMarkdown = "Your tenant does not have diagnostic settings configured for all logs:`n`n%unsetLogs%"
$testResultMarkdown = "Your tenant does not have [diagnostic settings]($link) configured for all logs:`n`n%TestResult%"
}
Add-MtTestResultDetail -Result $testResultMarkdown -GraphObjectType DiagnosticSettings

$result = "| Log Name | Result |`n"
$result += "| --- | --- |`n"

foreach ($item in $array) {
$itemResult = $resultFail
if($item.Enabled){
$itemResult = $resultPass
}
$result += "| $($item.Log) | $($itemResult) |`n"
}
$testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result

Add-MtTestResultDetail -Result $testResultMarkdown

return $testResult
}
3 changes: 0 additions & 3 deletions powershell/public/cisa/entra/Test-MtCisaGlobalAdminCount.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,5 @@ When counting the number of users assigned to the Global Administrator role, **c
* [CISA 7.1 Highly Privileged User Access - MS.AAD.7.1v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/aad.md#msaad71v1)
* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/AADConfig.rego#L761)

#### Note
Current test only captures active role assignments: https://github.com/maester365/maester/issues/195

<!--- Results --->
%TestResult%
3 changes: 0 additions & 3 deletions powershell/public/cisa/entra/Test-MtCisaGlobalAdminRatio.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,5 @@ This policy is based on the ratio below:
* [CISA 7.2 Highly Privileged User Access - MS.AAD.7.2v1](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/baselines/aad.md#msaad72v1)
* [CISA ScubaGear Rego Reference](https://github.com/cisagov/ScubaGear/blob/main/PowerShell/ScubaGear/Rego/AADConfig.rego#L792)

#### Note
Current test only captures active role assignments: https://github.com/maester365/maester/issues/195

<!--- Results --->
%TestResult%
11 changes: 7 additions & 4 deletions powershell/public/cisa/entra/Test-MtCisaGlobalAdminRatio.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@ Function Test-MtCisaGlobalAdminRatio {
$testResult = $false
}

$users = $roleAssignments.assignments | Sort-Object id -Unique
$link = "https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles"

if ($testResult) {
$testResultMarkdown = "Well done. Your tenant has more granular role assignments than global admin assignments:`n`n%TestResult%"
$testResultMarkdown = "Well done. Your tenant has more granular [role assignments]($link) than global admin assignments.`n`n%TestResult%"
} else {
$testResultMarkdown = "Your tenant does not have enough granular role assignments."
$testResultMarkdown = "Your tenant does not have enough granular [role assignments]($link).`n`n%TestResult%"
}
Add-MtTestResultDetail -Result $testResultMarkdown -GraphObjectType Users -GraphObjects $users
$result = "$ratio = $($globalAdministrators.Count) / $($otherAssignments.Count)"
$testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $result

Add-MtTestResultDetail -Result $testResultMarkdown

return $testResult
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
BeforeDiscovery {
$EntraIDPlan = Get-MtLicenseInformation -Product EntraID
}

Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.7.8", "CISA", "Security", "All" -Skip:( $EntraIDPlan -eq "Free" ) {
Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.7.8", "CISA", "Security", "All" {
It "MS.AAD.7.8: User activation of the Global Administrator role SHALL trigger an alert." {
Test-MtCisaActivationNotification -GlobalAdminOnly | Should -Be $true -Because "notifications are set for activation of the Global Admin role."
$result = Test-MtCisaActivationNotification -GlobalAdminOnly

if ($null -ne $result) {
$result | Should -Be $true -Because "notifications are set for activation of the Global Admin role."
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
BeforeDiscovery {
$EntraIDPlan = Get-MtLicenseInformation -Product EntraID
}

Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.7.9", "CISA", "Security", "All" -Skip:( $EntraIDPlan -eq "Free" ) {
Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.7.9", "CISA", "Security", "All" {
It "MS.AAD.7.9: User activation of other highly privileged roles SHOULD trigger an alert." {
Test-MtCisaActivationNotification -GlobalAdminOnly | Should -Be $true -Because "notifications are set for activation of highly privileged roles."
$result = Test-MtCisaActivationNotification

if ($null -ne $result) {
$result | Should -Be $true -Because "notifications are set for activation of highly privileged roles."
}
}
}
16 changes: 6 additions & 10 deletions tests/cisa/entra/Test-MtCisaAuthenticatorContext.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
BeforeDiscovery {
$EntraIDPlan = Get-MtLicenseInformation -Product EntraID

$result = Get-MtAuthenticationMethodPolicyConfig

$authenticator = $result | Where-Object { $_.id -eq "MicrosoftAuthenticator" }
}

Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.3.3", "CISA", "Security", "All" -Skip:( ($EntraIDPlan -eq "Free") -or (Test-MtCisaPhishResistant) -or $authenticator.state -eq "disabled") {
Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.3.3", "CISA", "Security", "All" {
It "MS.AAD.3.3: If phishing-resistant MFA has not been enforced and Microsoft Authenticator is enabled, it SHALL be configured to show login context information." {
Test-MtCisaAuthenticatorContext | Should -Be $true -Because "Microsoft Authenticator is configured to show login context information."
$result = Test-MtCisaAuthenticatorContext

if ($null -ne $result) {
$result | Should -Be $true -Because "Microsoft Authenticator is configured to show login context information."
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.8.3", "CISA", "Security", "All" {
It "MS.AAD.8.3: Guest invites SHOULD only be allowed to specific external domains that have been authorized by the agency for legitimate business purposes." {
Test-MtCisaCrossTenantInboundDefault -GlobalAdminOnly | Should -Be $true -Because "default inbound cross-tenant access policy is set to block."
Test-MtCisaCrossTenantInboundDefault | Should -Be $true -Because "default inbound cross-tenant access policy is set to block."
}
}
12 changes: 6 additions & 6 deletions tests/cisa/entra/Test-MtCisaDiagnosticSettings.Tests.ps1
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
BeforeAll {
$azureSession = Test-MtConnection -Service Azure
}

Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.4.1", "CISA", "Security", "All" -Skip:((-not $azureSession)) {
Describe "CISA SCuBA" -Tag "MS.AAD", "MS.AAD.4.1", "CISA", "Security", "All" {
It "MS.AAD.4.1: Security logs SHALL be sent to the agency's security operations center for monitoring." {
Test-MtCisaDiagnosticSettings | Should -Be $true -Because "diagnostic settings are configured for all logs."
$cisaDiagnosticSettings = Test-MtCisaDiagnosticSettings

if ($null -ne $cisaDiagnosticSettings) {
$cisaDiagnosticSettings | Should -Be $true -Because "diagnostic settings are configured for all logs."
}
}
}

0 comments on commit 65db165

Please sign in to comment.