Az - AzureAD (AAD)

Support HackTricks

Basic Information

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

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

Entities

Enumeration

Для цього перерахування ви можете використовувати az cli tool, модуль PowerShell AzureAD (або AzureAD Preview) та модуль Az PowerShell.

In linux you will need to install PowerShell Core:

sudo apt-get update
sudo apt-get install -y wget apt-transport-https software-properties-common

# Ubuntu 20.04
wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb

# Update repos
sudo apt-get update
sudo add-apt-repository universe

# Install & start powershell
sudo apt-get install -y powershell
pwsh

# Az cli
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Відмінності модулів

  • AzureAD - це модуль PowerShell від Microsoft для керування Azure AD. Він не показує всі властивості об'єктів Azure AD і не може бути використаний для доступу до інформації про ресурси Azure.

  • Az PowerShell - це модуль для керування ресурсами Azure з командного рядка PowerShell.

З'єднання

az login #This will open the browser
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
az login --service-principal -u http://azure-cli-2016-08-05-14-31-15 -p VerySecret --tenant contoso.onmicrosoft.com #With password
az login --service-principal -u http://azure-cli-2016-08-05-14-31-15 -p ~/mycertfile.pem --tenant contoso.onmicrosoft.com #With cert

# 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:

# 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

Користувачі

# 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 AzureAD
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
az role assignment list --include-groups --include-classic-administrators true --assignee <email>

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

$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

# 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 AzureAD
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 Apps where a group has a role (role not shown)
Get-AzureADGroup -ObjectId <id> | Get-AzureADGroupAppRoleAssignment | fl *

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

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

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

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

Az - Dynamic Groups Privesc

Service Principals / Enterprise Applications

Зверніть увагу, що Service Principal в термінології PowerShell називається Enterprise Applications в порталі Azure (веб).

# Get Service Principals
az ad sp list --all
az ad sp list --all --query "[].[displayName]" -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
# 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"

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

Список та спроба додати секрет клієнта до кожного корпоративного додатку

```powershell # 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." } }

</details>

### Ролі

<div data-gb-custom-block data-tag="tabs">

<div data-gb-custom-block data-tag="tab" data-title='az cli'>

```bash
# Get roles
az role definition list
# Get 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,resourceGroup:resourceGroup,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='<ROLE_NAME>']"
# Get all available role templates
Get-AzureADDirectoryroleTemplate
# Get enabled roles (Assigned roles)
Get-AzureADDirectoryRole
Get-AzureADDirectoryRole -ObjectId <roleID> #Get info about the role
# Get custom roles - use AzureAdPreview
Get-AzureADMSRoleDefinition | ?{$_.IsBuiltin -eq $False} | select DisplayName
# Users assigned a role (Global Administrator)
Get-AzureADDirectoryRole -Filter "DisplayName eq 'Global Administrator'" | Get-AzureADDirectoryRoleMember
Get-AzureADDirectoryRole -ObjectId <id> | fl
# Roles of the Administrative Unit (who has permissions over the administrative unit and its members)
Get-AzureADMSScopedRoleMembership -Id <id> | fl *
# Get role assignments on the subscription
Get-AzRoleDefinition
# Get Role definition
Get-AzRoleDefinition -Name "Virtual Machine Command Executor"
# Get roles of a user or resource
Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com
Get-AzRoleAssignment -Scope /subscriptions/<subscription-id>/resourceGroups/<res_group_name>/providers/Microsoft.Compute/virtualMachines/<vm_name>
# Get permissions over a resource using ARM directly
$Token = (Get-AzAccessToken).Token
$URI = 'https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Research/providers/Microsoft.Compute/virtualMachines/infradminsrv/providers/Microsoft.Authorization/permissions?api-version=2015-07-01'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value

Пристрої

# If you know how to do this send a PR!# Enumerate DevicesGet-AzureADDevice -All $true | fl *# List all the active devices (and not the stale devices)Get-AzureADDevice -All $true | ?{$_.ApproximateLastLogonTimeStamp -ne $null}# Get owners of all devicesGet-AzureADDevice -All $true | Get-AzureADDeviceRegisteredOwnerGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredOwner -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}# Registred users of all the devicesGet-AzureADDevice -All $true | Get-AzureADDeviceRegisteredUserGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredUser -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}# Get dives managed using IntuneGet-AzureADDevice -All $true | ?{$_.IsCompliant -eq "True"}# Get devices owned by a userGet-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com# Get Administrative Units of a deviceGet-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -ObjectId $_.ObjectId | where {$_.ObjectId -eq $deviceObjId} }

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

Додатки

