improvements

This commit is contained in:
carlospolop
2025-07-29 17:56:43 +02:00
parent baff049eb8
commit e324b93d88
13 changed files with 414 additions and 99 deletions

View File

@@ -420,6 +420,7 @@
- [Az - CosmosDB](pentesting-cloud/azure-security/az-services/az-cosmosDB.md)
- [Az - Defender](pentesting-cloud/azure-security/az-services/az-defender.md)
- [Az - File Shares](pentesting-cloud/azure-security/az-services/az-file-shares.md)
- [Az - Front Door](pentesting-cloud/azure-security/az-services/az-front-door.md)
- [Az - Function Apps](pentesting-cloud/azure-security/az-services/az-function-apps.md)
- [Az - Intune](pentesting-cloud/azure-security/az-services/intune.md)
- [Az - Key Vault](pentesting-cloud/azure-security/az-services/az-keyvault.md)
@@ -442,21 +443,19 @@
- [Az - Permissions for a Pentest](pentesting-cloud/azure-security/az-permissions-for-a-pentest.md)
- [Az - Lateral Movement (Cloud - On-Prem)](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/README.md)
- [Az AD Connect - Hybrid Identity](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/README.md)
- [Az - Synchronising New Users](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-synchronising-new-users.md)
- [Az - Hybrid Identity Misc Attacks](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-hybrid-identity-misc-attack.md)
- [Az - Cloud Kerberos Trust](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-cloud-kerberos-trust.md)
- [Az - Federation](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/federation.md)
- [Az - Federation](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-federation.md)
- [Az - Cloud Sync](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-cloud-sync.md)
- [Az - Connect Sync](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-connect-sync.md)
- [Az - Default Applications](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-default-applications.md)
- [Az - Domain Services](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-domain-services.md)
- [Az - PTA - Pass-through Authentication](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/pta-pass-through-authentication.md)
- [Az - PTA - Pass-through Authentication](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-pta-pass-through-authentication.md)
- [Az - Seamless SSO](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/seamless-sso.md)
- [Az - Arc vulnerable GPO Deploy Script](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-arc-vulnerable-gpo-deploy-script.md)
- [Az - Local Cloud Credentials](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-local-cloud-credentials.md)
- [Az - Pass the Cookie](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-pass-the-cookie.md)
- [Az - Pass the Certificate](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-pass-the-certificate.md)
- [Az - Pass the PRT](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/pass-the-prt.md)
- [Az - Phishing Primary Refresh Token (Microsoft Entra)](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-phishing-primary-refresh-token-microsoft-entra.md)
- [Az - Processes Memory Access Token](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-processes-memory-access-token.md)
- [Az - Primary Refresh Token (PRT)](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-primary-refresh-token-prt.md)
- [Az - Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/README.md)

View File

@@ -4,13 +4,13 @@
## Pass the Certificate (Azure)
In Azure joined machines, it's possible to authenticate from one machine to another using certificates that **must be issued by Azure AD CA** for the required user (as the subject) when both machines support the **NegoEx** authentication mechanism.
In Azure joined machines, it's possible to authenticate from one machine to another using certificates that **must be issued by Entra ID CA** for the required user (as the subject) when both machines support the **NegoEx** authentication mechanism.
In super simplified terms:
- The machine (client) initiating the connection **needs a certificate from Azure AD for a user**.
- Client creates a JSON Web Token (JWT) header containing PRT and other details, sign it using the Derived key (using the session key and the security context) and **sends it to Azure AD**
- Azure AD verifies the JWT signature using client session key and security context, checks validity of PRT and **responds** with the **certificate**.
- The machine (client) initiating the connection **needs a certificate from Entra ID for a user**.
- Client creates a JSON Web Token (JWT) header containing PRT and other details, sign it using the Derived key (using the session key and the security context) and **sends it to Entra ID**
- Entra ID verifies the JWT signature using client session key and security context, checks validity of PRT and **responds** with the **certificate**.
In this scenario and after grabbing all the info needed for a [**Pass the PRT**](pass-the-prt.md) attack:

View File

