Skip to content

Commit b423054

Browse files
Adding zero-trust assessments samples (#1341)
1 parent 7a7b7ec commit b423054

9 files changed

Lines changed: 333 additions & 0 deletions
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Type,Permission,Privilege,Reason
2+
Delegated,Mail.ReadBasic,Medium,DataExfiltration
3+
Delegated,Mail,High,Phishing
4+
Delegated,Contacts,High,Phishing
5+
Delegated,MailboxSettings,High,Phishing
6+
Delegated,People,High,Phishing
7+
Delegated,Files,High,Phishing
8+
Delegated,AllSites,High,Phishing
9+
Delegated,Notes,High,Phishing
10+
Delegated,Policy,High,Phishing
11+
Delegated,AppRoleAssignment.ReadWrite.All,High,Phishing
12+
Delegated,Directory.AccessAsUser.All,High,Phishing
13+
Delegated,user_impersonation,High,Phishing
14+
Delegated,Application.ReadWrite.All,High,BroadImpact
15+
Delegated,Directory.ReadWrite.All,High,BroadImpact
16+
Delegated,Domain.ReadWrite.All,High,BroadImpact
17+
Delegated,EduRoster.ReadWrite.All,High,BroadImpact
18+
Delegated,Group.ReadWrite.All,High,BroadImpact
19+
Delegated,Member.Read.Hidden,High,BroadImpact
20+
Delegated,RoleManagement.ReadWrite.Directory,High,BroadImpact
21+
Delegated,RoleAssignmentSchedule.ReadWrite.Directory,High,BroadImpact
22+
Delegated,RoleEligibilitySchedule.ReadWrite.Directory,High,BroadImpact
23+
Delegated,User.ReadWrite.All,High,BroadImpact
24+
Delegated,User.ManageCreds.All,High,BroadImpact
25+
Delegated,User.Export.All,High,BroadImpact
26+
Application,Mail,High,Phishing
27+
Application,Contacts,High,Phishing
28+
Application,MailboxSettings,High,Phishing
29+
Application,People,High,Phishing
30+
Application,Files,High,Phishing
31+
Application,Sites,High,Phishing
32+
Application,AllSites,High,Phishing
33+
Application,Notes,High,Phishing
34+
Application,Policy,High,BroadImpact
35+
Application,PrivilegedAccess,High,BroadImpact
36+
Application,PrivilegedAssignmentSchedule,High,BroadImpact
37+
Application,PrivilegedEligibilitySchedule,High,BroadImpact
38+
Application,AppRoleAssignment.ReadWrite.All,High,Phishing
39+
Application,Directory.AccessAsUser.All,High,Phishing
40+
Application,user_impersonation,High,Phishing
41+
Application,Application.ReadWrite.All,High,BroadImpact
42+
Application,Directory.ReadWrite.All,High,BroadImpact
43+
Application,Domain.ReadWrite.All,High,BroadImpact
44+
Application,EduRoster.ReadWrite.All,High,BroadImpact
45+
Application,Group.ReadWrite.All,High,BroadImpact
46+
Application,Member.Read.Hidden,High,BroadImpact
47+
Application,UserAuthenticationMethod.ReadWrite.All,High,BroadImpact
48+
Application,RoleManagement.ReadWrite.Directory,High,BroadImpact
49+
Application,User.ReadWrite.All,High,BroadImpact
50+
Application,User.ManageCreds.All,High,BroadImpact
51+
Application,CallRecords.Read.All,High,SensitiveData
52+
Delegated,User.Read,Low,Common pattern
53+
Delegated,User.ReadBasic.All,Low,Common pattern
54+
Delegated,openid,Low,Common pattern
55+
Delegated,email,Low,Common pattern
56+
Delegated,profile,Low,Common pattern
57+
Delegated,offline_access,Low,Common pattern when used with other low permissions
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Connect to Entra with required scopes
2+
Connect-Entra -Scopes 'AppRoleAssignment.ReadWrite.All', 'Application.ReadWrite.All', 'User.Read.All', 'Group.Read.All', 'DelegatedPermissionGrant.ReadWrite.All', 'AuditLog.Read.All'
3+
4+
# Define application name and redirect URI
5+
$appName = "Entra PowerShell App (Application)"
6+
$redirectUri = "http://localhost"
7+
8+
# Define Application permission and Graph API ID
9+
$applicationPermission = 'Group.Read.All'
10+
$graphApiId = '00000003-0000-0000-c000-000000000000'
11+
12+
# Get a user and a group
13+
$user = Get-EntraUser -UserId 'AdeleV@contoso.com'
14+
$group = Get-EntraGroup -Search 'Sales and Marketing'
15+
16+
# Create a new application
17+
$app = New-EntraApplication -DisplayName $appName -PublicClient @{ RedirectUris = $redirectUri } -IsFallbackPublicClient $False
18+
19+
# Create a service principal for the application
20+
$servicePrincipal = New-EntraServicePrincipal -AppId $app.AppId
21+
22+
# Assign users and groups to the application
23+
$emptyGuidUser = [Guid]::Empty.ToString()
24+
New-EntraUserAppRoleAssignment -ObjectId $user.Id -PrincipalId $user.Id -ResourceId $servicePrincipal.Id -Id $emptyGuidUser
25+
26+
$emptyGuidGroup = [Guid]::Empty.ToString()
27+
New-EntraGroupAppRoleAssignment -GroupId $group.Id -PrincipalId $group.Id -ResourceId $servicePrincipal.Id -Id $emptyGuidGroup
28+
29+
# Get Graph service principal
30+
$graphServicePrincipal = Get-EntraServicePrincipal -Filter "AppId eq '$graphApiId'"
31+
32+
# Create resource access object
33+
$resourceAccessAppPerms = New-Object Microsoft.Open.MSGraph.Model.ResourceAccess
34+
$resourceAccessAppPerms.Id = ((Get-EntraServicePrincipal -ServicePrincipalId $graphServicePrincipal.ObjectId).AppRoles | Where-Object { $_.Value -eq $applicationPermission}).Id
35+
$resourceAccessAppPerms.Type = 'Scope'
36+
37+
# Create required resource access object
38+
$requiredResourceAccessAppPerms = New-Object Microsoft.Open.MSGraph.Model.RequiredResourceAccess
39+
$requiredResourceAccessAppPerms.ResourceAppId = $graphApiId
40+
$requiredResourceAccessAppPerms.ResourceAccess = $resourceAccessAppPerms
41+
42+
# Set application required resource access
43+
Set-EntraApplication -ApplicationId $app.Id -RequiredResourceAccess $requiredResourceAccessAppPerms
44+
45+
# Set service principal parameters
46+
Set-EntraServicePrincipal -ServicePrincipalId $servicePrincipal.Id -AppRoleAssignmentRequired $True
47+
48+
# Get application role ID
49+
$appRoleId = ($graphServicePrincipal.AppRoles | Where-Object { $_.Value -eq $applicationPermission }).Id
50+
51+
New-EntraServicePrincipalAppRoleAssignment -ObjectId $servicePrincipal.Id -ResourceId $graphServicePrincipal.Id -Id $appRoleId -PrincipalId $servicePrincipal.Id
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Connect to Entra with required scopes
2+
Connect-Entra -Scopes 'AppRoleAssignment.ReadWrite.All', 'Application.ReadWrite.All', 'User.Read.All', 'Group.Read.All', 'DelegatedPermissionGrant.ReadWrite.All', 'AuditLog.Read.All'
3+
4+
# Define application name and redirect URI
5+
$appName = "Entra PowerShell App (Delegated)"
6+
$redirectUri = "http://localhost"
7+
8+
# Define delegated permission and Graph API ID
9+
$delegatedPermission = 'User.Read.All'
10+
$graphApiId = '00000003-0000-0000-c000-000000000000'
11+
12+
# Get a user and a group
13+
$user = Get-EntraUser -UserId 'AdeleV@contoso.com'
14+
$group = Get-EntraGroup -Search 'Sales and Marketing'
15+
16+
# Create a new application
17+
$app = New-EntraApplication -DisplayName $appName -PublicClient @{ RedirectUris = $redirectUri } -IsFallbackPublicClient $False
18+
19+
# Create a service principal for the application
20+
$servicePrincipal = New-EntraServicePrincipal -AppId $app.AppId
21+
22+
# Assign users and groups to the application
23+
$emptyGuidUser = [Guid]::Empty.ToString()
24+
New-EntraUserAppRoleAssignment -ObjectId $user.Id -PrincipalId $user.Id -ResourceId $servicePrincipal.Id -Id $emptyGuidUser
25+
26+
$emptyGuidGroup = [Guid]::Empty.ToString()
27+
New-EntraGroupAppRoleAssignment -GroupId $group.Id -PrincipalId $group.Id -ResourceId $servicePrincipal.Id -Id $emptyGuidGroup
28+
29+
# Get Graph service principal
30+
$graphServicePrincipal = Get-EntraServicePrincipal -Filter "AppId eq '$graphApiId'"
31+
32+
# Create resource access object
33+
$resourceAccessDelegated = New-Object Microsoft.Open.MSGraph.Model.ResourceAccess
34+
$resourceAccessDelegated.Id = ((Get-EntraServicePrincipal -ServicePrincipalId $graphServicePrincipal.Id).Oauth2PermissionScopes | Where-Object { $_.Value -eq $delegatedPermission }).Id
35+
$resourceAccessDelegated.Type = 'Scope'
36+
37+
# Create required resource access object
38+
$requiredResourceAccessDelegated = New-Object Microsoft.Open.MSGraph.Model.RequiredResourceAccess
39+
$requiredResourceAccessDelegated.ResourceAppId = $graphApiId
40+
$requiredResourceAccessDelegated.ResourceAccess = $resourceAccessDelegated
41+
42+
# Set application required resource access
43+
Set-EntraApplication -ApplicationId $app.Id -RequiredResourceAccess $requiredResourceAccessDelegated
44+
45+
# Set service principal parameters
46+
Set-EntraServicePrincipal -ServicePrincipalId $servicePrincipal.Id -AppRoleAssignmentRequired $True
47+
48+
# Grant OAuth2 permission
49+
$permissionGrant = New-EntraOauth2PermissionGrant -ClientId $servicePrincipal.Id -ConsentType 'AllPrincipals' -ResourceId $graphServicePrincipal.Id -Scope $delegatedPermission
50+
51+
# Get and filter OAuth2 permission grants
52+
Get-EntraOAuth2PermissionGrant -All | Where-Object { $_.Id -eq $permissionGrant.Id }
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<#
2+
DISCLAIMER: This script is not an official PowerShell script and is specifically designed for the current situation you are facing.
3+
It is provided "AS IS" with no warranties of any kind, either express or implied, including, but not limited to, any implied warranties of merchantability or fitness for a particular purpose.
4+
This script is not supported by any official Microsoft support programs or services. Microsoft disclaims all implied warranties, including but not limited to implied warranties of merchantability or fitness for a particular purpose.
5+
You assume all risk related to the use or performance of this script and its associated documentation. Under no circumstances shall Microsoft, its authors, or any other party involved in the creation, production, or delivery of this script be liable for any damages (including, but not limited to, loss of business profits, business interruptions, loss of business information, or other financial losses) arising from the use or inability to use the script or documentation, even if Microsoft has been advised of the possibility of such damages.
6+
7+
This script requires Microsoft Graph v1.0, as its logic depends on specific property values from this version. It is only compatible with Microsoft Graph PowerShell v2.x.x, which ensures that Microsoft Graph v1.0 is used. If you are using Microsoft Graph PowerShell v1, please upgrade to v2.
8+
For more information, visit: https://devblogs.microsoft.com/microsoft365dev/microsoft-graph-powershell-v2-is-now-in-public-preview-half-the-size-and-will-speed-up-your-automations/
9+
10+
Ensure you have the appropriate privileges when running this script, such as `Global Reader` or `Identity Governance Administrator`.
11+
#>
12+
Import-Module Microsoft.Graph.Authentication
13+
Import-Module Microsoft.Graph.Identity.Governance
14+
15+
# Connect to Microsoft Graph with the required scopes
16+
Connect-MgGraph -Scopes EntitlementManagement.Read.All
17+
18+
# Define allowed target scopes
19+
$allowedTargetScopes = @("allExternalUsers","allConfiguredConnectedOrganizationUsers","specificConnectedOrganizationUsers")
20+
$PoliciesToReview = @()
21+
22+
Write-Host "Starting to search for policies..."
23+
try{
24+
$Policies = Get-MgEntitlementManagementAssignmentPolicy -Property Id,DisplayName,AllowedTargetScope,RequestApprovalSettings -All -Top 999
25+
Write-Host "Successfully imported $($Policies.Count) policies"
26+
}catch{
27+
Write-Error "Error importing policies: $_"
28+
return
29+
}
30+
31+
Write-Host "Starting to analyze policies"
32+
foreach($Policy in $Policies){
33+
if($allowedTargetScopes -contains $Policy.AllowedTargetScope){
34+
if($Policy.RequestApprovalSettings.IsApprovalRequiredForAdd -ne $true){
35+
try {
36+
$PolicyDetails = Get-MgEntitlementManagementAssignmentPolicy -AccessPackageAssignmentPolicyId $Policy.Id -ExpandProperty accessPackage,catalog
37+
$PoliciesToReview += $PolicyDetails
38+
}
39+
catch {
40+
Write-Error "Error getting policy details: $_"
41+
return
42+
}
43+
44+
}
45+
}
46+
}
47+
48+
Write-Host "Analysis completed we have identified $($PoliciesToReview.Count) policies which should be reviewed:"
49+
Write-Host ($PoliciesToReview | Format-Table | Out-String)
50+
51+
Write-Host "Access packages associated with these policies:"
52+
Write-Host ($PoliciesToReview.AccessPackage | Format-Table | Out-String)
53+
54+
Write-Host "Script completed. More information can be found in the `$PoliciesToReview variable."

samples/export-apps-with-expiring-secrets-modified.ps1 renamed to samples/migration/export-apps-with-expiring-secrets-modified.ps1

File renamed without changes.
File renamed without changes.

samples/zero-trust/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: Zero Trust Scenarios
3+
description: Zero Trust scenarios.
4+
5+
ms.service: microsoft-entra-powershell
6+
ms.topic: reference
7+
ms.date: 02/03/2025
8+
ms.author: eunicewaweru
9+
ms.reviewer: stevemutungi
10+
manager: CelesteDG
11+
author: msewaweru
12+
---
13+
14+
# Zero Trust Scenarios
15+
16+
This section explains how scenario assessments can reduce the attack surface and limit the impact of breaches.
17+
18+
| Scenario | Rationale |
19+
| -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20+
| [Inactive applications shouldn't have highly privileged Microsoft Graph API permissions](./get-inactive-apps-with-high-priv-permissions.ps1) | Attackers can exploit inactive yet privileged applications to gain initial access and execute further attacks without detection. They may also manipulate these applications, such as by adding credentials, to maintain persistent access even if their primary method is discovered |
21+
| Scenario 2 | Description of scenario 2 |
22+
| Scenario 3 | Description of scenario 3 |
23+
| Scenario 4 | Description of scenario 4 |
24+
| Scenario 4 | Description of scenario 4 |
25+
| Scenario 4 | Description of scenario 4 |
26+
| Scenario 4 | Description of scenario 4 |
27+
| Scenario 4 | Description of scenario 4 |
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# ------------------------------------------------------------------------------
2+
# Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
# Licensed under the MIT License. See License in the project root for license information.
4+
# ------------------------------------------------------------------------------
5+
6+
# Connect to Microsoft Graph with necessary permissions
7+
Connect-Entra -Scopes "Application.Read.All", "Directory.Read.All", "AuditLog.Read.All" -NoWelcome
8+
9+
# Define inactivity threshold (e.g., 90 days)
10+
$inactiveThreshold = (Get-Date).AddDays(-90)
11+
12+
# Sample list of highly privileged Microsoft Graph API permissions
13+
$highPrivPermissions = @(
14+
"Directory.ReadWrite.All",
15+
"Directory.AccessAsUser.All",
16+
"User.ReadWrite.All",
17+
"Group.ReadWrite.All",
18+
"Application.ReadWrite.All",
19+
"RoleManagement.ReadWrite.Directory",
20+
"Policy.ReadWrite.ConditionalAccess",
21+
"Device.ReadWrite.All"
22+
)
23+
24+
# Get Microsoft Graph Service Principal - Note: You can also use the AppId ""00000003-0000-0000-c000-000000000000"" instead of the DisplayName
25+
$msGraphServicePrincipal = Get-EntraServicePrincipal -Filter "displayName eq 'Microsoft Graph'"
26+
27+
# Map permission IDs to friendly names
28+
$highPrivPermIds = @{}
29+
30+
foreach ($role in $msGraphServicePrincipal.AppRoles) {
31+
if ($highPrivPermissions -contains $role.Value) {
32+
$highPrivPermIds[$role.Id] = $role.Value
33+
}
34+
}
35+
36+
foreach ($scope in $msGraphServicePrincipal.OAuth2PermissionScopes) {
37+
if ($highPrivPermissions -contains $scope.Value) {
38+
$highPrivPermIds[$scope.Id] = $scope.Value
39+
}
40+
}
41+
42+
# Retrieve all registered applications
43+
$applications = Get-EntraApplication -All
44+
$appsWithHighPriv = @()
45+
46+
foreach ($app in $applications) {
47+
$hasHighPriv = $false
48+
$appHighPrivPermissions = @()
49+
if ($app.RequiredResourceAccess) {
50+
foreach ($req in $app.RequiredResourceAccess) {
51+
if ($req.ResourceAppId -eq $msGraphServicePrincipal.AppId) {
52+
foreach ($perm in $req.ResourceAccess) {
53+
if ($highPrivPermIds.ContainsKey($perm.Id)) {
54+
$hasHighPriv = $true
55+
$appHighPrivPermissions += $highPrivPermIds[$perm.Id]
56+
}
57+
}
58+
}
59+
if ($hasHighPriv) { break }
60+
}
61+
}
62+
if ($hasHighPriv) {
63+
$app | Add-Member -MemberType NoteProperty -Name HighPrivilegedPermissions -Value $appHighPrivPermissions
64+
$appsWithHighPriv += $app
65+
}
66+
}
67+
68+
# Check inactivity based on sign-in activity
69+
$inactiveApps = @()
70+
71+
foreach ($app in $appsWithHighPriv) {
72+
$sp = Get-EntraServicePrincipal -Filter "appId eq '$($app.AppId)'" -ErrorAction SilentlyContinue
73+
$lastSignIn = $null
74+
75+
if ($sp -and $sp.SignInActivity) {
76+
$lastSignIn = $sp.SignInActivity.LastSignInDateTime
77+
}
78+
79+
# Mark as inactive if never signed in or last sign-in is older than threshold
80+
$isInactive = -not $lastSignIn -or ([datetime]$lastSignIn -lt $inactiveThreshold)
81+
82+
if ($isInactive) {
83+
$inactiveApps += [PSCustomObject]@{
84+
ApplicationName = $app.DisplayName
85+
AppId = $app.AppId
86+
LastSignIn = $lastSignIn
87+
HighPrivilegedPermissions = $app.HighPrivilegedPermissions -join ", "
88+
}
89+
}
90+
}
91+
92+
$inactiveApps | Format-Table -AutoSize

0 commit comments

Comments
 (0)