Az - AzureAD (AAD)

Support HackTricks

Informações Básicas

O Azure Active Directory (Azure AD) serve como o serviço baseado em nuvem da Microsoft para gerenciamento de identidade e acesso. É fundamental para permitir que os funcionários façam login e acessem recursos, tanto dentro quanto fora da organização, abrangendo Microsoft 365, o portal do Azure e uma infinidade de outras aplicações SaaS. O design do Azure AD foca em fornecer serviços essenciais de identidade, incluindo autenticação, autorização e gerenciamento de usuários.

As principais características do Azure AD envolvem autenticação multifatorial e acesso condicional, além de integração perfeita com outros serviços de segurança da Microsoft. Essas características elevam significativamente a segurança das identidades dos usuários e capacitam as organizações a implementar e fazer cumprir suas políticas de acesso de forma eficaz. Como um componente fundamental do ecossistema de serviços em nuvem da Microsoft, o Azure AD é crucial para o gerenciamento baseado em nuvem das identidades dos usuários.

Entidades

Enumeração

Para esta enumeração, você pode usar a ferramenta az cli, o módulo PowerShell AzureAD (ou AzureAD Preview) e o módulo Az PowerShell.

No linux, você precisará instalar o 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

Diferenças entre Módulos

  • AzureAD é um módulo PowerShell da Microsoft para gerenciar o Azure AD. Ele não mostra todas as propriedades dos objetos do Azure AD e não pode ser usado para acessar informações de recursos do Azure.

  • Az PowerShell é um módulo para gerenciar recursos do Azure a partir da linha de comando do PowerShell.

Conexão

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

Quando você faz login via CLI no Azure com qualquer programa, você está usando uma Aplicação Azure de um tenant que pertence à Microsoft. Essas Aplicações, como as que você pode criar em sua conta, têm um id de cliente. Você não poderá ver todas elas nas listas de aplicações permitidas que você pode ver no console, mas elas são permitidas por padrão.

Por exemplo, um script powershell que autentica usa um aplicativo com id de cliente 1950a258-227b-4e31-a9cf-717495945fc2. Mesmo que o aplicativo não apareça no console, um sysadmin poderia bloquear essa aplicação para que os usuários não possam acessar usando ferramentas que se conectam via esse App.

No entanto, existem outros ids de cliente de aplicações que permitirão que você se conecte ao Azure:

# 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

Usuários

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

Alterar Senha do Usuário

$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

É altamente recomendável adicionar MFA a cada usuário, no entanto, algumas empresas não o farão ou podem configurá-lo com um Acesso Condicional: O usuário será obrigado a usar MFA se fizer login de um local específico, navegador ou alguma condição. Essas políticas, se não configuradas corretamente, podem ser propensas a bypasses. Verifique:

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 *

Adicionar usuário ao grupo

Os proprietários do grupo podem adicionar novos usuários ao grupo

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

Os grupos podem ser dinâmicos, o que basicamente significa que se um usuário atender a certas condições, ele será adicionado a um grupo. Claro, se as condições forem baseadas em atributos que um usuário pode controlar, ele pode abusar dessa funcionalidade para entrar em outros grupos. Verifique como abusar de grupos dinâmicos na página a seguir:

Principais Serviços / Aplicativos Empresariais

Observe que Service Principal na terminologia do PowerShell é chamado de Enterprise Applications no portal Azure (web).

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

O proprietário de um Principal de Serviço pode alterar sua senha.

Liste e tente adicionar um segredo de cliente em cada Aplicativo Empresarial

```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>

### Funções

<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

Dispositivos

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

Se um dispositivo (VM) estiver AzureAD joined, usuários do AzureAD poderão fazer login. Além disso, se o usuário logado for Owner do dispositivo, ele será administrador local.

Aplicações

Apps são App Registrations no portal (não Enterprise Applications). Mas cada App Registration criará uma Enterprise Application (Service Principal) com o mesmo nome. Além disso, se o App for um multi-tenant App, outra Enterprise App (Service Principal) será criada em aquele tenant com o mesmo nome.

Quando um App é gerado, 2 tipos de permissões são concedidas:

  • Permissões dadas ao Service Principal

  • Permissões que o app pode ter e usar em nome do usuário.

# 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

Um aplicativo com a permissão AppRoleAssignment.ReadWrite pode escalar para Global Admin ao se conceder o papel. Para mais informações verifique isso.

Uma string secreta que o aplicativo usa para provar sua identidade ao solicitar um token é a senha do aplicativo. Portanto, se encontrar esta senha, você pode acessar como o service principal dentro do tenant. Observe que esta senha só é visível quando gerada (você pode alterá-la, mas não pode obtê-la novamente). O proprietário do aplicativo pode adicionar uma senha a ele (para que possa se passar por ele). Logins como esses service principals não são marcados como arriscados e não terão MFA.

Diferença entre Aplicações e (Aplicações Empresariais ou Service Principals)

Diferença entre um aplicativo e um Service Principal no Azure:

  • Aplicação/Registro de Aplicativos: São aplicativos que existem no seu Azure AD

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

  • Service Principal/Aplicações Empresariais: Objetos de segurança no seu Azure AD que podem ter privilégios no Diretório Azure e estão vinculados ao seu aplicativo ou a um aplicativo de terceiros

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

  • Um administrador pode precisar aprovar as permissões concedidas se forem muito sensíveis.

Um aplicativo pode estar operando em um tenant de terceiros e, uma vez que você comece a usá-lo e conceda acesso, um Aplicativo Empresarial/Service Principal é criado em seu tenant para conceder acesso às informações de que precisa:

Unidades Administrativas

É usado para melhor gerenciamento de usuários.

Unidades administrativas restrigem permissões em um papel a qualquer parte da sua organização que você definir. Você poderia, por exemplo, usar unidades administrativas para delegar o papel de Administrador de Helpdesk a especialistas de suporte regional, para que possam gerenciar usuários apenas na região que apoiam.

Portanto, você pode atribuir papéis à unidade administrativa e os membros dela terão esses papéis.

# 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) é um serviço de segurança que usa detecção e remediação automatizadas para ajudar a proteger identidades de usuários no Azure Active Directory contra comprometimento. AIP monitora e avalia continuamente o risco de logins de usuários e configurações de identidade, aplicando automaticamente medidas de segurança apropriadas, como exigir autenticação multifator ou bloquear atividades potencialmente perigosas. Isso ajuda as organizações a prevenir violações de segurança baseadas em identidade.

Fluxo:

  1. Azure AD Identity Protection monitora atividades de usuários e coleta dados sobre logins, autenticação e outras atividades relevantes.

  2. O serviço usa algoritmos de aprendizado de máquina para analisar esses dados e detectar potenciais ameaças de segurança.

  3. Azure AD Identity Protection atribui um nível de risco à ameaça (por exemplo, login) e gera um alerta se necessário para realizar alguma ação automática.

Azure AD Password Protection (APP)

Azure AD Password Protection (APP) é um recurso de segurança que ajuda a prevenir senhas fracas no Azure Active Directory, aplicando políticas de senhas fortes. APP bloqueia senhas fracas comumente usadas e suas variantes, reduzindo o risco de violações relacionadas a senhas. Ele pode ser aplicado tanto no nível da nuvem quanto no Active Directory local, melhorando a segurança geral das senhas em toda a organização.

Referências

Last updated