Protegendo serviços antimalware

O Windows 8.1 introduziu um novo conceito de serviços protegidos para proteger os serviços antimalware, que são um alvo frequente de ataques de malware.

Saiba mais sobre como proteger os serviços de modo de usuário AM (antimalware) e como você pode optar por incluir esse recurso em seu serviço antimalware.

Essas informações se aplicam aos seguintes sistemas operacionais e os respectivos sucessores:

  • Windows 8.1
  • Windows Server 2012 R2

As referências e os recursos discutidos aqui estão listados no final deste tópico.

Introdução

A maioria das soluções antimalware inclui um serviço de modo de usuário que executa operações especializadas para detectar e remover malware do sistema. Esse serviço de modo de usuário também é frequentemente responsável por baixar as assinaturas e definições de vírus mais recentes. Esse serviço de modo de usuário se torna um alvo frequente de malware porque é o único ponto de falha para desabilitar a proteção em um sistema. Para se defender contra ataques ao serviço de modo de usuário, os fornecedores de antimalware precisam adicionar muitas funcionalidades e heurísticas ao software deles. No entanto, essas técnicas não são completamente infalíveis e tendem a ser propensas a erros porque precisam identificar a funcionalidade que o Windows executa em no serviço deles e habilitar seletivamente essa funcionalidade.

No Windows 8.1, um novo conceito de serviço protegido foi introduzido para permitir que os serviços de modo de usuário antimalware sejam iniciados como um serviço protegido. Depois que o serviço é iniciado como protegido, o Windows usa a integridade do código para permitir que apenas o código confiável seja carregado no serviço protegido. O Windows também protege esses processos contra injeção de código e outros ataques de processos administrativos.

Este documento descreve como um fornecedor de antimalware com um driver ELAM (Early Launch Anti-Malware) pode aceitar esse recurso e iniciar o serviço antimalware dele como um serviço protegido.

Processo protegido pelo sistema

A partir do Windows 8.1, um novo modelo de segurança foi colocado em prática no kernel para uma melhor defesa contra ataques maliciosos em componentes críticos do sistema. Esse novo modelo de segurança estende as versões do Windows anteriores da infraestrutura de processo protegida usadas para cenários específicos, como a reprodução de conteúdo DRM, em um modelo de uso geral que pode ser usado por terceiros fornecedores de antimalware. A infraestrutura de processo protegido só permite que código assinado confiável seja carregado e tem defesa interna contra ataques de injeção de código.

Observação

As DLLs de script a seguir são proibidas pelo CodeIntegrity dentro de um processo protegido (carregado direta ou indiretamente), como via WinVerifyTrust ou WinVerifyTrustEx, para verificar assinaturas de script via AuthentiCode: scrobj.dll, scrrun.dll, jscript.dll, jscript9.dll e vbscript.dll.

Consulte Processos protegidos no Windows Vista para obter mais informações sobre processos protegidos.

O novo modelo de segurança usa uma variante ligeiramente diferente da infraestrutura do processo de proteção chamada processo protegido do sistema, que é mais adequada para esse recurso, pois mantém o conteúdo do DRM separado. Cada processo protegido pelo sistema tem um nível ou atributo associado, que indica a política de assinatura do código assinado que tem permissão para carregar dentro do processo. Depois que os serviços antimalware optarem pelo modo de serviço protegido, somente código assinado pelo Windows ou código assinado com os certificados do fornecedor de antimalware poderá ser carregado nesse processo. Da mesma forma, outros níveis de processo protegidos têm políticas de código diferentes impostas pelo Windows.

Requisitos

Para que um serviço de modo de usuário antimalware seja executado como um serviço protegido, o fornecedor de antimalware precisa ter um driver ELAM instalado na no computador Windows. Além dos requisitos de certificação de driver ELAM existentes, o driver precisa ter uma seção de recursos inseridos contendo as informações dos certificados usados para assinar os binários de serviço do modo de usuário.

Importante

No Windows 8.1, a cadeia de certificação precisa ser uma raiz conhecida, conforme determinado pela verificação de driver, ou o certificado raiz precisa ser incluído.

Durante o processo de inicialização, esta seção de recursos será extraída do driver ELAM para validar as informações do certificado e registrar o serviço antimalware. O serviço antimalware também pode ser registrado durante o processo de instalação do software antimalware chamando uma API especial, conforme descrito posteriormente neste documento.

Depois que a seção de recursos for extraída com êxito do driver ELAM e o serviço de modo de usuário for registrado, o serviço poderá ser iniciado como serviço protegido. Depois que o serviço for iniciado como protegido, outros processos não protegidos no sistema não poderão injetar threads e não poderão gravar na memória virtual do processo protegido.

Além disso, todas as DLLs que não são do Windows que são carregadas no processo protegido precisam ser assinadas com um certificado apropriado.

Consulte Antimalware de lançamento antecipado para obter mais informações sobre drivers ELAM.

Requisitos de assinatura do serviço antimalware

O serviço de modo de usuário que precisa ser iniciado como protegido precisa ser assinado com certificados válidos. O EXE do serviço precisa ser assinado por hash de página e todas as DLLs que não são do Windows e que são carregadas no serviço também precisam ser assinadas com os mesmos certificados. O hash desses certificados precisa ser adicionado ao arquivo de recurso, que será vinculado ao driver ELAM.

Observação

Os hashes de arquivo/página SHA256 precisam ser usados, embora os certificados possam continuar a ser SHA1.

Recomendamos que os fornecedores de antimalware usem o certificado Authenticode existente deles para assinar os binários de serviço antimalware deles e que o hash desse certificado Authenticode seja incluído na seção de recursos para indicar o certificado usado para assinar os binários de serviço. Se você atualizar esse certificado, uma versão mais recente do driver ELAM precisará ser lançada com os hashes de certificado atualizados.

Assinatura secundária (opcional)

Os fornecedores de antimalware têm a opção de configurar uma autoridade de certificação privada e usar certificados dessa autoridade de certificação para assinar o código dos binários do serviço antimalware como uma assinatura secundária. A principal vantagem de usar a autoridade de certificação privada é que ela permite que os fornecedores criem certificados com uma propriedade EKU especializada, que pode ser usada para diferenciar entre vários produtos do mesmo fornecedor. Ele também reduz a necessidade de atualizar o driver ELAM devido à expiração do certificado, já que os certificados de autoridade de certificação privada normalmente têm datas de expiração mais longas.

Observe que, se os binários de serviço forem assinados com os certificados de autoridade de certificação privada, os binários também precisarão ser assinados duplamente com os certificados Authenticode existentes. Se os binários não forem assinados por uma autoridade de certificação confiável conhecida (por exemplo, VeriSign), o usuário da máquina não terá confiança nos binários porque não poderá confiar na autoridade de certificação privada. A assinatura dupla dos binários com o certificado Authenticode existente também permite que os binários sejam executados em sistemas operacionais de nível inferior.

Para obter mais informações sobre como configurar e instalar a Autoridade de Certificação, consulte Como configurar uma Autoridade de Certificação e Como instalar a Autoridade de Certificação.

Observação

Para compatibilidade com o Windows Vista ou Windows XP (ou Windows 7 sem o patch SHA2), você pode usar a opção "/as" ao assinar seus binários com SignTool.exe com os hashes de página/arquivo SHA256. Isso adicionará a assinatura como uma assinatura secundária ao arquivo. Assinar o arquivo por SHA1 primeiro, uma vez que o Windows XP, Windows Vista e Windows 7 só verão a primeira assinatura.

Requisitos de assinatura de DLL

Como mencionado anteriormente, todas as DLLs que não são do Windows que são carregadas no serviço protegido precisam ser assinadas com o mesmo certificado que foi usado para assinar o serviço antimalware.

Assinatura de catálogo

Os fornecedores de antimalware podem incluir pacotes desenvolvidos por outras empresas sem atualizar as assinaturas binárias. Isso pode ser obtido incluindo os binários em um catálogo que é assinado com seu certificado Authenticode, o que é realizado seguindo estas etapas:

  1. Gerar um catálogo usando o MakeCat
  2. Adicionar todos os binários sem uma assinatura apropriada ao catálogo
  3. Assine o catálogo com o certificado Authenticode, como você faria com qualquer outro binário
  4. Use a função adicionar catálogo para incluir o catálogo com o aplicativo.

Quando a integridade do código se deparar com os pacotes sem uma assinatura apropriada, ela procurará um catálogo com uma assinatura aprovada. Ele encontrará esse catálogo desde que essas etapas sejam seguidas e ele seja instalado com o aplicativo.

Informações do arquivo de recurso

Um arquivo de recurso precisa ser criado e vinculado ao driver ELAM. O hash do certificado, juntamente com outras informações de certificado, precisa ser adicionado ao arquivo de recurso.

A seção de recursos precisa estar no layout a seguir para que o sistema extraia com êxito os recursos da imagem binária e valide as informações de certificado inseridas.

MicrosoftElamCertificateInfo  MSElamCertInfoID
{
      3, // count of entries
      L”CertHash1\0”,
      Algorithm,
      L”EKU1\0”,
      L”CertHash2\0”,
      Algorithm,
      L”\0”, //No EKU for cert hash 2
      L”CertHash3\0”,
      Algorithm,
      L”EKU3a;EKU3b;EKU3c\0”,  //multiple EKU entries supported (max: 3)
}

Para obter mais informações sobre o arquivo de recurso definido pelo usuário, consulte Recurso definido pelo usuário.

CertHash

O hash do certificado usado para assinar o serviço antimalware. A ferramenta CertUtil.exe, fornecida no SDK do Windows, pode ser usada para obter o hash.

certutil.exe –v <path to the signed file>

Por exemplo:

anti-malware protected service certificate hash (certhash)

Algoritmo

O valor do algoritmo representa o algoritmo do certificado. Estes valores de algoritmo são suportados:

0x8004 – SHA1 0x800c – SHA256 0X800d – SHA384 0x800e – SHA512

Lembre-se de incluir o valor do algoritmo (como mostrado acima) e não o nome real do algoritmo. Por exemplo, se o certificado for baseado no algoritmo SHA256, inclua 0x800c na seção de recursos.

EKU

O objeto EKU representa apenas uma propriedade de EKU (uso de chave estendida) de um certificado. Isso é opcional e “\0” deve ser especificado se nenhum EKU está associado ao certificado. Em um caso em que há vários produtos e serviços de apenas um fornecedor antimalware em execução no mesmo sistema, o fornecedor antimalware pode usar a propriedade EKU do certificado de autoridade de certificação privada para diferenciar um serviço de outro. Por exemplo, se houver dois serviços em execução no sistema do mesmo fornecedor de antimalware e assinados pela mesma autoridade de certificação, o serviço que precisa ser iniciado como protegido pode ser assinado com um certificado emitido pela autoridade de certificação que contém um EKU especial. Esse EKU precisa ser adicionado à seção de recursos. O EKU é então registrado pelo sistema e emparelhado com o hash do certificado para validar e iniciar o serviço como protegido.

Observe que a cadeia de certificados precisa incluir o EKU de assinatura de código (1.3.6.1.5.5.7.3.3), mas esse EKU não pode ser incluído na seção de recursos do driver ELAM.

Observação

Se as informações de EKU estiverem incluídas nas informações de certificado para o driver ELAM, o mesmo EKU precisará ser usado ao assinar seus binários.

Observação

A representação de cadeia de caracteres de integridade de código do Windows de um OID em um EKU tem um comprimento máximo de 64 caracteres, incluindo o caractere de terminação zero.  

Observação

Se você especificar vários EKUs, eles serão avaliados com lógica AND. O certificado de entidade final precisa satisfazer todos os EKUs especificados na seção de recursos do ELAM para a entrada fornecida.

Count

Se o binário do serviço antimalware estiver assinado com o certificado Authenticode, bem como com o certificado de autoridade de certificação privada, somente as informações do certificado de autoridade de certificação privada poderão ser adicionadas na seção de recursos.

Iniciando serviços antimalware como protegidos

Registrando o serviço

O serviço antimalware precisa ser registrado no sistema antes de poder ser iniciado como protegido. Durante a instalação do software antimalware, o instalador pode instalar o driver ELAM e reiniciar o sistema para registrar automaticamente o serviço. O sistema registrará o serviço no momento da inicialização extraindo as informações do certificado do arquivo de recurso mencionado acima que está vinculado ao driver ELAM.

Durante a fase de instalação, é altamente recomendável que o sistema seja reiniciado para que o driver ELAM seja carregado e valide o estado do sistema. No entanto, para os casos em que uma reinicialização precisa ser evitada, o Windows também expõe um mecanismo para que o instalador antimalware registre o serviço como protegido usando uma API.

Como registrar o serviço sem reiniciar o sistema

Durante a instalação, um instalador de software antimalware pode chamar a API InstallELAMCertificateInfo e fornecer um identificador para o arquivo de driver ELAM. O sistema abre o driver ELAM, chama rotinas internas para garantir que o driver ELAM esteja assinado corretamente e extrai as informações do certificado da seção de recursos associada ao driver ELAM. Para sintaxe de função, consulte InstallELAMCertificateInfo.

Exemplo de código:

HANDLE FileHandle = NULL;

FileHandle = CreateFile(<Insert Elam driver file name>,
                        FILE_READ_DATA,
                        FILE_SHARE_READ,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL
                        );

if (InstallElamCertificateInfo(FileHandle) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

Iniciando o serviço como protegido

O instalador pode seguir estas etapas para criar, configurar e iniciar o serviço como protegido:

  1. Chame a API CreateService para criar um objeto de serviço e adicioná-lo ao banco de dados do SCM (gerenciador de controle de serviço).

  2. Chame a API SetServiceObjectSecurity para definir o descritor de segurança do objeto de serviço criado na etapa 1.

  3. Chame a API ChangeServiceConfig2 para marcar o serviço como protegido, especificando o novo valor de enumeração SERVICE_CONFIG_LAUNCH_PROTECTED, que foi adicionado no Winsvc.h (a partir do Windows 8.1).

    Exemplo de código:

    SERVICE_LAUNCH_PROTECTED_INFO Info;
    SC_HANDLE hService;
    
    Info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;
    
    hService = CreateService (/* ... */);
    
    if (ChangeServiceConfig2(hService,
                             SERVICE_CONFIG_LAUNCH_PROTECTED,
                             &Info) == FALSE)
    {
        Result = GetLastError();
    }
    
  4. Chame a API StartService para iniciar o serviço. Ao iniciar o serviço como protegido, o SCM verifica com o subsistema de CI (Integridade do Código) para validar as informações do certificado. Depois que as informações do certificado são validadas pelo CI, o SCM inicia o serviço como protegido.

    1. Observe que essa etapa falhará se você não tiver registrado o serviço chamando a API InstallELAMCertificateInfo.
    2. Se o serviço tiver sido configurado para iniciar automaticamente durante a fase de inicialização do sistema, você poderá evitar essa etapa e simplesmente reiniciar o sistema. Durante uma reinicialização, o sistema registrará automaticamente o serviço (se o driver ELAM for iniciado com êxito) e iniciará o serviço no modo protegido.
    3. Se o serviço não for iniciado, consulte as informações em Log de eventos de integridade do código e auditoria do sistema e os tópicos a seguir. Lá, você encontrará mensagens de erro mais detalhadas que explicam por que o sistema de integridade do código impediu a inicialização do serviço. Esses logs também podem ajudar a identificar DLLs que o serviço tentou carregar, mas não conseguiu.

Iniciar um processo filho como protegido

O novo modelo de segurança também permite que os serviços antimalware protegidos iniciem processos filho como protegidos. Esses processos filho serão executados no mesmo nível de proteção que o serviço pai e os respectivos binários precisam ser assinados com o mesmo certificado que foi registrado por meio da seção de recursos do ELAM.

Para permitir que o serviço protegido por antimalware inicie o processo filho como protegido, uma nova chave de atributo estendida, PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, foi exposta e precisa ser usada com a API UpdateProcThreadAttribute. Um ponteiro para o valor do atributo de PROTECTION_LEVEL_SAME precisa ser passado para a API UpdateProcThreadAttribute.

Observações:

  • Para usar esse novo atributo, o serviço também precisa especificar CREATE_PROTECTED_PROCESS no parâmetro de sinalizadores de criação do processo da chamada CreateProcess.
  • Você precisa ter seus binários de serviço assinados usando a opção /ac para incluir o certificado cruzado para encadeá-lo a uma autoridade de certificação conhecida. Um certificado autoassinado sem o encadeamento adequado a uma autoridade de certificação raiz conhecida não funcionará.

Exemplo de código:

DWORD ProtectionLevel = PROTECTION_LEVEL_SAME;
SIZE_T AttributeListSize;

STARTUPINFOEXW StartupInfoEx = { 0 };

StartupInfoEx.StartupInfo.cb = sizeof(StartupInfoEx);

if (InitializeProcThreadAttributeList(NULL,
                                      1,
                                      0,
                                      &AttributeListSize) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

StartupInfoEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(
    GetProcessHeap(),
    0,
    AttributeListSize
    );

if (InitializeProcThreadAttributeList(StartupInfoEx.lpAttributeList,
                                      1,
                                      0,
                                      &AttributeListSize) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

if (UpdateProcThreadAttribute(StartupInfoEx.lpAttributeList,
                              0,
                              PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL,
                              &ProtectionLevel,
                              sizeof(ProtectionLevel),
                              NULL,
                              NULL) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

PROCESS_INFORMATION ProcessInformation = { 0 };

if (CreateProcessW(ApplicationName,
                   CommandLine,
                   ProcessAttributes,
                   ThreadAttributes,
                   InheritHandles,
                   EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS,
                   Environment,
                   CurrentDirectory,
                   (LPSTARTUPINFOW)&StartupInfoEx,
                   &ProcessInformation) == FALSE)
{
    Result = GetLastError();
    goto exitFunc;
}

Atualizações e manutenção

Depois que o serviço antimalware é iniciado como protegido, outros processos não protegidos (e até mesmo administradores) não conseguem interromper o serviço. No caso de atualizações para os binários de serviço, o serviço antimalware precisa receber um retorno de chamada do instalador para parar a si mesmo para que possa ser atendido. Depois que o serviço for interrompido, o instalador antimalware poderá executar atualizações e seguir as etapas descritas acima nas seções Como registrar o serviço e Iniciar o serviço como protegido para registrar o certificado e iniciar o serviço como protegido.

Observe que o serviço deve garantir que apenas chamadores confiáveis possam interromper o serviço. Permitir que chamadores não confiáveis façam isso frustra o propósito de proteger o serviço.

Cancelar o registro do serviço

Quando você desinstala um serviço protegido, o serviço precisa marcar a si mesmo como desprotegido chamando a API ChangeServiceConfig2. Observe que, como o sistema não permite que nenhum processo não protegido altere a configuração de um serviço protegido, a chamada para ChangeServiceConfig2 precisa ser feita pelo próprio serviço protegido. Depois que o serviço tiver sido reconfigurado para ser executado como desprotegido, o desinstalador pode simplesmente tomar as medidas apropriadas para remover o software antimalware do sistema.

Depurando um serviço antimalware protegido

Como parte do modelo de segurança de processo protegido, outros processos não protegidos não são capazes de injetar threads ou gravar na memória virtual do processo protegido. No entanto, um KD (depurador de kernel) é permitido para depurar quaisquer processos antimalware protegidos. O KD também pode ser usado para verificar se o serviço antimalware está sendo executado como protegido ou não:

dt –r1 nt!_EPROCESS <Process Address>
+0x67a Protection       : _PS_PROTECTION
      +0x000 Level            : 0x31 '1'
      +0x000 Type             : 0y0001
      +0x000 Signer           : 0y0011

Se o valor do membro Type for 0y0001, o serviço será executado como protegido.

Além disso, somente os seguintes comandos SC são permitidos no serviço antimalware protegido:

  • sc config start=Auto
  • sc qc
  • sc start
  • sc interrogate
  • sc sdshow

Se o depurador estiver anexado, use o seguinte sinalizador no registro para interromper o depurador quando binários não assinados (ou assinados inadequadamente) forem carregados no serviço protegido contra malware.

Key:   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CI
Value: DebugFlags      REG_DWORD

Defina o valor para 00000400 para interromper o depurador quando a validação da assinatura falhar.

Observação

Limitações de processar protegido:

  1. Os processos que têm interface do usuário ou uma GUI não podem ser protegidos devido à maneira como o kernel bloqueia um processo na memória e não permite gravações nele.
  2. Antes do Windows 10, versão 1703 (a atualização dos Criadores), os processos protegidos não podem usar os protocolos de comunicação TLS ou SSL devido a limitações de compartilhamento de certificado entre a LSA (Autoridade de Segurança Local) e um processo protegido.

Recursos

Para saber mais, veja:

Essas funções de API do Windows são referenciadas neste artigo: