Created
April 5, 2022 01:07
-
-
Save andyrobbins/60de5b479c6d82766dab4725ad55e414 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Function for getting an MS Graph Token | |
Function Get-MSGraphToken { | |
<# | |
.DESCRIPTION | |
Requests a token from STS with the MS Graph specified as the resource/intended audience | |
#> | |
[cmdletbinding()] | |
param( | |
[Parameter(Mandatory = $True)] | |
[string] | |
$ClientID, | |
[Parameter(Mandatory = $True)] | |
[string] | |
$ClientSecret, | |
[Parameter(Mandatory = $True)] | |
[string] | |
$TenantName | |
) | |
$Body = @{ | |
Grant_Type = "client_credentials" | |
Scope = "https://graph.microsoft.com/.default" | |
client_Id = $ClientID | |
Client_Secret = $ClientSecret | |
} | |
$Token = Invoke-RestMethod ` | |
-URI "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" ` | |
-Method POST ` | |
-Body $Body | |
$Token | |
} | |
# Get a token for MS Graph API: | |
$Token = Get-MSGraphToken ` | |
-ClientID "<your client ID>" ` | |
-ClientSecret "<your client secret>" ` | |
-TenantName "<your tenant name>" | |
# Get all service principal IDs | |
$ServicePrincipalIDs = $null | |
$URI = 'https://graph.microsoft.com/v1.0/servicePrincipals/' | |
do { | |
$Results = Invoke-RestMethod ` | |
-Headers @{Authorization = "Bearer $($Token.access_token)"} ` | |
-URI $URI ` | |
-UseBasicParsing ` | |
-Method "GET" ` | |
-ContentType "application/json" | |
if ($Results.value) { | |
$ServicePrincipalIDs += $Results.value.id | |
} else { | |
$ServicePrincipalIDs += $Results | |
} | |
$uri = $Results.'@odata.nextlink' | |
} until (!($uri)) | |
# Fetch the app roles assigned to each SP: | |
$AppRoles = $null | |
ForEach ($id in $ServicePrincipalIDs){ | |
$req = $null | |
$URL = 'https://graph.microsoft.com/v1.0/servicePrincipals/{0}/appRoleAssignments' -f $id | |
$req = Invoke-RestMethod ` | |
-Headers @{Authorization = "Bearer $($Token.access_token)"} ` | |
-Uri $URL ` | |
-Method GET | |
$AppRoles += $req.value | |
} | |
# Get Global Admins: | |
$GlobalAdmins = Invoke-RestMethod ` | |
-Headers @{Authorization = "Bearer $($Token.access_token)" } ` | |
-Uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '62e90394-69f5-4237-9190-012177145e10'&`$expand=principal" ` | |
-Method GET | |
# Get Privileged Role Admins: | |
$PrivRoleAdmins = Invoke-RestMethod ` | |
-Headers @{Authorization = "Bearer $($Token.access_token)" } ` | |
-Uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq 'e8611ab8-c189-46e8-94e1-60213ab1f814'&`$expand=principal" ` | |
-Method GET | |
# Get Privileged Auth Admins: | |
$PrivAuthAdmins = Invoke-RestMethod ` | |
-Headers @{Authorization = "Bearer $($Token.access_token)" } ` | |
-Uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '7be44c8a-adaf-4e2a-84d6-ab2649e08a13'&`$expand=principal" ` | |
-Method GET | |
# Find service principals with dangerous app roles | |
# These application roles allow you to promote yourself or any other principal to Global Admin: | |
# 9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8 # RoleManagement.ReadWrite.Directory -> directly promote yourself to GA | |
# 06b708a9-e830-4db3-a914-8e69da51d44f # AppRoleAssignment.ReadWrite.All -> grant yourself the above role, then promote to GA | |
$DangerousAppRoles = ForEach ($RoleAssignment in $AppRoles){ | |
if ($RoleAssignment.appRoleId -eq "9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8" -Or $RoleAssignment.appRoleId -eq "06b708a9-e830-4db3-a914-8e69da51d44f") { | |
$RoleAssignment | |
} | |
} | |
Write-Host "Dangerous MS Graph API permissions held by service principals:" | |
$DangerousAppRoles | |
# Find service principals with dangerous AzureAD admin role assignments: | |
Write-Host "Dangerous AzureAD Admin role assignments held by service principals:" | |
$GlobalAdmins.value | ?{$_.principal."@odata.type" -match "#microsoft.graph.servicePrincipal"} | |
$PrivRoleAdmins.value | ?{$_.principal."@odata.type" -match "#microsoft.graph.servicePrincipal"} | |
$PrivAuthAdmins.value | ?{$_.principal."@odata.type" -match "#microsoft.graph.servicePrincipal"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment