Persistência no Active Directory através da manipulação do userAccountControl
Tenho feito algumas pesquisas sobre contas de serviço gerenciadas em grupo (gMSAs) recentemente e lendo a especificação do protocolo MS-SAMR para obter algumas informações. Aconteceu de eu tropeçar em algumas informações interessantes na seção userAccountControl que nos fez largar o que estávamos fazendo para testá-la:
Efetivamente, quando o bit UF_SERVER_TRUST_ACCOUNT está configurado no atributo userAccountControl de um objeto de computador, então o Active Directory deve definir o primaryGroupId do mesmo objeto para o RID do grupo Domain Controllers. Portanto, simplesmente alterar o userAccountControl pode conceder a um objeto de computador os privilégios de um controlador de domínio.
Investigando o comportamento
Começamos a testar usando uma conta de Administrador de Domínio em nosso laboratório e primeiro tentamos usar o valor padrão de userAccountControl para um controlador de domínio de 0x82000 (decimal 532480), que é a soma dos bits flags para SERVER_TRUST_ACCOUNT (0x2000, decimal 8192) e TRUSTED_FOR_DELEGATION (0x80000, decimal 524288).
Após alterar o valor de userAccountControl, observamos que o primaryGroupId é atualizado para 516 (o RID do grupo de Controladores de Domínio) e começamos muito bem! Em seguida, queríamos saber se apenas o bit SERVER_TRUST_ACCOUNT é necessário, então tentamos novamente definir o atributo userAccountControl para 8192.
Assim, confirmamos a precisão da especificação do protocolo e que é apenas o bit SERVER_TRUST_ACCOUNT que causa a mudança do primaryGroupId.
Pesquisando privilégios necessários
Começamos a considerar possíveis vetores de abuso. Se apenas a capacidade de modificar o atributo userAccountControl for necessária, então poderíamos estar diante de uma técnica interessante de privilege escalation. Começamos a testar com uma conta sem privilégios com permissões apenas para modificar o atributo userAccountControl e rapidamente nos deparamos com erros de acesso negado.
Descobriu-se que deveríamos ter lido apenas mais algumas linhas abaixo na documentação do MS-SAMR. A Seção 5 do atributo userAccountControl detalha permissões adicionais necessárias para configurar certos bits do userAccountControl. Para definir o bit UF_SERVER_TRUST_ACCOUNT do userAccountControl, o ator deve ter a permissão DS-Install-Replica (“Adicionar/remover réplica no domínio”) concedida no objeto do domínio.
Concedemos ao nosso usuário não privilegiado esta permissão e tentamos nosso teste novamente.
Após conceder o privilégio de escrita userAccountControl no computador e o privilégio DS-Install-Replica no objeto de domínio ao nosso usuário não privilegiado, nosso teste foi bem-sucedido.
Por padrão, a permissão DS-Install-Replica é concedida aos grupos “Domain Admins” e “Enterprise Admins”. Assim, exceto em ambientes mal configurados, essa abordagem não representa um vetor de escalada de privilégios. No entanto, dado o limitado conjunto de permissões necessário, começamos a pensar em aplicações para a persistência de domínio.
Aplicações para persistência de domínio
Ao avaliar se isso apresenta um método interessante para persistência, consideramos vários fatores: que um conjunto limitado de privilégios é necessário, que esses privilégios não são comumente revisados, que as contas (objectClass=computer) são fáceis de criar, que os computadores são revisados com pouca frequência (muitas organizações lutam com objetos de computador obsoletos) e que a exploração do mecanismo é fácil e os sinais são de curta duração.
Configurar este mecanismo requer apenas alguns passos simples:
- Crie uma conta falsa de computador, MSA ou gMSA. Uma conta existente também pode ser usada, mas a eficácia do mecanismo de persistência será limitada pela frequência das mudanças de senha. No entanto, uma conta de computador existente, mas obsoleta (não mais usada), pode ser um alvo atraente.
- Conceda o privilégio “Add/remove replica in domain” a um usuário regular comprometido, grupo ou entidade bem conhecida. Usamos “Authenticated Users” para que um adversário pudesse comprometer qualquer conta de usuário regular e recuperar a dominância do domínio.
- Conceda o privilégio “Write userAccountControl” no objeto do computador à mesma entidade que no passo anterior.
Criando uma conta de computador com uma senha conhecida
Pode parecer óbvio, mas nem todos podem estar familiarizados com a capacidade de criar uma conta de computador com uma senha conhecida usando os cmdlets New-ADComputer ou New-ADServiceAccount, por exemplo:
New-ADComputer “ComputerName” -AccountPassword (ConvertTo-SecureString -AsPlainText -Force “Password”)
Conhecer a senha em texto claro é benéfico por algumas razões. Mais importante, podemos calcular os hashes NTLM, AES-128 e AES-256 usando os cmdlets ConvertTo-NTHash e ConvertTo-KerberosKey do módulo PowerShell DSInternals de Michael Grafnetter. Quando o adversário opta por explorar a porta dos fundos, ele precisará se autenticar como a conta do computador para usar seus privilégios e fará isso com a técnica de overpass-the-hash. Especificar os hashes NTLM e AES evita a maioria das detecções de overpass-the-hash.
Recuperando a dominância do domínio
Após preparar a conta e as permissões, se o adversário perder o acesso às suas credenciais administrativas ou for expulso da rede, ele só precisa comprometer qualquer usuário comum para recuperar o domínio do domínio.
Com qualquer conta de usuário, o adversário só precisa modificar o atributo userAccountControl do seu computador preparado para 0x2000 (8192). Essa modificação também provoca uma replicação imediata, o que significa que o adversário não precisa mirar em controladores de domínio específicos. Uma vez que o userAccountControl esteja completo, o adversário pode usar seus privilégios de controlador de domínio para comprometer o domínio.
Por exemplo, o adversário poderia usar a conta do computador para realizar DCSync e comprometer o hash da senha krbtgt. Como a replicação parece estar vindo de um controlador de domínio, a maioria das detecções de ameaças DCSync não detecta a atividade. Uma vez que eles replicaram o segredo krbtgt, eles podem simplesmente alterar userAccountControl de volta para 0x1000 (4096) e a conta do computador parecerá uma conta de computador normal.
Automatizando a técnica
Para ajudar a demonstrar a potencial eficácia deste método, criei duas novas funções PowerShell que estão disponíveis no GitHub.
A primeira função, Add-ServerUntrustAccount, automatiza os três passos de configuração – criando uma conta de computador falsa com uma senha conhecida e concedendo aos “Usuários Autenticados” os privilégios de “Adicionar/remover réplica no domínio” e “Escrever userAccountControl”.
A segunda função, Invoke-ServerUntrustAccount, automatiza a exploração da porta dos fundos e destina-se a ser executada como um usuário não privilegiado. A função define o atributo userAccountControl para 0x2000 (8192), em seguida, utiliza pass-the-hash para autenticar como a conta falsa do computador, realiza um DCSync dos hashes krbtgt, e finalmente retorna userAccountControl para 0x1000 (4096).
Descoberta de mecanismos e detecção de exploração
Para encontrar este e outros mecanismos semelhantes, as organizações devem auditar periodicamente as permissões sensíveis do Active Directory. Monitorar (ou até bloquear) alterações de permissões sensíveis (como a “Adicionar/remover réplica no domínio”) em tempo real também é benéfico. Testamos várias ferramentas populares de código aberto para auditoria de permissões do Active Directory, e apenas AD ACL Scanner destacou corretamente as permissões do nosso adversário como preocupantes.
Os logs de eventos do Active Directory – especificamente os Event IDs 5136 e 4662 – permitem o monitoramento básico em tempo real das alterações de ACL e podem ser usados para detectar o privilégio de nível de domínio “Add/remove replica in domain”. No entanto, o processo de análise desses eventos não é simples.
Além disso, encontrar e remover contas de computador (e MSA e gMSA) que estão obsoletas ou que não correspondem a uma máquina real na rede é importante. Por exemplo, você pode encontrar rapidamente contas de computador inativas ou não utilizadas com o PowerShell (substituindo “-90” pela idade máxima de conta de computador do seu domínio):
$Date = [DateTime]::Today.AddDays(-90); Get-ADComputer -Filter ‘(Enabled -eq $true) -and (PasswordLastSet -le $Date)’ | Select Name
Detectando exploração
Detectar o uso dessa técnica por um adversário envolve o monitoramento de alterações no atributo userAccountControl. O Evento Id 4742 – Computer Account Management pode ser usado para monitorar mudanças nos valores de userAccountControl. Qualquer modificação de userAccountControl com o bit 0x2000 definido fora de uma promoção esperada de controlador de domínio é preocupante.
Concluindo
Embora obviamente não seja tão grave quanto uma vulnerabilidade crítica, esses tipos de técnicas frequentemente passam despercebidas nas empresas e podem tornar o trabalho de um profissional de resposta a incidentes ainda mais difícil. Dada a baixa taxa de detecção nas ferramentas de auditoria do Active Directory que testamos, achamos que esta é uma técnica interessante que abusa de um comportamento menos conhecido que poderia facilmente passar despercebido. Agradecemos seus comentários e perguntas, e seríamos negligentes se não lhe indicássemos o nosso Attack Catalog, onde você pode aprender mais sobre como certos ataques funcionam.
Compartilhar em
Saiba Mais
Sobre o autor
Joe Dibley
Pesquisador de Segurança
Pesquisador de Segurança na Netwrix e membro da Equipe de Pesquisa de Segurança da Netwrix. Joe é um especialista em Active Directory, Windows e uma ampla variedade de plataformas de software empresarial e tecnologias, Joe pesquisa novos riscos de segurança, técnicas de ataque complexas e as respectivas mitigações e detecções.
Saiba mais sobre este assunto
Exemplo de Análise de Risco: Como Avaliar Riscos
O Triângulo da CIA e Sua Aplicação no Mundo Real
Criar usuários do AD em massa e enviar suas credenciais por e-mail usando PowerShell
Como adicionar e remover grupos AD e objetos nos grupos com PowerShell
Atributos do Active Directory: Último Logon