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

모듈 차이점

  • AzureADAzure AD를 관리하기 위한 Microsoft의 PowerShell 모듈입니다. Azure AD 객체의 모든 속성을 표시하지 않으며 Azure 리소스 정보에 접근하는 데 사용할 수 없습니다.

  • Az PowerShellPowerShell 명령줄에서 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에 속하는 tenantAzure Application을 사용하고 있습니다. 이러한 애플리케이션은 귀하의 계정에서 생성할 수 있는 애플리케이션과 같이 클라이언트 ID를 가지고 있습니다. 콘솔에서 볼 수 있는 허용된 애플리케이션 목록에서 모든 애플리케이션을 볼 수는 없지만, 기본적으로 허용됩니다.

예를 들어, 1950a258-227b-4e31-a9cf-717495945fc2 클라이언트 ID를 가진 앱을 사용하여 인증하는 powershell 스크립트가 있습니다. 애플리케이션이 콘솔에 나타나지 않더라도, 시스템 관리자는 사용자가 해당 앱을 통해 연결할 수 없도록 해당 애플리케이션을 차단할 수 있습니다.

그러나 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 및 조건부 액세스 정책

모든 사용자에게 MFA를 추가하는 것이 강력히 권장되지만, 일부 회사는 이를 설정하지 않거나 특정 위치, 브라우저 또는 일부 조건에서 로그인할 경우에만 MFA를 요구하는 조건부 액세스와 함께 설정할 수 있습니다. 이러한 정책이 올바르게 구성되지 않으면 우회에 취약할 수 있습니다. 확인하세요:

Az - Conditional Access Policies / MFA Bypass

그룹

# 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

서비스 주체 / 엔터프라이즈 애플리케이션

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 *

Az PowerShell은 Azure 리소스를 관리하기 위한 명령줄 도구입니다. 이 도구를 사용하면 Azure 리소스를 쉽게 배포하고 관리할 수 있습니다.

# 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 디렉토리에서 권한을 가질 수 있는 귀하의 Azure AD의 보안 객체이며 귀하의 애플리케이션 또는 제3자 애플리케이션에 연결되어 있습니다.

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

  • 관리자는 매우 민감한 권한에 대해 승인을 요구할 수 있습니다.

애플리케이션은 제3자 테넌트에서 실행될 수 있으며, 사용을 시작하고 접근을 부여하면 귀하의 테넌트에 엔터프라이즈 애플리케이션/서비스 주체가 생성되어 필요한 정보에 접근할 수 있습니다.

관리 단위

사용자 관리를 개선하기 위해 사용됩니다.

관리 단위는 귀하가 정의한 조직의 일부에 대한 역할의 권한을 제한합니다. 예를 들어, 관리 단위를 사용하여 지역 지원 전문가에게 헬프데스크 관리자 역할을 위임하여 그들이 지원하는 지역의 사용자만 관리할 수 있도록 할 수 있습니다.

따라서 관리 단위에 역할을 할당할 수 있으며, 그 구성원은 이 역할을 갖게 됩니다.

# 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는 사용자 로그인 및 신원 구성의 위험을 지속적으로 모니터링하고 평가하며, 다단계 인증 요구 또는 잠재적으로 위험한 활동 차단과 같은 적절한 보안 조치를 자동으로 적용합니다. 이는 조직이 신원 기반 보안 위반을 방지하는 데 도움을 줍니다.

흐름:

  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