Az - Entra ID (AzureAD) & Azure IAM

Reading time: 29 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Основна інформація

Azure Active Directory (Azure AD) є хмарною службою Microsoft для управління ідентичністю та доступом. Вона є важливою для того, щоб співробітники могли входити в систему та отримувати доступ до ресурсів як всередині, так і за межами організації, включаючи Microsoft 365, портал Azure та безліч інших SaaS-додатків. Дизайн Azure AD зосереджений на наданні основних ідентифікаційних послуг, зокрема автентифікації, авторизації та управління користувачами.

Ключові функції Azure AD включають багатофакторну автентифікацію та умовний доступ, а також безшовну інтеграцію з іншими службами безпеки Microsoft. Ці функції значно підвищують безпеку ідентичностей користувачів і надають організаціям можливість ефективно впроваджувати та забезпечувати свої політики доступу. Як основний компонент екосистеми хмарних служб Microsoft, Azure AD є ключовим для управління ідентичностями користувачів у хмарі.

Перерахування

З'єднання

bash
az login #This will open the browser (if not use --use-device-code)
az login -u <username> -p <password> #Specify user and password
az login --identity #Use the current machine managed identity (metadata)
az login --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID #Login with user managed identity

# Login as service principal
## With password
az login --service-principal -u <application ID> -p VerySecret --tenant contoso.onmicrosoft.com # Tenant can also be the tenant UUID
## With cert
az login --service-principal -u <application ID> -p ~/mycertfile.pem --tenant contoso.onmicrosoft.com

# Request access token (ARM)
az account get-access-token
# Request access token for different resource. Supported tokens: aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
az account get-access-token --resource-type aad-graph

# If you want to configure some defaults
az configure

# Get user logged-in already
az ad signed-in-user show

# Help
az find "vm" # Find vm commands
az vm -h # Get subdomains
az ad user list --query-examples # Get examples

Коли ви входите через CLI в Azure з будь-якою програмою, ви використовуєте Azure Application з оренди, яка належить Microsoft. Ці програми, як ті, що ви можете створити у своєму обліковому записі, мають ідентифікатор клієнта. Ви не зможете побачити всі з них у списках дозволених програм, які ви можете побачити в консолі, але вони дозволені за замовчуванням.

Наприклад, скрипт powershell, який автентифікує, використовує додаток з ідентифікатором клієнта 1950a258-227b-4e31-a9cf-717495945fc2. Навіть якщо додаток не з'являється в консолі, системний адміністратор може заблокувати цю програму, щоб користувачі не могли отримати доступ, використовуючи інструменти, які підключаються через цей додаток.

Однак є інші ідентифікатори клієнтів програм, які дозволять вам підключитися до Azure:

bash
# The important part is the ClientId, which identifies the application to login inside Azure

$token = Invoke-Authorize -Credential $credential `
-ClientId '1dfb5f98-f363-4b0f-b63a-8d20ada1e62d' `
-Scope 'Files.Read.All openid profile Sites.Read.All User.Read email' `
-Redirect_Uri "https://graphtryit-staging.azurewebsites.net/" `
-Verbose -Debug `
-InformationAction Continue

$token = Invoke-Authorize -Credential $credential `
-ClientId '65611c08-af8c-46fc-ad20-1888eb1b70d9' `
-Scope 'openid profile Sites.Read.All User.Read email' `
-Redirect_Uri "chrome-extension://imjekgehfljppdblckcmjggcoboemlah" `
-Verbose -Debug `
-InformationAction Continue

