Skip to content

Instantly share code, notes, and snippets.

@andyrobbins
Created April 5, 2022 01:07
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andyrobbins/60de5b479c6d82766dab4725ad55e414 to your computer and use it in GitHub Desktop.
Save andyrobbins/60de5b479c6d82766dab4725ad55e414 to your computer and use it in GitHub Desktop.
# 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