Andrea Pierini Consultor de segurança sénior

Passei muitos anos a estudar a forma como os ciberatacantes abusam dos privilégios do Windows para escalar o seu acesso, partindo de contas com privilégios reduzidos até chegar à conta NT AUTHORITY\SYSTEM. O que começou por ser uma curiosidade em relação a um conjunto de primitivas de suplantação de identidade evoluiu gradualmente para um catálogo sistemático de técnicas de ataque centradas no abuso de privilégios do Windows . Muitas destas técnicas continuam a ser relevantes, mesmo em ambientes modernos e atualizados.

Neste artigo, vou explicar-vos quais são os privilégios do Windows mais aliciantes do ponto de vista de um atacante: aqueles que permitem uma escalada direta de privilégios. Continuem a ler para saberem:

  • Que privilégios representam o maior risco para o seu ambiente?
  • Por que razão os atacantes visam estes privilégios
  • Como os atacantes podem abusar destes privilégios para obter privilégios SYSTEM locais, muitas vezes com um esforço surpreendentemente reduzido

Como os privilégios do Windows podem aumentar o risco de cibersegurança

Desde 2018 que tenho vindo a debater com profissionais de TI e de cibersegurança os perigos do abuso de privilégios no Windows. Desde a manipulação clássica de tokens até à família de exploits «Potato», este tema tem marcado grande parte da investigação sobre a escalada de privilégios locais no Windows ao longo dos últimos 10 anos.

No entanto, a mensagem continua tão relevante como sempre. Muitos ainda subestimam estes privilégios, a forma como funcionam e o nível de controlo que podem proporcionar aos atacantes. Este risco persiste por duas razões:

  • Os privilégios não são o mesmo que permissões. As organizações que auditam cuidadosamente as suas ACL e delegações muitas vezes ignoram os privilégios atribuídos a contas de utilizador sem privilégios.
  • A Microsoft não corrige o abuso de privilégios. Abusar de um privilégio que detém legitimamente não constitui uma violação dos limites de segurança. As técnicas que descrevo neste artigo, incluindo as explorações «Potato», têm-se mantido ativas ao longo de muitos anos e em inúmeras versões do Windows, porque se baseiam em funcionalidades e não em erros. Por conseguinte, as suas defesas devem ser de natureza arquitetónica.

O abuso de privilégios está normalmente associado à escalada de privilégios locais (LPE). Mas todos sabemos que a comprometimento total de um domínio começa, muitas vezes, exatamente aí: uma escalada de privilégios locais que permite a um atacante obter o nível mais elevado de acesso numa única máquina. A partir daí, os atacantes podem, frequentemente, abusar de direitos elevados, credenciais, tokens ou outros recursos expostos para se deslocarem lateralmente e prosseguirem o seu percurso de escalada no seu ambiente.

O risco torna-se ainda mais grave em ambientes partilhados. Pense num servidor RDP, num host de transição ou em qualquer sistema onde vários utilizadores interajam. Obter controlo administrativo local numa máquina deste tipo pode ter consequências que vão muito além do próprio host.

Se executares whoami /priv e quiseres ver mais do que um punhado de publicações, este blogue é para ti.


O que são os privilégios do Windows?

A Microsoft define um privilégio como«o direito de uma conta, tal como uma conta de utilizador ou de grupo, de realizar várias operações relacionadas com o sistema no computador local, tais como desligar o sistema, carregar controladores de dispositivos ou alterar a hora do sistema».

Na prática, os privilégios são um mecanismo que coexiste com o modelo tradicional de permissões baseado em ACLs e que, por vezes, se sobrepõe a este. Há alguns aspetos que é fundamental compreender do ponto de vista da segurança:

  • Os privilégios são atribuídos através de Atribuição de direitos de utilizador no Editor de Políticas Locais ou de Grupo (Figura 1). Mas também podem ser geridas programaticamente através da API do Windows, utilizando funções como LsaOpenPolicy() e LsaAddAccountRights().
Atribuição de direitos de utilizador (privilégios) através do editor de GPO
Figura 1. Atribuição de direitos de utilizador (privilégios) através do editor de GPO
  • Os privilégios podem ser ativados ou desativados. Um privilégio predefinido é aquele que é ativado automaticamente sempre que o sistema determina que é necessário.
  • Alguns privilégios substituem explicitamente as permissões dos objetos (ACLs). Esta é a causa principal da maioria dos abusos aqui discutidos.
  • A maioria dos privilégios só está acessível no âmbito de um processo com um nível de integridade (IL) elevado, o que significa que é necessário um shell com privilégios elevados para os utilizar. No entanto, assim que se tiver esse shell com privilégios elevados, os privilégios estão à sua disposição para serem abusados.
  • O comando mais importante desta investigação é whoami /priv, que mostra todos os privilégios atribuídos ao token atual, juntamente com os respetivos estados (ativado/desativado). Um privilégio ativado está pronto a ser utilizado. Um privilégio desativado apenas necessita de uma chamada à API para AdjustTokenPrivileges() para o ativar, a menos que seja considerado um privilégio por predefinição.