Додатки - це Реєстрації Додатків в порталі (не Корпоративні Додатки). Але кожна Реєстрація Додатку створить Корпоративний Додаток (Службовий Принципал) з таким же ім'ям. Більше того, якщо Додаток є мультитенантним Додатком, інший Корпоративний Додаток (Службовий Принципал) буде створено в тому тенанті з таким же ім'ям.

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

  • Дозволи, надані Службовому Принципалу

  • Дозволи, які додаток може мати та використовувати від імені користувача.

# List Appsaz ad app listaz ad app list --query "[].[displayName]" -o table# Get info of 1 Appaz ad app show --id 00000000-0000-0000-0000-000000000000# Search App by stringaz ad app list --query "[?contains(displayName,'app')].displayName"# Get the owner of an applicationaz ad app owner list --id <id> --query "[].[displayName]" -o table# List all the apps with an application passwordaz 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"# List all registered applicationsGet-AzureADApplication -All $true# Get details of an applicationGet-AzureADApplication -ObjectId <id> | fl *# List all the apps with an application passwordGet-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}}# Get owner of an applicationGet-AzureADApplication -ObjectId <id> | Get-AzureADApplicationOwner |fl *# Get AppsGet-AzADApplication# Get details of one AppGet-AzADApplication -ObjectId <id># Get App searching by stringGet-AzADApplication | ?{$_.DisplayName -match "app"}# Get Apps with passwordGet-AzADAppCredential

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

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

Різниця між Додатками та (Корпоративними Додатками або Сервісними Принципалами)

Різниця між додатком і сервісним принципалом в Azure:

  • Додаток/Реєстрації додатків: Це додатки, які існують у вашому Azure AD

  • (Get-AzureADApplication -filter "DisplayName eq 'testapp'")

  • Сервісний принципал/Корпоративні додатки: Об'єкти безпеки у вашому Azure AD, які можуть мати привілеї в Azure Directory і пов'язані або з вашим додатком, або з додатком третьої сторони

  • Get-AzureADServicePrincipal -filter "DisplayName eq 'testapp'")

  • Адміністратору може знадобитися затвердити надані дозволи, якщо вони є дуже чутливими.

Додаток може працювати в орендарі третьої сторони, і як тільки ви почнете його використовувати і надасте доступ, Корпоративний Додаток/Сервісний Принципал створюється у вашому орендарі, щоб надати йому доступ до необхідної інформації:

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

Використовується для кращого управління користувачами.

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

Отже, ви можете призначати ролі адміністративній одиниці, і члени цієї одиниці матимуть ці ролі.

# Get Administrative UnitsGet-AzureADMSAdministrativeUnitGet-AzureADMSAdministrativeUnit -Id <id># Get ID of admin unit by string$adminUnitObj = Get-AzureADMSAdministrativeUnit -Filter "displayname eq 'Test administrative unit 2'"# List the users, groups, and devices affected by the administrative unitGet-AzureADMSAdministrativeUnitMember -Id <id># Get the roles users have over the members of the AUGet-AzureADMSScopedRoleMembership -Id <id> | fl #Get role ID and role members

Azure AD Identity Protection (AIP)

Azure AD Identity Protection (AIP) — це сервіс безпеки, який використовує автоматизоване виявлення та усунення проблем для захисту ідентичностей користувачів в Azure Active Directory від компрометації. AIP постійно моніторить та оцінює ризик входу користувачів та конфігурацій ідентичностей, автоматично застосовуючи відповідні заходи безпеки, такі як вимога багатофакторної аутентифікації або блокування потенційно небезпечних дій. Це допомагає організаціям запобігти порушенням безпеки на основі ідентичності.

Flow:

  1. Azure AD Identity Protection моніторить активність користувачів та збирає дані про входи, аутентифікацію та інші відповідні дії.

  2. Сервіс використовує алгоритми машинного навчання для аналізу цих даних та виявлення потенційних загроз безпеці.

  3. Azure AD Identity Protection присвоює рівень ризику загрозі (наприклад, вхід) та генерує сповіщення, якщо потрібно виконати автоматичну дію.

Azure AD Password Protection (APP)

Azure AD Password Protection (APP) — це функція безпеки, яка допомагає запобігти використанню слабких паролів в Azure Active Directory шляхом впровадження суворих політик паролів. APP блокує зазвичай використовувані слабкі паролі та їх варіанти, зменшуючи ризик порушень, пов'язаних з паролями. Її можна застосовувати як на рівні хмари, так і в локальному Active Directory, підвищуючи загальну безпеку паролів в організації.

References

Last updated