Charlie Clark

Enquanto brincava com bilhetes Kerberos, descobri um problema que me permitia autenticar noutros domínios de uma floresta do Active Directory (AD) através de relações de confiança externas não transitivas. Isto significa que não existe, de facto, uma "confiança não transitiva". O termo é, na melhor das hipóteses, enganador e oferece aos administradores de sistemas uma falsa sensação de segurança. Como parte do problema discutido nesta publicação, os atacantes podem autenticar-se noutros domínios através de uma confiança não transitiva e potencialmente elevar os privilégios dentro da floresta do domínio de confiança. Este post detalha o problema descoberto.

Depois de comunicar este problema à Microsoft, recebi a seguinte resposta:

Figura 1. Resposta da MSRC
Figura 1. Resposta da MSRC

Como a Microsoft determinou que o problema não afecta a segurança e, por isso, não planeia alterar o comportamento, não há forma de evitar o problema - para além de simplesmente não utilizar relações de confiança externas.

Trusts e transitividade

Nota: Esta publicação pressupõe um conhecimento básico sobre trusts e o seu funcionamento. (Para obter mais informações sobre esses tópicos, sugiro a leitura do excelente post de Will Schroedersobre trusts). O post não cobre trusts intra-floresta (ou seja, trusts dentro de uma única floresta) - a não ser quando se aplicam ao caminho de ataque específico discutido - ou trusts de autenticação seletiva - que são incrivelmente raros em ambientes reais.

As restantes fidedignidades são fidedignidades florestais e fidedignidades externas.

  • As relações de confiança de floresta são relações de confiança entre duas florestas. Mais exactamente, são relações de confiança transitivas entre os domínios raiz de duas florestas. Qualquer utilizador de qualquer domínio da floresta de confiança pode autenticar-se em qualquer domínio da floresta de confiança.
  • As relações de confiança externas são relações de confiança entre dois domínios. Estas relações de confiança não são transitivas. Apenas os utilizadores do domínio de confiança podem autenticar-se apenas no domínio de confiança(Figura 2).
Figura 2. Confiança externa não-transitiva
Figura 2. Confiança externa não-transitiva

A Microsoft descreve a transitividade da confiança da seguinte forma:

A transitividade determina se um trust pode ser alargado para além dos dois domínios com os quais foi formado.

  • Uma confiança transitiva pode ser utilizada para alargar as relações de confiança com outros domínios.
  • Uma confiança não-transitiva pode ser utilizada para negar relações de confiança com outros domínios.

Esta descrição é clara: para as relações de confiança não transitivas, apenas os dois domínios envolvidos na confiança podem autenticar-se mutuamente e não para além disso.

Infelizmente, como demonstrarei neste post, não é esse o caso.

Configuração do laboratório

Para demonstrar correctamente a questão da confiança não transitiva, configurei o laboratório com várias florestas multi-domínio que partilham confianças externas(Figura 3).

Figura 3. Configuração do laboratório
Figura 3. Configuração do laboratório

Esta configuração envolve três (3) florestas. Duas (2) das florestas contêm três (3) domínios. A terceira floresta contém dois (2) domínios. Os domínios semperis.lab e treetest.lab partilham uma confiança externa bidireccional não transitiva(Figura 4).

Figura 4. Confiança externa 1
Figura 4. Confiança externa 1

Os domínios grandchild1.child1.semperis.lab e semperisaz.lab também partilham uma confiança externa bidireccional não transitiva(Figura 5).

Figura 5. Confiança externa 2
Figura 5. Confiança externa 2

Esta configuração permite demonstrar as implicações e limitações da questão da confiança não transitiva.

Como funciona a autenticação de confiança cruzada Kerberos

Para se autenticar num serviço através de uma relação de confiança utilizando o Kerberos, é necessária uma referência (também conhecida como bilhete de concessão de bilhete de referência [TGT]). Este é um bilhete solicitado ao controlador de domínio local (DC) para o domínio estrangeiro. Para demonstrar como os pedidos de bilhete são executados entre relações de confiança, esta secção centra-se na floresta semperis.lab. No entanto, essas informações são aplicáveis a qualquer caminho de confiança "permitido".

Nota: Esta publicação pressupõe uma compreensão básica do fluxo normal de autenticação Kerberos. (Para uma explicação detalhada desse fluxo, consulte o post Detecting Kerberoasting Activity de Sean Metcalf). O restante do post usa o Rubeus para solicitar tickets manualmente.

O exemplo mais simples de autenticação de confiança cruzada é a autenticação de um serviço num domínio que tem uma confiança directa com o domínio local. A confiança que o domínio grandchild1.child1.semperis.lab tem com child1.semperis.lab(Figura 5) é um exemplo deste tipo de confiança. Nesta situação, após obter um TGT inicial, o primeiro passo para obter um bilhete de serviço para uma conta em grandchild1.child1.semperis.lab para um serviço em child1.semperis.lab é obter uma referência para child1.semperis.lab(Figura 6, Figura 7).

Figura 6. Pedido de referência para child1.semperis.lab
Figura 6. Pedido de referência para child1.semperis.lab
Figura 7. Pedido de referência
Figura 7. Pedido de referência

O pedido foi feito a um DC(SGC1DC1.grandchild1.child1.semperis.lab) dentro do domínio(grandchild1.child1.semperis.lab) local para o utilizador autenticador(lowpriv). O pedido foi efectuado para o serviço krbtgt/child1.semperis.lab. O facto de o ServiceRealm (srealm) ser o domínio local(grandchild1.child1.semperis.lab) no bilhete resultante mostra que este bilhete é uma referência.

Esta referência pode agora ser utilizada para solicitar bilhetes de serviço (STs) ao DC estrangeiro(SC1DC1.child1.semperis.lab) para o anfitrião de serviço/SC1DC1.child1.semperis.lab (Figura 8, Figura 9).

Figura 8. Exemplo de utilização de referência
Figura 8. Exemplo de utilização de referência
Figura 9. Pedido de ST com recurso a referência
Figura 9. Pedido de ST com recurso a referência

Para ir mais longe, se for necessário um serviço no domínio raiz da floresta(semperis.lab), não é possível solicitar directamente uma referência para este domínio a partir do domínio local(grandchild1.child1.semperis.lab). Uma referência para krbtgt/semperis.lab é solicitada ao DC local sgc1dc1.grandchild1.child1.semperis.lab. No entanto, o CD devolve um bilhete para o serviço krbtgt/child1.semperis.lab, indicando que este encaminhamento é para o domínio child1.semperis.lab, e não para semperis.lab (Figura 10, Figura 11).

Figura 10. Pedido de referência para semperis.lab
Figura 10. Pedido de referência para semperis.lab
Figura 11. Pedido de referência para semperis.lab
Figura 11. Pedido de referência para semperis.lab

Pode ver este problema ao tentar utilizar este pedido para solicitar um ST para o domínio semperis.lab. Fazer isso resulta em um erro AP_ERR_BAD_INTEGRITY. Isso ocorre porque o tíquete de referência é criptografado com a chave de confiança para a confiança grandchild1.child1.semperis.lab -> child1.semperis.lab. Os DCs no domínio raiz semperis.lab não têm conhecimento dessa chave e, portanto, não podem descriptografar o tíquete(Figura 12, Figura 13).

Figura 12. Pedido de ST do domínio raiz
Figura 12. Pedido de ST do domínio raiz
Figura 13. Pedido de ST a partir de semperis.lab
Figura 13. Pedido de ST a partir de semperis.lab

Para solicitar um tíquete de serviço para o domínio raiz semperis.lab, primeiro uma referência para semperis.lab deve ser solicitada a um DC no domínio child1.semperis.lab, usando essa referência. A Figura 14 e a Figura 15 mostram uma solicitação feita ao DC estrangeiro(sc1dc1.child1.semperis.lab), usando a referência para o domínio child1.semperis.lab para solicitar uma referência adicional para o domínio raiz semperis.lab.

Figura 14. Pedido de referência para semperis.lab
Figura 14. Pedido de referência para semperis.lab
Figura 15. Pedido de referência para semperis.lab
Figura 15. Pedido de referência para semperis.lab

Note-se que para solicitar este bilhete, o /domínio alvo é necessário. Por defeito, o Rubeus usa o domínio dentro do bilhete que lhe foi passado para preencher o domínio no TGS-REQ. Neste caso, esse domínio seria grandchild1.child1.semperis.lab e resultaria num erro ERR_WRONG_REALM porque o domínio local do DC é child1.semperis.lab. Esta informação será importante na próxima secção.

