- Cenário 1: Desvio de propriedade e perigo
- Visão geral do caminho de ataque
- Fluxo de ataque
- Por que razão é importante compreender a propriedade da aplicação?
- Como detetar e defender-se contra a utilização indevida da propriedade principal do serviço
- Apresentação passo-a-passo da solução
- Etapa 1: Ponto de apoio inicial
- Etapa 2: Enumeração
- Etapa 3: Pivotar para o contexto do responsável pelo serviço
- Passo 4: Tomada de controlo da conta - iniciar sessão como administrador global
- Conheça o seu elo mais fraco
- Aceite o seu próximo desafio EntraGoat
- Nota final
- Declaração de exoneração de responsabilidade
Nota do editor
Este cenário faz parte de uma série de exemplos que demonstram a utilização do EntraGoat, o nosso ambiente de simulação Entra ID. Pode ler uma visão geral do EntraGoat e o seu valor aqui.
Desconhecido e perigoso: Um Manual do Proprietário para a Administração Global
Começamos os nossos exemplos de utilização do EntraGoat com o Cenário 1, a que chamámos "Misowned and Dangerous": Um manual do proprietário para o administrador global. Este exercício prático mostra como a propriedade legítima do aplicativo no Microsoft Entra ID pode ser aproveitada para aumentar os privilégios e comprometer uma conta de administrador global, permitindo o controle completo do locatário.
Começando com uma conta de utilizador pouco privilegiada comprometida, o atacante descobre a propriedade de uma aplicação empresarial (service principal) à qual é atribuída uma função privilegiada.
Ao adicionar um segredo de cliente à entidade de serviço, o atacante entra na identidade da aplicação e, em seguida, utiliza a sua função para repor a palavra-passe do administrador e emitir um Passe de Acesso Temporário (TAP) para obter acesso interativo total ao portal do Azure.
Este cenário enfatiza as consequências reais da má gestão de aplicações e ilustra a diferença de comportamento, limites de acesso e exposição ao risco entre fluxos de autenticação delegados e apenas de aplicações.
Visão geral do caminho de ataque
- História do primeiro ponto de apoio: O atacante autentica-se como um utilizador financeiro comprometido (
david.martinez
) com credenciais roubadas. - Enumeração: Usando cmdlets nativos do PowerShell e do Microsoft Graph, o atacante descobre que o usuário possui uma entidade de serviço chamada
Finance Analytics Dashboard
ao qual é atribuído oPrivileged Authentication Administrator
papel. - Aumento de privilégios: O atacante adiciona um segredo de cliente à entidade proprietária do serviço e autentica-se utilizando credenciais apenas da aplicação, passando para uma identidade de entidade de serviço.
- Aquisição de conta: A partir do contexto só de aplicações com a função privilegiada, o atacante repõe a palavra-passe do Administrador Global ou adiciona um TAP para contornar a autenticação multifactor (MFA), depois inicia sessão interactivamente e recupera o sinalizador, confirmando o compromisso total do inquilino.
Fluxo de ataque
A Figura 1 mostra o fluxo deste ataque.
Por que razão é importante compreender a propriedade da aplicação?
Cada aplicação em Entra ID tem duas identidades distintas:
- Registo da aplicação, um objeto de definição global no inquilino de origem onde a aplicação foi originalmente criada. Este objeto contém as permissões (âmbitos) blueprint-OAuth2 da aplicação que a aplicação pode solicitar URIs de redireccionamento para fluxos de início de sessão, metadados de marca e editor, entre outros. Esta identidade não representa uma entidade de segurança ativa no inquilino por si só.
- Entidade de serviço, uma instância local da aplicação no locatário que actua como a sua identidade de segurança e impõe o controlo de acesso. Um principal de serviço é criado automaticamente quando um usuário no locatário registra um novo aplicativo, consente com um aplicativo externo e assim por diante. A identidade do principal de serviço é o que a Entra ID usa para atribuir funções, aplicar políticas e impor permissões. É também a identidade autenticada quando o aplicativo atua por conta própria (contexto somente de aplicativo).
A propriedade de aplicativos é um recurso administrativo legítimo. Este design suporta a administração descentralizada em grandes organizações, permitindo às equipas gerir as suas próprias aplicações empresariais. Ele permite que desenvolvedores, processos de automação e proprietários de serviços gerenciem o ciclo de vida e a configuração de seus aplicativos. No entanto, esse recurso se torna uma responsabilidade quando:
- São atribuídas funções privilegiadas às aplicações
- A propriedade é atribuída a utilizadores regulares sem governação
- A higiene das credenciais é fraca ou não é monitorizada
As entidades de serviço mal geridas permitem a adição de credenciais e o acesso apenas a aplicações, contornando controlos de identidade como o MFA e o acesso condicional.
Este passo a passo destaca por que os invasores priorizam o movimento lateral usando princípios de serviço em ambientes de nuvem modernos e por que os defensores devem entender a diferença entre contextos de segurança delegados e somente de aplicativo.
Como detetar e defender-se contra a utilização indevida da propriedade principal do serviço
Compreender e monitorar a propriedade do aplicativo não é opcional; é um controle de segurança fundamental em qualquer ambiente Entra ID. A propriedade do aplicativo concede a capacidade de gerenciar credenciais, configurar permissões e controlar efetivamente a identidade do aplicativo. Sem visibilidade da propriedade do aplicativo e das atribuições de permissão, os caminhos de escalonamento de privilégios permanecem ocultos tanto para os defensores quanto para os auditores.
Os defensores devem monitorizar e correlacionar:
- Que aplicações existem no inquilino?
- A quem pertencem?
- Que permissões ou funções de diretório lhes são atribuídas?
- Há algum utilizador sem privilégios que possua diretores de serviço com acesso elevado?
- Que aplicações já não estão a ser utilizadas e podem ser desactivadas?
As soluções Semperis ajudam a colmatar as lacunas na compreensão destas questões com várias camadas de defesa, começando com indicadores de exposição (IOEs) e indicadores de compromisso (IOCs).
Esses indicadores detectam e alertam automaticamente sobre padrões perigosos e configurações incorretas - como políticas de autorização excessivamente permissivas para a configuração de aplicativos, não-administradores que possuem princípios de serviço privilegiados e linhas de base de segurança de aplicativos fracas.
Mergulho profundo no cenário: Apresentação passo a passo da solução
Vejamos os passos específicos a seguir para simular a utilização indevida da propriedade da aplicação e compreender em que condições permite o compromisso do Administrador Global.
Etapa 1: Ponto de apoio inicial
Começamos com o contexto de segurança de um analista financeiro, david.martinez
(Figura 2) que introduziu as suas credenciais empresariais durante uma campanha de phishing.
Utilizar o Connect-MgGraph
cmdlet, autenticamos como o utilizador comprometido (Figura 3).
Para compreender as nossas capacidades actuais, começamos por inspecionar o contexto de segurança da sessão autenticada(Figura 4).
Um método alternativo e bem conhecido para autenticar como um usuário Entra ID e obter um token de acesso JWT é aproveitar as ferramentas de automação, como o BARK1. O seguinte snippet do PowerShell demonstra como adquirir e usar um token de acesso via autenticação de nome de usuário/senha a partir da CLI:
$userToken = Get-MSGraphTokenWithUsernamePassword -Username $UPN -Password $password -TenantID $tenantId $userAccessToken = $userToken.access_token $SecureToken = ConvertTo-SecureString $userAccessToken -AsPlainText -Force Ligar-MgGraph -AccessToken $SecureToken
O BARK também inclui uma funcionalidade para descodificar o JWT resultante, expondo metadados detalhados da sessão, tais como permissões delegadas (scp
), funções de diretório (wids
), método de autenticação (amr
), e informações do cliente (app_displayname
), como Figura 5 espectáculos.
Este passo de descodificação é particularmente útil para uma triagem rápida de privilégios. Por exemplo, se o token foi emitido para um utilizador com funções de diretório, o wids
listaria diretamente os GUIDs das funções atribuídas, como a função de Administrador Global que Figura 6 mostra, sem exigir enumeração adicional da API do Graph.
No entanto, este passo a passo evita depender de ferramentas ou abstrações de terceiros. Todas as etapas de enumeração e exploração são executadas usando o PowerShell nativo e chamadas diretas à API do Graph para garantir que cada fase do caminho do ataque seja totalmente transparente e tecnicamente explicada.
NOTA: Por defeito, todos os utilizadores autenticados no Entra ID podem consultar os dados básicos do perfil de outros utilizadores e atributos como extensionAttribute1–15
não são classificadas como sensíveis. Como resultado, o sinalizador armazenado no perfil do administrador pode tecnicamente ser recuperado imediatamente com a seguinte consulta da API:
$uri = "https://graph.microsoft.com/v1.0/users/EntraGoat-admin-s1@334brf.onmicrosoft.com?`$select=onPremisesExtensionAttributes" $response = Invoke-MgGraphRequest -Uri $uri -Method GET $response.onPremisesExtensionAttributes.extensionAttribute1
Este comportamento é intencional. O objetivo do EntraGoat não é ocultar o sinalizador, mas ensinar técnicas realistas de escalonamento de privilégios em ambientes Entra ID. É possível recuperar o sinalizador por meio de uma chamada direta à API; mas o objetivo real é escalar privilégios, acessar o portal do Azure como usuário administrador e visualizar o sinalizador na interface do usuário - demonstrando controle total sobre uma identidade de administrador global. A bandeira é um artefacto gamificado, não o objetivo principal.
Invoke-MgGraphRequest -Uri 'https://graph.microsoft.com/v1.0/me?$select=id,userPrincipalName,onPremisesExtensionAttributes' | Select-Object @{n='UPN';e={$_.userPrincipalName}}, @{n='Id';e={$_.id}}, @{n='Flag';e={$_.onPremisesExtensionAttributes.extensionAttribute1}}
Etapa 2: Enumeração
Como este é o primeiro cenário da série EntraGoat, vamos percorrer o processo de enumeração e destacar as técnicas fundamentais de escalonamento de privilégios. Em nossos outros cenários, assumiremos essa linha de base e nos concentraremos diretamente no caminho principal do ataque, ignorando as etapas de reconhecimento no estilo CTF.
Com acesso inicial a david.martinez
Se o sistema de segurança estiver comprometido, começamos a procurar caminhos para o aumento de privilégios. A nossa primeira tarefa é compreender o acesso que a identidade comprometida tem.
Começamos por verificar se o utilizador tem alguma função de diretório atribuída(Figura 7).
O Get-MgRoleManagementDirectoryRoleAssignment
não revela funções privilegiadas, confirmando que david.martinez
não tem acesso elevado por defeito. De seguida, analisamos as associações de grupos (Figura 8).
O utilizador faz apenas parte do grupo de inquilinos predefinido, que é atribuído a cada utilizador Entra ID para serviços de colaboração como o SharePoint ou o Teams. Nenhum caminho de escalonamento de privilégios aqui também.
Também verificamos se david.martinez
possui quaisquer grupos, uma vez que os proprietários de grupos podem adicionar-se a si próprios como membros e herdar os privilégios do grupo (tais como funções atribuídas). Esta verificação também retorna vazio (Figura 9).
No entanto, a consulta da propriedade principal do serviço apresenta um resultado(Figura 10).
david.martinez
possui o mandante do serviço Finance Analytics Dashboard
. Isto é importante porque os proprietários da entidade de serviço podem gerir credenciais - incluindo a adição de novos segredos para autenticar como entidade de serviço.
Vamos verificar se o Finance Analytics Dashboard
o responsável pelo serviço tem quaisquer permissões atribuídas (Figura 11).
Nenhum está configurado. Em seguida, verificamos se existem funções de diretório atribuídas ao mesmo(Figura 12).
Vemos uma atribuição de função, mas ela é representada apenas por um GUID. Cada função interna da Entra ID é representada por um GUID, que é global e o mesmo em todos os locatários da Entra ID. É possível visualizar todas as funções internas oficiais e seus GUIDs aqui.
Para resolver o GUID para um nome de função legível por humanos, podemos canalizar a saída de Get-MgRoleManagementDirectoryRoleAssignment
para Get-MgRoleManagementDirectoryRoleDefinition
(Figura 13), que traduzirá cada ID de função atribuído para o nome de apresentação correspondente.
Privileged Authentication Administrator
é uma função altamente sensível no Entra ID. Permite ao titular gerir métodos de autenticação para todos os utilizadores, incluindo a reposição de definições de MFA, a configuração de opções de início de sessão FIDO2 e sem palavra-passe e a modificação de políticas-chave que regem a forma como os utilizadores se autenticam. É por isso que um atacante, agindo como seu proprietário, certamente desejaria adicionar um segredo de cliente a ele e usá-lo para influenciar a conta de Administrador Global.
NOTA: Se você acompanhou de perto a fase de enumeração, provavelmente notou a verbosidade e o esforço manual necessários ao usar cmdlets nativos do Microsoft Graph. (E se tivéssemos 5[0] aplicativos Entra em vez de 1?) Essa é uma das principais limitações de depender exclusivamente de ferramentas nativas. Os comandos geralmente retornam dados de baixo nível (como GUIDs) que exigem consultas adicionais para serem resolvidos em informações significativas.
É exatamente por isso que muitas estruturas de enumeração automatizam estes processos. Elas abstraem as consultas repetitivas e simplificam o resultado, permitindo uma análise mais rápida dos privilégios e a tomada de decisões. Por exemplo, para melhorar a usabilidade, podemos escrever funções de wrapper simples, como Find-OwnedServicePrincipals
e Get-ServicePrincipalRoles
que foram concebidos para automatizar a descoberta de propriedade de SP e resolver atribuições de funções de diretório de forma mais eficiente:
function Find-OwnedServicePrincipals { param([string]$UserId) # Get all service principals in tenant $allSPs = Get-MgServicePrincipal -All Write-Host "Found $($allSPs.Count) service principals in tenant" $ownedSPs = @() $checkCount = 0 # Check ownership of each service principal foreach ($sp in $allSPs) { $checkCount++ if ($checkCount % 50 -eq 0) { Write-Host "Checked $checkCount/$($allSPs.Count) service principals..." } try { $owners = Get-MgServicePrincipalOwner -ServicePrincipalId $sp.Id -ErrorAction SilentlyContinue if ($owners) { foreach ($owner in $owners) { if ($owner.Id -eq $UserId) { $ownedSPs += $sp Write-Host "OWNED SERVICE PRINCIPAL FOUND!" -ForegroundColor Red Write-Host " Name: $($sp.DisplayName)" -ForegroundColor Yellow Write-Host " SP ID: $($sp.Id)" -ForegroundColor Yellow Write-Host " App ID: $($sp.AppId)" -ForegroundColor Yellow break } } } } catch { continue } } return $ownedSPs } function Get-ServicePrincipalRoles { param([object]$ServicePrincipal) Write-Host "Checking roles for: $($ServicePrincipal.DisplayName)" # Check directory role assignments for the SP $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "principalId eq '$($ServicePrincipal.Id)'" -ErrorAction SilentlyContinue $roles = @() if ($roleAssignments) { foreach ($assignment in $roleAssignments) { $roleDefinition = Get-MgRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $assignment.RoleDefinitionId $roles += $roleDefinition Write-Host " Role: $($roleDefinition.DisplayName)" -ForegroundColor Cyan } } else { Write-Host " No directory roles assigned" } return $roles }
Agora, para descobrir todos os princípios de serviço pertencentes ao utilizador comprometido e enumerar as suas funções atribuídas, podemos simplesmente executar Find-OwnedService Principals
, como Figura 14 espectáculos.
Etapa 3: Pivotar para o contexto do responsável pelo serviço
Esta etapa destaca o principal motivo pelo qual criamos este cenário e o posicionamos em primeiro lugar na série: As entidades de serviço moldam o cenário de escalonamento de privilégios na Entra ID. O movimento lateral para o contexto de segurança de uma entidade de serviço e sua utilização para realizar operações privilegiadas é uma técnica fundamental com a qual todo defensor, atacante e pesquisador que trabalha com o Entra ID deve estar familiarizado.
Vamos adicionar um segredo de cliente ao ficheiro Finance Analytics Dashboard
para estabelecer um acesso backdoor e autenticar-se como SP:
$secretDescription = "EntraGoat-Secret-$(Get-Date -Format 'yyyyMMdd-HHmmss')" $passwordCredential = @{ DisplayName = $secretDescription EndDateTime = (Get-Date).AddYears(1) } $newSecret = Add-MgServicePrincipalPassword -ServicePrincipalId $SP.Id -PasswordCredential $passwordCredential # Guardar os detalhes do segredo adicionado $clientSecret = $newSecret.SecretText
Em seguida, desligue a sessão do utilizador atual com Disconnect-MgGraph
construir as credenciais do cliente e autenticar utilizando a identidade do responsável pelo serviço através de Connect-MgGraph
:
$secureSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SP.AppId, $secureSecret Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential
E, de facto, agora estamos autenticados como os Finance Analytics Dashboard
chefe de serviço (Figura 15).
O Get-MgContext
revela informações sobre como a sessão atual do Microsoft Graph é autenticada, o que determina diretamente o contexto de segurança, o nível de acesso e o modelo de permissão que é aplicado. Vamos nos concentrar nos campos AuthType
e TokenCredentialType
uma vez que expõem a semântica de identidade central na Entra ID.
Depois de se autenticar como david.martinez
, estes valores apareceram como:
AuthType : Delegado TokenCredentialType : InteractiveBrowser
Isto indica uma sessão delegada, em que o token emitido representa uma identidade de utilizador. O acesso é regido pelas funções atribuídas ao utilizador e pelas permissões delegadas, e todas as operações são executadas em nome do utilizador. O contexto da sessão está limitado àquilo a que a identidade do utilizador tem acesso, uma vez que herda políticas de Acesso Condicional, imposição de MFA e restrições PIM.
Em contrapartida, um contexto apenas de aplicação, como um contexto iniciado por uma entidade de serviço que utiliza credenciais de cliente (AppId
+ Secret
+ TenantId
) funciona como uma identidade não-humana. Qualquer cliente (script, trabalho em segundo plano, daemon) usando essas credenciais pode autenticar como o aplicativo e invocar APIs do Microsoft Graph com base em suas permissões de aplicativo, independentemente do contexto do usuário. As políticas de Acesso Condicional, MFA e PIM não são aplicáveis ou impostas neste fluxo.
Esta distinção é fundamental na conceção da segurança da identidade e explica porque é que o comportamento da API, os âmbitos de acesso e os privilégios de token diferem nos mesmos cmdlets, dependendo do contexto da sessão.
E, como seria de esperar, esta distinção tem um grande impacto na superfície de ataque e no potencial de abuso. Os fluxos delegados são limitados pelo contexto do utilizador, enquanto os fluxos só de aplicações funcionam com confiança ao nível do serviço e, frequentemente, com limites de privilégios mais amplos e menos controlados. Para os atacantes, comprometer o segredo ou o certificado de uma aplicação resulta frequentemente num acesso persistente e com privilégios elevados que contorna os mecanismos de aplicação centrados na identidade.
Passo 4: Tomada de controlo da conta - iniciar sessão como administrador global
Agora que nos autenticámos como uma identidade com o Privileged Authentication Administrator
temos a possibilidade de repor as palavras-passe (Figura 16) para qualquer utilizador no locatário, incluindo o Administrador Global.
Com este nível de acesso, também podemos atribuir um TAP(Figura 17) como método de autenticação, permitindo-nos contornar o MFA e iniciar sessão diretamente no portal do Azure:
De seguida, iniciamos a sessão com a TAP(Figura 18).
De seguida, recuperamos a bandeira do cenário(Figura 19).
Uma vez terminado o cenário, executamos o script de limpeza para restaurar o locatário EntraGoat ao seu estado original(Figura 20).
Conheça o seu elo mais fraco
Este cenário demonstra como configurações aparentemente legítimas e comuns, como a atribuição da propriedade de uma aplicação a um utilizador padrão, podem abrir a porta a um compromisso total do inquilino quando emparelhadas com funções privilegiadas.
Ao tirar partido da propriedade de uma entidade de serviço, os atacantes podem aumentar os privilégios, contornar as defesas centradas no utilizador, como a MFA e o Acesso Condicional, e, em última análise, obter acesso de Administrador Global através de um fluxo apenas de aplicações.
Esse exercício ressalta a importância crítica de uma forte governança em torno das permissões de aplicativos, da propriedade da entidade de serviço e das atribuições de função. Nos ambientes de nuvem modernos, as entidades de serviço são frequentemente o elo mais fraco, e compreender o seu modelo de identidade dupla, os limites de acesso e o potencial de abuso é essencial tanto para os atacantes como para os defensores.
O Cenário 1 do EntraGoat estabelece as bases para uma maior exploração - e para os nossos próximos cenários. Por isso, continuem a piratear!
Aceite o seu próximo desafio EntraGoat
- GitHub - Semperis/EntraGoat
- O que é o EntraGoat? Um ambiente de simulação Entra ID deliberadamente vulnerável
- Começando com EntraGoat: Quebrando Entra ID a maneira inteligente
- Cenário 2: Explorando permissões de gráfico somente de aplicativo no Entra ID
Nota final
- https://github.com/BloodHoundAD/BARK
Declaração de exoneração de responsabilidade
Este conteúdo é fornecido apenas para fins educacionais e informativos. Destina-se a promover a consciencialização e a correção responsável das vulnerabilidades de segurança que possam existir nos sistemas que possui ou que está autorizado a testar. O uso não autorizado dessas informações para fins maliciosos, exploração ou acesso ilegal é estritamente proibido. A Semperis não endossa ou tolera qualquer atividade ilegal e se isenta de qualquer responsabilidade decorrente do uso indevido do material. Além disso, a Semperis não garante a exatidão ou a integridade do conteúdo e não assume qualquer responsabilidade por quaisquer danos resultantes da sua utilização.