From d033d7ae1bb62d0c2893d98c3a0f84735721388f Mon Sep 17 00:00:00 2001 From: DrIOS <58635327+DrIOSX@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:13:08 -0500 Subject: [PATCH] add: 1.1.1 test as automated and organized csv. --- helpers/Build-Help.ps1 | 4 +- helpers/Get-AdminRoleUserLicense.ps1 | 45 ++++++++ source/helper/TestDefinitions.csv | 103 +++++++++--------- .../Test-AdministrativeAccountCompliance .ps1 | 69 ++++++++++++ source/tests/Test-AntiPhishingPolicy.ps1 | 1 + .../tests/Test-BlockSharedMailboxSignIn.ps1 | 1 + source/tests/Test-IdentifyExternalEmail.ps1 | 1 + source/tests/Test-NotifyMalwareInternal.ps1 | 2 + source/tests/Test-SpamPolicyAdminNotify.ps1 | 2 + 9 files changed, 175 insertions(+), 53 deletions(-) create mode 100644 helpers/Get-AdminRoleUserLicense.ps1 create mode 100644 source/tests/Test-AdministrativeAccountCompliance .ps1 diff --git a/helpers/Build-Help.ps1 b/helpers/Build-Help.ps1 index b84d417..82e139f 100644 --- a/helpers/Build-Help.ps1 +++ b/helpers/Build-Help.ps1 @@ -4,10 +4,10 @@ Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1 <# - $ver = "v0.0.1" + $ver = "v0.1.1" git checkout main git pull origin main - git tag -a $ver -m "Release version $ver Minor Update" + git tag -a $ver -m "Release version $ver Bugfix Update" git push origin $ver "Fix: PR #37" git push origin $ver diff --git a/helpers/Get-AdminRoleUserLicense.ps1 b/helpers/Get-AdminRoleUserLicense.ps1 new file mode 100644 index 0000000..e9576ef --- /dev/null +++ b/helpers/Get-AdminRoleUserLicense.ps1 @@ -0,0 +1,45 @@ +function Get-AdminRoleUserLicense { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $false)] + [bool]$SkipGraphConnection = $false + ) + + # Connect to Microsoft Graph if not skipping connection + if (-not $SkipGraphConnection) { + Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome + } + + $adminRoleUsers = @() + $userIds = @() + $adminroles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" } + + foreach ($role in $adminroles) { + $usersInRole = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'" + + foreach ($user in $usersInRole) { + $userIds += $user.PrincipalId + $userDetails = Get-MgUser -UserId $user.PrincipalId -Property "DisplayName, UserPrincipalName, Id, onPremisesSyncEnabled" + + $adminRoleUsers += [PSCustomObject]@{ + RoleName = $role.DisplayName + UserName = $userDetails.DisplayName + UserPrincipalName = $userDetails.UserPrincipalName + UserId = $userDetails.Id + HybridUser = $userDetails.onPremisesSyncEnabled + Licenses = "" # Placeholder for licenses, to be filled later + } + } + } + + foreach ($userId in $userIds | Select-Object -Unique) { + $licenses = Get-MgUserLicenseDetail -UserId $userId + $licenseList = ($licenses.SkuPartNumber -join '|') + + $adminRoleUsers | Where-Object { $_.UserId -eq $userId } | ForEach-Object { + $_.Licenses = $licenseList + } + } + + return $adminRoleUsers +} \ No newline at end of file diff --git a/source/helper/TestDefinitions.csv b/source/helper/TestDefinitions.csv index 99ced50..653429c 100644 --- a/source/helper/TestDefinitions.csv +++ b/source/helper/TestDefinitions.csv @@ -1,51 +1,52 @@ -Index,TestFileName,Rec,ELevel,ProfileLevel,IG1,IG2,IG3 -1,Test-AntiPhishingPolicy.ps1,2.1.7,E5,L1,FALSE,FALSE,TRUE -2,Test-AuditDisabledFalse.ps1,6.1.1,E3,L1,TRUE,TRUE,TRUE -3,Test-AuditLogSearch.ps1,3.1.1,E3,L1,TRUE,TRUE,TRUE -4,Test-BlockChannelEmails.ps1,8.1.2,E3,L1,FALSE,FALSE,FALSE -5,Test-BlockMailForwarding.ps1,6.2.1,E3,L1,FALSE,FALSE,FALSE -6,Test-BlockSharedMailboxSignIn.ps1,1.2.2,E3,L1,FALSE,FALSE,FALSE -7,Test-CommonAttachmentFilter.ps1,2.1.2,E3,L1,FALSE,TRUE,TRUE -8,Test-CustomerLockbox.ps1,1.3.6,E5,L2,FALSE,FALSE,FALSE -9,Test-DialInBypassLobby.ps1,8.5.4,E3,L1,FALSE,FALSE,FALSE -10,Test-DisallowInfectedFilesDownload.ps1,7.3.1,E5,L2,TRUE,TRUE,TRUE -11,Test-EnableDKIM.ps1,2.1.9,E3,L1,FALSE,TRUE,TRUE -12,Test-ExternalNoControl.ps1,8.5.7,E3,L1,FALSE,FALSE,FALSE -13,Test-ExternalSharingCalendars.ps1,1.3.3,E3,L2,FALSE,TRUE,TRUE -14,Test-GlobalAdminsCount.ps1,1.1.3,E3,L1,TRUE,TRUE,TRUE -15,Test-GuestAccessExpiration.ps1,7.2.9,E3,L1,FALSE,FALSE,FALSE -16,Test-IdentifyExternalEmail.ps1,6.2.3,E3,L1,FALSE,FALSE,FALSE -17,Test-LinkSharingRestrictions.ps1,7.2.7,E3,L1,TRUE,TRUE,TRUE -18,Test-MailboxAuditingE3.ps1,6.1.2,E3,L1,TRUE,TRUE,TRUE -19,Test-MailboxAuditingE5.ps1,6.1.3,E5,L1,TRUE,TRUE,TRUE -20,Test-MailTipsEnabled.ps1,6.5.2,E3,L2,FALSE,FALSE,FALSE -21,Test-ManagedApprovedPublicGroups.ps1,1.2.1,E3,L2,TRUE,TRUE,TRUE -22,Test-MeetingChatNoAnonymous.ps1,8.5.5,E3,L1,FALSE,FALSE,FALSE -23,Test-ModernAuthExchangeOnline.ps1,6.5.1,E3,L1,FALSE,TRUE,TRUE -24,Test-ModernAuthSharePoint.ps1,7.2.1,E3,L1,FALSE,TRUE,TRUE -25,Test-NoAnonymousMeetingJoin.ps1,8.5.1,E3,L2,FALSE,FALSE,FALSE -26,Test-NoAnonymousMeetingStart.ps1,8.5.2,E3,L1,FALSE,FALSE,FALSE -27,Test-NotifyMalwareInternal.ps1,2.1.3,E3,L1,FALSE,TRUE,TRUE -28,Test-NoWhitelistDomains.ps1,6.2.2,E3,L1,FALSE,FALSE,FALSE -29,Test-OneDriveContentRestrictions.ps1,7.2.4,E3,L2,TRUE,TRUE,TRUE -30,Test-OneDriveSyncRestrictions.ps1,7.3.2,E3,L2,FALSE,FALSE,FALSE -31,Test-OrganizersPresent.ps1,8.5.6,E3,L1,FALSE,FALSE,FALSE -32,Test-OrgOnlyBypassLobby.ps1,8.5.3,E3,L1,FALSE,FALSE,TRUE -33,Test-PasswordHashSync.ps1,5.1.8.1,E3,L1,FALSE,TRUE,TRUE -34,Test-PasswordNeverExpirePolicy.ps1,1.3.1,E3,L1,TRUE,TRUE,TRUE -35,Test-ReauthWithCode.ps1,7.2.10,E3,L1,FALSE,FALSE,FALSE -36,Test-ReportSecurityInTeams.ps1,8.6.1,E3,L1,FALSE,FALSE,FALSE -37,Test-RestrictCustomScripts.ps1,7.3.4,E3,L1,FALSE,FALSE,TRUE -38,Test-RestrictExternalSharing.ps1,7.2.3,E3,L1,TRUE,TRUE,TRUE -39,Test-RestrictOutlookAddins.ps1,6.3.1,E3,L2,FALSE,TRUE,TRUE -40,Test-RestrictStorageProvidersOutlook.ps1,6.5.3,E3,L2,TRUE,TRUE,TRUE -41,Test-RestrictTenantCreation.ps1,5.1.2.3,E3,L1,FALSE,FALSE,FALSE -42,Test-SafeAttachmentsPolicy.ps1,2.1.4,E5,L2,FALSE,FALSE,TRUE -43,Test-SafeAttachmentsTeams.ps1,2.1.5,E5,L2,TRUE,TRUE,TRUE -44,Test-SafeLinksOfficeApps.ps1,2.1.1,E5,L2,TRUE,TRUE,TRUE -45,Test-SharePointAADB2B.ps1,7.2.2,E3,L1,FALSE,FALSE,FALSE -46,Test-SharePointExternalSharingDomains.ps1,7.2.6,E3,L2,TRUE,TRUE,TRUE -47,Test-SharePointGuestsItemSharing.ps1,7.2.5,E3,L2,TRUE,TRUE,TRUE -48,Test-SpamPolicyAdminNotify.ps1,2.1.6,E3,L1,FALSE,TRUE,TRUE -49,Test-TeamsExternalAccess.ps1,8.2.1,E3,L2,FALSE,FALSE,FALSE -50,Test-TeamsExternalFileSharing.ps1,8.1.1,E3,L2,TRUE,TRUE,TRUE +Index,TestFileName,Rec,ELevel,ProfileLevel,IG1,IG2,IG3,Automated +1,Test-AdministrativeAccountCompliance .ps1,1.1.1,E3,L1,TRUE,TRUE,TRUE,FALSE +2,Test-GlobalAdminsCount.ps1,1.1.3,E3,L1,TRUE,TRUE,TRUE,TRUE +3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,E3,L2,TRUE,TRUE,TRUE,TRUE +4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE +5,Test-PasswordNeverExpirePolicy.ps1,1.3.1,E3,L1,TRUE,TRUE,TRUE,TRUE +6,Test-ExternalSharingCalendars.ps1,1.3.3,E3,L2,FALSE,TRUE,TRUE,TRUE +7,Test-CustomerLockbox.ps1,1.3.6,E5,L2,FALSE,FALSE,FALSE,TRUE +8,Test-SafeLinksOfficeApps.ps1,2.1.1,E5,L2,TRUE,TRUE,TRUE,TRUE +9,Test-CommonAttachmentFilter.ps1,2.1.2,E3,L1,FALSE,TRUE,TRUE,TRUE +10,Test-NotifyMalwareInternal.ps1,2.1.3,E3,L1,FALSE,TRUE,TRUE,TRUE +11,Test-SafeAttachmentsPolicy.ps1,2.1.4,E5,L2,FALSE,FALSE,TRUE,TRUE +12,Test-SafeAttachmentsTeams.ps1,2.1.5,E5,L2,TRUE,TRUE,TRUE,TRUE +13,Test-SpamPolicyAdminNotify.ps1,2.1.6,E3,L1,FALSE,TRUE,TRUE,TRUE +14,Test-AntiPhishingPolicy.ps1,2.1.7,E5,L1,FALSE,FALSE,TRUE,TRUE +15,Test-EnableDKIM.ps1,2.1.9,E3,L1,FALSE,TRUE,TRUE,TRUE +16,Test-AuditLogSearch.ps1,3.1.1,E3,L1,TRUE,TRUE,TRUE,TRUE +17,Test-RestrictTenantCreation.ps1,5.1.2.3,E3,L1,FALSE,FALSE,FALSE,TRUE +18,Test-PasswordHashSync.ps1,5.1.8.1,E3,L1,FALSE,TRUE,TRUE,TRUE +19,Test-AuditDisabledFalse.ps1,6.1.1,E3,L1,TRUE,TRUE,TRUE,TRUE +20,Test-MailboxAuditingE3.ps1,6.1.2,E3,L1,TRUE,TRUE,TRUE,TRUE +21,Test-MailboxAuditingE5.ps1,6.1.3,E5,L1,TRUE,TRUE,TRUE,TRUE +22,Test-BlockMailForwarding.ps1,6.2.1,E3,L1,FALSE,FALSE,FALSE,TRUE +23,Test-NoWhitelistDomains.ps1,6.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE +24,Test-IdentifyExternalEmail.ps1,6.2.3,E3,L1,FALSE,FALSE,FALSE,TRUE +25,Test-RestrictOutlookAddins.ps1,6.3.1,E3,L2,FALSE,TRUE,TRUE,TRUE +26,Test-ModernAuthExchangeOnline.ps1,6.5.1,E3,L1,FALSE,TRUE,TRUE,TRUE +27,Test-MailTipsEnabled.ps1,6.5.2,E3,L2,FALSE,FALSE,FALSE,TRUE +28,Test-RestrictStorageProvidersOutlook.ps1,6.5.3,E3,L2,TRUE,TRUE,TRUE,TRUE +29,Test-ModernAuthSharePoint.ps1,7.2.1,E3,L1,FALSE,TRUE,TRUE,TRUE +30,Test-SharePointAADB2B.ps1,7.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE +31,Test-RestrictExternalSharing.ps1,7.2.3,E3,L1,TRUE,TRUE,TRUE,TRUE +32,Test-OneDriveContentRestrictions.ps1,7.2.4,E3,L2,TRUE,TRUE,TRUE,TRUE +33,Test-SharePointGuestsItemSharing.ps1,7.2.5,E3,L2,TRUE,TRUE,TRUE,TRUE +34,Test-SharePointExternalSharingDomains.ps1,7.2.6,E3,L2,TRUE,TRUE,TRUE,TRUE +35,Test-LinkSharingRestrictions.ps1,7.2.7,E3,L1,TRUE,TRUE,TRUE,TRUE +36,Test-GuestAccessExpiration.ps1,7.2.9,E3,L1,FALSE,FALSE,FALSE,TRUE +37,Test-ReauthWithCode.ps1,7.2.10,E3,L1,FALSE,FALSE,FALSE,TRUE +38,Test-DisallowInfectedFilesDownload.ps1,7.3.1,E5,L2,TRUE,TRUE,TRUE,TRUE +39,Test-OneDriveSyncRestrictions.ps1,7.3.2,E3,L2,FALSE,FALSE,FALSE,TRUE +40,Test-RestrictCustomScripts.ps1,7.3.4,E3,L1,FALSE,FALSE,TRUE,TRUE +41,Test-TeamsExternalFileSharing.ps1,8.1.1,E3,L2,TRUE,TRUE,TRUE,TRUE +42,Test-BlockChannelEmails.ps1,8.1.2,E3,L1,FALSE,FALSE,FALSE,TRUE +43,Test-TeamsExternalAccess.ps1,8.2.1,E3,L2,FALSE,FALSE,FALSE,TRUE +44,Test-NoAnonymousMeetingJoin.ps1,8.5.1,E3,L2,FALSE,FALSE,FALSE,TRUE +45,Test-NoAnonymousMeetingStart.ps1,8.5.2,E3,L1,FALSE,FALSE,FALSE,TRUE +46,Test-OrgOnlyBypassLobby.ps1,8.5.3,E3,L1,FALSE,FALSE,TRUE,TRUE +47,Test-DialInBypassLobby.ps1,8.5.4,E3,L1,FALSE,FALSE,FALSE,TRUE +48,Test-MeetingChatNoAnonymous.ps1,8.5.5,E3,L1,FALSE,FALSE,FALSE,TRUE +49,Test-OrganizersPresent.ps1,8.5.6,E3,L1,FALSE,FALSE,FALSE,TRUE +50,Test-ExternalNoControl.ps1,8.5.7,E3,L1,FALSE,FALSE,FALSE,TRUE +51,Test-ReportSecurityInTeams.ps1,8.6.1,E3,L1,FALSE,FALSE,FALSE,TRUE diff --git a/source/tests/Test-AdministrativeAccountCompliance .ps1 b/source/tests/Test-AdministrativeAccountCompliance .ps1 new file mode 100644 index 0000000..9841865 --- /dev/null +++ b/source/tests/Test-AdministrativeAccountCompliance .ps1 @@ -0,0 +1,69 @@ +function Test-AdministrativeAccountCompliance { + [CmdletBinding()] + param ( + [switch]$SkipGraphConnection + ) + begin { + #. C:\Temp\CISAuditResult.ps1 + $validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2') + } + process { + if (-not $SkipGraphConnection) { + Connect-MgGraph -Scopes "Directory.Read.All", "User.Read.All", "RoleManagement.Read.Directory" -NoWelcome + } + $adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" } + $adminRoleUsers = @() + foreach ($role in $adminRoles) { + $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'" + foreach ($assignment in $roleAssignments) { + $userDetails = Get-MgUser -UserId $assignment.PrincipalId -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" + $licenses = (Get-MgUserLicenseDetail -UserId $assignment.PrincipalId).SkuPartNumber -join '|' + $adminRoleUsers += [PSCustomObject]@{ + UserName = $userDetails.UserPrincipalName + RoleName = $role.DisplayName + UserId = $userDetails.Id + HybridUser = $userDetails.OnPremisesSyncEnabled + Licenses = $licenses + } + } + } + $uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object { + $first = $_.Group | Select-Object -First 1 + $roles = ($_.Group.RoleName -join ', ') + $licenses = (($_.Group | Select-Object -ExpandProperty Licenses) -join ',').Split(',') | Select-Object -Unique + + $first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } } + } + $nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object { + $_.HybridUser -or + -not ($_.Licenses -split '\|' | Where-Object { $validLicenses -contains $_ }) + } + $failureReasons = $nonCompliantUsers | ForEach-Object { + $accountType = if ($_.HybridUser) { "Hybrid" } else { "Cloud-Only" } + $missingLicenses = $validLicenses | Where-Object { $_ -notin ($_.Licenses -split '\|') } + "$($_.UserName)|$($_.Roles)|$accountType|Missing: $($missingLicenses -join ',')" + } + $failureReasons = $failureReasons -join "`n" + + $auditResult = [CISAuditResult]::new() + $auditResult.Status = if ($nonCompliantUsers) { 'Fail' } else { 'Pass' } + $auditResult.ELevel = 'E3' + $auditResult.ProfileLevel = 'L1' + $auditResult.Rec = '1.1.1' + $auditResult.RecDescription = "Ensure Administrative accounts are separate and cloud-only" + $auditResult.CISControlVer = 'v8' + $auditResult.CISControl = "5.4" + $auditResult.CISDescription = "Restrict Administrator Privileges to Dedicated Administrator Accounts" + $auditResult.IG1 = $true + $auditResult.IG2 = $true + $auditResult.IG3 = $true + $auditResult.Result = $nonCompliantUsers.Count -eq 0 + $auditResult.Details = "Compliant Accounts: $($uniqueAdminRoleUsers.Count - $nonCompliantUsers.Count); Non-Compliant Accounts: $($nonCompliantUsers.Count)" + $auditResult.FailureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons" } else { "N/A" } + } + + end { + # Output the result + return $auditResult + } +} \ No newline at end of file diff --git a/source/tests/Test-AntiPhishingPolicy.ps1 b/source/tests/Test-AntiPhishingPolicy.ps1 index 6ed2be0..de8f0ed 100644 --- a/source/tests/Test-AntiPhishingPolicy.ps1 +++ b/source/tests/Test-AntiPhishingPolicy.ps1 @@ -11,6 +11,7 @@ function Test-AntiPhishingPolicy { } process { + # 2.1.7 Ensure that an anti-phishing policy has been created # Retrieve and validate the anti-phishing policies $antiPhishPolicies = Get-AntiPhishPolicy diff --git a/source/tests/Test-BlockSharedMailboxSignIn.ps1 b/source/tests/Test-BlockSharedMailboxSignIn.ps1 index 68f8425..b74afad 100644 --- a/source/tests/Test-BlockSharedMailboxSignIn.ps1 +++ b/source/tests/Test-BlockSharedMailboxSignIn.ps1 @@ -14,6 +14,7 @@ function Test-BlockSharedMailboxSignIn { # 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked # Pass if all shared mailboxes have AccountEnabled set to False. # Fail if any shared mailbox has AccountEnabled set to True. + # Review: Details property - Add verbosity. $MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox $sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId } diff --git a/source/tests/Test-IdentifyExternalEmail.ps1 b/source/tests/Test-IdentifyExternalEmail.ps1 index 9881070..9c421c0 100644 --- a/source/tests/Test-IdentifyExternalEmail.ps1 +++ b/source/tests/Test-IdentifyExternalEmail.ps1 @@ -13,6 +13,7 @@ function Test-IdentifyExternalEmail { process { # 6.2.3 (L1) Ensure email from external senders is identified # Requirement is to have external sender tagging enabled + # Review $externalInOutlook = Get-ExternalInOutlook $externalTaggingEnabled = ($externalInOutlook | ForEach-Object { $_.Enabled }) -contains $true diff --git a/source/tests/Test-NotifyMalwareInternal.ps1 b/source/tests/Test-NotifyMalwareInternal.ps1 index b6df85b..90e7f74 100644 --- a/source/tests/Test-NotifyMalwareInternal.ps1 +++ b/source/tests/Test-NotifyMalwareInternal.ps1 @@ -10,6 +10,8 @@ function Test-NotifyMalwareInternal { } process { + # 2.1.3 Ensure notifications for internal users sending malware is Enabled + # Retrieve all 'Custom' malware filter policies and check notification settings $malwareNotifications = Get-MalwareFilterPolicy | Where-Object { $_.RecommendedPolicyType -eq 'Custom' } $policiesToReport = @() diff --git a/source/tests/Test-SpamPolicyAdminNotify.ps1 b/source/tests/Test-SpamPolicyAdminNotify.ps1 index 353f9a7..ebe2d81 100644 --- a/source/tests/Test-SpamPolicyAdminNotify.ps1 +++ b/source/tests/Test-SpamPolicyAdminNotify.ps1 @@ -10,6 +10,8 @@ function Test-SpamPolicyAdminNotify { } process { + # 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators + # Get the default hosted outbound spam filter policy $hostedOutboundSpamFilterPolicy = Get-HostedOutboundSpamFilterPolicy | Where-Object { $_.IsDefault -eq $true }