From 416e7cf6992256460851c45406423efaf63bedd2 Mon Sep 17 00:00:00 2001 From: Carlos Polop Date: Sat, 25 Jan 2025 15:33:23 +0100 Subject: [PATCH] improvements --- src/pentesting-cloud/azure-security/README.md | 157 +++++++++++------- .../az-tokens-and-public-applications.md | 14 ++ .../azure-security/az-enumeration-tools.md | 17 ++ .../azure-security/az-services/az-azuread.md | 139 ++++++++-------- .../README.md | 13 +- 5 files changed, 211 insertions(+), 129 deletions(-) diff --git a/src/pentesting-cloud/azure-security/README.md b/src/pentesting-cloud/azure-security/README.md index 94a939282..2e82437a9 100644 --- a/src/pentesting-cloud/azure-security/README.md +++ b/src/pentesting-cloud/azure-security/README.md @@ -16,53 +16,47 @@ In order to audit an AZURE environment it's very important to know: which **serv From a Red Team point of view, the **first step to compromise an Azure environment** is to manage to obtain some **foothold**. -### Initial Access +### External enum & Initial Access -Here you can find the most common ways to get initial access to an Azure/Entra ID environment: +The first step is of course to enumerate information about the tenant you are attacking and try to get a foothold. -- **OSINT**: Check for **leaks** in Github or any other open source platform that could contain **credentials** or interesting information. - - -- **Social** Engineering -- **Password** reuse, leaks or [password spraying](az-unauthenticated-enum-and-initial-entry/az-password-spraying.md) -- Vulnerabilities in Azure-Hosted Applications - - [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) with access to metadata endpoint - - **Local File Read** - - `/home/USERNAME/.azure` - - `C:\Users\USERNAME\.azure` - - The file **`accessTokens.json`** in `az cli` before 2.30 - Jan2022 - stored **access tokens in clear text** - - The file **`azureProfile.json`** contains **info** about logged user. - - **`az logout`** removes the token. - - Older versions of **`Az PowerShell`** stored **access tokens** in **clear** text in **`TokenCache.dat`**. It also stores **ServicePrincipalSecret** in **clear**-text in **`AzureRmContext.json`**. The cmdlet **`Save-AzContext`** can be used to **store** **tokens**.\ - Use `Disconnect-AzAccount` to remove them. -- 3rd parties **breached** -- **Internal** Employee -- [**Common Phishing**](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/phishing-methodology/index.html) (credentials or Oauth App) - - [Device Code Authentication Phishing](az-unauthenticated-enum-and-initial-entry/az-device-code-authentication-phishing.md) +Based on the domain name it's possible to know **if the company if using Azure**, get the **tenant ID**, get other **valid domains** in the same tenant (if more) and get **relevant information** like if SSO is enabled, mail configurations, valid user emails... -Even if you **haven't compromised any user** inside the Azure tenant you are attacking, you can **gather some information** from it: +Check the folloeing page to learn how to perform the **external enumeration**: {{#ref}} az-unauthenticated-enum-and-initial-entry/ {{#endref}} -> [!NOTE] -> After you have managed to obtain credentials, you need to know **to who do those creds belong**, and **what they have access to**, so you need to perform some basic enumeration: +With this information the most common ways to try to get a foothold are: +- **OSINT**: Check for **leaks** in Github or any other open source platform that could contain **credentials** or interesting information. +- **Password** reuse, leaks or [password spraying](az-unauthenticated-enum-and-initial-entry/az-password-spraying.md) + - Buy credentials to an employee +- [**Common Phishing**](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/phishing-methodology/index.html) (credentials or Oauth App) + - [Device Code Authentication Phishing](az-unauthenticated-enum-and-initial-entry/az-device-code-authentication-phishing.md) +- 3rd parties **breached** +- Vulnerabilities in Azure-Hosted Applications + - [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) with access to metadata endpoint + - **Subdomain takeovers** like in [https://godiego.co/posts/STO-Azure/](https://godiego.co/posts/STO-Azure/) +- If some developer laptop is compromised ([WinPEAS and LinPEAS](https://github.com/peass-ng/PEASS-ng) can find this info): + - Inside **`/.Azure`** + - **`azureProfile.json`** contains info about logged in users from the past + - **`clouds.config contains`** info about subscriptions + - **`service_principal_entries.json`** contains applications credentials (tenant id, clients and secret). Only in Linux & macOS + - **`msal_token_cache.json`** contains contains access tokens and refresh tokens. Only in Linux & macOS + - **`service_principal_entries.bin`** and msal_token_cache.bin are used in Windows and are encrypted with DPAPI + - **`msal_http_cache.bin`** is a cache of HTTP request + - Load it: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)` + - **`AzureRmContext.json`** contains information about previous logins using Az PowerShell (but no credentials) + - Inside **`C:\Users\\AppData\Local\Microsoft\IdentityCache\*`** are several `.bin` files with **access tokens**, ID tokens and account information encrypted with the users DPAPI. + - It’s possible to find more **access tokens** in the `.tbres` files inside **`C:\Users\\AppData\Local\Microsoft\TokenBroken\Cache\`** which contain a base64 encrypted with DPAPI with access tokens. + - In Linux and macOS you can get **access tokens, refresh tokens and id tokens** from Az PowerShell (if used) running `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` + - In Windows this just generates id tokens. + - Possible to see if Az PowerShell was used in Linux and macSO checking is `$HOME/.local/share/.IdentityService/` exists (although the contained files are empty and useless) -## Basic Enumeration > [!NOTE] -> Remember that the **noisiest** part of the enumeration is the **login**, not the enumeration itself. - -### SSRF - -If you found a SSRF in a server inside Azure check this page for tricks: - -{{#ref}} -https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure{{#endref}} - -### Subdomain Takeover - -- [https://godiego.co/posts/STO-Azure/](https://godiego.co/posts/STO-Azure/) +> Remember that usually the **noisiest** part of the enumeration is the **login**, not the enumeration itself. ### Azure & Entra ID tooling @@ -108,18 +102,7 @@ az account management-group list #Not allowed by default {{#endtab }} -{{#tab name="AzureAD" }} - -```bash -#Get the current session state -Get-AzureADCurrentSessionInfo -#Get details of the current tenant -Get-AzureADTenantDetail -``` - -{{#endtab }} - -{{#tab name="Az PowerShell" }} +{{#tab name="Az" }} ```bash # Get the information about the current context (Account, Tenant, Subscription etc.) @@ -130,22 +113,33 @@ Get-AzContext -ListAvailable Get-AzSubscription #Get Resource group Get-AzResourceGroup -# Enumerate all resources visible to the current user -Get-AzResource -# Enumerate all Azure RBAC role assignments -Get-AzRoleAssignment # For all users -Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com # For current user +``` + +{{#endtab }} + +{{#tab name="Mg" }} + +```bash +#Get the current session +Get-MgContext +``` + +{{#endtab }} + +{{#tab name="AzureAD" }} + +```bash +#Get the current session state +Get-AzureADCurrentSessionInfo +#Get details of the current tenant +Get-AzureADTenantDetail ``` {{#endtab }} {{#endtabs }} -> [!CAUTION] -> Oone of the most important commands to enumerate Azure is **`Get-AzResource`** from Az PowerShell as it lets you **know the resources your current user has visibility over**. -> -> You can get the same info in the **web console** going to [https://portal.azure.com/#view/HubsExtension/BrowseAll](https://portal.azure.com/#view/HubsExtension/BrowseAll) or searching for "All resources" -### Entra ID Enumeration +### Entra ID Enumeration & Privilege Escalation By default, any user should have **enough permissions to enumerate** things such as users, groups, roles, service principals... (check [default AzureAD permissions](az-basic-information/index.html#default-user-permissions)).\ You can find here a guide: @@ -154,11 +148,50 @@ You can find here a guide: az-services/az-azuread.md {{#endref}} -> [!NOTE] -> Now that you **have some information about your credentials** (and if you are a red team hopefully you **haven't been detected**). It's time to figure out which services are being used in the environment.\ -> In the following section you can check some ways to **enumerate some common services.** +Check the **Post-Exploitation tools** to find tools to escalate privileges in Entra ID like **AzureHound:** -### +{{#ref}} +az-enumeration-tools.md#automated-post-exploitation-tools +{{#endref}} + + +### Enumerate Azure Services + +Once you know who you are, you can start enumerating the **Azure services you have access to**. + +The Az PoswerShell command **`Get-AzResource`** lets you **know the resources your current user has visibility over**. + +Moreover, you can get the same info in the **web console** going to [https://portal.azure.com/#view/HubsExtension/BrowseAll](https://portal.azure.com/#view/HubsExtension/BrowseAll) or searching for "All resources" or executing: `az rest --method GET --url "https://management.azure.com/subscriptions//resources?api-version=2021-04-01"` + +Furthermore, with enough permissions, the role **`Get-AzRoleAssignment`** can be used to **enumerate all the roles** in the subscription or the permission over a specific resource indicatig it like in: **`Get-AzRoleAssignment -Scope /subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.RecoveryServices/vaults/vault-m3ww8ut4`** + +In the following section you can find information about the most common Azure services and how to enumerate them: + +{{#ref}} +az-services/ +{{#endref}} + +### Privilege Escalation, Post-Exploitation & Persistence in Azure Services + +Once you know how is the Azure environment structured and what services are being used, you can start looking for ways to **escalate privileges, move laterally, perform other post-exploitation attacks and maintain persistence**. + +In the following section you can find information about how to escalate privileges in the most common Azure services: + +{{#ref}} +az-privilege-escalation/ +{{#endref}} + +In the following one you can find information about how to perform post-exploitation attacks in the most common Azure services: + +{{#ref}} +az-post-exploitation/ +{{#endref}} + +In the following one you can find information about how to maintain persistence in the most common Azure services: + +{{#ref}} +az-persistence/ +{{#endref}} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md index 1d73642b2..14c25ae5c 100644 --- a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md +++ b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md @@ -146,6 +146,19 @@ new_azure_cli_bearer_tokens_for_graph_api = ( pprint(new_azure_cli_bearer_tokens_for_graph_api) ``` +### Other access token fields + +- **appid**: Application ID used to generate the token +- **appidacr**: The Application Authentication Context Class Reference indicates how the client was authenticated, for a public client the value is 0, and if a client secret is used the value is 1 +- **acr**: The Authentication Context Class Reference claim is "0" when the end-user authentication did not meet the requirements of ISO/IEC 29115. +- **amr**: The Authentication method indicates how the token was authenticated. A value of “pwd” indicates that a password was used. +- **groups**: Indicates the groups where the principal is a member. +- **iss**: The issues identifies the security token service (STS) that generated the token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID) +- **oid**: The object ID of the principal +- **tid**: Tenant ID +- **iat, nbf, exp**: Issued at (when it was issued), Not before (cannot be used before this time, usually same value as iat), Expiration time. + + ## FOCI Tokens Privilege Escalation Previously it was mentioned that refresh tokens should be tied to the **scopes** it was generated with, to the **application** and **tenant** it was generated to. If any of these boundaries is broken, it's possible to escalate privileges as it will be possible to generate access tokens to other resources and tenants the user has access to and with more scopes than it was originally intended. @@ -198,6 +211,7 @@ pprint(microsoft_office_bearer_tokens_for_graph_api) ## References - [https://github.com/secureworks/family-of-client-ids-research](https://github.com/secureworks/family-of-client-ids-research) +- [https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md](https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-enumeration-tools.md b/src/pentesting-cloud/azure-security/az-enumeration-tools.md index 4880c09de..bc55e22eb 100644 --- a/src/pentesting-cloud/azure-security/az-enumeration-tools.md +++ b/src/pentesting-cloud/azure-security/az-enumeration-tools.md @@ -93,6 +93,23 @@ export REQUESTS_CA_BUNDLE=/Users/user/Downloads/cacert.pem {{#endtab }} +{{#tab name="CMD" }} + +```bash +set ADAL_PYTHON_SSL_NO_VERIFY=1 +set AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1 +set HTTPS_PROXY="http://127.0.0.1:8080" +set HTTP_PROXY="http://127.0.0.1:8080" + +# If this is not enough +# Download the certificate from Burp and convert it into .pem format +# And export the following env variable +openssl x509 -in cacert.der -inform DER -out cacert.pem -outform PEM +set REQUESTS_CA_BUNDLE=C:\Users\user\Downloads\cacert.pem +``` + +{{#endtab }} + {{#tab name="PS" }} ```bash diff --git a/src/pentesting-cloud/azure-security/az-services/az-azuread.md b/src/pentesting-cloud/azure-security/az-services/az-azuread.md index 15042eeac..cc04587c4 100644 --- a/src/pentesting-cloud/azure-security/az-services/az-azuread.md +++ b/src/pentesting-cloud/azure-security/az-services/az-azuread.md @@ -69,13 +69,24 @@ $token = (az account get-access-token --resource https://graph.microsoft.com --q $secureToken = ConvertTo-SecureString $token -AsPlainText -Force Connect-MgGraph -AccessToken $secureToken +# Get token from session +Parameters = @{ + Method = "GET" + Uri = "/v1.0/me" + OutputType = "HttpResponseMessage" +} +$Response = Invoke-MgGraphRequest @Parameters +$Headers = $Response.RequestMessage.Headers +$Headers.Authorization.Parameter + + # Find commands Find-MgGraphCommand -command *Mg* ``` {{#endtab }} -{{#tab name="Az PowerShell" }} +{{#tab name="Az" }} ```bash Connect-AzAccount #Open browser @@ -85,15 +96,11 @@ $creds = New-Object System.Management.Automation.PSCredential("test@corp.onmicro Connect-AzAccount -Credential $creds # Get Access Token -(Get-AzAccessToken).Token # Request access token to other endpoints: AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, MSGraph, OperationalInsights, ResourceManager, Storage, Synapse -(Get-AzAccessToken -ResourceTypeName MSGraph).Token -(Get-AzAccessToken -Resource "https://graph.microsoft.com").Token +(ConvertFrom-SecureString (Get-AzAccessToken -ResourceTypeName Arm -AsSecureString).Token -AsPlainText) # Connect with access token -Connect-AzAccount -AccountId test@corp.onmicrosoft.com -AccessToken $token -Connect-AzAccount -AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId -## The -AccessToken is from management.azure.com +Connect-AzAccount -AccountId test@corp.onmicrosoft.com [-AccessToken $ManagementToken] [-GraphAccessToken $AADGraphToken] [-MicrosoftGraphAccessToken $MicrosoftGraphToken] [-KeyVaultAccessToken $KeyVaultToken] # Connect with Service principal/enterprise app secret $password = ConvertTo-SecureString 'KWEFNOIRFIPMWL.--DWPNVFI._EDWWEF_ADF~SODNFBWRBIF' -AsPlainText -Force @@ -299,7 +306,7 @@ Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember {{#endtab }} -{{#tab name="Az PowerShell" }} +{{#tab name="Az" }} ```bash # Enumerate users @@ -372,6 +379,24 @@ az role assignment list --include-groups --include-classic-administrators true - {{#endtab }} +{{#tab name="Az" }} + +```bash +# Get all groups +Get-AzADGroup +# Get details of a group +Get-AzADGroup -ObjectId +# Search group by string +Get-AzADGroup -SearchString "admin" | fl * #Search at the beginnig of DisplayName +Get-AzADGroup |?{$_.Displayname -match "admin"} +# Get members of group +Get-AzADGroupMember -GroupDisplayName +# Get roles of group +Get-AzRoleAssignment -ResourceGroupName +``` + +{{#endtab }} + {{#tab name="Azure AD" }} ```bash @@ -400,24 +425,6 @@ Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember Get-AzureADGroup -ObjectId | Get-AzureADGroupAppRoleAssignment | fl * ``` -{{#endtab }} - -{{#tab name="Az PowerShell" }} - -```bash -# Get all groups -Get-AzADGroup -# Get details of a group -Get-AzADGroup -ObjectId -# Search group by string -Get-AzADGroup -SearchString "admin" | fl * #Search at the beginnig of DisplayName -Get-AzADGroup |?{$_.Displayname -match "admin"} -# Get members of group -Get-AzADGroupMember -GroupDisplayName -# Get roles of group -Get-AzRoleAssignment -ResourceGroupName -``` - {{#endtab }} {{#endtabs }} @@ -467,30 +474,7 @@ az ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredenti {{#endtab }} -{{#tab name="Azure AD" }} - -```bash -# Get Service Principals -Get-AzureADServicePrincipal -All $true -# Get details about a SP -Get-AzureADServicePrincipal -ObjectId | fl * -# Get SP by string name or Id -Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -match "app"} | fl -Get-AzureADServicePrincipal -All $true | ?{$_.AppId -match "103947652-1234-5834-103846517389"} -# Get owner of SP -Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwner |fl * -# Get objects owned by a SP -Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwnedObject -# Get objects created by a SP -Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalCreatedObject -# Get groups where the SP is a member -Get-AzureADServicePrincipal | Get-AzureADServicePrincipalMembership -Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalMembership |fl * -``` - -{{#endtab }} - -{{#tab name="Az PowerShell" }} +{{#tab name="Az" }} ```bash # Get SPs @@ -520,6 +504,29 @@ $RequestParams = @{ (Invoke-RestMethod @RequestParams).value ``` +{{#endtab }} + +{{#tab name="Azure AD" }} + +```bash +# Get Service Principals +Get-AzureADServicePrincipal -All $true +# Get details about a SP +Get-AzureADServicePrincipal -ObjectId | fl * +# Get SP by string name or Id +Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -match "app"} | fl +Get-AzureADServicePrincipal -All $true | ?{$_.AppId -match "103947652-1234-5834-103846517389"} +# Get owner of SP +Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwner |fl * +# Get objects owned by a SP +Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwnedObject +# Get objects created by a SP +Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalCreatedObject +# Get groups where the SP is a member +Get-AzureADServicePrincipal | Get-AzureADServicePrincipalMembership +Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalMembership |fl * +``` + {{#endtab }} {{#endtabs }} @@ -669,6 +676,21 @@ az ad app list --query '[?length(keyCredentials) > `0` || length(passwordCredent {{#endtab }} +{{#tab name="Az" }} + +```bash +# Get Apps +Get-AzADApplication +# Get details of one App +Get-AzADApplication -ObjectId +# Get App searching by string +Get-AzADApplication | ?{$_.DisplayName -match "app"} +# Get Apps with password +Get-AzADAppCredential +``` + +{{#endtab }} + {{#tab name="Azure AD" }} ```bash @@ -682,21 +704,6 @@ Get-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredentia Get-AzureADApplication -ObjectId | Get-AzureADApplicationOwner |fl * ``` -{{#endtab }} - -{{#tab name="Az PowerShell" }} - -```bash -# Get Apps -Get-AzADApplication -# Get details of one App -Get-AzADApplication -ObjectId -# Get App searching by string -Get-AzADApplication | ?{$_.DisplayName -match "app"} -# Get Apps with password -Get-AzADAppCredential -``` - {{#endtab }} {{#endtabs }} @@ -768,7 +775,7 @@ az role assignment list --all --query "[?principalName=='carlos@carloshacktricks {{#endtab }} -{{#tab name="Az PowerShell" }} +{{#tab name="Az" }} ```bash # Get role assignments on the subscription diff --git a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md index 4b4587cc2..320eb2ada 100644 --- a/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md +++ b/src/pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/README.md @@ -245,12 +245,23 @@ Import-Module .\MicroBurst\MicroBurst.psm1 -Verbose Invoke-EnumerateAzureSubDomains -Base corp -Verbose ``` - ## Phishing - [**Common Phishing**](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/phishing-methodology/index.html) for credentials or via [OAuth Apps](az-oauth-apps-phishing.md) - [**Device Code Authentication** Phishing](az-device-code-authentication-phishing.md) +## Filesystem Credentials + +The **`az cli`** stores a lot of interesting information inside **`/.Azure`**: +- **`azureProfile.json`** contains info about logged in users from the past +- **`clouds.config`** contains info about subscriptions +- **`service_principal_entries.json`** contains applications **credentials** (tenant id, clients and secret) +- **`msal_token_cache.json`** contains **access tokens and refresh tokens** + +Note that in macOS and linux these files are **unprotected** stored in clear text. + + + ## References - [https://aadinternals.com/post/just-looking/](https://aadinternals.com/post/just-looking/)