Jake Hildreth Consultor Principal de Segurança

Na minha investigação recente, tenho vindo a analisar, de forma um pouco preguiçosa, os documentos de conceção da Infraestrutura de Chave Pública da Microsoft e os RFCs relacionados (em particular o RFC 4556), numa tentativa de encontrar um método fiável para escalar privilégios de um utilizador normal com privilégios reduzidos para qualquer conta arbitrária — sem erros de configuração. (Sim, é assim que passo o meu tempo livre. Estas questões são importantes para mim e para as pessoas com quem trabalho quando estamos a elaborar planos de preparação cibernética.)

Infelizmente, apesar de ter pesquisado em áreas semelhantes, não encontrei qualquer referência ao ataque Certighost na documentação, apesar de se tratar de uma vulnerabilidade conhecida dos Serviços de Certificados do Active Directory (AD CS).

Na verdade, não encontrei absolutamente nenhum método de escalada de privilégios.

No entanto, descobri um método de persistência pós-exploração baseado numa configuração incorreta que, embora não seja tão apelativo como o Certighost, é quase tão assustador.

  • Não requer acesso à chave privada de uma Autoridade de Certificação (um pré-requisito para um ataque do tipo «Golden Certificate» ou «Golden Ticket» ).
  • Isso vai contra as orientações generalizadas sobre como recuperar o acesso a contas comprometidas.
  • Ao contrário do Certighost, esta vulnerabilidade não será corrigida, uma vez que se baseia numa configuração documentada pela Microsoft, concebida para testes e resolução de problemas.

Se é responsável pela prevenção e resposta a violações de sistemas de identificação no seu ambiente, vai querer manter-se atento a esta questão.

Hoje, vou apresentar-vos os «Certificados Zumbis» — certificados de autenticação que não se deixam eliminar!

«Quem é este?» O processo de autenticação PKINIT

Num ambiente típico do Active Directory (AD), a principal forma de credencial de autenticação é a conhecida combinação de nome de utilizador e palavra-passe. O seu nome de utilizador é uma declaração sobre quem é; a sua palavra-passe verifica essa declaração.

No entanto, o AD também suporta a utilização de certificados de chave pública como credenciais de autenticação, frequentemente sob a forma de cartões inteligentes. Este processo de autenticação baseado em certificados denomina-se «Criptografia de Chave Pública para Autenticação Inicial», também conhecido como PKINIT. A implementação da PKINIT pela Microsoft está descrita na íntegra na especificação MS-PKCA, mas, resumidamente, em vez de encriptar os tickets relacionados com a autenticação (AS-REP/AS-REQ) com a sua palavra-passe, utiliza-se uma chave privada, controlada por si, para encriptar esses tickets.

Ao analisar a RFC 5280, secção 6.3.3, encontrei a definição do algoritmo sobre o que acontece quando um verificador não consegue determinar o estado de revogação:

Após o processamento dessas CRLs, se o estado de revogação ainda não tiver sido determinado, deve-se devolver o cert_status como UNDETERMINED.

«Conheço-te?» PKINIT no Active Directory

Quando tenta autenticar-se no AD com um certificado através do PKINIT, interage com um Controlador de Domínio (DC) que funciona como um Centro de Distribuição de Chaves Kerberos (KDC). Durante o PKINIT, o KDC verifica se o certificado que está a utilizar está atualmente válido para autenticação.

O KDC verifica vários atributos do certificado antes de confirmar «sim, reconheço-te», incluindo (entre outros):

  • Emitente: O KDC tem de confiar na Autoridade de Certificação (CA) que emitiu o certificado. Se o KDC não confiar no emitente do certificado, não vais conseguir entrar.
  • Utilização prevista: Os certificados incluem informações que explicam como podem ser utilizados (mais detalhes abaixo). Se tentares autenticar-te com um certificado destinado à assinatura de código, não vais conseguir aceder.
  • Período de validade: Se tentares autenticar-te hoje com um certificado que só é válido a partir de 20X6, não vais conseguir entrar. E se tentares autenticar-te hoje com um certificado que expirou em 1666, também não vais conseguir entrar.
  • Estado de revogação: Um emitente pode revogar um certificado ao incluí-lo numa Lista de Revogação de Certificados (CRL). Se tentares utilizar um certificado que conste numa CRL, muito provavelmente — como já deves ter adivinhado — não vais conseguir aceder.

Mas esse último ponto é um pouco complicado…

O que acontece se a CRL não estiver disponível? Afinal, as CRLs são normalmente publicadas como URLs HTTP em servidores web, e estes quase nunca têm um tempo de atividade perfeito.

Como já vimos, as RFC são claras quanto a esta questão. Quando uma CRL não está disponível, o KDC deve marcar o estado de revogação do certificado como «UNDETERMINED». O que não fica tão claro nas RFC e na documentação da Microsoft é o que «UNDETERMINED» significa no contexto do processo PKINIT.


Forçar o desconhecido

Ao criar deteções do ESC16 para Serralheiro e Serralheiro 2 (ferramentas da comunidade de código aberto que se podem encontrar no GitHub), fui apresentado ao DisableExtensionList configuração das autoridades de certificação (CA) dos Serviços de Certificados do AD (AD CS). Extensões são pequenos elementos de informação adicionados a um certificado que explicam qual é a finalidade do certificado e como este pode e deve ser utilizado.

Num servidor AD CS CA, o DisableExtensionList esta configuração é utilizada para impedir impedir que determinadas extensões sejam adicionadas aos certificados emitidos por uma CA. Geralmente, esta lista permanece vazia, mas é possível adicionar extensões à lista (e, consequentemente, removê-las dos certificados emitidos) para fins de teste, para melhorar a compatibilidade, para aumentar a segurança, etc.

Uma das extensões normalmente adicionadas a um certificado é a extensão «Ponto de Distribuição de CRL» (CDP), também conhecida como OID 2.5.29.31. A extensão CDP indica a um KDC (ou a qualquer outra entidade verificadora) exatamente onde encontrar o estado de revogação de um certificado.

Pergunta: O que acontece se eu adicionar a extensão CDP ao DisableExtensionList? Uma CA do AD CS emitiria um certificado sem a extensão CDP?

Resposta: Afinal de contas… sim! Quando o OID 2.5.29.31 existe no DisableExtensionList, todos os certificados emitidos pela CA não têm a extensão CDP, uma vez que Figura 1 espectáculos.

Figura 1: Um certificado típico e um certificado sem a extensão CDP

Agora, a questão mais importante: será que poderia utilizar um certificado sem a extensão CDP para executar com sucesso o PKINIT?

Infelizmente, não.

Durante o processo PKINIT, o KDC tenta verificar o estado de revogação do certificado apresentado. Sem a extensão CDP, o KDC não sabe onde verificar o estado do certificado. Responde com KDC_REVOCATION_UNKNOWN, e o pedido de autenticação é rejeitado. O certificado está inválido… por enquanto.

Esta resposta do tipo «fail-closed» é a forma como o AD está configurado para funcionar por predefinição, mas este comportamento não é imutável.


Ignorar o desconhecido

À medida que fui aprofundando o assunto, percebi que a Microsoft já tinha tido em conta a situação de inacessibilidade da CRL e criado um valor de registo para a resolver: UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors. Tal como o nome do valor sugere, quando UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors está definido para 1, as CRLs armazenadas em cache são utilizadas para verificar o estado de revogação (mais vale isso do que nada!) e os erros de revogação desconhecida são ignorados.

Então perguntei-me: se este valor do registo estiver definido e eu conseguir provocar um erro desconhecido, será que o PKINIT seria executado com sucesso?

Caro leitor, sinto-me simultaneamente muito triste e super entusiasmado por lhe comunicar que a resposta é um sonoro SIM.

Um único valor no registo altera todo o processo PKINIT, passando do modo «fail-closed» para o modo «fail-open».

Figura 2: És um «Good Cert» ou um «Bad Cert»?

Este comportamento perturba-me profundamente. Mas também faz todo o sentido. De acordo com a documentação de vários fornecedores (incluindo a Microsoft), este valor do registo pode ser utilizado para flexibilizar os controlos de segurança em situações como testes e resolução de problemas.

Não se destina a ser utilizado de forma permanente. Na verdade, indica ao KDC para deixar o portão destrancado para qualquer coisa que não consiga provar que está realmente inativa.


Esconder o desconhecido

Existe um efeito secundário interessante e inesperado associado a um certificado sem extensão CDP: pode ser revogado e adicionado à CRL de uma CA tal como qualquer outro certificado, mas a sua inclusão na lista é, essencialmente, insignificante.

Pense na CRL como um cemitério e em cada entrada de revogação como uma lápide. O certificado «zombie» tem uma lápide com o seu nome, mas o certificado não contém quaisquer indicações para chegar ao cemitério, pelo que ninguém vai lá verificar.

Parece morto, mas não está. É um Certificado Zumbi!

Isto representa um verdadeiro problema durante uma resposta a incidentes. Por vezes, durante a resposta a incidentes, é necessário reiniciar ou revogar todas as credenciais associadas a uma conta comprometida, incluindo palavras-passe e todos os certificados de autenticação.

O que acontece quando não é possível revogar um certificado de autenticação?


Fazer com que as peças se encaixem para uma persistência discreta

Nesta fase da minha investigação, já tinha observado alguns comportamentos diferentes:

  1. É possível criar certificados de autenticação sem uma extensão CDP.
  2. É impossível verificar o estado de revogação de um certificado que não possua uma extensão CDP.
  3. Sem uma extensão CDP, um certificado pode parecer revogado para a CA e para os seus administradores, mas essa aparência não tem qualquer significado se não for possível verificar o estado de revogação.
  4. Se um verificador não conseguir consultar o estado de revogação de um certificado (por qualquer motivo), o estado do certificado é «desconhecido», e não «revogado» ou «válido».
  5. Por predefinição, a implementação do PKINIT pela Microsoft rejeita certificados com um estado de revogação desconhecido.
  6. O comportamento predefinido de «fechado em caso de falha» pode ser alterado para «aberto em caso de falha» através da modificação de um único valor do registo.

Todas as peças estavam lá. Só precisava de deixar de tentar fazê-las andar.

Passei demasiado tempo a tentar juntar estes elementos comportamentais numa cadeia completa de escalada de privilégios, mas acabei por desistir. Parecia simplesmente impossível. Sem acesso administrativo ao anfitrião da CA ou ao serviço da CA, é impossível editar DisableExtensionList. Alterar o UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors A alteração de um valor do Registo nos servidores DC requer, normalmente, a pertença ao grupo BUILTIN\Administrators (BA) do domínio. Nenhuma das operações é possível sem permissões e privilégios pré-existentes.

Mas e se eu deixasse de me concentrar nas ESC (técnicas de escalada) e, em vez disso, começasse a pensar nas PERSIST (técnicas de persistência)?

No documento técnico da SpecterOps de 2021 ,intitulado «Certified Pre-Owned», os autores enumeraram várias opções de persistência ao nível do domínio, do utilizador e do computador, com base no AD CS. A persistência não é tão apelativa como a escalada de privilégios e raramente é destacada num teste de penetração típico. No entanto, os atacantes recorrem à persistência para recuperar o acesso a um ambiente que já tenham comprometido anteriormente.

É um aspeto importante a ter em conta!


Resumindo: Como os atacantes criam certificados «zombie»

Quando mudei a minha forma de pensar de «Tenho de encontrar um novo ESC!» para «O PERSIST também dá medo!», o quadro ficou mais claro e, sinceramente, assustou-me um pouco. Imagina um atacante a seguir os seguintes passos:

  1. Eles obtêm acesso altamente privilegiado ao seu ambiente AD: BA, Administradores de Domínio (DA) ou Administradores Empresariais (EA). (Este passo é intencionalmente muito vago. Tenha paciência!)
  2. O atacante confirma que existe uma Infraestrutura de Chaves Públicas (PKI) do AD CS na floresta e que esta suporta o PKINIT, verificando se há uma ou mais autoridades de certificação (CAs) na floresta NtAuthCertificates objeto.
  3. Através do RemoteRegistry ou da modificação direta do registo, o atacante define o UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors valor para 1 num ou mais centros de dados.
  4. Eles adicionam o OID 2.5.29.31 de um CA DisableExtensionList, quer seja através de certutil.exe ou a modificação direta do registo do anfitrião da CA.
  5. O atacante solicita um certificado de autenticação para um utilizador que controla — provavelmente a conta BA/DA/EA que está a utilizar neste momento.
  6. Eles confirmam que o «Zombie Certificate» funciona com o PKINIT.

Num ambiente típico, as fases de reconhecimento, modificação do registo, pedido de certificado e validação do PKINIT deste ataque podem ser automatizadas através de scripts e executadas em segundos, uma vez que muitos destes elementos são bem conhecidos ou extremamente fáceis de identificar utilizando binários integrados e código .NET indesejado presente em todos os computadores Windows modernos.

A menos que esteja a correlacionar eventos de várias fontes num único conjunto de indicadores, simplesmente não irá perceber que este ataque está a ocorrer.

No entanto, imaginemos que os nossos valentes defensores se apercebam da intrusão e tomem rapidamente medidas para a conter. Eles:

  • Encerre todas as sessões de início de sessão ativas da conta comprometida
  • Reiniciar a palavra-passe do AD da conta comprometida
  • Revogar os certificados de autenticação da conta comprometida
  • Faz outras coisas… Não faço parte da equipa de Relações com Investidores da Semperis, por isso confio na experiência deles…

Apesar destas medidas, o atacante pode utilizar o «Certificado Zumbi» que solicitou no Passo 6 acima para executar o PKINIT e recuperar o acesso à conta que controlava anteriormente.

Como? Porque o estado de revogação do certificado é desconhecido e o atacante modificou o processo PKINIT para que este adote a política de «fail-open» quando o estado de revogação é desconhecido.


E fica ainda mais assustador: a reanimação dos zombies

A resposta de IR que descrevi acima foi intencionalmente incompleta: a conta comprometida deveria ter sido desativada e substituída na totalidade por uma nova conta. No entanto, no meio da confusão de um incidente, as medidas de correção podem passar despercebidas.

A contenção incompleta é uma realidade!

No entanto, um atacante mais perspicaz poderia ter introduzido algumas alterações no seu processo para tornar o seu acesso ainda mais persistente. Em vez de utilizar um modelo pré-existente para solicitar um certificado de autenticação para a conta que comprometeu, o atacante poderia:

  • Criar um novo modelo que inclua a configuração incorreta do ESC1
  • Utilize o modelo ESC1 para solicitar um certificado que inclua o SAN de uma conta privilegiada diferente

Ora, se o utilizador inicialmente comprometido for desativado ou eliminado, o atacante continuaria a manter o controlo da conta com privilégios incluída no SAN.

Este zombie tem um segundo batimento cardíaco. Se matares o hospedeiro, ele continua a andar, assumindo uma identidade diferente.

Nota à parte: Existem várias outras formas maliciosas de tornar este ataque mais discreto, mas a minha consciência não me permite detalhá-las aqui.


Como detetar certificados «zombie»

Como é que se sabe se há uma infestação de zombies? Começa pelos cérebros.

O «cérebro» de um Certificado Zumbi é o UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors valor do registo. Verifique todos os controladores de domínio da sua floresta e quaisquer florestas de confiança. O caminho completo no Registo é:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc\UseCachedCRLOnly AndIgnoreRevocationUnknownErrors

Se algum DC tiver este valor definido para 1, considere-o um indício confirmado de adulteração até prova em contrário. Avance com as seguintes medidas:

  • Verifique se existem certificados de autenticação emitidos a utilizadores com privilégios, mesmo que pareçam ter sido revogados.
  • Encontre quaisquer certificados de autenticação que incluam o SAN de um utilizador privilegiado, independentemente do estado (ativado/desativado) do requerente.
  • Verifique todas as CA’s DisableExtensionList executando o seguinte comando: certutil -config <CA-HOST-FQDN\CAName> -getreg policy\DisableExtensionList

Se vir o resultado seguinte, significa que algo mudou que não devia ter mudado:

Figura 3: O agressor está dentro de casa

Como matar o zombie

O valor do registo é o verdadeiro golpe fatal. Um certificado «zombie» só é perigoso enquanto houver pelo menos um DC que aceite um estado de revogação desconhecido. Elimine essa condição em primeiro lugar.

  1. Em cada DC afetado, elimine UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors e reinicie o Centro de Distribuição de Chaves Kerberos. Isto restabelece imediatamente o comportamento de «fail-closed». O PKINIT rejeitará qualquer certificado cujo estado de revogação não possa ser confirmado.
  2. Remover OID 2.5.29.31 da CA’s DisableExtensionList. Os novos certificados voltarão a incluir a extensão CDP.
    Um ponto fundamental: Os certificados já emitidos sem uma extensão CDP estão permanentemente imunes à revogação, independentemente do que conste na CRL da CA. A entrada de revogação existe, mas nenhum verificador a encontrará jamais, uma vez que o certificado não contém qualquer referência à CRL. Estes certificados são inofensivos assim que o registo for corrigido, mas devem ser identificados e substituídos.
  3. Identificar todos os certificados emitidos durante o período em que DisableExtensionList contenham o OID do CDP. Revogue-os todos. Eles já estão funcionalmente inativos assim que o valor do registo for corrigido, mas a revogação explícita fecha o ciclo e cria um registo de auditoria.
  4. Exigir o registo automático de todas as contas afetadas, especialmente as que têm privilégios. Emitir novos certificados que incluam uma extensão CDP válida.

Prevenir o próximo surto

Não basta matar o zombie ativo. Tens de impedir o próximo.

  • Monitorize o registo de cada controlador de domínio em que confia. Aviso em caso de qualquer alteração a UseCachedCRLOnlyAndIgnoreRevocationUnknownErrors em todos os centros de dados. Qualquer valor que não seja absent ou 0 deveria dar origem a uma investigação imediata.
  • Auditoria DisableExtensionList segundo um horário. Deve estar vazio em todas as CA da sua floresta. Pode verificar diretamente o caminho do registo ou consultá-lo através de certutil: certutil -config <CA-HOST-FQDN\CAName> -getreg policy\DisableExtensionList
    Dica de profissional: O Plataforma Semperis Lightning pode monitorizar o registo por si!
  • Utilize o Locksmith 2. Tanto o Locksmith como o Locksmith 2 incluem a deteção da configuração incorreta do DisableExtensionList. Execute-os regularmente como parte das suas verificações de integridade do AD CS.

Para que ocorra um surto de «Certificados Zumbis», é necessário que duas condições se verifiquem simultaneamente:

  • Uma CA que emite certificados sem a extensão CDP
  • Pelo menos um DC que entra em modo «fail-open» devido a um estado de revogação desconhecido

Se eliminar qualquer uma dessas condições, o ataque falha. Se eliminar ambas, terá uma PKI muito mais segura.


Preparem-se para o regresso dos zombies — e estejam prontos

Os «Certificados Zumbis» não são um caso extremo teórico. Baseiam-se inteiramente em funcionalidades documentadas e intencionais da Microsoft.

Nenhum CVE irá resolver este problema. Não está previsto nenhum patch. O ataque funciona porque os administradores precisam, ocasionalmente, de flexibilizar a verificação de revogação — e os atacantes podem tirar partido dessa mesma flexibilidade.

A boa notícia é que os pré-requisitos são significativos. Um atacante precisa de acesso com privilégios elevados para que qualquer uma destas ações seja possível, o que significa que uma boa gestão de privilégios faz toda a diferença. A má notícia é que, uma vez cumpridos esses pré-requisitos, o ataque é rápido, pode ser automatizado através de scripts e consegue contornar a maioria dos procedimentos padrão de resposta a incidentes.

Se utilizar o AD CS no seu ambiente, verifique o valor do registo e o DisableExtensionList em todos os CA hoje. Se encontrares qualquer um deles ativado de forma inesperada, tens um problema que vale a pena investigar. Se encontrares os dois ativados em simultâneo, talvez já tenhas um zombie a vaguear pela tua floresta.

Se precisar de ajuda para eliminar os «certificados zombie», contacte a Semperis. Os nossos especialistas em resposta a incidentes lidam com estas situações diariamente — e estamos aqui para o ajudar.

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.


Saiba mais sobre como prevenir e eliminar a persistência no Active Directory e no Entra ID