-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace AzureAD with Microsoft Graph in consent grant functions
- Updates Get-AzureADPSPermissions to use Microsoft Graph cmdlets instead of deprecated AzureAD module. - Modifies Get-HawkTenantConsentGrants to leverage Graph-based authentication. - Maintains exact output format and data structure for backward compatibility. - Updates documentation links to point to current Microsoft Learn pages for Microsoft Graph. - Preserves original permission and consent validation logic while ensuring functionality with Graph. - Improves object caching mechanism to handle Graph object types efficiently. This migration ensures full feature parity with the previous AzureAD implementation while aligning with the modern Microsoft Graph SDK.
- Loading branch information
1 parent
e168e63
commit a89076c
Showing
6 changed files
with
227 additions
and
313 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,48 @@ | ||
Function Get-HawkTenantConsentGrants { | ||
<# | ||
.SYNOPSIS | ||
Gathers application grants | ||
.DESCRIPTION | ||
Used the script from https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants to gather information about | ||
application and delegate grants. Attempts to detect high risk grants for review. | ||
.OUTPUTS | ||
File: Consent_Grants.csv | ||
Path: \Tenant | ||
Description: Output of all consent grants | ||
.EXAMPLE | ||
Get-HawkTenantConsentGrants | ||
Function Get-HawkTenantConsentGrant { | ||
<# | ||
.SYNOPSIS | ||
Gathers application grants | ||
.DESCRIPTION | ||
Uses Microsoft Graph to gather information about application and delegate grants. | ||
Attempts to detect high risk grants for review. | ||
.OUTPUTS | ||
File: Consent_Grants.csv | ||
Path: \Tenant | ||
Description: Output of all consent grants | ||
.EXAMPLE | ||
Get-HawkTenantConsentGrant | ||
Gathers Grants | ||
#> | ||
[CmdletBinding()] | ||
param() | ||
|
||
Gathers Grants | ||
#> | ||
Out-LogFile "Gathering OAuth / Application Grants" | ||
|
||
Out-LogFile "Gathering Oauth / Application Grants" | ||
Test-GraphConnection | ||
Send-AIEvent -Event "CmdRun" | ||
|
||
Test-AzureADConnection | ||
Send-AIEvent -Event "CmdRun" | ||
# Gather the grants using the internal Graph-based implementation | ||
[array]$Grants = Get-AzureADPSPermission -ShowProgress | ||
[bool]$flag = $false | ||
|
||
# Gather the grants | ||
# Using the script from the article https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants | ||
[array]$Grants = Get-AzureADPSPermissions -ShowProgress | ||
[bool]$flag = $false | ||
# Search the Grants for the listed bad grants that we can detect | ||
if ($Grants.ConsentType -contains 'AllPrincipals') { | ||
Out-LogFile "Found at least one 'AllPrincipals' Grant" -notice | ||
$flag = $true | ||
} | ||
if ([bool]($Grants.Permission -match 'all')) { | ||
Out-LogFile "Found at least one 'All' Grant" -notice | ||
$flag = $true | ||
} | ||
|
||
# Search the Grants for the listed bad grants that we can detect | ||
if ($Grants.consenttype -contains 'AllPrinciples') { | ||
Out-LogFile "Found at least one `'AllPrinciples`' Grant" -notice | ||
$flag = $true | ||
} | ||
if ([bool]($Grants.permission -match 'all')){ | ||
Out-LogFile "Found at least one `'All`' Grant" -notice | ||
$flag = $true | ||
} | ||
if ($flag) { | ||
Out-LogFile 'Review the information at the following link to understand these results' -notice | ||
Out-LogFile 'https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants' -notice | ||
} | ||
else { | ||
Out-LogFile "To review this data follow:" | ||
Out-LogFile "https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants" | ||
} | ||
|
||
if ($flag){ | ||
Out-LogFile 'Review the information at the following link to understand these results' -notice | ||
Out-LogFile 'https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants#inventory-apps-with-access-in-your-organization' -notice | ||
} | ||
else { | ||
Out-LogFile "To review this data follow:" | ||
Out-LogFile "https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/detect-and-remediate-illicit-consent-grants#inventory-apps-with-access-in-your-organization" | ||
} | ||
|
||
$Grants | Out-MultipleFileType -FilePrefix "Consent_Grants" -csv -json | ||
} | ||
$Grants | Out-MultipleFileType -FilePrefix "Consent_Grants" -csv -json | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
Function Get-AzureADPSPermission { | ||
[CmdletBinding()] | ||
param( | ||
[switch] $DelegatedPermissions, | ||
[switch] $ApplicationPermissions, | ||
[string[]] $UserProperties = @("DisplayName"), | ||
[string[]] $ServicePrincipalProperties = @("DisplayName"), | ||
[switch] $ShowProgress, | ||
[int] $PrecacheSize = 999 | ||
) | ||
|
||
# Verify Graph connection | ||
try { | ||
$tenant_details = Get-MgOrganization | ||
} | ||
catch { | ||
throw "You must call Connect-MgGraph before running this script." | ||
} | ||
Write-Verbose ("TenantId: {0}" -f $tenant_details.Id) | ||
|
||
# Cache objects | ||
$script:ObjectByObjectId = @{} | ||
$script:ObjectByObjectType = @{ | ||
'ServicePrincipal' = @{} | ||
'User' = @{} | ||
} | ||
|
||
function CacheObject ($Object, $Type) { | ||
if ($Object) { | ||
$script:ObjectByObjectType[$Type][$Object.Id] = $Object | ||
$script:ObjectByObjectId[$Object.Id] = $Object | ||
} | ||
} | ||
|
||
function GetObjectByObjectId ($ObjectId) { | ||
if (-not $script:ObjectByObjectId.ContainsKey($ObjectId)) { | ||
Write-Verbose ("Querying Graph API for object '{0}'" -f $ObjectId) | ||
try { | ||
$object = Get-MgDirectoryObject -DirectoryObjectId $ObjectId | ||
# Determine type from OdataType | ||
$type = $object.AdditionalProperties.'@odata.type'.Split('.')[-1] | ||
CacheObject -Object $object -Type $type | ||
} | ||
catch { | ||
Write-Verbose "Object not found." | ||
} | ||
} | ||
return $script:ObjectByObjectId[$ObjectId] | ||
} | ||
|
||
# Cache all service principals | ||
Write-Verbose "Retrieving all ServicePrincipal objects..." | ||
$servicePrincipals = Get-MgServicePrincipal -All | ||
foreach($sp in $servicePrincipals) { | ||
CacheObject -Object $sp -Type 'ServicePrincipal' | ||
} | ||
$servicePrincipalCount = $servicePrincipals.Count | ||
|
||
# Cache users | ||
Write-Verbose ("Retrieving up to {0} User objects..." -f $PrecacheSize) | ||
$users = Get-MgUser -Top $PrecacheSize | ||
foreach($user in $users) { | ||
CacheObject -Object $user -Type 'User' | ||
} | ||
|
||
if ($DelegatedPermissions -or (-not ($DelegatedPermissions -or $ApplicationPermissions))) { | ||
Write-Verbose "Retrieving OAuth2PermissionGrants..." | ||
$oauth2Grants = Get-MgOAuth2PermissionGrant -All | ||
|
||
foreach ($grant in $oauth2Grants) { | ||
if ($grant.Scope) { | ||
$grant.Scope.Split(" ") | Where-Object { $_ } | ForEach-Object { | ||
$scope = $_ | ||
|
||
$grantDetails = [ordered]@{ | ||
"PermissionType" = "Delegated" | ||
"ClientObjectId" = $grant.ClientId | ||
"ResourceObjectId" = $grant.ResourceId | ||
"Permission" = $scope | ||
"ConsentType" = $grant.ConsentType | ||
"PrincipalObjectId" = $grant.PrincipalId | ||
} | ||
|
||
# Add service principal properties | ||
if ($ServicePrincipalProperties.Count -gt 0) { | ||
$client = $script:ObjectByObjectId[$grant.ClientId] | ||
$resource = $script:ObjectByObjectId[$grant.ResourceId] | ||
|
||
$insertAtClient = 2 | ||
$insertAtResource = 3 | ||
foreach ($propertyName in $ServicePrincipalProperties) { | ||
$grantDetails.Insert($insertAtClient++, "Client$propertyName", $client.$propertyName) | ||
$insertAtResource++ | ||
$grantDetails.Insert($insertAtResource, "Resource$propertyName", $resource.$propertyName) | ||
$insertAtResource++ | ||
} | ||
} | ||
|
||
# Add user properties | ||
if ($UserProperties.Count -gt 0) { | ||
$principal = if ($grant.PrincipalId) { | ||
$script:ObjectByObjectId[$grant.PrincipalId] | ||
} else { @{} } | ||
|
||
foreach ($propertyName in $UserProperties) { | ||
$grantDetails["Principal$propertyName"] = $principal.$propertyName | ||
} | ||
} | ||
|
||
New-Object PSObject -Property $grantDetails | ||
} | ||
} | ||
} | ||
} | ||
|
||
if ($ApplicationPermissions -or (-not ($DelegatedPermissions -or $ApplicationPermissions))) { | ||
Write-Verbose "Retrieving AppRoleAssignments..." | ||
|
||
$i = 0 | ||
foreach ($sp in $servicePrincipals) { | ||
if ($ShowProgress) { | ||
Write-Progress -Activity "Retrieving application permissions..." ` | ||
-Status ("Checked {0}/{1} apps" -f $i++, $servicePrincipalCount) ` | ||
-PercentComplete (($i / $servicePrincipalCount) * 100) | ||
} | ||
|
||
$appRoleAssignments = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -All | ||
|
||
foreach ($assignment in $appRoleAssignments) { | ||
if ($assignment.PrincipalType -eq "ServicePrincipal") { | ||
$resource = $script:ObjectByObjectId[$assignment.ResourceId] | ||
$appRole = $resource.AppRoles | Where-Object { $_.Id -eq $assignment.AppRoleId } | ||
|
||
$grantDetails = [ordered]@{ | ||
"PermissionType" = "Application" | ||
"ClientObjectId" = $assignment.PrincipalId | ||
"ResourceObjectId" = $assignment.ResourceId | ||
"Permission" = $appRole.Value | ||
} | ||
|
||
if ($ServicePrincipalProperties.Count -gt 0) { | ||
$client = $script:ObjectByObjectId[$assignment.PrincipalId] | ||
|
||
$insertAtClient = 2 | ||
$insertAtResource = 3 | ||
foreach ($propertyName in $ServicePrincipalProperties) { | ||
$grantDetails.Insert($insertAtClient++, "Client$propertyName", $client.$propertyName) | ||
$insertAtResource++ | ||
$grantDetails.Insert($insertAtResource, "Resource$propertyName", $resource.$propertyName) | ||
$insertAtResource++ | ||
} | ||
} | ||
|
||
New-Object PSObject -Property $grantDetails | ||
} | ||
} | ||
} | ||
|
||
if ($ShowProgress) { | ||
Write-Progress -Completed -Activity "Retrieving application permissions..." | ||
} | ||
} | ||
} |
Oops, something went wrong.