O Active Directory (AD) continua a ser a joia da coroa da infraestrutura empresarial e, para os autores de ameaças, o Santo Graal é claro: obter privilégios de administrador de domínio. Este nível de privilégios confere, efetivamente, controlo total sobre o seu ambiente. A proteção da identidade desempenha, portanto, um papel fundamental na segurança empresarial, e as organizações investem grandes esforços para impedir que os autores de ameaças obtenham acesso às credenciais dos administradores.
Mas e se os atacantes pudessem simplesmente induzir os controladores de domínio (DCs) em erro, levando-os a identificá-los como outra pessoa?
Há algum tempo, assisti a uma palestra de Yossi Sassi sobre técnicas de persistência no Active Directory. Sassi apresentou um conceito com o qual eu ainda não me tinha deparado: a possibilidade de adicionar caracteres Unicode «invisíveis» aos atributos dos objetos. Ele apresentou esta possibilidade como uma técnica de persistência que permite a criação de utilizadores que parecem ter o mesmo nome que outros utilizadores legítimos já existentes. Esta técnica pode confundir as equipas de segurança e de TI e atrasar consideravelmente as investigações.
O tema despertou a minha curiosidade. Perguntei a mim mesmo:
- O Active Directory aceita outros caracteres «invisíveis»?
- Como é que se poderia detetar eficazmente a utilização indevida destas personagens?
- Os caracteres ocultos têm outras utilidades, para além da persistência?
Este artigo detalha a minha investigação sobre estas questões, que conduziu à descoberta de duas novas vulnerabilidades de escalonamento de privilégios no Active Directory: KerberLoss (CVE-2026-25177) e ResetNightmare (CVE-2026-27912). Cada vulnerabilidade utiliza uma abordagem única para causar confusão de identidade nos controladores de domínio (DCs), resultando em vários impactos. A segunda (e mais grave) vulnerabilidade permite que um utilizador com privilégios reduzidos obtenha instantaneamente privilégios de administrador de domínio.
Pesquisa inicial: Unicode e Active Directory
As minhas perguntas levaram-me a uma investigação interessante sobre o Unicode e o processamento LDAP do lado do servidor. Comecei por pesquisar na Internet os caracteres Unicode que podem parecer invisíveis e por compilá-los numa lista. Estava particularmente interessado nos caracteres que parecem invisíveis nos nomes dos objetos, pois essa parecia-me a forma mais interessante de abusar desta técnica.
Para dar início aos meus testes, criei uma conta de utilizador de exemplo com o nome UniqueUser. Como era de esperar, não foi possível criar outra conta de utilizador com o mesmo nome (Figura 1).

No entanto, ao utilizar um caractere «invisível», consegui criar uma conta de utilizador aparentemente idêntica (Figura 2).

A Figura 2 mostra que a consola do PowerShell interpreta a conta resultante como tendo um espaço estranho (antes de «ser»). No entanto, ao observar as duas contas nas ferramentas gráficas de gestão do AD, estas parecem idênticas (Figura 3).

Utilizando este método básico, percorri a minha lista de caracteres Unicode, criando contas de utilizador com cada um deles. Como mostra a Figura 4, alguns dos caracteres foram analisados de uma forma estranha, e definitivamente não invisível, no AD.

Depois de limpar tudo isto, fiquei com um diretório semelhante ao da Figura 5.

Além disso, embora o meu script tenha ignorado alguns caracteres porque o DC não os aceitava, também ignorou outros porque o DC interpretou o nome de utilizador como já existente. (Em retrospetiva, isto era um indício.) Para testar o maior número possível destes caracteres sem estar limitado por restrições de exclusividade, criei também mais nomes de utilizador (Figura 6), cada um representando um caractere invisível único escondido entre dois traços («–»).

Nessa altura, estava convencido de que a minha lista de 385 caracteres invisíveis respondia à minha primeira questão de investigação. Agora, era altura de enfrentar o desafio da deteção.
Uma abordagem diferente à deteção
Na sua apresentação original, Sassi apresentou uma ferramenta que pode ser utilizada para detetar caracteres Unicode ocultos em objetos do AD. Fiquei interessado em compreender como essa ferramenta funciona. O script adota uma abordagem simples:
- Crie um dicionário com 29 personagens «invisíveis».
- Obter todas as propriedades de todos os objetos no domínio.
- Percorra cada atributo.
- Converte o atributo numa matriz de caracteres.
- Recupere o valor hexadecimal de cada carácter e compare esse valor com o dicionário.
Esta abordagem é abrangente. No entanto, tenho uma preferência por detecções que possam ser executadas de forma rotineira e eficiente em ambientes de produção, pelo que me perguntei se a filtragem poderia ser feita diretamente nas próprias solicitações LDAP (ou seja, do lado do servidor), em vez de processar cada carácter individualmente do lado do cliente.
Para descobrir, comecei por fazer um teste simples para determinar se o DC conseguia processar estes caracteres «tal como estão». Converti um caractere (0x200B) para a sua forma de cadeia de caracteres «invisível» e, em seguida, copiou-a e colou-a no PowerShell (Figura 7).

Até aqui, tudo bem! Ao colar o carácter diretamente num filtro LDAP, foi devolvido apenas o objeto esperado. No entanto, quando comecei a experimentar com caracteres diferentes, deparei-me com algumas situações mais estranhas.
Fiz o mesmo teste, mas desta vez usei a personagem 0x200C, que é outro carácter invisível. Como este carácter não passou nos testes de exclusividade de utilizador, não tinha nenhum utilizador com o nome Unique{0x200C}User no meu diretório naquele momento. No entanto, a minha consulta continuou a apresentar um resultado (Figura 8).

Quem tiver um olho mais atento poderá reparar que, desta vez, o resultado não apresenta aquele espaçamento estranho que observei ao apresentar estes caracteres na consola. Após verificar o utilizador devolvido pelo identificador de segurança (SID), confirmei que se tratava do nome de utilizador sem caracteres adicionais. O caractere Unicode no filtro foi ignorado, quer pelo PowerShell, quer pelo DC.
Se a minha teoria estivesse correta, então alterar a consulta para procurar qualquer objeto com o 0x200C O caractere deve apresentar todos os objetos presentes no diretório. Desta vez, converti o valor Unicode no console para tornar o texto mais legível (Figura 9).

Nesta altura, o comportamento do servidor LDAP não era consistente; alguns caracteres eram avaliados e outros eram ignorados. Ao procurar eliminar a possibilidade de a cadeia de filtro ser a origem do problema, deparei-me com a RFC 4515, que estabelece:
A representação em cadeia de caracteres de um filtro de pesquisa LDAP é uma cadeia de caracteres Unicode codificados em UTF-8
O RFC também apresenta alguns exemplos. Isso deu-me esperança de que seja possível converter e consultar qualquer carácter Unicode, independentemente da sua imprimibilidade. Com base no RFC, criei a seguinte função para receber um valor hexadecimal Unicode (por exemplo, 0x200B) e devolve a sua cadeia de caracteres compatível com o filtro LDAP (Figura 10).

Verifiquei se a minha função realizava corretamente a conversão utilizando o valor 0x200B, que consegui filtrar com sucesso nos meus testes anteriores (Figura 11).

Depois de verificar isto, passei a testar os meus caracteres problemáticos (Figura 12).

Infelizmente, mesmo seguindo o RFC não resultou. Ao utilizar este método para procurar os meus 385 caracteres invisíveis com LDAP, observei três categorias distintas de caracteres:
- Caracteres filtráveis: apenas 106 de um total de 385
- Caracteres tratados como espaços em branco: embora sejam invisíveis na interface gráfica, a função char devolve todos os nomes de objetos com espaços (por exemplo, «Domain Admins», «Print Operators»)
- Caracteres completamente ignorados pelo DC: char devolve todos os objetos
A essa altura, já estava demasiado envolvido. Tinha de saber se havia alguma forma de filtrar esses caracteres. Ao pensar em ideias sobre o que poderia ser alterado (para além da própria cadeia de filtro), perguntei-me se uma das Controlos Alargados do LDAP poderia ajudar. Ao analisar as diferentes opções, a única que me chamou a atenção foi LDAP_SERVER_SORT_OID. Embora a descrição do controlo mencione apenas a ordem de ordenação, A documentação da AD refere isso várias vezes que a presença do controlo também afeta o comportamento da comparação de cadeias de caracteres Unicode.
Para testar isto, criei uma função que me permitiu, de forma prática, adicionar o LDAP_SERVER_SORT_OID controlo e para consultar o LDAP com qualquer «OID de regra de ordenação» que eu escolhesse. Em seguida, recriei um cenário com o qual me deparei num Fórum da Microsoft. Criei dois utilizadores:
- Shai
- Shäi II
Repare na diferença entre «a» (Unicode 0x0061) e «ä» (Unicode 0x00E4).
Verifiquei a diferença entre consultar o LDAP sem o controlo alargado (que, por predefinição, utiliza o inglês dos EUA) e com o controlo e uma regra de ordenação «sueca». A segunda abordagem alterou, de facto, o resultado devolvido, e não apenas a ordem de classificação (Figura 13).

Este comportamento também ocorreu quando utilizei o meu Convert-UnicodeToLdapUtf8 função para converter «ä» no seu valor com escape UTF-8 (Figura 14).

