diff --git a/SUMMARY.md b/SUMMARY.md
index 211b24d327..b8583dbb0f 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -397,6 +397,7 @@
* [Az - Device Code Authentication Phishing](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-device-code-authentication-phishing.md)
* [Az - Password Spraying](pentesting-cloud/azure-security/az-unauthenticated-enum-and-initial-entry/az-password-spraying.md)
* [Az - Services](pentesting-cloud/azure-security/az-services/README.md)
+ * [Az - Management Groups, Subscriptions & Resource Groups](pentesting-cloud/azure-security/az-services/az-management-groups-subscriptions-and-resource-groups.md)
* [Az - ACR](pentesting-cloud/azure-security/az-services/az-acr.md)
* [Az - Application Proxy](pentesting-cloud/azure-security/az-services/az-application-proxy.md)
* [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md)
@@ -430,7 +431,7 @@
* [Az - Primary Refresh Token (PRT)](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-primary-refresh-token-prt.md)
* [Az - Persistence](pentesting-cloud/azure-security/az-persistence.md)
* [Az - Device Registration](pentesting-cloud/azure-security/az-device-registration.md)
- * [Az - AzureAD (AAD)](pentesting-cloud/azure-security/az-azuread/README.md)
+ * [Az - Entra ID (formerly AzureAD - AAD)](pentesting-cloud/azure-security/az-azuread/README.md)
* [Az - Conditional Access Policies / MFA Bypass](pentesting-cloud/azure-security/az-azuread/az-conditional-access-policies-mfa-bypass.md)
* [Az - Dynamic Groups Privesc](pentesting-cloud/azure-security/az-azuread/dynamic-groups.md)
* [Digital Ocean Pentesting](pentesting-cloud/digital-ocean-pentesting/README.md)
diff --git a/pentesting-cloud/azure-security/README.md b/pentesting-cloud/azure-security/README.md
index 6319e5c5da..71b08d3fad 100644
--- a/pentesting-cloud/azure-security/README.md
+++ b/pentesting-cloud/azure-security/README.md
@@ -173,6 +173,36 @@ Use portal.azure.com and select the shell, or use shell.azure.com, for a bash or
Azure DevOps is separate from Azure. It has repositories, pipelines (yaml or release), boards, wiki, and more. Variable Groups are used to store variable values and secrets.
+## Debug | MitM az cli
+
+Using the parameter **`--debug`** it's possible to see all the requests the tool **`az`** is sending:
+
+```bash
+az account management-group list --output table --debug
+```
+
+In order to do a **MitM** to the tool and **check all the requests** it's sending manually you can do:
+
+{% tabs %}
+{% tab title="Bash" %}
+```bash
+export ADAL_PYTHON_SSL_NO_VERIFY=1
+export AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1
+export HTTPS_PROXY="http://127.0.0.1:8080"
+export HTTP_PROXY="http://127.0.0.1:8080"
+```
+{% endtab %}
+
+{% tab title="PS" %}
+```bash
+$env:ADAL_PYTHON_SSL_NO_VERIFY=1
+$env:AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1
+$env:HTTPS_PROXY="http://127.0.0.1:8080"
+$env:HTTP_PROXY="http://127.0.0.1:8080"
+```
+{% endtab %}
+{% endtabs %}
+
## Automated Recon Tools
### [**ROADRecon**](https://github.com/dirkjanm/ROADtools)
diff --git a/pentesting-cloud/azure-security/az-azuread/README.md b/pentesting-cloud/azure-security/az-azuread/README.md
index c2e16ec48a..e176d89776 100644
--- a/pentesting-cloud/azure-security/az-azuread/README.md
+++ b/pentesting-cloud/azure-security/az-azuread/README.md
@@ -1,4 +1,4 @@
-# Az - AzureAD (AAD)
+# Az - Entra ID (formerly AzureAD - AAD)
{% hint style="success" %}
Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
@@ -173,7 +173,7 @@ curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01
{% endtab %}
{% endtabs %}
-When you **login** via **CLI** into Azure with any progam, you are using an **Azure Application** from a **tenant** that belongs to **Microsoft**. These Applications, like the ones you can create in your account, **have a client id**. You **won't be able to see all of them** in the **allowed applications lists** you can see in the console, **but they are allower by default**.
+When you **login** via **CLI** into Azure with any program, you are using an **Azure Application** from a **tenant** that belongs to **Microsoft**. These Applications, like the ones you can create in your account, **have a client id**. You **won't be able to see all of them** in the **allowed applications lists** you can see in the console, **but they are allowed by default**.
For example a **powershell script** that **authenticates** use an app with client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Even if the app doesn't appear in the console, a sysadmin could **block that application** so users cannot access using tools that connects via that App.
@@ -204,8 +204,25 @@ $token = Invoke-Authorize -Credential $credential `
-InformationAction Continue
```
+### Tenants
+
+{% tabs %}
+{% tab title="az cli" %}
+```bash
+# List tenants
+az account tenant list
+```
+{% endtab %}
+{% endtabs %}
+
### Users
+For more information about Entra ID users check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
{% tabs %}
{% tab title="az cli" %}
```bash
@@ -219,7 +236,7 @@ az ad user list --query "[].displayName" | findstr /i "admin"
az ad user list --query "[?contains(displayName,'admin')].displayName"
# Search attributes containing the word "password"
az ad user list | findstr /i "password" | findstr /v "null,"
-# All users from AzureAD
+# All users from Entra ID
az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi==null]"
az ad user list --query "[?onPremisesSecurityIdentifier==null].displayName"
# All users synced from on-prem
@@ -227,8 +244,23 @@ az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalN
az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName"
# Get groups where the user is a member
az ad user get-member-groups --id
-# Get roles assigned to the user
-az role assignment list --include-groups --include-classic-administrators true --assignee
+# Get roles assigned to the user in Azure (NOT in Entra ID)
+az role assignment list --include-inherited --include-groups --include-classic-administrators true --assignee
+
+# Get EntraID roles assigned to a user
+## Get Token
+export TOKEN=$(az account get-access-token --resource https://graph.microsoft.com/ --query accessToken -o tsv)
+## Get users
+curl -X GET "https://graph.microsoft.com/v1.0/users" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" | jq
+## Get EntraID roles assigned to an user
+curl -X GET "https://graph.microsoft.com/beta/rolemanagement/directory/transitiveRoleAssignments?\$count=true&\$filter=principalId%20eq%20'86b10631-ff01-4e73-a031-29e505565caa'" \
+-H "Authorization: Bearer $TOKEN" \
+-H "ConsistencyLevel: eventual" \
+-H "Content-Type: application/json" | jq
+## Get role details
+curl -X GET "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions/cf1c38e5-3621-4004-a7cb-879624dced7c" \
+-H "Authorization: Bearer $TOKEN" \
+-H "Content-Type: application/json" | jq
```
{% endtab %}
@@ -305,6 +337,12 @@ It's highly recommended to add MFA to every user, however, some companies won't
### Groups
+For more information about Entra ID groups check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
{% tabs %}
{% tab title="az cli" %}
```powershell
@@ -316,7 +354,7 @@ az ad group show --group
# Get "admin" groups
az ad group list --query "[].displayName" | findstr /i "admin"
az ad group list --query "[?contains(displayName,'admin')].displayName"
-# All groups from AzureAD
+# All groups from Entra ID
az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi==null]"
az ad group list --query "[?onPremisesSecurityIdentifier==null].displayName"
# All groups synced from on-prem
@@ -328,8 +366,10 @@ az ad group member list --group --query "[].userPrincipalName" -o table
az ad group member check --group "VM Admins" --member-id
# Get which groups a group is member of
az ad group get-member-groups -g "VM Admins"
-# Get Apps where a group has a role (role not shown)
-Get-AzureADGroup -ObjectId | Get-AzureADGroupAppRoleAssignment | fl *
+# Get roles assigned to the group in Azure (NOT in Entra ID)
+az role assignment list --include-groups --include-classic-administrators true --assignee
+
+# To get Entra ID roles assigned check how it's done with users and use a group ID
```
{% endtab %}
@@ -356,6 +396,8 @@ Get-AzureADMSRoleAssignment -Filter "principalId eq '69584002-b4d1-4055-9c94-320
# Get Administrative Units of a group
$groupObj = Get-AzureADGroup -Filter "displayname eq 'TestGroup'"
Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where {$_.Id -eq $groupObj.ObjectId} }
+# Get Apps where a group has a role (role not shown)
+Get-AzureADGroup -ObjectId | Get-AzureADGroupAppRoleAssignment | fl *
```
{% endtab %}
@@ -395,18 +437,20 @@ Check how to abuse dynamic groups in the following page:
[dynamic-groups.md](dynamic-groups.md)
{% endcontent-ref %}
-### Service Principals / Enterprise Applications
+### Service Principals
-{% hint style="info" %}
-Note that **Service Principal** in PowerShell terminology **is** called **Enterprise Applications** in the Azure portal (web).
-{% endhint %}
+For more information about Entra ID service principals check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
{% tabs %}
{% tab title="az cli" %}
```bash
# Get Service Principals
az ad sp list --all
-az ad sp list --all --query "[].[displayName]" -o table
+az ad sp list --all --query "[].[displayName,appId]" -o table
# Get details of one SP
az ad sp show --id 00000000-0000-0000-0000-000000000000
# Search SP by string
@@ -415,10 +459,9 @@ az ad sp list --all --query "[?contains(displayName,'app')].displayName"
az ad sp owner list --id --query "[].[displayName]" -o table
# Get service principals owned by the current user
az ad sp list --show-mine
-# List apps that have password credentials
-az ad sp list --all --query "[?passwordCredentials != null].displayName"
-# List apps that have key credentials (use of certificate authentication)
-az ad sp list -all --query "[?keyCredentials != null].displayName"
+
+# Get SPs with generated secret or certificate
+az ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
```
{% endtab %}
@@ -585,8 +628,104 @@ Function Add-AzADAppSecret
+### Applications
+
+For more information about Applications check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
+When an App is generated 2 types of permissions are given:
+
+* **Permissions** given to the **Service Principal**
+* **Permissions** the **app** can have and use on **behalf of the user**.
+
+{% tabs %}
+{% tab title="az cli" %}
+```bash
+# List Apps
+az ad app list
+az ad app list --query "[].[displayName,appId]" -o table
+# Get info of 1 App
+az ad app show --id 00000000-0000-0000-0000-000000000000
+# Search App by string
+az ad app list --query "[?contains(displayName,'app')].displayName"
+# Get the owner of an application
+az ad app owner list --id --query "[].[displayName]" -o table
+# Get SPs owned by current user
+az ad app list --show-mine
+# Get apps with generated secret or certificate
+az ad app list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
+```
+{% endtab %}
+
+{% tab title="Azure AD" %}
+```powershell
+# List all registered applications
+Get-AzureADApplication -All $true
+# Get details of an application
+Get-AzureADApplication -ObjectId | fl *
+# List all the apps with an application password
+Get-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}}
+# Get owner of an application
+Get-AzureADApplication -ObjectId | Get-AzureADApplicationOwner |fl *
+```
+{% endtab %}
+
+{% tab title="Az PowerShell" %}
+```powershell
+# 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 %}
+
+{% hint style="warning" %}
+An app with the permission **`AppRoleAssignment.ReadWrite`** can **escalate to Global Admin** by grating itself the role.\
+For more information [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48).
+{% endhint %}
+
+{% hint style="info" %}
+A secret string that the application uses to prove its identity when requesting a token is the application password.\
+So, if find this **password** you can access as the **service principal** **inside** the **tenant**.\
+Note that this password is only visible when generated (you could change it but you cannot get it again).\
+The **owner** of the **application** can **add a password** to it (so he can impersonate it).\
+Logins as these service principals are **not marked as risky** and they **won't have MFA.**
+{% endhint %}
+
+### Managed Identities
+
+For more information about Managed Identities check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
+{% tabs %}
+{% tab title="az cli" %}
+```bash
+# List all manged identities
+az identity list --output table
+# With the principal ID you can continue the enumeration in service principals
+```
+{% endtab %}
+{% endtabs %}
+
### Roles
+For more information about Azure and Entra ID roles check:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
{% tabs %}
{% tab title="az cli" %}
```bash
@@ -690,101 +829,25 @@ If a device (VM) is **AzureAD joined**, users from AzureAD are going to be **abl
Moreover, if the logged user is **Owner** of the device, he is going to be **local admin**.
{% endhint %}
-### Applications
-
-{% hint style="info" %}
-**Apps** are **App Registrations** in the portal (not Enterprise Applications).\
-But each App Registration will create an **Enterprise Application** (**Service Principal**) with the same name.\
-Moreover, if the App is a **multi-tenant App**, **another** Enterprise App (**Service Principal**) will be created in **that tenant** with the same name.
-{% endhint %}
-
-When an App is generated 2 types of permissions are given:
-
-* **Permissions** given to the **Service Principal**
-* **Permissions** the **app** can have and use on **behalf of the user**.
-
-{% tabs %}
-{% tab title="az cli" %}
-```bash
-# List Apps
-az ad app list
-az ad app list --query "[].[displayName]" -o table
-# Get info of 1 App
-az ad app show --id 00000000-0000-0000-0000-000000000000
-# Search App by string
-az ad app list --query "[?contains(displayName,'app')].displayName"
-# Get the owner of an application
-az ad app owner list --id --query "[].[displayName]" -o table
-# List all the apps with an application password
-az ad app list --query "[?passwordCredentials != null].displayName"
-# List apps that have key credentials (use of certificate authentication)
-az ad app list --query "[?keyCredentials != null].displayName"
-```
-{% endtab %}
-
-{% tab title="Azure AD" %}
-```powershell
-# List all registered applications
-Get-AzureADApplication -All $true
-# Get details of an application
-Get-AzureADApplication -ObjectId | fl *
-# List all the apps with an application password
-Get-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}}
-# Get owner of an application
-Get-AzureADApplication -ObjectId | Get-AzureADApplicationOwner |fl *
-```
-{% endtab %}
-
-{% tab title="Az PowerShell" %}
-```powershell
-# 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 %}
-
-{% hint style="warning" %}
-An app with the permission **`AppRoleAssignment.ReadWrite`** can **escalate to Global Admin** by grating itself the role.\
-For more information [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48).
-{% endhint %}
-
-{% hint style="info" %}
-A secret string that the application uses to prove its identity when requesting a token is the application password.\
-So, if find this **password** you can access as the **service principal** **inside** the **tenant**.\
-Note that this password is only visible when generated (you could change it but you cannot get it again).\
-The **owner** of the **application** can **add a password** to it (so he can impersonate it).\
-Logins as these service principals are **not marked as risky** and they **won't have MFA.**
-{% endhint %}
-
-### Difference Applications & (Enterprise Applications or Service Principals)
-
-Difference between an application and a Service Principal in Azure:
-
-* **Application/App Registrations**: Are applications that exist in your Azure AD
- * `(Get-AzureADApplication -filter "DisplayName eq 'testapp'")`
-* **Service Principal/Enterprise Applications**: Security objects in your Azure AD that can have **privileges** in the Azure Directory and are linked to either your application or a third party application
- * `Get-AzureADServicePrincipal -filter "DisplayName eq 'testapp'")`
- * An admin might need to approve the given permissions if they are very sensitive.
-
-An application can be ruining a **Third party tenant** and once you start using it and give it access an **Enterprise Application/Service Principal is created in your tenant** to give it access to the info it needs:
-
### Administrative Units
-It's used for better management of users.
-
-Administrative units **restrict permissions in a role to any portion of your organization** that you define. You could, for example, use administrative units to delegate the [Helpdesk Administrator](https://learn.microsoft.com/en-us/azure/active-directory/roles/permissions-reference#helpdesk-administrator) role to regional support specialists, so they can manage users only in the region that they support.
+For more information about administrative units check:
-Therefore, you can assign roles to the administrator unit and members of it will have this roles.
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
{% tabs %}
{% tab title="az cli" %}
-```
+```bash
+# List all administrative units
+az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits"
+# Get AU info
+az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53"
+# Get members
+az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/members"
+# Get principals with roles over the AU
+az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/scopedRoleMembers"
```
{% endtab %}
diff --git a/pentesting-cloud/azure-security/az-services/az-management-groups-subscriptions-and-resource-groups.md b/pentesting-cloud/azure-security/az-services/az-management-groups-subscriptions-and-resource-groups.md
new file mode 100644
index 0000000000..8d74959c35
--- /dev/null
+++ b/pentesting-cloud/azure-security/az-services/az-management-groups-subscriptions-and-resource-groups.md
@@ -0,0 +1,86 @@
+# Az - Management Groups, Subscriptions & Resource Groups
+
+{% hint style="success" %}
+Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
+Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
+
+
+
+Support HackTricks
+
+* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
+* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
+* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
+
+
+{% endhint %}
+
+## Management Groups
+
+You can find more info about Management Groups in:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
+### Enumeration
+
+```bash
+# List
+az account management-group list
+# Get details and management groups and subscriptions that are children
+az account management-group show --name --expand --recurse
+```
+
+## Subscriptions
+
+You can find more info about Subscriptions in:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
+### Enumeration
+
+{% code overflow="wrap" %}
+```bash
+# List all subscriptions
+az account list --output table
+# Get details
+az account management-group subscription show --name --subscription
+```
+{% endcode %}
+
+## Resource Groups
+
+You can find more info about Resource Groups in:
+
+{% content-ref url="../az-basic-information.md" %}
+[az-basic-information.md](../az-basic-information.md)
+{% endcontent-ref %}
+
+### Enumeration
+
+{% code overflow="wrap" %}
+```bash
+# List all resource groups
+az group list
+# Get resource groups of specific subscription
+az group list --subscription "" --output table
+```
+{% endcode %}
+
+{% hint style="success" %}
+Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
+Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
+
+
+
+Support HackTricks
+
+* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
+* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
+* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
+
+
+{% endhint %}