Por fim, essa referência resultante para semperis.lab pode ser usada para solicitar STs para o domínio semperis.lab. A Figura 16 mostra o pedido de ST feito pelo utilizador lowpriv@grandchild1.child1.semperis.lab ao DC SDC1.semperis.lab para o anfitrião SPN/SDC1.semperis.lab. Como o caminho de confiança é permitido, este pedido foi bem sucedido, apesar de os dois domínios envolvidos não terem uma confiança directa(Figura 17).

Figura 16. Pedido de ST para semperis.lab
Figura 16. Pedido de ST para semperis.lab
Figura 17. Pedido de ST para o anfitrião/sdc1.semperis.lab
Figura 17. Pedido de ST para o anfitrião/sdc1.semperis.lab

Este método de pedido de referências para domínios de confiança pode ser seguido para pedir STs para qualquer serviço dentro de qualquer domínio para o qual o caminho de confiança é permitido.

Tornar a confiança não transitiva transitiva

Então, como é possível atravessar relações de confiança externas para autenticar domínios que deveriam ser proibidos?

Os domínios semperisaz.lab e grandchild1.child1.semperis.lab têm uma confiança externa bidireccional. Por conseguinte, depois de obter um TGT para qualquer conta no domínio semperisaz.lab, é possível solicitar uma referência para grandchild1.child1.semperis.lab(Figura 18, Figura 19).

Figura 18. Referência a granchild1.child1.semperis.lab
Figura 18. Referência a granchild1.child1.semperis.lab
Figura 19. Pedido de referência para grandchild1.child1.semperis.lab
Figura 19. Pedido de referência para grandchild1.child1.semperis.lab

Essa referência pode ser usada para solicitar STs para serviços no domínio grandchild1.child1.semperis.lab. No entanto, uma tentativa de obter uma referência para outros domínios dentro da mesma floresta (por exemplo, child1.semperis.lab) retorna um erro ERR_PATH_NOT_ACCEPTED, como esperado(Figura 20).

Figura 20. Erro de caminho não aceite
Figura 20. Erro de caminho não aceite

Este erro ocorre porque a confiança semperisaz.lab -> granchild1.child1.semperis.lab não é transitiva. Portanto, o caminho de semperisaz. lab para child1.semperis.lab não é permitido(Figura 21).

Figura 21. Pedido de referência para child1.semperis.lab
Figura 21. Pedido de referência para child1.semperis.lab

No entanto, é possível solicitar um TGT local para grandchild1.child1.semperis.lab. Chamo a isto um TGT local porque, ao contrário da referência - que tem um ServiceRealm (srealm) de semperisaz.lab - oServiceRealm deste TGT é grandchild1.child1.semperis.lab(Figura 22, Figura 23).

Figura 22. Pedido de TGT local para grandchild1.child1.semperis.lab
Figura 22. Pedido de TGT local para grandchild1.child1.semperis.lab
Figura 23. Pedido de um TGT local
Figura 23. Pedido de um TGT local

Utilizando este TGT local, pode agora ser pedida uma referência para child1.semperis.lab(Figura 24, Figura 25).

Figura 24. Referência para child1.semperis.lab
Figura 24. Referência para child1.semperis.lab
Figura 25. TGT local para pedir encaminhamento para child1.semperis.lab
Figura 25. TGT local para pedir encaminhamento para child1.semperis.lab

Agora você tem uma referência utilizável que pode ser usada para solicitar STs para child1.semperis.lab, usando qualquer conta do domínio semperisaz.lab e sem fazer alterações em trusts ou contas no AD. A Figura 26 e a Figura 27 mostram um pedido de ST do DC sc1dc1.child1.semperis.lab para o serviço host/sc1dc1.child1.semperis.lab como o utilizador lowpriv@semperisaz.lab.

Figura 26. Pedido de ST para DC Em child1.semperis.lab
Figura 26. Pedido de ST para DC Em child1.semperis.lab
Figura 27. Pedido de ST para o anfitrião/sc1dc1.child1.semperis.lab
Figura 27. Pedido de ST para o anfitrião/sc1dc1.child1.semperis.lab

Além disso, esse método pode ser usado para percorrer qualquer domínio dentro da mesma floresta em que existe grandchild1.child1.semperis.lab. Podemos demonstrar isso solicitando uma referência para o domínio raiz semperis.lab. Foi solicitada uma referência para semperis.lab a partir do DC sc1dc1.child1.semperis.lab como o utilizador lowpriv@semperisaz.lab(Figura 28, Figura 29).

Figura 28. Pedido de referência para semperis.lab
Figura 28. Pedido de referência para semperis.lab
Figura 29. Pedido de encaminhamento para o semperis.lab
Figura 29. Pedido de encaminhamento para o semperis.lab

Felizmente, não é possível saltar entre outras relações de confiança fora da floresta (relações de confiança externas ou da floresta) usando este método. Como mostra a Figura 3, o domínio raiz semperis.lab tem uma confiança externa bidirecional com treetest.lab. Essa confiança pode ser usada para demonstrar essa limitação(Figura 30, Figura 31).

Figura 30. Pedido de referência para treetest.lab
Figura 30. Pedido de referência para treetest.lab
Figura 31. Pedido de referência para treetest.lab
Figura 31. Pedido de referência para treetest.lab

Isso pelo menos impede que um invasor que use esse método faça trust hopping em outra floresta. Ainda assim, esse problema de confiança não transitiva é claramente útil para invasores que tentam elevar privilégios dentro de uma floresta a partir de uma confiança. Os atacantes poderiam consultar informações de domínios supostamente não permitidos, consultar domínios mais sensíveis ou domínios com segurança potencialmente mais fraca, ou realizar ataques Kerberoasting ou coerção de autenticação NTLM em domínios que são assumidos como não permitidos.

Ir mais longe

Embora os atacantes não possam ir mais longe utilizando apenas o método descrito neste post, o problema pode abrir novas vias de ataque. Anteriormente, escrevi um post que demonstrava a capacidade de criar contas de máquinas através de relações de confiança e as implicações desse facto. Ao incorporar esse método de salto de domínio com este novo método, é possível ultrapassar a limitação descrita no final da secção anterior.

Usando a referência recuperada para semperis.lab (no final da seção anterior), é possível solicitar um ticket para o serviço LDAP em um DC em semperis.lab. Aqui, um ST para ldap/sdc1.semperis.lab foi solicitado usando a referência para semperis.lab como o usuário lowpriv@semperisaz.lab(Figura 32, Figura 33).

Figura 32. Pedido ST para ldap
Figura 32. Pedido ST para ldap
Figura 33. Pedido ST para ldap/sdc1.semperis.lab
Figura 33. Pedido ST para ldap/sdc1.semperis.lab

Este ST pode ser injectado e utilizado para criar uma conta de máquina directamente em semperis.lab se a configuração permitir Utilizadores Autenticados, que é a predefinição(Figura 34).

Figura 34. Criar uma conta de máquina em semperis.lab
Figura 34. Criar uma conta de máquina em semperis.lab

Esta acção faz com que o DC sdc1.semperis.lab crie a conta de máquina TestComp dentro do domínio semperis.lab(Figura 35).

Figura 35. Criar conta de máquina TestComp
Figura 35. Criar conta de máquina TestComp

A nova conta de máquina TestComp é uma conta local dentro do domínio semperis.lab. Agora, pode obter um TGT para essa conta de máquina(Figura 36, Figura 37).

Figura 36. Conta da máquina TGT
Figura 36. Conta da máquina TGT
Figura 37. Pedido de TGT para TestComp
Figura 37. Pedido de TGT para TestComp

Esta conta de máquina TGT tem permissão para solicitar uma referência para o domínio de confiança treetest.lab. A conta de máquina TGT pode ser utilizada para solicitar uma referenciação para o domínio treetest.lab a partir do DC SDC1.semperis.lab (Figura 38, Figura 39).

Figura 38. Pedido de referência para treetest.lab
Figura 38. Pedido de referência para treetest.lab
Figura 39. Pedido de referência para treetest.lab
Figura 39. Pedido de referência para treetest.lab

Por fim, o problema descrito nesta publicação pode ser usado para obter acesso ao domínio inacessível dsptest.lab. Primeiro, solicite um TGT local para treetest.lab. O TGT local é solicitado usando a referência para treetest.lab como a conta TestComp$@semperis.lab do DC TDC1.treetest.lab(Figura 40, Figura 41).

Figura 40. Pedido de TGT local para treetest.lab
Figura 40. Pedido de TGT local para treetest.lab
Figura 41. Pedido de TGT local para treetest.lab
Figura 41. Pedido de TGT local para treetest.lab

Em seguida, utilize este TGT local para solicitar uma referência para dsptest.lab. A Figura 42 e a Figura 43 mostram que foi pedida uma referência para o domínio dsptest.lab a partir do DC TDC1.treetest.lab como o utilizador TestComp$@semperis.lab.

Figura 42. Pedido de referência para dsptest.lab
Figura 42. Pedido de referência para dsptest.lab
Figura 43. Pedido de referência para dsptest.lab
Figura 43. Pedido de referência para dsptest.lab

Claramente, a combinação destes dois métodos pode tornar possível penetrar muito profundamente nas infra-estruturas empresariais do AD, utilizando qualquer conta de baixo privilégio num domínio que tenha uma confiança externa em qualquer domínio de uma floresta.

Detecção da vulnerabilidade da transitividade da confiança

Infelizmente, dada a resposta da Microsoft, a única forma de evitar o problema é remover as confianças externas.

Se não for possível remover todas as relações de confiança externas, terá de monitorizar o evento 4769 do Windows(Foi solicitado um bilhete de serviço Kerberos). A primeira indicação a procurar é que foi solicitado um TGT local a uma conta numa floresta diferente(Figura 44).

Figura 44. 4769 para TGT local
Figura 44. 4769 para TGT local

Aqui, o campo Domínio da conta é um domínio que pertence a uma floresta diferente e o Nome do serviço é krbtgt. Este evento é seguido por outro evento 4769, solicitando uma referência(Figura 45).

Figura 45. 4769 para encaminhamento
Figura 45. 4769 para encaminhamento

Aqui, o Domínio da conta é um domínio numa floresta diferente e o Nome do serviço é outro domínio na floresta local.

Observe que esses dois eventos podem ocorrer em DCs diferentes dentro do mesmo domínio. Os eventos não precisam ocorrer no mesmo DC. Nesta altura, qualquer ST solicitado (evento 4769) que utilize esta referência terá um Domínio de Conta que contém um domínio que não deve ser autorizado a autenticar no domínio local.

A monitorização destes eventos e a detecção deste tipo de ataque estarão disponíveis numa versão futura do Semperis Directory Services Protector (DSP).

Em quem é que se pode confiar?

Como pode ver, a descrição oficial das relações de confiança externas não transitivas é enganadora. Tal como está, quando cria uma confiança externa não transitiva, tem de aceitar que qualquer conta no domínio fidedigno será capaz de se autenticar em qualquer domínio em toda a floresta em que o domínio fidedigno reside.

Conforme demonstrado na secção "Saltando mais além" desta publicação, a melhor prática é não permitir que os utilizadores autenticados criem contas de máquina. Não o fazer não só coloca os domínios dentro da floresta em maior risco de ataque, mas também coloca quaisquer domínios (e a floresta em que residem) que tenham uma confiança externa com qualquer domínio dentro da floresta em maior risco devido à capacidade de criar contas de máquina através de confianças e autenticação contra domínios que não devem ser permitidos. (Mais informações sobre a quota de contas de máquina e como impedir a criação de contas de máquina com privilégios baixos podem ser encontradas na excelente publicação de Kevin Robertson"MachineAccountQuota is USEFUL Sometimes").

Espero que este post informe os administradores de sistemas sobre o risco real para toda a floresta envolvido na implementação de relações de confiança externas.

Linha do tempo

  • 4 de Maio de 2022: criação do processo MSRC
  • 12 de Maio de 2022: Estado do processo alterado para "Revisão/Reprovação"
  • 17 de Junho de 2022: O estado do caso foi alterado para "Em desenvolvimento" com um e-mail que indicava "Confirmámos o comportamento que comunicou. Continuaremos a nossa investigação e determinaremos como resolver este problema."
  • 17 de Junho de 2022: O estado do processo foi alterado para "Concluído - Resolvido"
  • 24 de Agosto de 2022: Comentário deixado no processo para saber o estado do processo
  • 2 de Setembro de 2022: Comentário de acompanhamento deixado no processo para saber o estado do processo
  • 14 de Setembro de 2022: Envio de correio electrónico de acompanhamento para saber o estado do processo
  • 29 de Setembro de 2022: Recebida uma mensagem de correio electrónico a explicar que o problema não foi considerado como afectando a segurança
  • 7 de Março de 2023: Divulgação pública

Agradecimentos

Saiba mais

Pretende mais investigação sobre segurança do AD? Consulte estes artigos.