@@ -1,10 +0,0 @@
# Az - Phishing Primary Refresh Token (Microsoft Entra)
{{#include ../../../banners/hacktricks-training.md}}
**Check:** [**https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/**](https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -2,7 +2,287 @@
{{#include ../../../banners/hacktricks-training.md}}
**Chec the post in** [**https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/**](https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/) although another post explaining the same can be found in [**https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30**](https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30)
## What is a Primary Refresh Token (PRT)?
A **Primary Refresh Token (PRT)** is a long-lived refresh token used in Azure AD (Entra ID) authentication, analogous to a Kerberos TGT. It is issued upon user login on an Azure AD-joined device and can be used to request access tokens for various applications without re-prompting credentials. Each PRT is accompanied by a **session key** (also called a Proof-of-Possession key) -- a symmetric key used to sign requests and prove the client has the PRT. The PRT itself is an opaque, encrypted blob (not readable by the client), while the session key is used to **sign** a JWT containing the PRT when requesting tokens. In other words, possession of the PRT alone is insufficient; an attacker needs the session key to prove legitimacy, similar to needing both a Kerberos TGT and its session key for authentication.
On Windows, the PRT and session key are cached in the LSASS process via the CloudAP plugin. If a device has a **TPM** (Trusted Platform Module), Azure AD binds keys to the TPM for extra security. This means on TPM-equipped devices, the session key is stored or used within the TPM such that it cannot be directly read from memory under normal circumstances. If no TPM is available (e.g. many VMs or older systems), the keys are kept in software and protected with DPAPI encryption. In both cases, an attacker with administrative privileges or code execution on the machine can attempt to **dump the PRT and session key from memory** as part of post-exploitation, and then use them to impersonate the user in the cloud.
Unlike typical refresh tokens (which are usually application-specific), a PRT is broader, allowing your device to request tokens for almost any Entra ID-integrated resource or service.
## How Does a PRT Work?
Here's a simplified breakdown of how a PRT operates:
1. **Device Registration:**
- When your device (like a Windows laptop or mobile phone) joins or registers with Entra ID, it authenticates using your credentials (username/password/MFA).
- Upon successful authentication, Entra ID issues a PRT bound specifically to your device.
2. **Token Storage:**
- The PRT is securely stored on your device, often protected by hardware features like the Trusted Platform Module (TPM), ensuring that it's difficult for unauthorized parties to extract or misuse.
3. **Single Sign-On (SSO):**
- Each time you access an Entra ID-protected application (e.g., Microsoft 365 apps, SharePoint, Teams), your device silently uses the stored PRT to request and obtain a specific access token for that app.
- You don't need to enter your credentials repeatedly because the PRT transparently handles authentication.
4. **Renewal and Security:**
- PRTs have a long lifetime (typically around 14 days), but are continually renewed as long as your device is actively in use.
- If your device becomes compromised or lost, administrators can revoke your PRT remotely, immediately blocking unauthorized access.
### Why are PRTs Powerful?
- **Universal Access:** Unlike typical tokens limited to one app or resource, a PRT can facilitate access to all Entra ID-integrated services.
- **Enhanced Security:** With built-in hardware protections (like TPM), PRTs ensure secure token storage and usage.
- **User Experience:** PRTs significantly improve the user experience by reducing frequent authentication prompts and enabling true seamless SSO.
## How to know if a PRT is present?
- Check if PRT is present:
```bash
# Execute
dsregcmd /status
## Check if the value of AzureAdPrt is set to YES
```
- Check if protected by TPM:
```bash
Get-Tpm | Select TpmPresent,TpmReady,TpmEnabled,TpmOwned
# TpmPresent/Ready = True indicates the device can bind secrets to TPM.
dsregcmd /status
# In Device State / WHfB prerequisites youll typically see:
# KeyProvider = Microsoft Platform Crypto Provider ⇒ TPM hardware key;
# KeyProvider = Software Key Storage Provider ⇒ not TPMbound.
# Some builds also show TpmProtected: YES/NO and KeySignTest (run elevated to test).
```
## Dump and user unprotected PRTs
According to [this post](https://dirkjanm.io/digging-further-into-the-primary-refresh-token/) on Windows devices **without TPM binding**, the PRT and its session key live in LSASS (CloudAP plugin). With local admin/SYSTEM on that device, the PRT blob and the DPAPIencrypted session key can be **read from LSASS, the session key decrypted via DPAPI, and the signing key derived** to mint a valid PRT cookie (`xmsRefreshTokenCredential`). You need both the PRT and its session key—the PRT string alone isnt enough.
### Mimikatz
```bash
privilege::debug
sekurlsa::cloudap
```
The **PRT field** contains the encrypted refresh token (typically base64 string), and KeyValue in the ProofOfPossessionKey is the DPAPI-encrypted session key (also base64).
Then, from the **`sekurlsa::cloudap`** output, copy the base64 blob from **`KeyValue`** inside the field `ProofOfPossessionKey` (this is the session key encrypted with DPAPI). This encrypted key cannot be used as-is it must be decrypted using the systems DPAPI credentials.
Because DPAPI encryption for system secrets requires the machines system context, elevate your token to SYSTEM and use Mimikatzs DPAPI module to decrypt:
```bash
token::elevate
dpapi::cloudapkd /keyvalue:<EncryptedKeyBlob> /unprotect
```
The `token::elevate` will impersonate SYSTEM and the `dpapi::cloudapkd` command with `/unprotect` will use the DPAPI master key to decrypt the provided KeyValue blob. This yields the clear-text session key and also the associated Derived Key and Context used for signing:
- **Clear key** the 32-byte session key in plaintext (represented as a hex string).
- **Derived Key** a 32-byte key derived from the session key and a context value (more on this below).
- **Context** a 24-byte random context that was used when deriving the signing key for the PRT cookie.
> [!NOTE]
> If this doesn't work for you to impersonate the user, check the following section using **`AADInternals`**.
Then, you can also use mimikatz to generate a valid PRT cookie:
```bash
# Context is obtained from papi::cloudapkd /keyvalue:<EncryptedKeyBlob> /unprotect
# Derivedkey is obtained from papi::cloudapkd /keyvalue:<EncryptedKeyBlob> /unprotect
# PRT is obtained from sekurlsa::cloudap (filed "Prt"
dpapi::cloudapkd /context:<ContextHex> /derivedkey:<DerivedKeyHex> /prt:<PRT>
```
Mimikatz will output a signed JWT (the `PRT cookie`) after the line “Signature with key”, which contains the PRT and is signed using the derived key. This JWT can be copied and then used in a web session. For example, an attacker can open a browser, go to `login.microsoftonline.com`, and set a cookie named `x-ms-RefreshTokenCredential` with the value being this JWT. When the browser refreshes or navigates, Azure AD will treat the session as authenticated (the PRT cookie is presented as if SSO occurred), and it will issue an authorization code or access token for the specified resource. In practice, one would navigate to a resource like Office 365 or Azure portal; the presence of a valid PRT cookie means Azure AD will grant access without additional login (bypassing MFA, since the PRT is already authenticated).
You could also use **`roadtx`** and **`roadrecon`** with the PRT of the PRT cookie to impersonate the user *(TODO: Find the exact command lines to use roadtx/roadrecon to get credentials from a PRT)*.
### AADInternals
The **`AADInternals`** PowerShell module can also be used with the previously obtained PRT and session key to generate a valid PRT token. This is useful for automating the process of obtaining a new PRT token with nonce, which can be used to fetch access tokens for Azure AD Graph API or other resources:
```bash
# Code from https://aadinternals.com/post/prt/
# Add the PRT to a variable
$MimikatzPRT = "MS5BVUVCNFdiUV9UZnV2RW13ajlEaFVoR2JCSWM3cWpodG9CZElzblY2TVdtSTJUdENBY1JCQVEuQWdBQkF3RUFBQUJWclNwZXVXYW1SYW0yakFGMVhSUUVBd0RzX3dVQTlQO...R0RjNFQ0QxaHJ1RFdJeHZUM0stWjJpQVhmMnBLeWpPaHBIOVc"
# Add padding
while($MimikatzPRT.Length % 4) {$MimikatzPRT += "="}
# Convert from Base 64
$PRT = [text.encoding]::UTF8.GetString([convert]::FromBase64String($MimikatzPRT))
# Add the session key (Clear key) to a variable
$MimikatzKey = "7ee0b1f2eccbae440190bf0761bc52099ad7ae7d10d28bd83b67a81a0dfa0808"
# Convert to byte array and base 64 encode
$SKey = [convert]::ToBase64String( [byte[]] ($MimikatzKey -replace '..', '0x$&,' -split ',' -ne ''))
# Generate a new PRTToken with nonce
$prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SKey
# Get an access token for MS Graph API
Get-AADIntAccessTokenForMSGraph -PRTToken $prtToken
```
This obtains a fresh PRT cookie (with a nonce) and then uses it to fetch an access token for the Azure AD Graph API(demonstrating cloud access on behalf of the user). AADInternals abstracts much of the cryptography and uses Windows components or its own logic under the hood.
## Abusing protected PRTs
Despite the mentioned protections, an attacker who has already compromised a device (as a local user or even SYSTEM) can still **abuse the PRT to obtain fresh access tokens** by leveraging Windows' own token broker APIs and security components. Instead of **extracting** the raw PRT or key, the attacker essentially **"asks" Windows to use the PRT on their behalf**. In the sections below, we outline currently valid techniques for abusing PRTs and their session keys on up-to-date Windows devices where TPM protections are in effect. All these techniques assume post-exploitation access on the target machine, and **focus on abusing built-in authentication flows** (no unpatched vulnerabilities needed).
### Windows Token Broker Architecture and SSO Flow
Modern Windows handles cloud authentication via a built-in **token broker** stack, which includes components in both user mode and LSASS (Local Security Authority). Key pieces of this architecture include:
- **LSASS CloudAP Plugin:** When a device is Azure AD joined, LSASS loads cloud authentication packages (e.g. `CloudAP.dll`, `aadcloudap.dll`, `MicrosoftAccountCloudAP.dll`) that manage PRTs and token requests. LSASS (running as SYSTEM) orchestrates PRT storage, renewal, and usage, and interfaces with the TPM to perform cryptographic operations (like signing a PRT challenge with the session key).
- **Web Account Manager (WAM):** The Windows Web Account Manager is a user-mode framework (accessible via COM/WinRT APIs) that allows applications or browsers to request tokens for cloud accounts without prompting for credentials. WAM acts as a broker between user applications and the secure LSASS/TPM-backed PRT. For example, Microsoft's MSAL library and certain OS components use WAM to silently acquire tokens using the logged-in user's PRT.
- **BrowserCore.exe and Token Broker COM interfaces:** For browser SSO, Windows includes a component called **BrowserCore.exe** (located under *Windows Security\BrowserCore*). This is a native messaging host used by browsers (Edge, Chrome via an extension, etc.) to obtain a PRT-derived SSO token for Azure AD login. Under the hood, BrowserCore leverages a COM object provided by `MicrosoftAccountTokenProvider.dll` to retrieve a PRT-based cookie/token. In essence, this COM interface is a first-party "token broker" API that any process running as the user can obscall to get an SSO token (provided the user has a valid PRT in LSASS).
When an Azure AD joined user tries to access a resource (say, the Azure Portal), the flow is typically: an application calls into WAM or BrowserCore's COM interface, which in turn communicates with LSASS. LSASS uses the PRT and session key (secured by TPM) to produce an **SSO token** -- often called a **PRT cookie** -- which is then given back to the application or browser. The PRT cookie is a special JWT containing the encrypted PRT and a nonce, signed with a key derived from the PRT's session key. This cookie is sent to Azure AD (in an `x-ms-RefreshTokenCredential` header) to prove the device and user hold a valid PRT, allowing Azure AD to issue standard OAuth refresh and access tokens for various applications. Notably, any Multi-Factor Authentication (MFA) claim present in the PRT will be carried into tokens obtained via this SSO process, meaning PRT-derived tokens can satisfy MFA-protected resources.
### User-Level Token Theft (Non-Admin)
When an attacker has **user-level code execution**, the TPM protection of PRT doesn't stop the attacker from obtaining tokens. The attacker **leverages built-in Windows Token Broker APIs**:
#### **BrowserCore (MicrosoftAccountTokenProvider COM)**
BrowserCore exposes a COM class (`MicrosoftAccountTokenProvider`, CLSID `{a9927f85-a304-4390-8b23-a75f1c668600}`) to fetch PRT cookies. This COM API is invoked legitimately by browsers (Chrome/Edge extensions) for Azure AD SSO.
- **[RequestAADRefreshToken](https://github.com/leechristensen/RequestAADRefreshToken)**
```bash
RequestAADRefreshToken.exe --uri https://login.microsoftonline.com
```
*(Returns an Azure AD refresh token or PRT cookie)*
- **[ROADtoken](https://github.com/dirkjanm/ROADtoken)** & **[ROADtools](https://github.com/dirkjanm/ROADtools)**
```bash
ROADtoken.exe --nonce <nonce-value>
roadrecon auth --prt-cookie <cookie>
```
*(Generates nonce, invokes BrowserCore to get PRT cookie, then redeems it via ROADtools)*
### **Web Account Manager (WAM) APIs**
Attackers use legitimate Microsoft authentication libraries (**MSAL**, **WAM APIs**, **WebAuthenticationCoreManager**) from user-level processes to silently retrieve tokens leveraging TPM-protected PRT.
- **[aadprt](https://posts.specterops.io/)**
```bash
execute-assembly aadprt.exe
```
*(Retrieves PRT cookie via COM interfaces)*
- **[listwamaccounts](https://posts.specterops.io/)**
```bash
execute-assembly listwamaccounts.exe
```
*(Lists Azure AD accounts logged in via WAM; identifies token targets)*
- **Generic Example (PowerShell with MSAL)**:
```powershell
$app = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create("client-id").Build()
$result = $app.AcquireTokenSilent(@("https://graph.microsoft.com/.default"), $app.GetAccountsAsync().Result[0]).ExecuteAsync().Result
$result.AccessToken
```
*(Silently gets an access token leveraging PRT)*
#### Administrator / SYSTEM-Level Token Abuse
If the attacker escalates to **Administrator or SYSTEM**, they can directly impersonate any Azure AD logged-on user and use the same **COM/WAM token broker APIs**. TPM-protected PRTs do not prevent this legitimate token issuance.
### **User Impersonation and Token Retrieval**
Admin/SYSTEM could impersonate running sessions of other users to invoke BrowserCore or WAM for token generation.
For this just impersonate the user process (e.g., `explorer.exe`) and invoke the token broker APIs using any technique commented in the previous section.
### **Direct LSASS & Token Broker Interaction (Advanced)**
An administrator can still work with LSASS to abuse the PRT: for instance, an admin could inject code into LSASS or call internal CloudAP functions to prompt LSASS to produce a token. Dirk-jans research noted that an admin can “interact with PRT keys in LSASS using crypto APIs”. In practice, this could mean using LSASSs own functions (via a technique like API hooking or RPC, if available) to generate a PRT cookie. Another approach is to exploit any window where the session key might appear in memory for example, at the moment of PRT renewal or device registration when it is unencrypted for use. Such attacks are considerably more complex and situational. A more straightforward admin tactic is abusing existing token handles or caches: LSASS caches recently issued refresh tokens for apps in memory (encrypted with DPAPI). A determined SYSTEM attacker could attempt to extract these DPAPI-protected tokens (using the users master key, which an admin can obtain) to directly steal refresh tokens for specific applications. However, the easiest and most generic method remains impersonation and use of the documented token broker interfaces, since these guarantee that Azure AD will issue fresh tokens (with all proper claims) rather than trying to crack encryption.
## Phishing PRTs
Abuse the **OAuth Device Code** flow using the **Microsoft Authentication Broker client ID** (**`29d9ed98-a469-4536-ade2-f981bc1d605e`**) and the **Device Registration Service (DRS)** resource to obtain a **refresh token that can be upgraded to a Primary Refresh Token (PRT)** after registering a **rogue device**.
### **Why this works**
- **PRT** is **devicebound** and enables **SSO for (almost) any Entraprotected app**.
- The **Broker client + DRS** combination allows a phished **refresh token** to be **exchanged for a PRT** once a device is registered.
- **MFA isn't bypassed**: the **user performs MFA** during the phish; **MFA claims propagate** into the resulting PRT, letting the attacker access apps **without further prompts**.
**Prerequisites**:
- **User authentication via Device Code** using the **Broker client ID** (`29d9ed98-a469-4536-ade2-f981bc1d605e`) and **DRS scopes/resource** (e.g., **`01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9/.default`** or **`https://enrollment.manage.microsoft.com/`**).
- **User can register devices** in Entra ID (**default: allowed**, but can be restricted or quotalimited).
- **No blocking CA policies** that **disable Device Code** or **require compliant/hybrid devices** for target apps (those won't stop PRT issuance, but **will** block **using** it to access protected apps).
- **Attackercontrolled host** to run the flow and hold the tokens/device keys.
**Attack Flow**:
1. **Initiate Device Code auth** with **client_id = Broker** and **DRS scope/resource**; show the **user code** to the victim.
```bash
curl -s -X POST \
"https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode" \
-d "client_id=29d9ed98-a469-4536-ade2-f981bc1d605e" \
-d "scope=01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9/.default offline_access openid profile"
```
2. **Victim signs in on Microsoft's site** (legit UI) and completes **MFA****attacker receives a DRSscoped refresh token** for the Broker client.
3. **Register a rogue device** in the tenant using that refresh token (device object is created and linked to the victim).
4. **Upgrade to a PRT** by exchanging the **refresh token + device identity/keys****PRT** bound to the attacker's device.
5. **(Optional persistence)**: if MFA was fresh, **register a Windows Hello for Business key** to maintain **longterm, passwordless access**.
6. **Abuse**: redeem the **PRT** (or mint a **PRT cookie**) to obtain **access tokens** for **Exchange/Graph/SharePoint/Teams/custom apps** as the user.
### Public Tools and Proof-of-Concepts
- [ROADtools/ROADtx](https://github.com/dirkjanm/ROADtools): Automates OAuth flow, device registration, and token upgrades.
- [DeviceCode2WinHello](https://github.com/kiwids0220/deviceCode2WinHello): Single-command script automating device code phish-to-PRT+WHfB keys.
## References
- [Dirkjan's blog post on PRT](https://dirkjanm.io/digging-further-into-the-primary-refresh-token/)
- [Dirkjan's post on phishing PRTs](https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/)
- [Dirkjan's post on abusing PRTs](https://dirkjanm.io/abusing-azure-ad-sso-with-the-primary-refresh-token/)
- SpecterOps post on [Requesting Azure AD Request Tokens](https://posts.specterops.io/requesting-azure-ad-request-tokens-on-azure-ad-joined-machines-for-browser-sso-2b0409caad30)
- [AADInternals post on PRTs](https://aadinternals.com/post/prt/)
- [blog.3or.de](https://blog.3or.de/understanding-primary-refresh-tokens-and-cve-2021-33779-how-pass-the-prt-was-eliminated#:~:text=,the%20Token%20Broker%20on%20Windows)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -28,8 +28,7 @@ curl -s -H "Authorization: Bearer <token>" https://graph.microsoft.com/v1.0/site
curl -s -H "Authorization: Bearer <token>" 'https://graph.microsoft.com/v1.0/sites/<site_id>/drives/<drive_id>' | jq
## Finally, download a file from that drive:
┌──(magichk㉿black-pearl)-[~]
└─$ curl -o <filename_output> -L -H "Authorization: Bearer <token>" '<@microsoft.graph.downloadUrl>'
curl -o <filename_output> -L -H "Authorization: Bearer <token>" '<@microsoft.graph.downloadUrl>'
```
**Note that these kind of access tokens can be also found inside other processes.**

View File

@@ -4,47 +4,83 @@
**This post is a summary of** [**https://dirkjanm.io/obtaining-domain-admin-from-azure-ad-via-cloud-kerberos-trust/**](https://dirkjanm.io/obtaining-domain-admin-from-azure-ad-via-cloud-kerberos-trust/) **which can be checked for further information about the attack. This technique is also commented in** [**https://www.youtube.com/watch?v=AFay_58QubY**](https://www.youtube.com/watch?v=AFay_58QubY)**.**
## Basic Information
## Kerberos Trust Relationship Overview
### Trust
**Cloud Kerberos Trust (Entra ID -> AD)** -- This feature (part of Windows Hello for Business) establishes a one-way trust where on-prem AD **trusts Entra ID** to issue Kerberos tickets for AD. Enabling it creates an **AzureADKerberos$** computer object in AD (appearing as a Read-Only Domain Controller) and a linked **`krbtgt_AzureAD`** account (a secondary KRBTGT). Entra ID holds the keys for these accounts and can issue "partial" Kerberos TGTs for AD users. AD domain controllers will honor these tickets, but with RODC-like restrictions: by default, **high-privilege groups (Domain Admins, Enterprise Admins, etc.) are *denied*** and ordinary users are allowed. This prevents Entra ID from authenticating domain admins via the trust under normal conditions. However, as we'll see, an attacker with sufficient Entra ID privileges can abuse this trust design.
When a trust is stablished with Azure AD, a **Read Only Domain Controller (RODC) is created in the AD.** The **RODC computer account**, named **`AzureADKerberos$`**. Also, a secondary `krbtgt` account named **`krbtgt_AzureAD`**. This account contains the **Kerberos keys** used for tickets that Azure AD creates.
## Pivoting from Entra ID to On-Prem AD
Therefore, if this account is compromised it could be possible to impersonate any user... although this is not true because this account is prevented from creating tickets for any common privileged AD group like Domain Admins, Enterprise Admins, Administrators...
**Scenario:** The target organization has **Cloud Kerberos Trust** enabled for passwordless authentication. An attacker has gained **Global Administrator** privileges in Entra ID (Azure AD) but does **not** yet control the on-prem AD. The attacker also has a foothold with network access to a Domain Controller (via VPN or an Azure VM in hybrid network). Using the cloud trust, the attacker can leverage Azure AD control to obtain a **Domain Admin**--level foothold in AD.
> [!CAUTION]
> However, in a real scenario there are going to be privileged users that aren't in those groups. So the **new krbtgt account, if compromised, could be used to impersonate them.**
**Prerequisites:**
### Kerberos TGT
- **Cloud Kerberos Trust** is configured in the hybrid environment (indicator: an `AzureADKerberos$` RODC account exists in AD).
Moreover, when a user authenticates on Windows using a hybrid identity **Azure AD** will issue **partial Kerberos ticket along with the PRT.** The TGT is partial because **AzureAD has limited information** of the user in the on-prem AD (like the security identifier (SID) and the name).\
Windows can then **exchange this partial TGT for a full TGT** by requesting a service ticket for the `krbtgt` service.
- The attacker has **Global Admin (or Hybrid Identity Admin)** rights in the Entra ID tenant (these roles can use the AD Connect **synchronization API** to modify Azure AD users).
### NTLM
- At least one **hybrid user account** (exists in both AD and AAD) that the attacker can authenticate as. This could be obtained by knowing or resetting its credentials or assigning a passwordless method (e.g. a Temporary Access Pass) to generate a Primary Refresh Token (PRT) for it.
As there could be services that doesn't support kerberos authentication but NTLM, it's possible to request a **partial TGT signed using a secondary `krbtgt`** key including the **`KERB-KEY-LIST-REQ`** field in the **PADATA** part of the request and then get a full TGT signed with the primary `krbtgt` key **including the NT hash in the response**.
- An **on-prem AD target account** with high privileges that is *not* in the default RODC "deny" policy. In practice, a great target is the **AD Connect sync account** (often named **MSOL_***), which has DCSync (replication) rights in AD but is usually not a member of built-in admin groups. This account is typically not synchronized to Entra ID, making its SID available to impersonate without conflict.
## Abusing Cloud Kerberos Trust to obtain Domain Admin <a href="#abusing-cloud-kerberos-trust-to-obtain-domain-admin" id="abusing-cloud-kerberos-trust-to-obtain-domain-admin"></a>
**Attack Steps:**
When AzureAD generates a **partial TGT** it will be using the details it has about the user. Therefore, if a Global Admin could modify data like the **security identifier and name of the user in AzureAD**, when requesting a TGT for that user the **security identifier would be a different one**.
1. **Obtain Azure AD sync API Access:** Using the Global Admin account, acquire an access token for the Azure AD **Provisioning (sync) API**. This can be done with tools like **ROADtools** or **AADInternals**. For example, with ROADtools (roadtx):
It's not possible to do that through the Microsoft Graph or the Azure AD Graph, but it's possible to use the **API Active Directory Connect** uses to create and update synced users, which can be used by the Global Admins to **modify the SAM name and SID of any hybrid user**, and then if we authenticate, we get a partial TGT containing the modified SID.
```bash
# Using roadtx to get an Azure AD Graph token (no MFA)
roadtx gettokens -u <GlobalAdminUPN> -p <Password> --resource aadgraph
```
Note that we can do this with AADInternals and update to synced users via the [Set-AADIntAzureADObject](https://aadinternals.com/aadinternals/#set-aadintazureadobject-a) cmdlet.
*(Alternatively, AADInternals' `Connect-AADInt` can be used to authenticate as Global Admin.)*
### Attack prerequisites <a href="#attack-prerequisites" id="attack-prerequisites"></a>
2. **Modify a Hybrid User's On-Prem Attributes:** Leverage the Azure AD **synchronization API** to set a chosen hybrid user's **onPremises Security Identifier (SID)** and **onPremises SAMAccountName** to match the target AD account. This effectively tells Azure AD that the cloud user corresponds to the on-prem account we want to impersonate. Using the open-source **ROADtools Hybrid** toolkit:
The success of the attack and attainment of Domain Admin privileges hinge on meeting certain prerequisites:
```bash
# Example: modify a hybrid user to impersonate the MSOL account
python3 modifyuser.py -u <GlobalAdminUPN> -p <Password>\
--sourceanchor <ImmutableID_of_User>\
--sid <TargetAD_SID> --sam <TargetAD_SAMName>
```
- The capability to alter accounts via the Synchronization API is crucial. This can be achieved by having the role of Global Admin or possessing an AD Connect sync account. Alternatively, the Hybrid Identity Administrator role would suffice, as it grants the ability to manage AD Connect and establish new sync accounts.
- Presence of a **hybrid account** is essential. This account must be amenable to modification with the victim account's details and should also be accessible for authentication.
- Identification of a **target victim account** within Active Directory is a necessity. Although the attack can be executed on any account already synchronized, the Azure AD tenant must not have replicated on-premises security identifiers, necessitating the modification of an unsynchronized account to procure the ticket.
- Additionally, this account should possess domain admin equivalent privileges but must not be a member of typical AD administrator groups to avoid the generation of invalid TGTs by the AzureAD RODC.
- The most suitable target is the **Active Directory account utilized by the AD Connect Sync service**. This account is not synchronized with Azure AD, leaving its SID as a viable target, and it inherently holds Domain Admin equivalent privileges due to its role in synchronizing password hashes (assuming Password Hash Sync is active). For domains with express installation, this account is prefixed with **MSOL\_**. For other instances, the account can be pinpointed by enumerating all accounts endowed with Directory Replication privileges on the domain object.
> The `sourceAnchor` (immutable ID) of the user is needed to identify the Azure AD object to modify. The tool sets the hybrid user's on-prem SID and SAM account name to the values of the target (e.g., the MSOL_xxxx account's SID and SAM). Azure AD normally disallows altering these attributes via Graph (they're read-only), but the sync service API permits it and Global Admins can invoke this sync functionality.
3. **Obtain a Partial TGT from Azure AD:** After modification, authenticate as the hybrid user to Azure AD (for example, by obtaining a PRT on a device or using their credentials). When the user signs in (especially on a domain-joined or Entra joined Windows device), Azure AD will issue a **partial Kerberos TGT (TGT**<sub>**AD**</sub>) for that account because Cloud Kerberos Trust is enabled. This partial TGT is encrypted with the AzureADKerberos$ RODC key and includes the **target SID** we set. We can simulate this by requesting a PRT for the user via ROADtools:
```bash
roadtx getprt -u <HybridUserUPN> -p <Password> -d <DeviceID_or_Cert>
```
This outputs a `.prt` file containing the partial TGT and session key. If the account was cloud-only password, Azure AD still includes a TGT_AD in the PRT response.
4. **Exchange Partial TGT for Full TGT (on AD):** The partial TGT can now be presented to the on-prem Domain Controller to get a **full TGT** for the target account. We do this by performing a TGS request for the `krbtgt` service (the domain's primary TGT service) -- essentially upgrading the ticket to a normal TGT with a full PAC. Tools are available to automate this exchange. For example, using ROADtools Hybrid's script:
```bash
# Use the partial TGT from the PRT file to get a full TGT and NTLM hash
python3 partialtofulltgt.py -p roadtx.prt -o full_tgt.ccache --extract-hash
```
This script (or Impacket equivalents) will contact the Domain Controller and retrieve a valid TGT for the target AD account, including the NTLM hash of the account if the special Kerberos extension is used. The **`KERB-KEY-LIST-REQ`** extension is automatically included to ask the DC to return the target account's NTLM hash in the encrypted reply. The result is a credential cache (`full_tgt.ccache`) for the target account *or* the recovered NTLM password hash.
5. **Impersonate Target and Elevate to Domain Admin:** Now the attacker effectively **controls the target AD account**. For instance, if the target was the AD Connect **MSOL account**, it has replication rights on the directory. The attacker can perform a **DCSync** attack using that account's credentials or Kerberos TGT to dump password hashes from AD (including the domain KRBTGT account). For example:
```bash
# Using impacket's secretsdump to DCSync as the MSOL account (using NTLM hash)
secretsdump.py 'AD_DOMAIN/<TargetSAM>$@<DC_IP>' -hashes :<NTLM_hash> LOCAL
```
This dumps all AD user password hashes, giving the attacker the KRBTGT hash (letting them forge domain Kerberos tickets at will) and effectively **Domain Admin** privileges over AD. If the target account were another privileged user, the attacker could use the full TGT to access any domain resource as that user.
6. **Cleanup:** Optionally, the attacker can restore the modified Azure AD user's original `onPremisesSAMAccountName` and SID via the same API or simply delete any temporary user created. In many cases, the next Azure AD Connect sync cycle will automatically revert unauthorized changes on synced attributes. (However, by this point the damage is done -- the attacker has DA privileges.)
> [!WARNING]
> By abusing the cloud trust and sync mechanism, a Global Admin of Azure AD can impersonate nearly *any* AD account not explicitly protected by the RODC policy, even if that account was never cloud-synced. In a default configuration, this **bridges a complete trust from Azure AD compromise to on-prem AD compromise**.
## References
- [Obtaining Domain Admin from Azure AD via Cloud Kerberos Trust](https://dirkjanm.io/obtaining-domain-admin-from-azure-ad-via-cloud-kerberos-trust/)
### The full attack <a href="#the-full-attack" id="the-full-attack"></a>
Check it in the original post: [https://dirkjanm.io/obtaining-domain-admin-from-azure-ad-via-cloud-kerberos-trust/](https://dirkjanm.io/obtaining-domain-admin-from-azure-ad-via-cloud-kerberos-trust/)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -1,12 +0,0 @@
# Az - Default Applications
{{#include ../../../../banners/hacktricks-training.md}}
**Check the techinque in:** [**https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/**](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)**,** [**https://www.youtube.com/watch?v=JEIR5oGCwdg**](https://www.youtube.com/watch?v=JEIR5oGCwdg) and [**https://www.youtube.com/watch?v=xei8lAPitX8**](https://www.youtube.com/watch?v=xei8lAPitX8)
The blog post discusses a privilege escalation vulnerability in Azure AD, allowing Application Admins or compromised On-Premise Sync Accounts to escalate privileges by assigning credentials to applications. The vulnerability, stemming from the "by-design" behavior of Azure AD's handling of applications and service principals, notably affects default Office 365 applications. Although reported, the issue is not considered a vulnerability by Microsoft due to documentation of the admin rights assignment behavior. The post provides detailed technical insights and advises regular reviews of service principal credentials in Azure AD environments. For more detailed information, you can visit the original blog post.
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -4,13 +4,14 @@
## Basic Information
[From the docs:](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/whatis-fed)**Federation** is a collection of **domains** that have established **trust**. The level of trust may vary, but typically includes **authentication** and almost always includes **authorization**. A typical federation might include a **number of organizations** that have established **trust** for **shared access** to a set of resources.
[From the docs:](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/whatis-fed)
You can **federate your on-premises** environment **with Azure AD** and use this federation for authentication and authorization. This sign-in method ensures that all user **authentication occurs on-premises**. This method allows administrators to implement more rigorous levels of access control. Federation with **AD FS** and PingFederate is available.
>**Federation** is a collection of **domains** that have established **trust**. The level of trust may vary, but typically includes **authentication** and almost always includes **authorization**. A typical federation might include a **number of organizations** that have established **trust** for **shared access** to a set of resources.
>You can **federate your on-premises** environment **with Azure AD** and use this federation for authentication and authorization. This sign-in method ensures that all user **authentication occurs on-premises**. This method allows administrators to implement more rigorous levels of access control. Federation with **AD FS** and PingFederate is available.
<figure><img src="../../../../images/image (154).png" alt=""><figcaption></figcaption></figure>
Bsiacally, in Federation, all **authentication** occurs in the **on-prem** environment and the user experiences SSO across all the trusted environments. Therefore, users can **access** **cloud** applications by using their **on-prem credentials**.
Basically, in Federation, all **authentication** occurs in the **on-prem** environment and the user experiences SSO across all the trusted environments. Therefore, users can **access** **cloud** applications by using their **on-prem credentials**.
**Security Assertion Markup Language (SAML)** is used for **exchanging** all the authentication and authorization **information** between the providers.
@@ -20,9 +21,8 @@ In any federation setup there are three parties:
- Identity Provider (IdP)
- Service Provider (SP)
(Images from https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps)
<figure><img src="../../../../images/image (121).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../../images/image (121).png" alt="https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps"><figcaption>https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps</figcaption></figure>
1. Initially, an application (Service Provider or SP, such as AWS console or vSphere web client) is accessed by a user. This step might be bypassed, leading the client directly to the IdP (Identity Provider) depending on the specific implementation.
2. Subsequently, the SP identifies the appropriate IdP (e.g., AD FS, Okta) for user authentication. It then crafts a SAML (Security Assertion Markup Language) AuthnRequest and reroutes the client to the chosen IdP.
@@ -116,7 +116,7 @@ python .\shimit.py -idp http://adfs.lab.local/adfs/services/trust -pk key_file -
python .\shimit.py -idp http://adfs.lab.local/adfs/services/trust -pk key_file -c cert_file -u domain\admin -n admin@domain.com -r ADFS-admin -r ADFS-monitor -id 123456789012 -o saml_response.xml
```
<figure><img src="../../../../images/image (128).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../../../images/image (128).png" alt="https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps"><figcaption>https://www.cyberark.com/resources/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-to-cloud-apps</figcaption></figure>
### On-prem -> cloud

View File

@@ -0,0 +1,32 @@
# Hybrid Identity Miscellaneous Attacks
{{#include ../../../../banners/hacktricks-training.md}}
## Forcing Synchronization of Entra ID users to on-prem
As mentioned in [https://www.youtube.com/watch?v=JEIR5oGCwdg](https://www.youtube.com/watch?v=JEIR5oGCwdg), it was possible to change the value of **`ProxyAddress`** inside an AD user in the on-prem AD adding the email of an Entra ID admin user and also making sure the UPN of the user in AD and in Entra ID matched (this is the Entra ID again), like **`SMTP:admin@domain.onmicrosoft.com`**. And this would **force the synchronization of this user** from Entra ID to the on-prem AD, so if the password of the user was known, it could be used to **access the admin used in Entra ID.**
In order to synchronize a new user from Entra ID to the on-prem AD these are the requirements the only requirements are:
- Control the attributes of a user in the on-prem AD (or have permissions to create new users)
- Know the user cloud-only to synchronize from Entra ID to the on-prem AD
- You might also need to be able to change immutableID attribute from the Entra ID user to the on-prem AD user to do a **hard match**.
> [!CAUTION]
> Entra ID doesn't allow to synchronize admins anymore from Entra ID to the on-prem AD.
> Also, this **won't bypass MFA**.
## References
- [https://www.youtube.com/watch?v=JEIR5oGCwdg](https://www.youtube.com/watch?v=JEIR5oGCwdg)
- [https://activedirectorypro.com/sync-on-prem-ad-with-existing-azure-ad-users/](https://activedirectorypro.com/sync-on-prem-ad-with-existing-azure-ad-users/)
- [https://www.orbid365.be/manually-match-on-premise-ad-user-to-existing-office365-user/](https://www.orbid365.be/manually-match-on-premise-ad-user-to-existing-office365-user/)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -1,35 +0,0 @@
# Az- Synchronising New Users
{{#include ../../../../banners/hacktricks-training.md}}
## Syncing AzureAD users to on-prem to escalate from on-prem to AzureAD
I order to synchronize a new user f**rom AzureAD to the on-prem AD** these are the requirements:
- The **AzureAD user** needs to have a proxy address (a **mailbox**)
- License is not required
- Should **not be already synced**
```bash
Get-MsolUser -SerachString admintest | select displayname, lastdirsynctime, proxyaddresses, lastpasswordchangetimestamp | fl
```
When a user like these is found in AzureAD, in order to **access it from the on-prem AD** you just need to **create a new account** with the **proxyAddress** the SMTP email.
An automatically, this user will be **synced from AzureAD to the on-prem AD user**.
> [!CAUTION]
> Notice that to perform this attack you **don't need Domain Admin**, you just need permissions to **create new users**.
>
> Also, this **won't bypass MFA**.
>
> Moreover, this was reported an **account sync is no longer possible for admin accounts**.
## References
- [https://www.youtube.com/watch?v=JEIR5oGCwdg](https://www.youtube.com/watch?v=JEIR5oGCwdg)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@@ -188,6 +188,14 @@ az rest --method POST \
--body "{\"id\": \"$credID\"}"
```
### Applications Privilege Escalation
**As explained in [this post](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** it was very common to find default applications that have **API permissions** of type **`Application`** assigned to them. An API Permission (as called in the Entra ID console) of type **`Application`** means that the application can access the API without a user context (without a user login into the app), and without needing Entra ID roles to allow it. Therefore, it's very common to find **high privileged applications in every Entra ID tenant**.
Then, if an attacker has any permission/role that allows to **update the credentials (secret o certificate) of the application**, the attacker can generate a new credential and then use it to **authenticate as the application**, gaining all the permissions that the application has.
Note that the mentioned blog shares some **API permissions** of common Microsoft default applications however some time after this report Microsoft fixed this issue and now it's not possible to login as Microsoft applications anymore. However, it's still possible to find **custom applications with high privileges that could be abused**.
---
## Groups

View File

@@ -0,0 +1,18 @@
# Az - File Shares
{{#include ../../../banners/hacktricks-training.md}}
## RemoteAddr Bypass
This **[blog post](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** explains how when you are configuring some network restrictions with Azure Front Door you can filter based on **`RemoteAddr`** or **`SocketAddr`**. Being the main difference that **`RemoteAddr`** actually uses the value from the **`X-Forwarded-For`** HTTP header making it very easy to bypass.
To bypass this rule automated tools can be used that **brute-force IP addresses** until it finds a valid one.
This is mentioned in the [Microsoft documentation](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
## References
- [https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)
{{#include ../../../banners/hacktricks-training.md}}