Tinha esperança de que talvez um destes OIDs de regras de ordenação pudesse «filtrar o que não se pode filtrar» no que diz respeito à minha lista de caracteres invisíveis.
Escrevi um script que percorre cada regra de ordenação e consulta cada carácter não filtrável com base nessa regra. Cheguei à conclusão de que nenhuma regra de ordenação faz com que o DC «veja» qualquer um dos caracteres problemáticos.
Aqui terminou a minha investigação sobre os caracteres LDAP invisíveis do ponto de vista da deteção, deixando-me com um problema por resolver: existem caracteres Unicode que o servidor LDAP do Active Directory ignora completamente.
No entanto, este problema de deteção apresentava uma possibilidade ofensiva interessante.
Mudar de papel
Para recapitular rapidamente:
- Alguns caracteres Unicode não são analisados corretamente pelo Active Directory e, por isso, parecem estar invisíveis.
- Alguns destes caracteres não podem ser filtrados pelo LDAP, o que significa que, ao filtrar por um valor «normal», poderão ser devolvidos valores que contenham esses caracteres.
Essencialmente, existe um potencial para contornar as restrições de unicidade para qualquer atributo baseado em Unicode. Nos meus testes iniciais com SamAccountNamee cnAssim, verifiquei que o Active Directory bloqueia a criação de objetos duplicados que contenham caracteres não filtráveis (e com razão). No entanto, isso não se verificava em todos os atributos.
Em 2021, a Microsoft lançou uma correção para uma vulnerabilidade identificada como CVE-2021-42282. A correção introduziu três novas verificações de exclusividade:
- Exclusividade do Nome Principal do Utilizador (UPN)
- Exclusividade do Nome do Principal de Serviço (SPN)
- Exclusividade dos aliases SPN
Cada um destes valores deve ser único em toda a floresta, e todas as três verificações são aplicadas por predefinição a nível da floresta dSHeuristics atributo. Qualquer utilizador com privilégios inferiores aos de administrador do domínio receberá um «erro de exclusividade» ao tentar definir um valor que viole estas verificações de exclusividade.
No entanto, como poderá ver nas secções seguintes, os caracteres não filtráveis podem permitir que utilizadores com privilégios reduzidos contornem estas verificações. Esta é a primeira vulnerabilidade que descobri. Devido aos seus diversos impactos, denominei-a «KerberLoss»; a Microsoft atribuiu-lhe o código CVE-2026-25177.
KerberLoss: Começando com os SPNs
Para compreender o impacto desta vulnerabilidade, é necessário, em primeiro lugar, compreender devidamente os Nomes Principais de Serviço (SPNs).
O que são Nomes de Entidade de Serviço?
Os SPNs são um conceito do Active Directory frequentemente mal compreendido. Um SPN é a forma como o Kerberos identifica instâncias de serviço. No contexto do Active Directory, um serviço é qualquer recurso ao qual o utilizador acede e que, normalmente, requer autenticação. Entre os exemplos incluem-se partilhas de ficheiros SMB (cifs), ligações de Ambiente de Trabalho Remoto (TERMSRV), LDAP e HTTP… todos exemplos das chamadas «classes de serviço ».
Os serviços da mesma classe podem ser executados em diferentes anfitriões, e um anfitrião pode fornecer serviços de várias classes. Por conseguinte, um SPN deve incluir estes dois componentes, com a seguinte estrutura básica:
<service class>/<host>
Nota: Os SPNs podem também incluir dois componentes adicionais e opcionais, que estão fora do âmbito deste artigo.
Os conceitos básicos acima referidos são bastante conhecidos. No entanto, gostaria de salientar alguns pontos importantes:
- No mundo do Active Directory e do Kerberos, um serviço é hospedado por algum tipo de identidade. Esta pode ser uma conta de computador, uma conta de utilizador ou uma conta de serviço gerida, mas tem de existir uma identidade por trás do serviço. Isto deve-se aos princípios criptográficos em que o Kerberos se baseia. Os bilhetes de serviço são encriptados utilizando o segredo pertencente ao «serviço de destino» (ou seja, a sua identidade).
- O objeto que representa cada identidade no Active Directory possui um atributo denominado
servicePrincipalName, que é utilizado para gerir uma lista dos SPNs da identidade. - Ao solicitar um bilhete de serviço Kerberos, o Centro de Distribuição de Chaves (KDC) utiliza o SPN da solicitação para identificar o serviço de destino. Neste contexto, o serviço de destino é a identidade que detém o SPN relevante.
- Por fim, os bilhetes Kerberos contêm uma parte em texto simples e uma parte encriptada. O SPN encontra-se na parte em texto simples do bilhete. Como o SPN não está encriptado, podemos editá-lo nos bilhetes e transferi-los entre diferentes serviços da mesma identidade. O que importa é qual a chave que foi utilizada para encriptar o bilhete.
O que são os aliases SPN?
Se já alguma vez geriu um domínio do Active Directory, provavelmente reparou que cada computador tem alguns SPNs predefinidos, incluindo SPNs com o HOST classe de serviço (HOST/computer). Para quem não está familiarizado com eles, estes SPNs podem ser bastante confusos.
A partição de configuração do Active Directory contém um atributo denominado sPNMappings. Este atributo permite o mapeamento de SPNs para os chamados Aliases do SPN. Por predefinição, este atributo contém um único valor, que mapeia o HOST alias para os seguintes serviços:
alerter, appmgmt, cisvc, clipsrv, browser, dhcp, dnscache, replicator, eventlog, eventsystem, policyagent, oakley, dmserver, dns, mcsvc, fax, msiserver, ias, messenger, netlogon, netman, netdde, netddedsm, nmagent, plugplay, protectedstorage, rasman, rpclocator, rpc, rpcss, remoteaccess, rsvp, samss, scardsvr, scesrv, seclogon, scm, dcom, cifs, spooler, snmp, schedule, tapisrv, trksvr, trkwks, ups, time, wins, www, http, w3svc, iisadmin, msdtc
Quando adicionada ao domínio, cada conta de computador do Active Directory recebe um HOST classe SPN. Quando os utilizadores tentam aceder a um serviço mapeado para HOST (por exemplo, cifs, http), o KDC encripta o bilhete de serviço com a chave pertencente à conta com o correspondente HOST SPN.
Um caso-limite interessante
A verificação da exclusividade dos aliases SPN, já abordada anteriormente, impede a criação de SPNs mapeados que entrem em conflito. Por exemplo, se a floresta tiver um computador com o nome Server, que tem o HOST/Server SPN, atribuição do cifs/Server A ligação SPN a outro servidor será bloqueada, mesmo que o cifs/Server O SPN não existe explicitamente.
Já referi que a vulnerabilidade descoberta consegue contornar esta verificação de exclusividade. Mas o que é interessante é que o algoritmo de pesquisa de SPN procura sempre primeiro um SPN explícito. O algoritmo só procura o alias mapeado do SPN se não for encontrado um SPN explícito.
Com esta introdução (bastante extensa) às SPNs, já dispõe dos conhecimentos necessários para compreender como é que esta vulnerabilidade pode ser explorada.
Demonstrar o impacto
Vou apresentar vários cenários. Para o efeito, vou utilizar um ambiente simples, que inclui três servidores membros do domínio:
- Servidor A
- Servidor B
- ServerC
O atacante está a operar como um utilizador sem privilégios chamado NotAdmin.
Cenário n.º 1: Ataque de negação de serviço a serviços mapeados para HOST
Para o nosso primeiro cenário, suponhamos que ServerB aloja uma importante partilha de ficheiros SMB. Os utilizadores que acedem à partilha solicitam bilhetes de serviço para cifs/SERVERB. Porque ServerB tem o HOST/SERVERB Por predefinição, o DC identifica o SPN como a conta que detém a chave de encriptação relevante para o serviço de destino. Se o utilizador NotAdmin tiver a permissão WriteSPN no ServerC, não podem adicionar o cifs/SERVERB SPN para isso, uma vez que a verificação da exclusividade do alias SPN impede esta ação (Figura 15).

