diff --git a/collectors/aad/msgraph/groups/Get-MonkeyAADGroup.ps1 b/collectors/aad/msgraph/groups/Get-MonkeyAADGroup.ps1 new file mode 100644 index 00000000..67006645 --- /dev/null +++ b/collectors/aad/msgraph/groups/Get-MonkeyAADGroup.ps1 @@ -0,0 +1,132 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +function Get-MonkeyAADGroup { +<# + .SYNOPSIS + Collector to get information about groups from Microsoft Entra ID + + .DESCRIPTION + Collector to get information about groups from Microsoft Entra ID + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyAADGroup + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory = $false,HelpMessage = "Background Collector ID")] + [string]$collectorId + ) + begin { + #Collector metadata + $monkey_metadata = @{ + Id = "aad0007"; + Provider = "EntraID"; + Resource = "EntraID"; + ResourceType = $null; + resourceName = $null; + collectorName = "Get-MonkeyAADGroup"; + ApiType = "MSGraph"; + description = "Collector to get information about groups from Microsoft Entra ID"; + Group = @( + "EntraID" + ); + Tags = @{ + "enabled" = $true + }; + Docs = "https://silverhack.github.io/monkey365/"; + ruleSuffixes = @( + "aad_groups" + ); + dependsOn = @( + + ); + } + #Get Config + try { + $aadConf = $O365Object.internal_config.entraId.Provider.msgraph + } + catch { + $msg = @{ + MessageData = ($message.MonkeyInternalConfigError); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'verbose'; + InformationAction = $O365Object.InformationAction; + Tags = @('Monkey365ConfigError'); + } + Write-Verbose @msg + break + } + $groups = $null + } + process { + $msg = @{ + MessageData = ($message.MonkeyGenericTaskMessage -f $collectorId,"Microsoft Entra ID Groups Information",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDGroupInfo'); + } + Write-Information @msg + $p = @{ + APIVersion = $aadConf.api_version; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Debug = $O365Object.Debug; + } + $groups = Get-MonkeyMSGraphGroup @p + } + end { + if ($null -ne $groups) { + $domains.PSObject.TypeNames.Insert(0,'Monkey365.EntraID.GroupInfo') + [pscustomobject]$obj = @{ + Data = $groups; + Metadata = $monkey_metadata; + } + $returnData.aad_groups = $obj; + } + else { + $msg = @{ + MessageData = ($message.MonkeyEmptyResponseMessage -f "Microsoft Entra ID Groups Info",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = "verbose"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Tags = @('EntraIDGroupEmptyResponse') + } + Write-Verbose @msg + } + } +} + + + + + + + diff --git a/collectors/m365/SecurityCompliance/RBAC/Get-MonkeySeCompRoleManagement.ps1 b/collectors/m365/SecurityCompliance/RBAC/Get-MonkeySeCompRoleManagement.ps1 index 963df4f0..9bf49e88 100644 --- a/collectors/m365/SecurityCompliance/RBAC/Get-MonkeySeCompRoleManagement.ps1 +++ b/collectors/m365/SecurityCompliance/RBAC/Get-MonkeySeCompRoleManagement.ps1 @@ -84,7 +84,7 @@ function Get-MonkeySeCompRoleManagement { MessageData = ($message.MonkeyGenericTaskMessage -f $collectorId,"Security & Compliance role management",$O365Object.TenantID); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'info'; - InformationAction = $InformationAction; + InformationAction = $O365Object.InformationAction; Tags = @('SecCompRoleManagementInfo'); } Write-Information @msg @@ -193,7 +193,7 @@ function Get-MonkeySeCompRoleManagement { } elseif ($getExoGroups -eq $false) { $msg = @{ - MessageData = ("EXO groups for PurView disabled in configuration file for {0}",$O365Object.TenantID); + MessageData = ("EXO groups for PurView disabled in configuration file for {0}" -f $O365Object.TenantID); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = "verbose"; InformationAction = $O365Object.InformationAction; @@ -204,7 +204,7 @@ function Get-MonkeySeCompRoleManagement { } else { $msg = @{ - MessageData = ($message.MonkeyEmptyResponseMessage -f "Security \\u0026 Compliance role management",$O365Object.TenantID); + MessageData = ($message.MonkeyEmptyResponseMessage -f "Security & Compliance role management",$O365Object.TenantID); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = "verbose"; InformationAction = $O365Object.InformationAction; diff --git a/collectors/m365/microsoft_admin/general/Get-MonkeyM365CortanaAppConfig.ps1 b/collectors/m365/microsoft_admin/general/Get-MonkeyM365CortanaAppConfig.ps1 new file mode 100644 index 00000000..d31b17e8 --- /dev/null +++ b/collectors/m365/microsoft_admin/general/Get-MonkeyM365CortanaAppConfig.ps1 @@ -0,0 +1,126 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +function Get-MonkeyM365CortanaAppConfig { +<# + .SYNOPSIS + Collector to get information about cortana app settings in Microsoft 365 + + .DESCRIPTION + Collector to get information about cortana app settings in Microsoft 365 + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyM365CortanaAppConfig + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory = $false,HelpMessage = "Background Collector ID")] + [string]$collectorId + ) + begin { + #Collector metadata + $monkey_metadata = @{ + Id = "m365admin004"; + Provider = "Microsoft365"; + Resource = "Microsoft365"; + ResourceType = $null; + resourceName = $null; + collectorName = "Get-MonkeyM365CortanaAppConfig"; + ApiType = "MSGraph"; + description = "Collector to get information about cortana app settings in Microsoft 365"; + Group = @( + "Microsoft365" + ); + Tags = @{ + "enabled" = $true + }; + Docs = "https://silverhack.github.io/monkey365/"; + ruleSuffixes = @( + "m365_cortana_app" + ); + dependsOn = @( + + ); + } + #Get Config + try { + $aadConf = $O365Object.internal_config.entraId.Provider.msgraph + } + catch { + $msg = @{ + MessageData = ($message.MonkeyInternalConfigError); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'verbose'; + InformationAction = $O365Object.InformationAction; + Tags = @('Monkey365ConfigError'); + } + Write-Verbose @msg + break + } + $app = $null + } + process { + $msg = @{ + MessageData = ($message.MonkeyGenericTaskMessage -f $collectorId,"Microsoft MSGraph applications",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MSGraphApplicationInfo'); + } + Write-Information @msg + $p = @{ + APIVersion = $aadConf.api_version; + Filter = "appId eq '0a0a29f9-0a25-49c7-94bf-c53c3f8fa69d'"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Debug = $O365Object.Debug; + } + $app = Get-MonkeyMSGraphAADServicePrincipal @p + } + end { + if ($null -ne $app) { + $app.PSObject.TypeNames.Insert(0,'Monkey365.MSGraph.CortanaApp') + [pscustomobject]$obj = @{ + Data = $app; + Metadata = $monkey_metadata; + } + $returnData.m365_cortana_app = $obj; + } + else { + $msg = @{ + MessageData = ($message.MonkeyEmptyResponseMessage -f "Microsoft MSGraph applications",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = "verbose"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Tags = @('MSGraphApplicationEmptyMessage') + } + Write-Verbose @msg + } + } +} \ No newline at end of file diff --git a/collectors/m365/microsoft_admin/general/Get-MonkeyM365ThirdPartyStorageConfig.ps1 b/collectors/m365/microsoft_admin/general/Get-MonkeyM365ThirdPartyStorageConfig.ps1 new file mode 100644 index 00000000..6671db4c --- /dev/null +++ b/collectors/m365/microsoft_admin/general/Get-MonkeyM365ThirdPartyStorageConfig.ps1 @@ -0,0 +1,126 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +function Get-MonkeyM365ThirdPartyStorageConfig { +<# + .SYNOPSIS + Collector to get information about third party storage settings in Microsoft 365 + + .DESCRIPTION + Collector to get information about third party storage settings in Microsoft 365 + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyM365ThirdPartyStorageConfig + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory = $false,HelpMessage = "Background Collector ID")] + [string]$collectorId + ) + begin { + #Collector metadata + $monkey_metadata = @{ + Id = "m365admin003"; + Provider = "Microsoft365"; + Resource = "Microsoft365"; + ResourceType = $null; + resourceName = $null; + collectorName = "Get-MonkeyM365ThirdPartyStorageConfig"; + ApiType = "MSGraph"; + description = "Collector to get information about third party storage settings in Microsoft 365"; + Group = @( + "Microsoft365" + ); + Tags = @{ + "enabled" = $true + }; + Docs = "https://silverhack.github.io/monkey365/"; + ruleSuffixes = @( + "m365_thirdparty_app" + ); + dependsOn = @( + + ); + } + #Get Config + try { + $aadConf = $O365Object.internal_config.entraId.Provider.msgraph + } + catch { + $msg = @{ + MessageData = ($message.MonkeyInternalConfigError); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'verbose'; + InformationAction = $O365Object.InformationAction; + Tags = @('Monkey365ConfigError'); + } + Write-Verbose @msg + break + } + $app = $null + } + process { + $msg = @{ + MessageData = ($message.MonkeyGenericTaskMessage -f $collectorId,"Microsoft MSGraph applications",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MSGraphApplicationInfo'); + } + Write-Information @msg + $p = @{ + APIVersion = $aadConf.api_version; + Filter = "appId eq 'c1f33bc0-bdb4-4248-ba9b-096807ddb43e'"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Debug = $O365Object.Debug; + } + $app = Get-MonkeyMSGraphAADServicePrincipal @p + } + end { + if ($null -ne $app) { + $app.PSObject.TypeNames.Insert(0,'Monkey365.MSGraph.ThirdPartyApp') + [pscustomobject]$obj = @{ + Data = $app; + Metadata = $monkey_metadata; + } + $returnData.m365_thirdparty_app = $obj; + } + else { + $msg = @{ + MessageData = ($message.MonkeyEmptyResponseMessage -f "Microsoft MSGraph applications",$O365Object.TenantID); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = "verbose"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.Verbose; + Tags = @('MSGraphApplicationEmptyMessage') + } + Write-Verbose @msg + } + } +} \ No newline at end of file diff --git a/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 b/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 index d91e315c..107b97e3 100644 --- a/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 +++ b/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 @@ -102,8 +102,13 @@ Function Connect-MonkeySPO { foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ $new_params.add($param.Key, $param.Value) } - #Create a new MSAL application + #Create a new msal client application + $client_app = @{} + foreach ($param in $O365Object.application_args.GetEnumerator()){ + $client_app.add($param.Key, $param.Value) + } $p = @{ + app_params = $client_app; Environment = $O365Object.initParams.Environment; Verbose = $O365Object.verbose; Debug = $O365Object.debug; diff --git a/core/modules/monkeycloudutils/public/New-MsalApplicationForSPO.ps1 b/core/modules/monkeycloudutils/public/New-MsalApplicationForSPO.ps1 index aa4efdca..c96fd23e 100644 --- a/core/modules/monkeycloudutils/public/New-MsalApplicationForSPO.ps1 +++ b/core/modules/monkeycloudutils/public/New-MsalApplicationForSPO.ps1 @@ -80,6 +80,24 @@ Function New-MsalApplicationForSPO{ Environment = $Environment; } } + Else{ + if(-NOT $app_params.ContainsKey('clientId')){ + #Add clientId + [ref]$null = $app_params.Add('clientId',$clientId) + } + else{ + $app_params.ClientId = $clientId + } + if($null -ne $redirectUri){ + if(-NOT $app_params.ContainsKey('redirectUri')){ + #Add redirect uri + [ref]$null = $app_params.Add('redirectUri',$redirectUri) + } + else{ + $app_params.redirectUri = $redirectUri + } + } + } } End{ try{ diff --git a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json similarity index 94% rename from rules/findings/AzureAD/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json rename to rules/findings/EntraId/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json index 47b8877f..637f53f8 100644 --- a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json +++ b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-cap-block-basic-authentication-not-enabled.json @@ -89,14 +89,14 @@ "returnObject": null, "idSuffix": "aad_cap_block_basic_auth", "status": { - "keyName": [], - "message": "Lack of conditional access policy to block legacy authentication" + "keyName": ["policyName"], + "message": "The {policyName} policy is not configured to block legacy authentication" }, "notes": [], "categories": [], "fields": { - "resourceName": null, - "resourceId": null, - "resourceType": null + "resourceName": "policyName", + "resourceId": "policyId", + "resourceType": "conditionalAccess/policies" } } diff --git a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-azure-management-missing-cap.json b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-azure-management-missing-cap.json similarity index 100% rename from rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-azure-management-missing-cap.json rename to rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-azure-management-missing-cap.json diff --git a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-high-privileged-users-missing-cap.json b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-high-privileged-users-missing-cap.json similarity index 100% rename from rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-high-privileged-users-missing-cap.json rename to rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-high-privileged-users-missing-cap.json diff --git a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-risky-signs-missing-cap.json b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-risky-signs-missing-cap.json similarity index 100% rename from rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-risky-signs-missing-cap.json rename to rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-risky-signs-missing-cap.json diff --git a/rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-users-missing-cap.json b/rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-users-missing-cap.json similarity index 100% rename from rules/findings/AzureAD/Conditional Access/CIS1.5/aad-ensure-mfa-for-users-missing-cap.json rename to rules/findings/EntraId/Conditional Access/CIS1.5/aad-ensure-mfa-for-users-missing-cap.json diff --git a/rules/findings/AzureAD/Devices/CIS1.4/azure-activedirectory-devices-require-mfa-settings.json b/rules/findings/EntraId/Devices/CIS1.4/azure-activedirectory-devices-require-mfa-settings.json similarity index 100% rename from rules/findings/AzureAD/Devices/CIS1.4/azure-activedirectory-devices-require-mfa-settings.json rename to rules/findings/EntraId/Devices/CIS1.4/azure-activedirectory-devices-require-mfa-settings.json diff --git a/rules/findings/AzureAD/General/CIS1.4/aad-linkedin-sync-enabled.json b/rules/findings/EntraId/General/CIS1.4/aad-linkedin-sync-enabled.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/aad-linkedin-sync-enabled.json rename to rules/findings/EntraId/General/CIS1.4/aad-linkedin-sync-enabled.json diff --git a/rules/findings/AzureAD/General/CIS1.4/aad-password-hash-sync-disabled.json b/rules/findings/EntraId/General/CIS1.4/aad-password-hash-sync-disabled.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/aad-password-hash-sync-disabled.json rename to rules/findings/EntraId/General/CIS1.4/aad-password-hash-sync-disabled.json diff --git a/rules/findings/AzureAD/General/CIS1.4/aad-password-protection-disabled.json b/rules/findings/EntraId/General/CIS1.4/aad-password-protection-disabled.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/aad-password-protection-disabled.json rename to rules/findings/EntraId/General/CIS1.4/aad-password-protection-disabled.json diff --git a/rules/findings/AzureAD/General/CIS1.4/aad-security-defaults-disabled.json b/rules/findings/EntraId/General/CIS1.4/aad-security-defaults-disabled.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/aad-security-defaults-disabled.json rename to rules/findings/EntraId/General/CIS1.4/aad-security-defaults-disabled.json diff --git a/rules/findings/AzureAD/General/CIS1.4/aad-security-defaults-enabled.json b/rules/findings/EntraId/General/CIS1.4/aad-security-defaults-enabled.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/aad-security-defaults-enabled.json rename to rules/findings/EntraId/General/CIS1.4/aad-security-defaults-enabled.json diff --git a/rules/findings/AzureAD/General/CIS1.4/azure-activedirectory-apps-required-admin-consent.json b/rules/findings/EntraId/General/CIS1.4/azure-activedirectory-apps-required-admin-consent.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/azure-activedirectory-apps-required-admin-consent.json rename to rules/findings/EntraId/General/CIS1.4/azure-activedirectory-apps-required-admin-consent.json diff --git a/rules/findings/AzureAD/General/CIS1.4/azure-activedirectory-restrict-users-ad-portal.json b/rules/findings/EntraId/General/CIS1.4/azure-activedirectory-restrict-users-ad-portal.json similarity index 100% rename from rules/findings/AzureAD/General/CIS1.4/azure-activedirectory-restrict-users-ad-portal.json rename to rules/findings/EntraId/General/CIS1.4/azure-activedirectory-restrict-users-ad-portal.json diff --git a/rules/findings/EntraId/General/CIS2.0/non-admin-users-allowedto-create-tenants.json b/rules/findings/EntraId/General/CIS2.0/non-admin-users-allowedto-create-tenants.json new file mode 100644 index 00000000..d102248e --- /dev/null +++ b/rules/findings/EntraId/General/CIS2.0/non-admin-users-allowedto-create-tenants.json @@ -0,0 +1,50 @@ +{ + "serviceType": "General", + "serviceName": "Microsoft Entra ID", + "displayName": "Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'", + "description": "Non-privileged users can create tenants in the Azure AD and Entra administration portal under Manage tenant. The creation of a tenant is recorded in the Audit log as category DirectoryManagement and activity Create Company. Anyone who creates a tenant becomes the Global Administrator of that tenant. The newly created tenant doesn't inherit any settings or configurations.", + "rationale": "Restricting tenant creation prevents unauthorized or uncontrolled deployment of resources and ensures that the organization retains control over its infrastructure. User generation of shadow IT could lead to multiple, disjointed environments that can make it difficult for IT to manage and secure the organization's data, especially if other users in the organization began using these tenants for business purposes under the misunderstanding that they were secured by the organization's security team.", + "impact": null, + "remediation": null, + "references": [ + "https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/methods-for-assigning-users-and-groups", + "https://ezcloudinfo.com/2019/01/22/configure-access-panel-in-azure-active-directory/" + ], + "compliance": [ + { + "name": "CIS Microsoft 365 Foundations", + "version": "2.0.0", + "reference": "1.1.22" + } + ], + "level": "medium", + "tags": null, + "path": "aad_authorization_policy", + "conditions": [ + { + "statements": [ + { + "conditions": [ + [ + "TenantAuthPolicy.defaultUserRolePermissions.allowedToCreateTenants", + "eq", + "true" + ] + ] + } + ] + } + ], + "idSuffix": "aad_non_admin_allowed_tenant_creation", + "status": { + "keyName": [], + "message": "Restrict non-admin users from creating tenants is disabled" + }, + "notes": [], + "categories": [], + "fields": { + "resourceName": null, + "resourceId": null, + "resourceType": null + } +} diff --git a/rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-owners-can-manage-group-membership-enabled.json b/rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-owners-can-manage-group-membership-enabled.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-owners-can-manage-group-membership-enabled.json rename to rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-owners-can-manage-group-membership-enabled.json diff --git a/rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-access-group-features.json b/rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-access-group-features.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-access-group-features.json rename to rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-access-group-features.json diff --git a/rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-create-o365-groups.json b/rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-create-o365-groups.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-create-o365-groups.json rename to rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-create-o365-groups.json diff --git a/rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-create-security-groups.json b/rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-create-security-groups.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.4/azure-activedirectory-users-can-create-security-groups.json rename to rules/findings/EntraId/Groups/CIS1.4/azure-activedirectory-users-can-create-security-groups.json diff --git a/rules/findings/AzureAD/Groups/CIS1.5/azure-ad-group-features-disabled.json b/rules/findings/EntraId/Groups/CIS1.5/azure-ad-group-features-disabled.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.5/azure-ad-group-features-disabled.json rename to rules/findings/EntraId/Groups/CIS1.5/azure-ad-group-features-disabled.json diff --git a/rules/findings/AzureAD/Groups/CIS1.5/azure-ad-users-can-create-security-groups.json b/rules/findings/EntraId/Groups/CIS1.5/azure-ad-users-can-create-security-groups.json similarity index 100% rename from rules/findings/AzureAD/Groups/CIS1.5/azure-ad-users-can-create-security-groups.json rename to rules/findings/EntraId/Groups/CIS1.5/azure-ad-users-can-create-security-groups.json diff --git a/rules/findings/AzureAD/Guest/CIS1.4/aad-guest-can-invite.json b/rules/findings/EntraId/Guest/CIS1.4/aad-guest-can-invite.json similarity index 100% rename from rules/findings/AzureAD/Guest/CIS1.4/aad-guest-can-invite.json rename to rules/findings/EntraId/Guest/CIS1.4/aad-guest-can-invite.json diff --git a/rules/findings/AzureAD/Guest/CIS1.4/aad-guest-users-present.json b/rules/findings/EntraId/Guest/CIS1.4/aad-guest-users-present.json similarity index 100% rename from rules/findings/AzureAD/Guest/CIS1.4/aad-guest-users-present.json rename to rules/findings/EntraId/Guest/CIS1.4/aad-guest-users-present.json diff --git a/rules/findings/AzureAD/IAM/CIS1.4/aad-iam-excessive-global-admins.json b/rules/findings/EntraId/IAM/CIS1.4/aad-iam-excessive-global-admins.json similarity index 100% rename from rules/findings/AzureAD/IAM/CIS1.4/aad-iam-excessive-global-admins.json rename to rules/findings/EntraId/IAM/CIS1.4/aad-iam-excessive-global-admins.json diff --git a/rules/findings/AzureAD/IAM/CIS1.4/aad-iam-only-one-global-admin.json b/rules/findings/EntraId/IAM/CIS1.4/aad-iam-only-one-global-admin.json similarity index 100% rename from rules/findings/AzureAD/IAM/CIS1.4/aad-iam-only-one-global-admin.json rename to rules/findings/EntraId/IAM/CIS1.4/aad-iam-only-one-global-admin.json diff --git a/rules/findings/AzureAD/IAM/CIS1.4/aad-iam-privileged-users-active-assignment.json b/rules/findings/EntraId/IAM/CIS1.4/aad-iam-privileged-users-active-assignment.json similarity index 100% rename from rules/findings/AzureAD/IAM/CIS1.4/aad-iam-privileged-users-active-assignment.json rename to rules/findings/EntraId/IAM/CIS1.4/aad-iam-privileged-users-active-assignment.json diff --git a/rules/findings/AzureAD/IAM/CIS1.4/aad-iam-privileged-users-disabled-mfa.json b/rules/findings/EntraId/IAM/CIS1.4/aad-iam-privileged-users-disabled-mfa.json similarity index 100% rename from rules/findings/AzureAD/IAM/CIS1.4/aad-iam-privileged-users-disabled-mfa.json rename to rules/findings/EntraId/IAM/CIS1.4/aad-iam-privileged-users-disabled-mfa.json diff --git a/rules/findings/AzureAD/IAM/CIS1.4/aad-iam-users-disabled-mfa.json b/rules/findings/EntraId/IAM/CIS1.4/aad-iam-users-disabled-mfa.json similarity index 100% rename from rules/findings/AzureAD/IAM/CIS1.4/aad-iam-users-disabled-mfa.json rename to rules/findings/EntraId/IAM/CIS1.4/aad-iam-users-disabled-mfa.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-bad-password-list-disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-bad-password-list-disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-bad-password-list-disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-bad-password-list-disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-password-expiring-enabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-password-expiring-enabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-password-expiring-enabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-password-expiring-enabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-restrict-collaboration-specific-domains-disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-restrict-collaboration-specific-domains-disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-restrict-collaboration-specific-domains-disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-restrict-collaboration-specific-domains-disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-sign-in-policy-all_users_disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-sign-in-policy-all_users_disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-sign-in-policy-all_users_disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-sign-in-policy-all_users_disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-sign-in-policy-disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-sign-in-policy-disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-sign-in-policy-disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-sign-in-policy-disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-stay_signed_policy-disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-stay_signed_policy-disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-stay_signed_policy-disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-stay_signed_policy-disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-user-risk-policy-all_users_disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-user-risk-policy-all_users_disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-user-risk-policy-all_users_disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-user-risk-policy-all_users_disabled.json diff --git a/rules/findings/AzureAD/Policy/CIS1.4/aad-user-risk-policy-disabled.json b/rules/findings/EntraId/Policy/CIS1.4/aad-user-risk-policy-disabled.json similarity index 100% rename from rules/findings/AzureAD/Policy/CIS1.4/aad-user-risk-policy-disabled.json rename to rules/findings/EntraId/Policy/CIS1.4/aad-user-risk-policy-disabled.json diff --git a/rules/findings/AzureAD/SSPR/CIS1.4/aad-sspr-disabled.json b/rules/findings/EntraId/SSPR/CIS1.4/aad-sspr-disabled.json similarity index 100% rename from rules/findings/AzureAD/SSPR/CIS1.4/aad-sspr-disabled.json rename to rules/findings/EntraId/SSPR/CIS1.4/aad-sspr-disabled.json diff --git a/rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-mfa-reconfirm-days.json b/rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-mfa-reconfirm-days.json similarity index 100% rename from rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-mfa-reconfirm-days.json rename to rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-mfa-reconfirm-days.json diff --git a/rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-notify-admin-disabled.json b/rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-notify-admin-disabled.json similarity index 100% rename from rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-notify-admin-disabled.json rename to rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-notify-admin-disabled.json diff --git a/rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-notify-users-disabled.json b/rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-notify-users-disabled.json similarity index 100% rename from rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-notify-users-disabled.json rename to rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-notify-users-disabled.json diff --git a/rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-reset-methods.json b/rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-reset-methods.json similarity index 100% rename from rules/findings/AzureAD/SSPR/CIS1.4/azure-activedirectory-sspr-reset-methods.json rename to rules/findings/EntraId/SSPR/CIS1.4/azure-activedirectory-sspr-reset-methods.json diff --git a/rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-add-gallery-apps.json b/rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-add-gallery-apps.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-add-gallery-apps.json rename to rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-add-gallery-apps.json diff --git a/rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-consent-apps-data-access.json b/rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-consent-apps-data-access.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-consent-apps-data-access.json rename to rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-consent-apps-data-access.json diff --git a/rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-register-apps-enabled.json b/rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-register-apps-enabled.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.4/azure-activedirectory-users-can-register-apps-enabled.json rename to rules/findings/EntraId/Users/CIS1.4/azure-activedirectory-users-can-register-apps-enabled.json diff --git a/rules/findings/AzureAD/Users/CIS1.5/azure-activedirectory-users-can-consent-apps-data-access-trusted-publishers-disabled.json b/rules/findings/EntraId/Users/CIS1.5/azure-activedirectory-users-can-consent-apps-data-access-trusted-publishers-disabled.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.5/azure-activedirectory-users-can-consent-apps-data-access-trusted-publishers-disabled.json rename to rules/findings/EntraId/Users/CIS1.5/azure-activedirectory-users-can-consent-apps-data-access-trusted-publishers-disabled.json diff --git a/rules/findings/AzureAD/Users/CIS1.5/azure-ad-guest-invite-restriction-disabled.json b/rules/findings/EntraId/Users/CIS1.5/azure-ad-guest-invite-restriction-disabled.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.5/azure-ad-guest-invite-restriction-disabled.json rename to rules/findings/EntraId/Users/CIS1.5/azure-ad-guest-invite-restriction-disabled.json diff --git a/rules/findings/AzureAD/Users/CIS1.5/azure-ad-guest-object-restriction-disabled.json b/rules/findings/EntraId/Users/CIS1.5/azure-ad-guest-object-restriction-disabled.json similarity index 100% rename from rules/findings/AzureAD/Users/CIS1.5/azure-ad-guest-object-restriction-disabled.json rename to rules/findings/EntraId/Users/CIS1.5/azure-ad-guest-object-restriction-disabled.json diff --git a/rules/findings/Microsoft365/Admin/CIS2.0/third-party-storage-allowed-microsoft365.json b/rules/findings/Microsoft365/Admin/CIS2.0/third-party-storage-allowed-microsoft365.json new file mode 100644 index 00000000..d66b2fd0 --- /dev/null +++ b/rules/findings/Microsoft365/Admin/CIS2.0/third-party-storage-allowed-microsoft365.json @@ -0,0 +1,53 @@ +{ + "serviceType": "Microsoft 365 Admin", + "serviceName": "Microsoft 365", + "displayName": "Ensure 'third-party storage services' are restricted in 'Microsoft 365 on the web'", + "description": "Third-party storage can be enabled for users in Microsoft 365, allowing them to store and share documents using services such as Dropbox, alongside OneDrive and team sites. + Ensure `Microsoft 365 on the web` third-party storage services are restricted. + ", + "rationale": "By using external storage services an organization may increases the risk of data breaches and unauthorized access to confidential information. Additionally, third-party services may not adhere to the same security standards as the organization, making it difficult to maintain data privacy and security.", + "impact": "Impact associated with this change is highly dependent upon current practices in the tenant. If users do not use other storage providers, then minimal impact is likely. However, if users do regularly utilize providers outside of the tenant this will affect their ability to continue to do so.", + "remediation": "1. Navigate to Microsoft 365 admin center\r\n\t\t\t\t\t2. Go to `Settings` > `Org Settings` > `Services` > `Microsoft 365 on the webt` \r\n\t\t\t\t\t3. Ensure `Let users open files stored in third-party storage services in Microsoft 365 on the web` is not checked.\r\n\t", + "references": [ + "https://learn.microsoft.com/en-us/microsoft-365/admin/setup/set-up-file-storage-and-sharing?view=o365-worldwide#enable-or-disable-third-party-storage-services" + ], + "compliance": [ + { + "name": "CIS Microsoft 365 Foundations", + "version": "2.0.0", + "reference": "6.4" + } + ], + "tags": [ + "Microsoft 365 CIS benchmark 2.0 reference 6.4" + ], + "level": "low", + "path": "o365_exo_owa_mbox_policy", + "conditions": [ + { + "statements": [ + { + "conditions": [ + [ + "AdditionalStorageProvidersAvailable", + "eq", + "true" + ] + ] + } + ] + } + ], + "idSuffix": "o365_admin_thirdparty_storage_allowed", + "status": { + "keyName": [], + "message": "Ensure external storage providers available in Outlook on the Web are restricted" + }, + "notes": [], + "categories": [], + "fields": { + "resourceName": null, + "resourceId": null, + "resourceType": null + } +} diff --git a/rules/findings/Microsoft365/SharepointOnline/CIS2.0/sharepoint-b2b-integration-disabled.json b/rules/findings/Microsoft365/SharepointOnline/CIS2.0/sharepoint-b2b-integration-disabled.json new file mode 100644 index 00000000..6a43a89f --- /dev/null +++ b/rules/findings/Microsoft365/SharepointOnline/CIS2.0/sharepoint-b2b-integration-disabled.json @@ -0,0 +1,53 @@ +{ + "serviceType": "SharePoint Online", + "serviceName": "Microsoft 365", + "displayName": "Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled", + "description": "Azure AD B2B provides authentication and management of guests. Authentication happens via one-time passcode when they don't already have a work or school account or a Microsoft account. Integration with SharePoint and OneDrive allows for more granular control of how guest user accounts are managed in the organization's AAD, unifying a similar guest experience already deployed in other Microsoft 365 services such as Teams.", + "rationale": "External users assigned guest accounts will be subject to Azure AD access policies, such as multi-factor authentication. This provides a way to manage guest identities and control access to SharePoint and OneDrive resources. Without this integration, files can be shared without account registration, making it more challenging to audit and manage who has access to the organization's data.", + "impact": "Azure B2B collaboration is used with other Azure services so should not be new or unusual. Microsoft also has made the experience seamless when turning on integration on SharePoint sites that already have active files shared with guest users. The referenced Microsoft article on the subject has more details on this.", + "remediation": "\r\n\t\t\t\t\t###### To enable Azure AD B2B integration using PowerShell:\r\n\t\t\t\t\t1. Connect to SharePoint Online using Connect-SPOService -Url https://monkey-admin.sharepoint.com, replacing "monkey" with the appropiate value..\r\n\t\t\t\t\t2. Run the following command:\r\n\t\t\t\t\t\r\n\t```powershell\r\n\t\t\t\t\tSet-SPOTenant -EnableAzureADB2BIntegration $true\r\n\t\t\t\t\t```", + "references": [ + "https://learn.microsoft.com/en-us/sharepoint/sharepoint-azureb2b-integration#enabling-the-integration", + "https://learn.microsoft.com/en-us/entra/external-id/what-is-b2b", + "https://learn.microsoft.com/en-us/powershell/module/sharepoint-online/set-spotenant?view=sharepoint-ps" + ], + "compliance": [ + { + "name": "CIS Microsoft 365 Foundations", + "version": "2.0", + "reference": "2.12" + } + ], + "level": "medium", + "tags": [ + "Microsoft 365 CIS benchmark 2.0 reference 2.12" + ], + "path": "o365_spo_tenant_details", + "conditions": [ + { + "statements": [ + { + "conditions": [ + [ + "EnableAzureADB2BIntegration", + "ne", + "false" + ] + ] + } + ] + } + ], + "idSuffix": "sps_azure_b2b_integration_disabled", + "status": { + "keyName": [], + "message": "Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled" + }, + "notes": [], + "categories": [], + "fields": { + "resourceName": null, + "resourceId": null, + "resourceType": null + } +} diff --git a/tests/MonkeyJob.Tests.ps1 b/tests/MonkeyJob.Tests.ps1 index 4a626589..fc4b9209 100644 --- a/tests/MonkeyJob.Tests.ps1 +++ b/tests/MonkeyJob.Tests.ps1 @@ -64,6 +64,7 @@ Describe 'MonkeyJob' { } #Start Job Start-MonkeyJob @p + Start-Sleep -Milliseconds 500 $Job = Get-MonkeyJob #Get result $Job.Task.Result | Should -Be '5' @@ -87,6 +88,7 @@ Describe 'MonkeyJob' { } #Start Job Start-MonkeyJob @p + Start-Sleep -Milliseconds 500 $Job = Get-MonkeyJob #Get result $Job.Task | Should -BeOfType [System.Threading.Tasks.Task]