O que são os tokens de acesso do Windows?

Para compreender o abuso de privilégios, é necessário, em primeiro lugar, compreender os tokens de acesso. Trata-se de objetos que o Windows utiliza para representar o contexto de segurança de um processo ou de um thread (Figura 2).

Estrutura do token de acesso do Windows
Figura 2. Estrutura do token de acesso do Windows

Um sistema cria um token durante o processo de início de sessão através de NtCreateToken(). Este token é então utilizado sempre que um processo ou thread tenta interagir com um objeto protegível. Quando um novo processo ou thread é criado, é-lhe atribuída uma cópia do token do processo ou thread pai.

Um token contém, entre outras coisas:

  • O SID do utilizador e do proprietário
  • SIDs para cada grupo a que o utilizador pertence
  • O SID de início de sessão
  • O DACL que é aplicado quando o utilizador cria objetos protegíveis sem especificar um descritor de segurança
  • O tipo de token (primário ou de representação)
  • O nível atual de representação: SecurityAnonymous, SecurityIdentification, SecurityImpersonation ou SecurityDelegation
  • A lista completa dos privilégios de que o utilizador ou os seus grupos dispõem (Figura 3)
Privilégios na estrutura dos tokens
Figura 3. Privilégios na estrutura do token

Existe uma restrição importante: assim que o PrimaryTokenFrozen Se o bit estiver definido num token, não é possível adicionar-lhe novos privilégios. Só é possível ativar ou desativar os privilégios que já estão presentes, através de AdjustTokenPrivileges. No entanto, pode alterar o tipo de token utilizando DuplicateToken, o que abre a porta a situações de suplantação de identidade.
Esta configuração significa que os privilégios de que dispõe são, em grande parte, determinados no momento do início de sessão. A questão que se coloca, então, é a seguinte: Quem iniciou sessão e com o quê?


Quais são as contas do Windows que os atacantes visam?

Antes de nos debruçarmos sobre privilégios específicos, vale a pena saber quais as contas que, por predefinição, possuem privilégios perigosos. Eis uma breve lista:

  • Os administradores e o Sistema Local detêm, essencialmente, todos os privilégios.
  • Os grupos predefinidos, tais como Operadores de Cópia de Segurança, Operadores de Servidor e Operadores de Impressão, dispõem de um subconjunto de privilégios poderosos que são frequentemente ignorados.
  • As contas de serviço locais e de rede possuem normalmente os privilégios SeImpersonatePrivilege e SeAssignPrimaryTokenPrivilege, que são suficientes para atingir o nível SYSTEM.
  • As contas de serviço geridas e as contas virtuais têm os mesmos privilégios que as contas de serviço.
  • Os utilizadores de aplicações de terceiros, tais como os conjuntos de aplicações do IIS, as contas de serviço do SQL Server e os agentes de cópia de segurança, são frequentemente configurados com mais privilégios do que aqueles de que necessitam.

Mais uma vez, a Microsoft considera o abuso de privilégios legítimos uma violação dos limites de segurança, e não uma violação dos limites de proteção. As técnicas de abuso de privilégios não são consideradas erros de software e, por isso, não são corrigidas.


Como os atacantes descobrem e exploram os privilégios do Windows

Então, como é que os atacantes conseguem aceder a contas com privilégios que podem ser explorados? O processo envolve normalmente uma ou mais das seguintes abordagens:

  • Compromisso das contas de serviço, tais como configurações de serviço inadequadas, execução remota de código em aplicações Web ou injeção de SQL, o que conduz a xp_cmdshell execução
  • Intercepção da autenticação NTLM ou Kerberos através de técnicas como a coação, ataques de retransmissão ou captura de credenciais
  • Roubar credenciais ou realizar Kerberoasting através da obtenção de dados de contas de serviço e da quebra de hashes offline
  • Manipulação de tokens através da falsificação de tokens provenientes de processos com privilégios ou do seu roubo direto
  • Gravações parciais ou arbitrárias através da Manipulação Direta de Objetos do Kernel (DKOM), que permite aos atacantes, dotados de primitivas de escrita ao nível do kernel — frequentemente obtidas através de controladores vulneráveis —, contornar totalmente as APIs do modo de utilizador. Ao localizar o _TOKEN estrutura através de _EPROCESS e, ao alterarem os campos de privilégios, os atacantes podem adicionar e ativar privilégios adicionais (Figura 4).
Funcionamento interno do token de acesso do Windows apresentado através do WinDbg
Figura 4. Funcionamento interno do token de acesso do Windows apresentado através do WinDbg

Quais são os privilégios do Windows que os atacantes visam?

Agora que já tem uma noção do risco que o abuso de privilégios no Windows representa, vamos analisar em pormenor os privilégios que os atacantes tendem a visar, por que razão esses privilégios são aliciantes para os agentes maliciosos e como são explorados.


SeCreateTokenPrivilege: Alguém tem tokens de acesso?

SeCreateTokenPrivilege é um privilégio poderoso relacionado com tokens que permite que um processo chame APIs de criação de tokens, nomeadamente ZwCreateToken, para criar um token de acesso totalmente personalizado com quaisquer privilégios e pertenças a grupos que se desejar:

      NTSTATUS ZwCreateToken(
PHANDLE                            TokenHandle,
ACCESS_MASK                     DesiredAccess,
POBJECT_ATTRIBUTES         ObjectAttributes,
TOKEN_TYPE                        Type,
PLUID                                   AuthenticationId,
PLARGE_INTEGER                 ExpirationTime,
PTOKEN_USER                      User,
PTOKEN_GROUPS                Groups,
PTOKEN_PRIVILEGES            Privileges,
PTOKEN_OWNER                 Owner,
PTOKEN_PRIMARY_GROUP PrimaryGroup,
PTOKEN_DEFAULT_DACL     DefaultDacl,
PTOKEN_SOURCE                Source
);

No Windows Server 2016 / Windows 10 Versão 1809 e versões anteriores, o token resultante pode ser utilizado para assumir a identidade de threads sem necessitar de quaisquer privilégios adicionais de representação. A Microsoft corrigiu esse vetor específico em versões posteriores do Windows, mas o token resultante ainda pode ser utilizado para escrever e sobrescrever ficheiros protegidos — uma técnica útil para os atacantes, mesmo em cenários restritos.


SeDebugPrivilege: o acesso SYSTEM em poucas palavras

O SeDebugPrivilege é um dos privilégios mais poderosos do modelo de privilégios do Windows. Permite ao seu detentor ligar um depurador a qualquer processo, independentemente de quem seja o proprietário desse processo ou de quais as ACLs que o protegem, e ler ou modificar a memória do processo.

É importante referir que o SeDebugPrivilege contorna as verificações normais da DACL. Não contorna os mecanismos de processos protegidos (por exemplo, PPL, processos assinados por ELAM), mas estes representam uma pequena fração dos processos em execução num sistema típico.

Os cenários de abuso incluem:

  • Injeção de código. Os atacantes podem injetar código malicioso em processos com privilégios utilizando a sequência clássica VirtualAlloc()WriteProcessMemory()CreateRemoteThread(). Alvo lsass.exe, winlogon.exe, ou qualquer processo NT AUTHORITY\SYSTEM, e terá a possibilidade de executar código arbitrário ao mais alto nível de privilégios.
  • Falsificação do processo pai. Os atacantes podem criar um novo processo e designar um processo com privilégios como seu processo pai, fazendo com que o processo filho herde o token de privilégios (Figura 5).
Falsificação do processo pai com SeDebugPrivilege
Figura 5. Simulação do processo pai com SeDebugPrivilege

Na prática, qualquer serviço ou aplicação que conceda a uma conta o privilégio SeDebugPrivilege concede, na prática, a essa conta acesso ao nível SYSTEM. Existem poucas razões legítimas para que este privilégio seja amplamente atribuído.


SeBackupPrivilege e SeRestorePrivilege: Da escalada de privilégios locais à extração do NTDS.DIT

Os atacantes podem abusar das funções SeBackupPrivilege e SeRestorePrivilege para aceder a ficheiros confidenciais e, em alguns cenários, extrair a base de dados NTDS.DIT dos controladores de domínio (DCs), o que pode levar à comprometimento total do Active Directory… um cenário preocupante.


SeBackupPrivilege: O caminho mais rápido para a extração de credenciais

A descrição na documentação da Microsoft refere que SeBackupPrivilege «permite ao utilizador contornar as permissões de ficheiros e diretórios para fazer uma cópia de segurança do sistema.» Por outras palavras, este privilégio concede acesso de leitura a qualquer ficheiro no sistema, independentemente das ACLs, desde que o ficheiro seja aberto com FILE_FLAG_BACKUP_SEMANTICS.

A forma mais imediata de abuso consiste em descarregar as estruturas do registo do Windows necessárias para a extração de credenciais fora de linha:

reg save HKLM\SYSTEM c:\temp\system.hive
reg save HKLM\SAM c:\temp\sam.hive

Assim que um atacante tiver estes dois ficheiros, pode utilizar qualquer ferramenta offline para extrair os hashes NTLM locais. Num servidor, onde a reutilização da palavra-passe de administrador local continua a ser uma prática demasiado frequente, esta capacidade pode proporcionar aos agentes maliciosos um ponto de apoio para o movimento lateral ao longo de todo um segmento (Figura 6).

Recuperação de hashes do NT a partir de uma cópia de segurança do hive SAM utilizando o SeBackupPrivilege
Figura 6. Recuperação de hashes do NT a partir de uma cópia de segurança do «hive» do SAM utilizando o SeBackupPrivilege

Para além do registo, o SeBackupPrivilege pode ser utilizado para ler qualquer ficheiro ao qual o sistema de ficheiros normalmente negaria o acesso:

      source = CreateFile(
L"c:\users\administrator\supersecretfile4admins.doc",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);

A chave é a FILE_FLAG_BACKUP_SEMANTICS sinalizador, que faz com que o Windows reconheça uma operação de cópia de segurança e ignore a avaliação normal da DACL.


SeRestorePrivilege: Acesso de escrita sem restrições

Enquanto o SeBackupPrivilege concede acesso de leitura a tudo, o SeRestorePrivilege concede acesso de escrita a tudo, incluindo ficheiros protegidos por TrustedInstaller e chaves do registo do sistema. Duas chamadas à API ativam este comportamento:

  • CreateFile() com FILE_FLAG_BACKUP_SEMANTICS
  • RegCreateKeyEx() com REG_OPTION_BACKUP_RESTORE

Com acesso de escrita sem restrições, a superfície de ataque torna-se enorme. Uma técnica simples e frequentemente utilizada de forma abusiva consiste em modificar um serviço do Windows para executar um código malicioso controlado pelo atacante. Os atacantes limitam-se a:

  1. Criar uma DLL ou um ficheiro executável de serviço malicioso.
  2. Utilização RegCreateKeyEx() com REG_OPTION_BACKUP_RESTORE para substituir o ficheiro do serviço ServiceDLL valor do registo:
    std::string buffer = "c:\windows\system32\hackerservice.dll";
    LSTATUS stat = RegCreateKeyExA(
    HKEY_LOCAL_MACHINE,
    "SYSTEM\CurrentControlSet\Services\dmwappushservice\Parameters",
    0, NULL, REG_OPTION_BACKUP_RESTORE, KEY_SET_VALUE, NULL, &hk, NULL
    );
    stat = RegSetValueExA(
    hk, "ServiceDLL", 0, REG_EXPAND_SZ,
    (const BYTE*)buffer.c_str(), buffer.length() + 1
    );
  3. Utilização CreateFile() com FILE_FLAG_BACKUP_SEMANTICS para copiar a DLL para C:\Windows\System32. (A localização pode ser qualquer uma; este exemplo serve apenas para demonstrar que o privilégio permite escrever em ficheiros de sistema protegidos, ou mesmo sobrescrevê-los.)
  4. Reinicie o serviço alvo. O serviço, a ser executado como SYSTEM, carrega agora a DLL do atacante.

Figura 7 apresenta um exemplo desta técnica utilizando dmwappushservice, que está presente por predefinição, é executado como SYSTEM e pode ser iniciado por qualquer utilizador. No entanto, a mesma técnica pode ser utilizada para explorar qualquer serviço.

Manipulação do caminho de uma imagem de serviço utilizando o SeRestorePrivilege
Figura 7. Manipulação do caminho de uma imagem de serviço utilizando a função SeRestorePrivilege

Operadores de cópias de segurança: o dobro dos privilégios, o dobro do risco

Os membros do grupo integrado «Backup Operators» detêm os privilégios «SeBackupPrivilege» e «SeRestorePrivilege». Mais importante ainda, têm permissão para iniciar sessão localmente nos controladores de domínio (DCs), uma capacidade que acarreta um risco gravemente subestimado na maioria dos ambientes AD.

Esta combinação significa que qualquer atacante que consiga aceder ao grupo «Backup Operators» pode fazer uma cópia de segurança do ficheiro NTDS.DIT diretamente a partir de um DC, utilizando ferramentas como o wbadmin.exe:

      wbadmin start backup -backuptarget:e: -include:c:\windows\ntds
wbadmin get versions
wbadmin start recovery -version:07/12/2025-11:09 -itemtype:file
-items:c:\windows\ntds\ntds.dit -recoverytarget:c:\temp\srvdc1 -notrestoreacl
reg save HKLM\SYSTEM c:\temp\system

A abordagem que utiliza o ficheiro «diskshadow.exe» integrado funciona igualmente bem e é frequentemente ignorada pelos defensores:

      set metadata C:\temp\metadata.cab
set context clientaccessible
set context persistent
begin backup
add volume c: alias mydrive
create
expose %mydrive% z:

Note-se que esta técnica não funciona com o ntdsutil.exe, que requer privilégios de administrador.

Assim que um atacante tiver o ficheiro NTDS.DIT e o hive SYSTEM, poderá utilizar ferramentas como o DSInternals ou o impacket-secretsdump para extrair offline todas as credenciais do domínio, incluindo o hash krbtgt necessário para lançar um ataque «Golden Ticket».

Além disso, com ambos os privilégios, um atacante que se infiltre no grupo «Backup Operators» pode definir a propriedade e as permissões de qualquer ficheiro ou pasta no sistema, o que lhe permite obter acesso ao SYSTEM apenas através da manipulação do sistema de ficheiros.


SeImpersonatePrivilege e SeAssignPrimaryTokenPrivilege: Por que é que as explorações do Potato não desaparecem?

Estes dois privilégios são os que mais frequentemente são alvo de abuso em situações reais e são a razão pela qual existe a família de exploits Potato.

  • SeImpersonatePrivilege (“Fingir ser um cliente após a autenticação”) permite que um thread assuma a identidade de qualquer token de acesso através de SetThreadToken(), ImpersonateLoggedOnUser(), ou CreateProcessWithToken().
  • SeAssignPrimaryTokenPrivilege (“Atribuir o token principal de um processo”) permite que um processo crie um processo filho com um token primário diferente através de CreateProcessAsUser(). Este privilégio também está disponível num shell IL padrão de nível médio.

Ambos os privilégios são normalmente atribuídos a contas de serviço, identidades de conjuntos de aplicações do IIS, contas de serviço do SQL Server e entidades semelhantes. Resumindo: se tiver RCE como conta de serviço, é quase certo que detenha pelo menos um destes privilégios.

Mas como é que os atacantes obtêm tokens privilegiados para se fazerem passar por outros utilizadores? Existem várias técnicas, por exemplo:

  • Criação de um pipe com nome, obrigando um processo com privilégios a estabelecer ligação ao mesmo e, em seguida, chamando ImpersonateNamedPipeClient() para obter o token do autor da chamada
  • Utilização de callbacks DCOM/RPC via CoImpersonateClient(), RpcImpersonateClient()
  • Utilizando as vulnerabilidades «Potato», uma família de técnicas bem conhecidas de escalada de privilégios locais (por exemplo, RottenPotato, JuicyPotato, SweetPotato, GodPotato) que abusam desses privilégios, forçando a autenticação COM/RPC ao nível do sistema a ser redirecionada para um listener controlado pelo atacante

A técnica remonta a uma observação feita por James Forshaw em 2016:

«As ligações DCOM DCE/RPC locais podem ser redirecionadas para um socket TCP em escuta, permitindo o acesso ao desafio de autenticação NTLM do utilizador LocalSystem, que pode ser reproduzido no serviço de ativação DCOM local para elevar os privilégios.»

Ao longo dos últimos 10 anos, esta vulnerabilidade central foi reimplementada, adaptada e aproveitada de novo numa variedade notável de técnicas que, em conjunto, formam a família Potato. O mecanismo geral, em todas as variantes, segue esta estrutura:

  1. Inicie um ouvinte local numa porta TCP para funcionar como um ponto final COM ou RPC falso.
  2. Ativar um CLSID através da instanciação de uma classe COM que seja executada sob a identidade NT AUTHORITY\SYSTEM.
  3. Desmarcação forçada via CoGetInstanceFromIStorage, passando por um IStorage OBJREF apontando para 127.0.0.1: <listener>. O servidor SYSTEM COM tenta estabelecer ligação com o ouvinte e autentica o tráfego de saída utilizando o NTLM.
  4. Interceptar o handshake NTLM localmente através da SSPI (AcceptSecurityContextQuerySecurityContextToken) para obter um token de representação do SYSTEM.
  5. Assumir a identidade do token e escalar via CreateProcessWithTokenW ou CreateProcessAsUser para iniciar um shell como SYSTEM.

A ideia central é elegante: o CLSID faz com que o SYSTEM inicie a autenticação de saída, CoGetInstanceFromIStorage encaminha essa autenticação para o listener do atacante, e o relé NTLM local captura o token. Não se trata de uma vulnerabilidade no sentido tradicional… são apenas privilégios a fazer exatamente aquilo para que foram concebidos.

A Figura 8 mostra como a ferramenta JuicyPotatoNG pode ser utilizada para criar um shell SYSTEM, explorando a função SeAssignPrimaryTokenPrivilege a partir de um shell em execução num IL de nível médio.

Escalação de privilégios através de técnicas «Potato» que exploram as funções SeImpersonatePrivilege e SeAssignPrimaryTokenPrivilege
Figura 8. Escalada de privilégios através das técnicas do Potato que exploram as funções SeImpersonatePrivilege e SeAssignPrimaryTokenPrivilege

SeLoadDriverPrivilege: Do controlador de dispositivo ao comprometimento total do sistema

O SeLoadDriverPrivilege determina quais os utilizadores que podem carregar e descarregar dinamicamente controladores de dispositivos ou outro código no modo do kernel. Este privilégio é particularmente digno de nota porque os membros do grupo de domínio «Operadores de Impressoras» detêm esse privilégio nos servidores de domínio (DCs) por predefinição.

O padrão de ataque está bem estabelecido: carregar um controlador do kernel assinado, mas vulnerável, e, em seguida, explorá-lo a partir do espaço do utilizador para ler ou escrever na memória do kernel, permitindo o roubo de tokens, a ativação de privilégios, a contornagem do PPL, o encerramento de programas antivírus/EDR ou a execução arbitrária em modo de kernel.

A técnica canónica baseia-se no facto de os utilizadores poderem criar entradas no registo na sua estrutura atual HKCU, e NtLoadDriver() aceita caminhos de registo criados a partir do SID do utilizador, permitindo que um utilizador sem privilégios registe um serviço de controlador do kernel sem alterar o HKLM:

      std::string data = "\??\C:\TEMP\evildriver.sys";
RegCreateKeyExA(HKEY_CURRENT_USER,
"SYSTEM\CurrentControlSet\Services\Evil",
0, NULL, NULL, KEY_SET_VALUE, NULL, &hk, NULL);
RegSetValueExA(hk, "ImagePath", 0, REG_EXPAND_SZ,
(const BYTE)data.c_str(), data.length() + 1); RegSetValueExA(hk, "Type", 0, REG_DWORD, (const BYTE)&val, sizeof(val));

WCHAR winregPath[256];
wcscpy(winregPath, L"\Registry\User\");
wcscat(winregPath, sidstring);
wcscat(winregPath, L"\System\CurrentControlSet\Services\Evil");
RtlInitUnicodeString(&DriverServiceName, winregPath);
status = NtLoadDriver(&DriverServiceName);

A Microsoft bloqueou agora os locais alternativos do registo, mas ainda existem caminhos graváveis em HKLM\System.

Não é raro que os GPOs concedam o SeLoadDriverPrivilege a grupos amplos, o que provavelmente decorre da ideia errada de que esse privilégio é necessário para que os utilizadores instalem impressoras. O resultado é um privilégio desnecessariamente exposto, que proporciona aos atacantes um caminho direto para a execução de código ao nível do kernel.


SeManageVolumePrivilege: Acesso à modificação da ACL

O SeManageVolumePrivilege permite que um utilizador execute operações relacionadas com volumes, tais como desfragmentação, montagem ou desmontagem de volumes. Este privilégio está disponível num shell IL de nível médio. Do ponto de vista de um atacante, a exploração deste privilégio desbloqueia várias capacidades úteis:

  • Montar volumes que contenham dados sensíveis, contornando potencialmente os mecanismos de controlo de acesso que regulam a forma como os dados são expostos através do sistema de ficheiros
  • Manipular sistemas de ficheiros ao nível do volume, incluindo a alteração de permissões em volumes inteiros (Figura 9) — um privilégio que pode permitir que um atacante, por exemplo, modifique a ACL em toda a unidade C:\ e, em seguida, utilize outras técnicas para criar caminhos graváveis em áreas do sistema que, de outra forma, estariam protegidas
Alterar as permissões de volume utilizando o SeManageVolumePrivilege
Figura 9. Alteração das permissões de volume através da utilização do SeManageVolumePrivilege

Embora este privilégio seja menos frequente na prática do que o SeImpersonatePrivilege ou o SeBackupPrivilege, a sua presença numa conta que não seja de administrador deve ser considerada um risco grave.


SeRelabelPrivilege: Menor integridade, maior risco

O SeRelabelPrivilege é um privilégio menos conhecido, mas interessante. De acordo com a documentação da Microsoft, este privilégio«determina quais as contas de utilizador que podem modificar o rótulo de integridade de objetos, tais como ficheiros, chaves do registo ou processos pertencentes a outros utilizadores».

Sem este privilégio, um processo só pode reduzir o rótulo de integridade dos objetos de que é proprietário. Com o SeRelabelPrivilege, um processo pode modificar os rótulos de integridade de objetos pertencentes a outros utilizadores, incluindo elevar os rótulos para um nível de integridade superior ao do próprio processo. Por outras palavras:

  • O SeRelabelPrivilege permite-lhe assumir a propriedade de um recurso, mesmo que o nível de ilibidade (IL) deste seja superior ao seu.
  • Assim que assumir a propriedade, poderá conceder a si próprio acesso total ao processo e aos tokens.
  • Do ponto de vista da exploração de vulnerabilidades, o resultado é semelhante ao do SeDebugPrivilege.
  • A alteração do rótulo obrigatório é apenas uma consequência.

A motivação original por trás deste privilégio continua a ser pouco clara, mas o seu impacto não o é. Permite-lhe assumir a propriedade de objetos acima do seu nível de integridade (Figura 10), tornando-o um dos privilégios mais perigosos e subestimados do modelo de segurança do Windows.

Utilizar o SeRelabelPrivilege para obter a propriedade de um processo com privilégios
Figura 10. Utilização do SeRelabelPrivilege para obter a posse de um processo com privilégios

Qualquer atribuição fora das contas administrativas sujeitas a um controlo rigoroso deve ser cuidadosamente analisada e considerada um sinal de alerta.


SeTakeOwnershipPrivilege: Agora és nosso

Este privilégio faz exatamente o que o próprio nome sugere: permite ao seu detentor assumir a propriedade de qualquer objeto protegível no sistema. As duas chamadas de API relevantes utilizam ambas o OWNER_SECURITY_INFORMATION bandeira:

  • SetSecurityInfo()
  • SetNamedSecurityInfo()

Os tipos de objetos que podem ser alvo são variados: ficheiros, impressoras, recursos partilhados, serviços, chaves do registo e objetos do kernel.

Assim que a posse for estabelecida, aplicam-se as mesmas técnicas de manipulação de ficheiros e do registo utilizadas na exploração do SeRestorePrivilege. Um exemplo prático é visar o msiserver Serviço (Windows Installer):

Passo 1. Assumir a propriedade da chave de registo do serviço:

      wchar_t infile[] = L"SYSTEM\CurrentControlSet\Services\msiserver";
PSID UserSid = GetCurrentUserSID();
dwRes = SetNamedSecurityInfoW(
infile,
SE_REGISTRY_KEY,
OWNER_SECURITY_INFORMATION,
UserSid, NULL, NULL, NULL
);

Passo 2. Altere as permissões da chave do registo para conceder acesso total:

      ea[0].grfAccessPermissions = KEY_ALL_ACCESS;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR)pSIDEveryone;
SetEntriesInAcl(NUM_ACES, ea, NULL, &pACL);

Passo 3. Modificar o serviço ImagePath para executar um comando arbitrário:

      std::string buffer = "cmd.exe /c net localgroup administrators hacker /add";
stat = RegSetValueExA(
hk, "ImagePath", 0, REG_EXPAND_SZ,
(const BYTE*)buffer.c_str(), buffer.length() + 1
);

Quando o serviço é iniciado pelo utilizador, executa o comando controlado pelo atacante sob a conta SYSTEM.


SeTCBPrivilege: Apropriação de identidade

O SeTCBPrivilege é um dos privilégios mais invulgares desta lista. A documentação descreve-o como «funcionar como parte do sistema operativo,”, mas a consequência prática é a possibilidade de utilizar LsaLogonUser() assumir a identidade de qualquer utilizador, sem precisar das credenciais desse utilizador.

O mecanismo é o Service For User Logon (S4ULogon), uma funcionalidade que permite que um processo com o SeTCBPrivilege obtenha um token de segurança para um utilizador arbitrário. É importante referir que o processo que efetua a chamada pode solicitar que sejam adicionadas ao token resultante filiações em grupos ou privilégios adicionais, incluindo grupos aos quais o utilizador não pertence efetivamente:

      pS4uLogon->MessageType = MsV1_0S4ULogon;
// SzUsername=UTILIZADOR ALVO A REPRESENTAR
InitUnicodeString(&pS4uLogon->UserPrincipalName, szusername, pbPosition);
InitUnicodeString(&pS4uLogon->DomainName, szDomain, pbPosition);

// Adicionar S-1-5-32-544 (Administradores Locais) ao token
ConvertStringSidToSid("S-1-5-32-544", &pExtraSid);
pGroups->Groups[pGroups->GroupCount].Attributes =
SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
pGroups->Groups[pGroups->GroupCount].Sid = pExtraSid;
Status = LsaLogonUser(…)

O token de representação resultante, válido no contexto da máquina local, pode ser utilizado para representar threads sem necessitar de privilégios adicionais, como o SeImpersonatePrivilege. Isto torna o SeTcbPrivilege uma primitiva autónoma de escalada de privilégios.

No PowerShell, o caminho do S4ULogon do Kerberos tem o seguinte aspeto:

      $ident = [System.Security.Principal.WindowsIdentity]::new("administrator@domain.local")
$ctx = $ident.Impersonate()
try {
[System.IO.File]::WriteAllText("C:\Windows\System32\text.txt", "hello from Domain Admin")
}
finally {
$ctx.Undo()
}

Por predefinição, este privilégio é detido apenas pela conta SYSTEM. Não há qualquer motivo legítimo para o conceder a outras contas. Qualquer atribuição a contas que não sejam a SYSTEM deve ser considerada uma configuração incorreta ou um indício de violação de segurança.


Reduzir o risco de abuso de privilégios no Windows: medidas práticas para ambientes do Active Directory

Eis o que pode fazer hoje para reduzir os riscos de abuso de privilégios:

  • O comando whoami /priv é uma das primeiras coisas que um atacante executa depois de conseguir um ponto de acesso. Por isso, deve ser também uma das primeiras coisas que deve executar ao analisar o estado de segurança de uma conta sensível.
  • Analise todos os GPO que atribuem privilégios através de «Configuração do Computador» → «Definições do Windows» → «Definições de Segurança» → «Políticas Locais» → «Atribuição de Direitos do Utilizador» em todo o domínio. Audite as atribuições efetivas em todos os sistemas, prestando especial atenção aos ativos de Nível 0. Este é o principal vetor para a distribuição involuntária de privilégios. Audite não só o que está explicitamente configurado, mas também a política resultante, uma vez que a herança e a precedência dos GPO produzem frequentemente atribuições que nenhum administrador pretendia. Remova tudo o que não se justifique do ponto de vista operacional.
  • Analise a pertença a grupos integrados com conjuntos de privilégios avançados: Operadores de Cópia de Segurança, Operadores de Impressão, Operadores de Servidor, Operadores de Conta.
  • As contas de serviço devem ser executadas com os privilégios mínimos necessários. Por predefinição, as contas de serviço possuem o privilégio SeImpersonatePrivilege. É possível restringir os privilégios atribuídos através do Required Privileges chave de registo na configuração do serviço; esta é uma boa prática de reforço de segurança. No entanto, tenha em atenção que estes privilégios podem ser recuperados por um atacante em determinadas condições; por isso, considere este passo como uma camada de uma estratégia mais ampla de defesa em profundidade, em vez de uma medida de mitigação completa.
  • Acompanhar whoami /priv execução e para chamadas à API associadas à manipulação de tokens (DuplicateToken, ImpersonateLoggedOnUser, CreateProcessWithToken, LsaLogonUser) na sua telemetria EDR.
  • Considere qualquer conta que possa iniciar sessão localmente num DC como um ativo de Nível 0, independentemente de fazer parte ou não do grupo «Domain Admins».

Não deixe que o abuso de privilégios no Windows coloque a sua organização em risco

Vale a pena reiterar: uma vez que os privilégios abordados neste artigo funcionam conforme previsto, o risco de abuso de privilégios no Windows — e as técnicas de ataque que esse abuso possibilita — existe mesmo em ambientes devidamente atualizados. Os agentes maliciosos podem utilizar estas técnicas para comprometer o Active Directory e escalar os seus privilégios em toda a sua organização. Não subestime o risco; tome medidas hoje mesmo para proteger a sua resiliência cibernética.


Mais investigação especializada


Fontes