No entanto, ao utilizar um carácter invisível e não filtrável e inseri-lo na cadeia de caracteres, o NotAdmin consegue adicionar com sucesso o SPN em conflito (Figura 16).

Como já era de esperar, o carácter não é totalmente invisível na consola do PowerShell. No entanto, é invisível quando se acede ao dsa.msc (Figura 17).

E, mais importante ainda, quando alguém consulta o LDAP para obter o cifs/SERVERB SPN, ServerC é o objeto que é devolvido (Figura 18).

Neste cenário, devido à precedência explícita do SPN que expliquei anteriormente, quando qualquer utilizador do domínio tentar aceder a ServerB através do SMB, O KDC irá encriptar o bilhete com ServerCa chave de. Quando o utilizador tenta utilizar este bilhete, ServerB não é possível descodificá-lo, o que resulta num KRB_AP_ERR_MODIFIED erro. Para o utilizador comum, isto pode aparecer como várias mensagens diferentes e ambíguas:
- O nome de rede indicado já não está disponível.
- O nome da conta de destino está incorreto.
- Não é possível encontrar o caminho «path», uma vez que este não existe.
A remoção do SPN falso restabelece imediatamente o acesso normal (Figura 19).

Ter a permissão WriteSPN em qualquer uma conta de computador ou de utilizador na floresta permitiu a realização de um ataque de negação de serviço (DoS) contra qualquer HOST- serviço mapeado na floresta, utilizando caracteres não filtráveis. Figura 20 ilustra este cenário.

HOST- serviços mapeadosCenário n.º 2: SPN-jacking
Outra oportunidade interessante prende-se com os ataques de delegação restrita do Kerberos, uma vez que a delegação restrita clássica é configurada através de SPNs. Para demonstrar isto, modifiquei um cenário do blogue de Elad Shamir sobre o «SPN-jacking».
Nota: Este cenário pressupõe a compreensão dos ataques de delegação do Kerberos (ou seja, «o ataque S4U completo»). Uma explicação sobre a delegação do Kerberos está fora do âmbito deste artigo.
Na sua publicação, Shamir apresentou o seguinte cenário, no qual um atacante com acesso de administrador a ServerA pretende obter acesso de administrador a ServerC. ServerA está configurado para delegação restrita a cifs/ServerB, e o atacante tem direitos WriteSPN sobre ServerB e ServerC (Figura 21).

Shamir sugeriu resolver a verificação da exclusividade dos aliases SPN recorrendo ao WriteSPN em ambos ServerB e ServerC, removendo temporariamente o HOST/SERVERB SPN de ServerB, e só depois adicionar cifs/SERVERB para ServerC. Agora, o atacante pode executar o ataque S4U completo utilizando ServerAa conta de… para obter um ticket de assistência para um utilizador com privilégios para ServerC, antes de reverter as alterações.
Utilizando o KerberLoss, em combinação com a precedência explícita do SPN, um atacante pode eliminar a necessidade de utilizar o WriteSPN no serviço intermédio. Para demonstrar isto, configurei o meu laboratório conforme ilustrado na Figura 22.

ServerBTal como no exemplo anterior de DoS, o atacante pode utilizar caracteres que não podem ser filtrados para provocar ServerC o cifs/SERVERB SPN, contornando a verificação de exclusividade e criando uma situação em que os bilhetes para cifs/SERVERB será encriptado com ServerCa chave de (Figura 23).

cifs/SERVERB retornos ServerCAgora, o atacante pode executar todo o fluxo do ataque S4U para obter um bilhete privilegiado para cifs/SERVERB (Figura 24).

cifs/ServerBConsegui obter com sucesso um bilhete de assistência para um utilizador administrador. Agora, vou verificar se o bilhete foi encriptado com sucesso com ServerCé a chave. Como o SPN se encontra na parte não encriptada do bilhete, posso alterá-lo para cifs/ServerC e aceder ao servidor. O acesso só funcionará se o bilhete estiver encriptado com ServerCé a chave, não ServerB’s (Figura 25).

ServerCCenário n.º 3: Redução do nível de autenticação
Já sabemos qual é o impacto da criação de SPNs mapeados em conflito. Mas e no caso de SPNs explícitos duplicados? Recordemos a nossa capacidade de DoS mapeada por HOST.
No caso de aliases SPN em conflito, quando é solicitado um bilhete de serviço, é identificado um SPN e é criado um bilhete de serviço. Do ponto de vista do DC, o Kerberos funcionou; o efeito DoS ocorre porque o próprio recurso não é possível descodificar o bilhete, o que resulta num KRB_AP_ERR_MODIFIED erro. No entanto, se criarmos uma cópia exata de um SPN, o resultado é diferente.
No caso de duplicados explícitos de SPN, quando é solicitado um bilhete de serviço, o DC encontra duas contas que possuem o SPN. Nesta situação, o DC não consegue «escolher» que chave deve ser utilizada para o bilhete e, assim, devolve um KDC_ERR_S_PRINCIPAL_UNKNOWN erro. Desta vez, o DC devolve o erro, indicando que a autenticação Kerberos falhou e levando o cliente a recorrer ao NTLM.
Isto significa que, ao dispor da permissão WriteSPN em qualquer computador ou conta de utilizador na floresta, além de poder provocar uma falha de serviço (DoS) total em qualquer serviço mapeado por HOST na floresta, seria possível forçar qualquer serviço na floresta, quer esteja mapeado por HOST ou não, a utilizar apenas NTLM (a menos que esta opção esteja desativada, o que resultaria numa falha de serviço).
Do ponto de vista do utilizador, o acesso normal parece manter-se (Figura 26, Figura 27).

HOST SPN: o acesso em si continua a funcionar
A Figura 28 ilustra este cenário.

ResetNightmare: E quanto aos UPNs?
Na procura de um método direto de escalonamento de privilégios, recorri aos Nomes Principais de Utilizador (UPNs). Tendo em conta que a verificação da unicidade dos UPNs é controlada pelo mesmo mecanismo que a verificação da unicidade dos SPNs, presumi, corretamente, que poderia ser contornada da mesma forma (Figura 29).

A verificação de exclusividade foi corrigida juntamente com uma série de outras vulnerabilidades descobertas por Andrew Bartlett, sendo a mais notável o ataque Dollar Ticket/noPac (CVE-2021-42287 + CVE-2021-42278), que permitia a qualquer utilizador obter instantaneamente privilégios de administrador de domínio. Como o ataque envolvia uma confusão na nomenclatura do DC, esperava que o KerberLoss abrisse a porta para reativar esta vulnerabilidade ou para descobrir uma semelhante. Para esta e todas as minhas outras ideias, tive de compreender se, e em caso afirmativo, de que forma, o Kerberos utiliza os UPNs.
Tipos de nomes Kerberos
No Kerberos, um identificador de entidade é composto por um Realm e um PrincipalName. A PrincipalName está estruturado da seguinte forma:
PrincipalName ::= SEQUENCE {
name-type [0] Int32,
name-string [1] SEQUENCE OF KerberosString
}
O name-string O campo especifica o nome como uma cadeia de caracteres Kerberos. No entanto, o name-string por si só não é suficiente para identificar um mandante. O name-type O campo especifica o tipo do nome, o que, em termos simples, significa qual atributo Este campo é analisado em primeiro lugar para identificar o principal. O protocolo Kerberos ([RFC4120], secção 6.2) define vários valores possíveis para este campo.
O Active Directory utiliza normalmente o NT-PRINCIPAL tipo de nome para identificar clientes Kerberos, e corresponde à conta SamAccountName. Ao enviar pedidos de Ticket Granting Ticket (TGT) do Kerberos, também é possível utilizar o NT-ENTERPRISE nome do tipo, que identifica as contas pelo seu UserPrincipalName (UPN). O nome real do cliente no ticket resultante pode ser o SamAccountName (NT-PRINCIPAL) ou a UPN (NT-ENTERPRISE), e isto é normalmente controlado pelo Name-canonicalize bandeira.
Felizmente, ferramentas comuns do Kerberos, como o Rubeus e o Impacket, já incluem a funcionalidade de especificar que tipo de nome deve ser utilizado no pedido de TGT, pelo que consegui solicitar bilhetes com o NT-ENTERPRISE nome-tipo.
No entanto, quando tentei solicitar bilhetes com o meu UPN duplicado, o DC continuou a tentar autenticar-me como o destinatário com privilégios, o que provocou um erro de «falha na pré-autenticação» (Figura 30).

Isto funcionou ao remover o UPN do DemoAdmin1 , mas este método exigiria ter permissões de escrita sobre o alvo, o que não é viável para a escalada de privilégios (Figura 31).

Pouco tempo depois, encontrei uma solução para este problema: em vez de contornar a verificação da exclusividade do UPN utilizando caracteres que não podem ser filtrados, basta definir o meu UPN como SamAccountName do meu alvo. Isto é permitido, uma vez que as cadeias de caracteres não são idênticas (Figura 32).

SamAccountNameAgora, a tentativa de solicitar um bilhete para o DemoAdmin1 utilizando a palavra-passe do UPNUser irá falhar, como seria de esperar. Mas, ao alterar o tipo de nome para NT-ENTERPRISE, posso obter um bilhete em nome do DemoAdmin1 (Figura 33).

Este método permitiu-me, essencialmente, obter um bilhete com o nome de qualquer utilizador que eu quisesse. Com base nisso, tentei encontrar outra vulnerabilidade de confusão, através de vários métodos, incluindo:
- AS-REQ normal para TGS-REQ
- Fluxo do ataque «Modified Dollar Ticket»
- S4U2: Abuso de si próprio
- Abuso do Kerberos no U2U
- Ataque DoS ao início de sessão do utilizador, tal como referido por Andrew Bartlett
- Ativar a correspondência hard/soft no SyncJacking
- Prioridade do UPN entre domínios
No entanto, todas as minhas tentativas de explorar os UPNs para escalar privilégios falharam. Dependendo do método e da ferramenta específicos, recebia constantemente erros ou um ticket direcionado ao utilizador correto, sem privilégios. Analisei este comportamento para perceber o motivo.
A correção para o CVE-2021-42287
Como já foi referido, a vulnerabilidade «Dollar Ticket» provocava uma confusão na atribuição de nomes, semelhante ao que eu estava a tentar conseguir aqui. A Microsoft corrigiu a vulnerabilidade adicionando duas funcionalidades importantes ao Kerberos:
- Os TGTs devolvidos incluirão sempre um Certificado de Atributos Privilegiados (PAC), mesmo que o cliente tenha solicitado um bilhete sem PAC.
- O PAC nos TGTs inclui agora um campo denominado
PAC_REQUESTOR_SID, que contém o SID do cliente que solicitou o bilhete.
Isto PAC_REQUESTOR_SID valor deve e, em seguida, ser validados durante o TGS Exchange, invalidando o antigo vetor de ataque, no qual o atacante eliminava a conta que tinha solicitado o TGT, levando o DC a pensar que o TGT pertencia, em vez disso, ao DC com um nome semelhante.
Este (excelente) patch teve o efeito secundário, um pouco incómodo, de invalidar todas as minhas tentativas de escalonamento de privilégios através da confusão de UPN. O PAC passava agora a conter sempre o meu SID original, e o DC ignorava completamente o nome do cliente no meu bilhete, baseando-se exclusivamente no SID como fonte de referência do bilhete.
Quando já estava prestes a desistir de tentar escalar privilégios utilizando UPNs, decidi rever pela última vez a minha lista de ideias de exploração, verificando se cada uma delas poderia funcionar. Foi então que me deparei com algo interessante.
Descoberta: (Ab)uso do protocolo Kerberos de alteração de palavra-passe
Por predefinição, todos os utilizadores do Active Directory podem alterar a sua própria palavra-passe. Uma forma de o fazer é utilizar o Protocolo Kerberos de Alteração e Definição de Palavra-passe da Microsoft, que especifica como as alterações de palavra-passe são realizadas através do Kerberos. O protocolo é extremamente simples (o RFC tem apenas 7 páginas), contendo uma única mensagem de pedido e uma única mensagem de resposta.
A Microsoft utiliza as expressões «alterar palavra-passe» e «definir palavra-passe» para distinguir, respetivamente, entre um utilizador que altera a sua própria palavra-passe e um administrador que define a palavra-passe de um utilizador.
O protocolo recebe mensagens na porta 464 (kpasswd), com a estrutura do pedido apresentada na Figura 34.

As duas partes principais desta mensagem são a mensagem KRB-PRIV e a estrutura AP-REQ.
A mensagem KRB-PRIV é, essencialmente, apenas uma forma de enviar dados encriptados. Permite também a inclusão de dados personalizados. O protocolo tira partido desta característica, colocando o valor da nova palavra-passe dentro desta estrutura (Figura 35).

A parte mais interessante é a estrutura AP-REQ. Esta estrutura contém um bilhete e um autenticador, que comprova a posse legítima do bilhete, uma vez que este é encriptado utilizando a sua chave de sessão (Figura 36).

Na maioria dos casos com o Kerberos, um TGS_REQ/TGS_REP resulta num bilhete de serviço (e na chave de sessão correspondente). Esta resposta é então utilizada para construir a mensagem AP_REQ, que é enviada ao serviço para comprovar a posse do bilhete.
No caso do protocolo de alteração de palavra-passe do Kerberos, o bilhete na estrutura AP-REQ deve ter como âmbito o kadmin/changepw SPN. No entanto, trata-se de um SPN pertencente à conta krbtgt, e sabemos que o único aspeto relevante é a chave de encriptação, pelo que um bilhete para kadmin/changepw é apenas um TGT cujo SPN (sname) foi alterado.
Isto significa que tudo o que precisamos para alterar a palavra-passe de um utilizador é o seu TGT. Significa também que o fluxo do processo de alteração da palavra-passe de um utilizador através do Kerberos é o ilustrado na Figura 37.

O que é interessante é que este fluxo passa diretamente de um TGT-REQ para um AP-REQ, sem um TGS-REQ intermédio. Lembrem-se do patch que analisámos anteriormente: O TGS-REQ é onde o PAC_REQUESTOR_SID a validação é efetuada.
Tendo em conta que já podia solicitar um TGT com qualquer nome de utilizador (utilizando o NT-ENTERPRISE nome tipo), se o PAC_REQUESTOR_SID Se a correção não tiver sido implementada aqui, o protocolo poderá estar potencialmente vulnerável.
Combinando todo o conhecimento que adquiri nos meus testes anteriores, decidi sentar-me para experimentar. Tendo em conta que, por predefinição, todos os utilizadores do Active Directory têm permissões para alterar a sua própria palavra-passe, a minha ideia de exploração era a seguinte:
- Um atacante conseguiu aceder a uma conta de utilizador denominada UPNUser, sem quaisquer permissões especiais para além da capacidade de alterar o seu próprio valor UPN.
- O atacante define o UPN do utilizador como
SamAccountNameda conta visada; por exemplo, DemoAdmin1.
Esta ação não requer que se contorne as verificações de exclusividade da UPN. DemoAdmin1O UPN real deveria ser DemoAdmin1@demo.lab, pelo que definir UPNUserda UPN para apenas DemoAdmin1 é permitido (Figura 38).

- O atacante solicita um TGT para
kadmin/changepwespecificando DemoAdmin1 como nome de utilizador,NT-ENTERPRISEcomo o tipo de nome, e Palavra-passe do utilizador UPN. - O DC devolve um TGT_REP com um TGT para o UPNUser (conforme indicado por
PAC_REQUESTOR_SIDno PAC), mas com o nome de utilizador DemoAdmin1(NT_ENTERPRISE), como Figura 39 espectáculos.

NT-ENTERPRISE É devolvido o tipo «nome»- A utilização deste bilhete para emitir um pedido de alteração de palavra-passe irá repor a palavra-passe do UPNUser. Para escalar privilégios, o atacante altera ou apaga o valor UPN do UPNUser, de modo a que nenhum utilizador com esse UPN conste no bilhete.
- Tentar utilizar este bilhete para um TGS_REQ após a alteração do UPN resultará num
KDC_ERR_TGT_REVOKEDerro, devido aoPAC_REQUESTOR_SIDcorreção, que impede a falsificação de identidade. No entanto, ao utilizar este bilhete para criar o pedido de alteração da palavra-passe, a alteração da palavra-passe funciona. - Agora, o atacante pode solicitar um novo TGT para DemoAdmin1, sem especificando o
NT-ENTERPRISEtipo de nome. O pedido já funciona e o tipo de nome do bilhete é NT-PRINCIPAL, indicando que o bilhete pertence ao verdadeiro (SamAccountName) DemoAdmin1 utilizador (Figura 40).

Sucesso! Basta ter a capacidade de escrever um UPN para que tenhamos comprometido o domínio.
Denominei esta vulnerabilidade «ResetNightmare»; foi-lhe atribuído o código CVE-2026-27912. A vulnerabilidade permite a tomada de controlo total do domínio por parte de um atacante que possua permissões genéricas de escrita sobre qualquer objeto de utilizador ou computador no domínio, ou que possa criar objetos de utilizador ou computador no domínio (excluindo o MachineAccountQuota).
A Figura 41 ilustra o fluxo de utilização abusiva do ResetNightmare.

O único outro requisito é que a palavra-passe do utilizador em questão tenha uma antiguidade suficiente. No entanto, a duração mínima predefinida da palavra-passe no Active Directory é de 1 dia, pelo que é altamente provável que a palavra-passe do utilizador em questão cumpra este requisito.
Como bónus (graças a Andrea Pierini), esta vulnerabilidade também pode ser combinada com a técnica «Shadow Credentials», permitindo uma via de ataque mais discreta através do abuso de contas de computador com direitos de escrita.
Criei também uma ferramenta comunitária de código aberto, a ResetNightmare, que implementa todo o fluxo do ataque ResetNightmare, incluindo diferentes parâmetros para personalizar a execução. A ferramenta foi escrita em PowerShell e utiliza o Rubeus.exe e o módulo ActiveDirectory do PowerShell (Figura 42). Pode encontrar a ferramenta no GitHub.

Detecção e defesa contra o KerberLoss e o ResetNightmare
Os clientes do Semperis Directory Services Protector (DSP) podem utilizar os seguintes novos indicadores de segurança para detetar várias configurações incorretas mencionadas neste artigo:
- A verificação da exclusividade do UPN ou do SPN está desativada
- Objetos que contêm caracteres Unicode ocultos
- Objetos duplicados suspeitos que utilizam caracteres Unicode ocultos
- Entidade principal sem privilégios capaz de definir um nome de entidade de serviço
- Entidade principal sem privilégios capaz de definir um nome de entidade principal de utilizador
Além disso, os clientes do DSP podem detetar alterações anómalas nos SPN e UPN através de dois indicadores de comprometimento (IoCs):
- Foi adicionado um Nome Principal de Serviço (SPN) em conflito (CVE-2026-25177)
- Foi adicionado um Nome Principal do Utilizador (User Principal Name) que coincide com o nome da conta SAM de outra conta (CVE-2026-27912)
Sem o « DSP », a melhor forma de detetar o uso indevido de ambas as técnicas consiste em configurar as SACLs para auditar as modificações nos objetos do Active Directory. Quando as SACLs estão configuradas, o ID de evento 5136 do registo de segurança («Um objeto do serviço de diretório foi modificado») nos controladores de domínio (DCs) pode ser utilizado para detetar alterações que conduzam ao impacto da vulnerabilidade.
No KerberLoss, a entrada com o ID de evento 5136 indicará a adição de um ServicePrincipalName que entra em conflito com um já existente (Figura 43).

No ResetNightmare, a entrada com o ID de evento 5136 indicará a adição de um UserPrincipalName que corresponde a um SamAccountName (Figura 44).

A melhor forma de prevenção contra estas vulnerabilidades consiste na aplicação de correções em todos os servidores de domínio (DCs). A Microsoft lançou correções para o KerberLoss (CVE-2026-25177) em março de 2026 e para o ResetNightmare (CVE-2026-27912) em abril de 2026.
Para além das correções, as organizações devem respeitar o princípio do privilégio mínimo e monitorizar a adição anómala de permissões que não sejam as predefinidas. Permissões mais restritas podem tornar mais difícil o abuso destas vulnerabilidades.
Calendário de divulgação
- 26 de novembro de 2025: A vulnerabilidade «KerberLoss» é descoberta e comunicada ao MSRC.
- 17 de dezembro de 2025: O ResetNightmare é descoberto e comunicado ao MSRC.
- 9 de janeiro de 2026: O MSRC confirma que o ResetNightmare funciona tal como relatado.
- 17 de janeiro de 2026: O MSRC confirma que o KerberLoss funciona tal como relatado.
- 10 de março de 2026: A Microsoft corrige a vulnerabilidade KerberLoss (CVE-2026-25177) na «Patch Tuesday», classificando-a como uma vulnerabilidade importante de elevação de privilégios.
- 14 de abril de 2026: A Microsoft corrige a vulnerabilidade ResetNightmare (CVE-2026-27912), classificada como uma vulnerabilidade importante de elevação de privilégios.
Agradecimentos
Um agradecimento especial aos seguintes investigadores, que serviram de grande inspiração para várias partes deste trabalho de investigação:
- Yossi Sassi (@Yossi_Sassi)
- Andrew Bartlett
- Elad Shamir (@elad_shamir)
- Charlie Clark (@exploitph)
- Will Schroeder (@harmj0y)
- Andrea Pierini (@decoder_it)
- Benjamin Delpy (@gentilkiwi)
Mais recursos
- Biblioteca de Investigação sobre Segurança de Identidade da Semperis
- Catálogo de Ameaças à Identidade da Semperis
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.
