38 KiB
Az - Entra ID (AzureAD) & Azure IAM
{{#include ../../../banners/hacktricks-training.md}}
基本情報
Azure Active Directory (Azure AD) は、Microsoft のクラウドベースのアイデンティティおよびアクセス管理サービスです。これは、従業員がサインインし、Microsoft 365、Azure ポータル、その他の多くの SaaS アプリケーションを含む、組織内外のリソースにアクセスするのを可能にする上で重要です。Azure AD の設計は、認証、承認、およびユーザー管理を主に含む、基本的なアイデンティティサービスを提供することに焦点を当てています。
Azure AD の主な機能には、多要素認証と条件付きアクセスが含まれ、他の Microsoft セキュリティサービスとのシームレスな統合が行われています。これらの機能は、ユーザーのアイデンティティのセキュリティを大幅に向上させ、組織がアクセスポリシーを効果的に実施および強制するのを支援します。Microsoft のクラウドサービスエコシステムの基本的なコンポーネントとして、Azure AD はユーザーアイデンティティのクラウドベースの管理において重要です。
列挙
接続
{{#tabs }} {{#tab name="az cli" }}
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
{{#endtab }}
{{#tab name="Mg" }}
# Login Open browser
Connect-MgGraph
# Login with service principal secret
## App ID and Tenant ID of your Azure AD App Registration
$appId = "<appId>"
$tenantId = "<tenantId>"
$clientSecret = "<clientSecret>"
## Convert the client secret to a SecureString
$secureSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
## Create a PSCredential object
$credential = New-Object System.Management.Automation.PSCredential ($appId, $secureSecret)
## Connect using client credentials
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential
# Login with token
$token = (az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv)
$secureToken = ConvertTo-SecureString $token -AsPlainText -Force
Connect-MgGraph -AccessToken $secureToken
# Find commands
Find-MgGraphCommand -command *Mg*
{{#endtab }}
{{#tab name="Az PowerShell" }}
Connect-AzAccount #Open browser
# Using credentials
$passwd = ConvertTo-SecureString "Welcome2022!" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential("test@corp.onmicrosoft.com", $passwd)
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
# Connect with access token
Connect-AzAccount -AccountId test@corp.onmicrosoft.com -AccessToken $token
Connect-AzAccount -AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId <ACCOUNT-ID>
## The -AccessToken is from management.azure.com
# Connect with Service principal/enterprise app secret
$password = ConvertTo-SecureString 'KWEFNOIRFIPMWL.--DWPNVFI._EDWWEF_ADF~SODNFBWRBIF' -AsPlainText -Force
$creds = New-Object
System.Management.Automation.PSCredential('2923847f-fca2-a420-df10-a01928bec653', $password)
Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant 29sd87e56-a192-a934-bca3-0398471ab4e7d
#All the Azure AD cmdlets have the format *-AzAD*
Get-Command *azad*
#Cmdlets for other Azure resources have the format *Az*
Get-Command *az*
{{#endtab }}
{{#tab name="Raw PS" }}
#Using management
$Token = 'eyJ0eXAi..'
# List subscriptions
$URI = 'https://management.azure.com/subscriptions?api-version=2020-01-01'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value
# Using graph
Invoke-WebRequest -Uri "https://graph.windows.net/myorganization/users?api-version=1.6" -Headers @{Authorization="Bearer {0}" -f $Token}
{{#endtab }}
{{#tab name="curl" }}
# Request tokens to access endpoints
# ARM
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
# Vault
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
{{#endtab }}
{{#tab name="Azure AD" }}
Connect-AzureAD #Open browser
# Using credentials
$passwd = ConvertTo-SecureString "Welcome2022!" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("test@corp.onmicrosoft.com", $passwd)
Connect-AzureAD -Credential $creds
# Using tokens
## AzureAD cannot request tokens, but can use AADGraph and MSGraph tokens to connect
Connect-AzureAD -AccountId test@corp.onmicrosoft.com -AadAccessToken $token
{{#endtab }} {{#endtabs }}
AzureにCLIを通じてログインするとき、あなたはMicrosoftに属するテナントからのAzureアプリケーションを使用しています。これらのアプリケーションは、あなたのアカウントで作成できるものと同様に、クライアントIDを持っています。コンソールで見ることができる許可されたアプリケーションのリストにはすべて表示されませんが、デフォルトで許可されています。
例えば、認証を行うPowerShellスクリプトは、クライアントID**1950a258-227b-4e31-a9cf-717495945fc2を持つアプリを使用します。アプリがコンソールに表示されなくても、システム管理者はそのアプリケーションをブロック**して、ユーザーがそのアプリを介して接続できないようにすることができます。
しかし、Azureに接続を許可する他のクライアントIDのアプリケーションもあります:
# 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
テナント
{{#tabs }} {{#tab name="az cli" }}
# List tenants
az account tenant list
{{#endtab }} {{#endtabs }}
ユーザー
Entra ID ユーザーに関する詳細情報は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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
{{#endtab }}
{{#tab name="Azure AD" }}
# Enumerate Users
Get-AzureADUser -All $true
Get-AzureADUser -All $true | select UserPrincipalName
# Get info of 1 user
Get-AzureADUser -ObjectId test@corp.onmicrosoft.com | fl
# Search "admin" users
Get-AzureADUser -SearchString "admin" #Search admin at the begining of DisplayName or userPrincipalName
Get-AzureADUser -All $true |?{$_.Displayname -match "admin"} #Search "admin" word in DisplayName
# Get all attributes of a user
Get-AzureADUser -ObjectId test@defcorphq.onmicrosoft.com|%{$_.PSObject.Properties.Name}
# Search attributes containing the word "password"
Get-AzureADUser -All $true |%{$Properties = $_;$Properties.PSObject.Properties.Name | % {if ($Properties.$_ -match 'password') {"$($Properties.UserPrincipalName) - $_ - $($Properties.$_)"}}}
# All users from AzureAD# All users from AzureAD
Get-AzureADUser -All $true | ?{$_.OnPremisesSecurityIdentifier -eq $null}
# All users synced from on-prem
Get-AzureADUser -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null}
# Objects created by a/any user
Get-AzureADUser [-ObjectId <email>] | Get-AzureADUserCreatedObject
# Devices owned by a user
Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com
# Objects owned by a specific user
Get-AzureADUserOwnedObject -ObjectId test@corp.onmicrosoft.com
# Get groups & roles where the user is a member
Get-AzureADUserMembership -ObjectId 'test@corp.onmicrosoft.com'
# Get devices owned by a user
Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com
# Get devices registered by a user
Get-AzureADUserRegisteredDevice -ObjectId test@defcorphq.onmicrosoft.com
# Apps where a user has a role (role not shown)
Get-AzureADUser -ObjectId roygcain@defcorphq.onmicrosoft.com | Get-AzureADUserAppRoleAssignment | fl *
# Get Administrative Units of a user
$userObj = Get-AzureADUser -Filter "UserPrincipalName eq 'bill@example.com'"
Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where { $_.Id -eq $userObj.ObjectId } }
{{#endtab }}
{{#tab name="Az PowerShell" }}
# Enumerate users
Get-AzADUser
# Get details of a user
Get-AzADUser -UserPrincipalName test@defcorphq.onmicrosoft.com
# Search user by string
Get-AzADUser -SearchString "admin" #Search at the beginnig of DisplayName
Get-AzADUser | ?{$_.Displayname -match "admin"}
# Get roles assigned to a user
Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com
{{#endtab }} {{#endtabs }}
ユーザーパスワードの変更
$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を要求するConditional Accessを設定するかもしれません。これらのポリシーは、正しく構成されていない場合、バイパスされる可能性があります。確認してください:
{{#ref}} ../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md {{#endref}}
Groups
Entra IDグループに関する詳細情報は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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
{{#endtab }}
{{#tab name="Azure AD" }}
# Enumerate Groups
Get-AzureADGroup -All $true
# Get info of 1 group
Get-AzADGroup -DisplayName <resource_group_name> | fl
# Get "admin" groups
Get-AzureADGroup -SearchString "admin" | fl #Groups starting by "admin"
Get-AzureADGroup -All $true |?{$_.Displayname -match "admin"} #Groups with the word "admin"
# Get groups allowing dynamic membership
Get-AzureADMSGroup | ?{$_.GroupTypes -eq 'DynamicMembership'}
# All groups that are from Azure AD
Get-AzureADGroup -All $true | ?{$_.OnPremisesSecurityIdentifier -eq $null}
# All groups that are synced from on-prem (note that security groups are not synced)
Get-AzureADGroup -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null}
# Get members of a group
Get-AzureADGroupMember -ObjectId <group_id>
# Get roles of group
Get-AzureADMSGroup -SearchString "Contoso_Helpdesk_Administrators" #Get group id
Get-AzureADMSRoleAssignment -Filter "principalId eq '69584002-b4d1-4055-9c94-320542efd653'"
# 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 <id> | Get-AzureADGroupAppRoleAssignment | fl *
{{#endtab }}
{{#tab name="Az PowerShell" }}
# Get all groups
Get-AzADGroup
# Get details of a group
Get-AzADGroup -ObjectId <id>
# 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 <resource_group_name>
# Get roles of group
Get-AzRoleAssignment -ResourceGroupName <resource_group_name>
{{#endtab }} {{#endtabs }}
グループにユーザーを追加
グループの所有者は新しいユーザーをグループに追加できます
Add-AzureADGroupMember -ObjectId <group_id> -RefObjectId <user_id> -Verbose
Warning
グループは動的であり、基本的にはユーザーが特定の条件を満たすとグループに追加されることを意味します。もちろん、条件が属性に基づいている場合、ユーザーが制御できると、彼はこの機能を悪用して他のグループに入ることができます。
動的グループを悪用する方法については、次のページを確認してください:
{{#ref}} ../az-privilege-escalation/az-entraid-privesc/dynamic-groups.md {{#endref}}
サービスプリンシパル
Entra ID サービスプリンシパルに関する詳細情報は、次を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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
{{#endtab }}
{{#tab name="Azure AD" }}
# Get Service Principals
Get-AzureADServicePrincipal -All $true
# Get details about a SP
Get-AzureADServicePrincipal -ObjectId <id> | 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 <id> | Get-AzureADServicePrincipalOwner |fl *
# Get objects owned by a SP
Get-AzureADServicePrincipal -ObjectId <id> | Get-AzureADServicePrincipalOwnedObject
# Get objects created by a SP
Get-AzureADServicePrincipal -ObjectId <id> | Get-AzureADServicePrincipalCreatedObject
# Get groups where the SP is a member
Get-AzureADServicePrincipal | Get-AzureADServicePrincipalMembership
Get-AzureADServicePrincipal -ObjectId <id> | Get-AzureADServicePrincipalMembership |fl *
{{#endtab }}
{{#tab name="Az PowerShell" }}
# Get SPs
Get-AzADServicePrincipal
# Get info of 1 SP
Get-AzADServicePrincipal -ObjectId <id>
# Search SP by string
Get-AzADServicePrincipal | ?{$_.DisplayName -match "app"}
# Get roles of a SP
Get-AzRoleAssignment -ServicePrincipalName <String>
{{#endtab }}
{{#tab name="Raw" }}
$Token = 'eyJ0eX..'
$URI = 'https://graph.microsoft.com/v1.0/applications'
$RequestParams = @{
Method = 'GET'
Uri = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value
{{#endtab }} {{#endtabs }}
Warning
サービスプリンシパルのオーナーは、そのパスワードを変更できます。
各エンタープライズアプリにクライアントシークレットを追加しようとするリスト
```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>
### アプリケーション
アプリケーションに関する詳細情報は、以下を確認してください:
{{#ref}}
../az-basic-information/
{{#endref}}
アプリが生成されると、2種類の権限が付与されます:
- **サービスプリンシパル**に与えられる**権限**
- **ユーザー**の**代理**として**アプリ**が持ち、使用できる**権限**。
{{#tabs }}
{{#tab name="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 <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 name="Azure AD" }}
# List all registered applications
Get-AzureADApplication -All $true
# Get details of an application
Get-AzureADApplication -ObjectId <id> | 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 <id> | Get-AzureADApplicationOwner |fl *
{{#endtab }}
{{#tab name="Az PowerShell" }}
# Get Apps
Get-AzADApplication
# Get details of one App
Get-AzADApplication -ObjectId <id>
# Get App searching by string
Get-AzADApplication | ?{$_.DisplayName -match "app"}
# Get Apps with password
Get-AzADAppCredential
{{#endtab }} {{#endtabs }}
Warning
AppRoleAssignment.ReadWriteの権限を持つアプリは、役割を自分に付与することで Global Admin に 昇格 できます。
詳細については こちらを確認してください。
Note
アプリケーションがトークンを要求する際にそのアイデンティティを証明するために使用する秘密の文字列は、アプリケーションパスワードです。
したがって、この パスワード を見つけると、テナント 内の サービスプリンシパル としてアクセスできます。
このパスワードは生成時にのみ表示されることに注意してください(変更することはできますが、再取得することはできません)。
アプリケーション の 所有者 は、(彼がそれを偽装できるように)パスワード を追加できます。
これらのサービスプリンシパルとしてのログインは リスクあり としてマークされず、MFA はありません。
一般的に使用される Microsoft のアプリ ID のリストを見つけることができます https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications
Managed Identities
Managed Identities についての詳細は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals
{{#endtab }} {{#endtabs }}
Azure Roles
Azure ロールに関する詳細情報は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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,resourceGroup:resourceGroup,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=='carlos@carloshacktricks.onmicrosoft.com']" --output table
{{#endtab }}
{{#tab name="Az PowerShell" }}
# 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>
{{#endtab }}
{{#tab name="Raw" }}
# 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
{{#endtab }} {{#endtabs }}
Entra ID ロール
Azure ロールに関する詳細情報は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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
{{#endtab }}
{{#tab name="Azure AD" }}
# 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 *
{{#endtab }} {{#endtabs }}
デバイス
{{#tabs }} {{#tab name="az cli" }}
# If you know how to do this send a PR!
{{#endtab }}
{{#tab name="Azure AD" }}
# Enumerate Devices
Get-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 devices
Get-AzureADDevice -All $true | Get-AzureADDeviceRegisteredOwner
Get-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredOwner -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}
# Registred users of all the devices
Get-AzureADDevice -All $true | Get-AzureADDeviceRegisteredUser
Get-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredUser -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}
# Get dives managed using Intune
Get-AzureADDevice -All $true | ?{$_.IsCompliant -eq "True"}
# Get devices owned by a user
Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com
# Get Administrative Units of a device
Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -ObjectId $_.ObjectId | where {$_.ObjectId -eq $deviceObjId} }
{{#endtab }} {{#endtabs }}
Warning
デバイス (VM) が AzureAD に参加している 場合、AzureAD のユーザーは ログインできる ようになります。
さらに、ログインしているユーザーがデバイスの オーナー である場合、彼は ローカル管理者 になります。
管理単位
管理単位に関する詳細情報は、以下を確認してください:
{{#ref}} ../az-basic-information/ {{#endref}}
{{#tabs }} {{#tab name="az cli" }}
# 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 }}
{{#tab name="AzureAD" }}
# Get Administrative Units
Get-AzureADMSAdministrativeUnit
Get-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 unit
Get-AzureADMSAdministrativeUnitMember -Id <id>
# Get the roles users have over the members of the AU
Get-AzureADMSScopedRoleMembership -Id <id> | fl #Get role ID and role members
{{#endtab }} {{#endtabs }}
Entra ID 特権昇格
{{#ref}} ../az-privilege-escalation/az-entraid-privesc/ {{#endref}}
Azure 特権昇格
{{#ref}} ../az-privilege-escalation/az-authorization-privesc.md {{#endref}}
防御メカニズム
特権アイデンティティ管理 (PIM)
Azure の特権アイデンティティ管理 (PIM) は、不必要にユーザーに過剰な特権が割り当てられるのを防ぐのに役立ちます。
PIM が提供する主な機能の一つは、常にアクティブなプリンシパルにロールを割り当てるのではなく、一定期間(例:6ヶ月)資格を与えることができる点です。ユーザーがそのロールをアクティブにしたい場合、必要な特権の時間(例:3時間)を示してリクエストを行う必要があります。その後、管理者がリクエストを承認する必要があります。
ユーザーはまた、時間を延長するようにリクエストすることもできます。
さらに、PIM は特権ロールが誰かに割り当てられるたびにメールを送信します。

PIM が有効になっていると、各ロールに対して次のような特定の要件を設定することができます:
- アクティベーションの最大期間(時間)
- アクティベーション時に MFA を要求
- 条件付きアクセス認証コンテキストを要求
- アクティベーション時に正当化を要求
- アクティベーション時にチケット情報を要求
- アクティベートするための承認を要求
- 資格のある割り当ての最大期限
- 特定のアクションがそのロールで発生したときに通知を送信するタイミングと送信先に関する多くの設定
条件付きアクセス ポリシー
確認:
{{#ref}} ../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md {{#endref}}
Entra アイデンティティ保護
Entra アイデンティティ保護は、ユーザーまたはサインインが受け入れられるにはリスクが高すぎる場合を検出するセキュリティサービスで、ユーザーまたはサインインの試行をブロックすることができます。
管理者は、リスクが「低およびそれ以上」、「中程度およびそれ以上」または「高」である場合に試行をブロックするように設定できます。ただし、デフォルトでは完全に無効です:

Tip
現在、同じオプションを設定できる条件付きアクセス ポリシーを介してこれらの制限を追加することが推奨されています。
Entra パスワード保護
Entra パスワード保護 (https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade) は、複数の不成功なログイン試行が発生した場合にアカウントをロックアウトすることで、弱いパスワードの悪用を防ぐのに役立つセキュリティ機能です。
また、提供する必要があるカスタムパスワードリストを禁止することもできます。
これは、クラウドレベルとオンプレミスの Active Directory の両方に適用できます。
デフォルトモードは監査です:

参考文献
{{#include ../../../banners/hacktricks-training.md}}