$token = Invoke-Authorize -Credential $credential `
-ClientId 'd3ce4cf8-6810-442d-b42e-375e14710095' `
-Scope 'openid' `
-Redirect_Uri "https://graphexplorer.azurewebsites.net/" `
-Verbose -Debug `
-InformationAction Continue

Тенанти

bash
# List tenants
az account tenant list

Користувачі

Для отримання додаткової інформації про користувачів Entra ID перегляньте:

Az - Basic Information

bash
# Enumerate users
az ad user list --output table
az ad user list --query "[].userPrincipalName"
# Get info of 1 user
az ad user show --id "test@corp.onmicrosoft.com"
# Search "admin" users
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 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
az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi!=null]"
az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName"
# Get groups where the user is a member
az ad user get-member-groups --id <email>
# 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 <email>
# Get ALL roles assigned in Azure in the current subscription (NOT in Entra ID)
az role assignment list --include-inherited --include-groups --include-classic-administrators true --all

# 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

Змінити пароль користувача

bash
$password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText –Force

(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password –Verbose

MFA & Conditional Access Policies

Рекомендується додати MFA для кожного користувача, однак деякі компанії можуть не налаштовувати його або можуть налаштувати його з умовним доступом: Користувач буде зобов'язаний використовувати MFA, якщо він входить з певного місця, браузера або якоїсь умови. Ці політики, якщо не налаштовані правильно, можуть бути схильні до обхідних шляхів. Перевірте:

Az - Conditional Access Policies & MFA Bypass

Groups

Для отримання додаткової інформації про групи Entra ID перевірте:

Az - Basic Information

bash
# Enumerate groups
az ad group list
az ad group list --query "[].[displayName]" -o table
# Get info of 1 group
az ad group show --group <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 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
az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi!=null]"
az ad group list --query "[?onPremisesSecurityIdentifier!=null].displayName"
# Get members of group
az ad group member list --group <group> --query "[].userPrincipalName" -o table
# Check if member of group
az ad group member check --group "VM Admins" --member-id <id>
# Get which groups a group is member of
az ad group get-member-groups -g "VM Admins"
# Get roles assigned to the group in Azure (NOT in Entra ID)
az role assignment list --include-groups --include-classic-administrators true --assignee <group-id>

# To get Entra ID roles assigned check how it's done with users and use a group ID

Додати користувача до групи

Власники групи можуть додавати нових користувачів до групи

bash
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose

warning

Групи можуть бути динамічними, що в основному означає, що якщо користувач виконує певні умови, його буде додано до групи. Звичайно, якщо умови базуються на атрибутах, які користувач може контролювати, він може зловживати цією функцією, щоб потрапити до інших груп.
Перевірте, як зловживати динамічними групами на наступній сторінці:

Az - Dynamic Groups Privesc

Службові принципали

Для отримання додаткової інформації про службові принципали Entra ID перевірте:

Az - Basic Information

bash
# Get Service Principals
az ad sp list --all
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
az ad sp list --all --query "[?contains(displayName,'app')].displayName"
# Get owner of service principal
az ad sp owner list --id <id> --query "[].[displayName]" -o table
# Get service principals owned by the current user
az ad sp list --show-mine

# Get SPs with generated secret or certificate
az ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json

warning

Власник сервісного принципалу може змінити його пароль.

Список та спроба додати клієнтський секрет до кожного корпоративного додатку
bash
# Just call Add-AzADAppSecret
Function Add-AzADAppSecret
{
<#
.SYNOPSIS
Add client secret to the applications.

.PARAMETER GraphToken
Pass the Graph API Token

.EXAMPLE
PS C:\> Add-AzADAppSecret -GraphToken 'eyJ0eX..'

.LINK
https://docs.microsoft.com/en-us/graph/api/application-list?view=graph-rest-1.0&tabs=http
https://docs.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http
#>

[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[String]
$GraphToken = $null
)

$AppList = $null
$AppPassword = $null

# List All the Applications

$Params = @{
"URI"     = "https://graph.microsoft.com/v1.0/applications"
"Method"  = "GET"
"Headers" = @{
"Content-Type"  = "application/json"
"Authorization" = "Bearer $GraphToken"
}
}

try
{
$AppList = Invoke-RestMethod @Params -UseBasicParsing
}
catch
{
}

# Add Password in the Application

if($AppList -ne $null)
{
[System.Collections.ArrayList]$Details = @()

foreach($App in $AppList.value)
{
$ID = $App.ID
$psobj = New-Object PSObject

$Params = @{
"URI"     = "https://graph.microsoft.com/v1.0/applications/$ID/addPassword"
"Method"  = "POST"
"Headers" = @{
"Content-Type"  = "application/json"
"Authorization" = "Bearer $GraphToken"
}
}

$Body = @{
"passwordCredential"= @{
"displayName" = "Password"
}
}

try
{
$AppPassword = Invoke-RestMethod @Params -UseBasicParsing -Body ($Body | ConvertTo-Json)
Add-Member -InputObject $psobj -NotePropertyName "Object ID" -NotePropertyValue $ID
Add-Member -InputObject $psobj -NotePropertyName "App ID" -NotePropertyValue $App.appId
Add-Member -InputObject $psobj -NotePropertyName "App Name" -NotePropertyValue $App.displayName
Add-Member -InputObject $psobj -NotePropertyName "Key ID" -NotePropertyValue $AppPassword.keyId
Add-Member -InputObject $psobj -NotePropertyName "Secret" -NotePropertyValue $AppPassword.secretText
$Details.Add($psobj) | Out-Null
}
catch
{
Write-Output "Failed to add new client secret to '$($App.displayName)' Application."
}
}
if($Details -ne $null)
{
Write-Output ""
Write-Output "Client secret added to : "
Write-Output $Details | fl *
}
}
else
{
Write-Output "Failed to Enumerate the Applications."
}
}

Застосунки

Для отримання додаткової інформації про Застосунки перегляньте:

Az - Basic Information

Коли створюється додаток, надаються 2 типи дозволів:

  • Дозволи, надані Службовому Принципалу
  • Дозволи, які додаток може мати та використовувати від імені користувача.
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 <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
# Get Global Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1b2256f9-46c1-4fc2-a125-5b2f51bb43b7/members"
# Get Application Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1e92c3b7-2363-4826-93a6-7f7a5b53e7f9/members"
# Get Cloud Applications Administrators (full access over apps)
az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/0d601d27-7b9c-476f-8134-8e7cd6744f02/members"

warning

Додаток з дозволом AppRoleAssignment.ReadWrite може підвищити привілеї до Global Admin, надавши собі цю роль.
Для отримання додаткової інформації перевірте це.

note

Секретний рядок, який додаток використовує для підтвердження своєї особи при запиті токена, є паролем додатка.
Отже, якщо ви знайдете цей пароль, ви зможете отримати доступ як сервісний принципал всередині орендаря.
Зверніть увагу, що цей пароль видимий лише під час генерації (ви можете змінити його, але не зможете отримати його знову).
Власник додатка може додати пароль до нього (щоб він міг його імітувати).
Вхід як ці сервісні принципали не позначається як ризиковий і вони не матимуть MFA.

Можливо знайти список загальновживаних ID додатків, що належать Microsoft, за адресою https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications

Керовані ідентичності

Для отримання додаткової інформації про Керовані ідентичності перевірте:

Az - Basic Information

bash
# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals

Ролі Azure

Для отримання додаткової інформації про ролі Azure перегляньте:

Az - Basic Information

bash
# Get roles
az role definition list
# Get all assigned roles
az role assignment list --all --query "[].roleDefinitionName"
az role assignment list --all | jq '.[] | .roleDefinitionName,.scope'
# Get info of 1 role
az role definition list --name "AzureML Registry User"
# Get only custom roles
az role definition list --custom-role-only
# Get only roles assigned to the resource group indicated
az role definition list --resource-group <resource_group>
# Get only roles assigned to the indicated scope
az role definition list --scope <scope>
# Get all the principals a role is assigned to
az role assignment list --all --query "[].{principalName:principalName,principalType:principalType,scope:scope,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='<ROLE_NAME>']"
# Get all the roles assigned to a user
az role assignment list --assignee "<email>" --all --output table
# Get all the roles assigned to a user by filtering
az role assignment list --all --query "[?principalName=='admin@organizationadmin.onmicrosoft.com']" --output table
# Get deny assignments
az rest --method GET --uri "https://management.azure.com/{scope}/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01"
## Example scope of subscription
az rest --method GET --uri "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01"

Ролі Entra ID

Для отримання додаткової інформації про ролі Azure дивіться:

Az - Basic Information

bash
# List template Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoleTemplates"

# List enabled built-in Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles"

# List all Entra ID roles with their permissions (including custom roles)
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions"

# List only custom Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" | jq '.value[] | select(.isBuiltIn == false)'

# List all assigned Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments"

# List members of a Entra ID roles
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles/<role-id>/members"

# List Entra ID roles assigned to a user
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/users/<user-id>/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json

# List Entra ID roles assigned to a group
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/groups/$GROUP_ID/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json

# List Entra ID roles assigned to a service principal
az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$SP_ID/memberOf/microsoft.graph.directoryRole" \
--query "value[]" \
--output json

Пристрої

bash
# If you know how to do this send a PR!

warning

Якщо пристрій (VM) приєднаний до AzureAD, користувачі з AzureAD зможуть увійти в систему.
Більше того, якщо увійшовший користувач є Власником пристрою, він буде локальним адміністратором.

Адміністративні одиниці

Для отримання додаткової інформації про адміністративні одиниці перегляньте:

Az - Basic Information

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"

Підвищення привілеїв Entra ID

Az - EntraID Privesc

Підвищення привілеїв Azure

Az - Azure IAM Privesc (Authorization)

Захисні механізми

Управління привілейованими ідентичностями (PIM)

Управління привілейованими ідентичностями (PIM) в Azure допомагає запобігти надмірним привілеям, які без потреби надаються користувачам.

Однією з основних функцій, які надає PIM, є те, що він дозволяє не призначати ролі принципалам, які постійно активні, а робити їх придатними на певний період часу (наприклад, 6 місяців). Тоді, коли користувач хоче активувати цю роль, він повинен запитати її, вказуючи час, на який йому потрібен привілей (наприклад, 3 години). Потім адміністратор повинен затвердити запит.
Зверніть увагу, що користувач також зможе попросити продовжити час.

Більше того, PIM надсилає електронні листи щоразу, коли привілейована роль призначається комусь.

Коли PIM увімкнено, можна налаштувати кожну роль з певними вимогами, такими як:

  • Максимальна тривалість (години) активації
  • Вимагати MFA при активації
  • Вимагати контекст аутентифікації умовного доступу
  • Вимагати обґрунтування при активації
  • Вимагати інформацію про квиток при активації
  • Вимагати затвердження для активації
  • Максимальний час для закінчення дії придатних призначень
  • Багато інших налаштувань щодо того, коли і кому надсилати сповіщення, коли певні дії відбуваються з цією роллю

Політики умовного доступу

Перевірте:

Az - Conditional Access Policies & MFA Bypass

Захист ідентичності Entra

Захист ідентичності Entra - це сервіс безпеки, який дозволяє виявляти, коли користувач або вхід занадто ризикований для прийняття, дозволяючи блокувати користувача або спробу входу.

Це дозволяє адміністратору налаштувати його для блокування спроб, коли ризик "Низький і вище", "Середній і вище" або "Високий". Хоча за замовчуванням він повністю вимкнений:

tip

Сьогодні рекомендується додавати ці обмеження через політики умовного доступу, де можна налаштувати ті ж самі опції.

Захист паролів Entra

Захист паролів Entra (https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade) - це функція безпеки, яка допомагає запобігти зловживанню слабкими паролями, блокуючи облікові записи, коли відбувається кілька невдалих спроб входу.
Вона також дозволяє заборонити користувацький список паролів, який потрібно надати.

Вона може бути застосована як на рівні хмари, так і в локальному Active Directory.

Режим за замовчуванням - Аудит:

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks