Partilhar via


Lista de verificação de segurança do condutor

Este artigo fornece uma lista de verificação de segurança para desenvolvedores de drivers, ajudando a reduzir o risco de comprometimento dos mesmos. A segurança do motorista é fundamental e afeta diretamente a confiabilidade. Quando o Windows deteta que o acesso incorreto à memória está ocorrendo, ele desligará o sistema operacional e exibirá uma tela de erro azul. Como parceiro do Windows, você deve trabalhar para reduzir o impacto significativo que um driver com falha tem na vida de nossos clientes.

Para obter mais informações sobre os benefícios de fornecer um driver seguro e confiável, consulte Diretrizes de segurança do driver.

Visão geral da segurança do controlador

Uma falha de segurança é qualquer falha que permite que um invasor faça com que um driver funcione mal de tal forma que permita que um invasor obtenha acesso não autorizado, manipule o sistema ou comprometa dados, potencialmente fazendo com que o sistema falhe ou se torne inutilizável. Além disso, vulnerabilidades no código do driver podem permitir que um invasor obtenha acesso ao kernel, criando a possibilidade de comprometer todo o sistema operacional.

Quando a maioria dos desenvolvedores está trabalhando em seu driver, seu foco é fazer com que o driver funcione corretamente, e não se um invasor mal-intencionado tentará explorar vulnerabilidades em seu código. Depois que um driver é liberado, no entanto, os invasores podem tentar investigar e identificar falhas de segurança. Os desenvolvedores devem considerar esses problemas durante a fase de design e implementação, a fim de minimizar a probabilidade de tais vulnerabilidades. O objetivo é eliminar todas as falhas de segurança conhecidas antes que o driver seja liberado.

Criar drivers mais seguros requer a cooperação do arquiteto do sistema (pensando conscientemente em ameaças potenciais ao driver), do desenvolvedor que implementa o código (codificando defensivamente operações comuns que podem ser a fonte de exploits) e da equipe de teste (tentando proativamente encontrar fraquezas e vulnerabilidades). Ao coordenar adequadamente todas estas atividades, a segurança do condutor é dramaticamente melhorada.

Além de evitar os problemas associados a um driver sendo atacado, muitas das etapas descritas, como o uso mais preciso da memória do kernel, aumentarão a confiabilidade do seu driver. Isso reduz os custos de suporte e aumenta a satisfação do cliente com seu produto. Completar as tarefas na lista de verificação abaixo ajudará a alcançar todos esses objetivos.

Lista de verificação de segurança:Conclua a tarefa de segurança descrita em cada um destes tópicos.

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Confirme se é necessário um controlador de kernel

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Use as estruturas de controladores

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Gerir o controlo de acesso do motorista

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Controlar o acesso apenas aos drivers de software

Caixa de seleção não marcada que representa um item numa lista de verificação de segurança. Siga as diretrizes de codificação segura do driver

Caixa de seleção não marcada que representa um item no checklist de segurança. Implementar código compatível com HVCI

Caixa de verificação não marcada que representa um item na lista de verificação de segurança. Siga as melhores práticas de código específicas da tecnologia

Caixa de seleção Não marcado que representa um item na lista de verificação de segurança. Adicione anotações SAL ao seu código de driver

Caixa de seleção desmarcada que representa um item na lista de verificação de segurança. Executar revisão de código por pares

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Realize análise de ameaças

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Use o CodeQL para verificar o código do driver

Caixa de seleção Não marcado que representa um item na lista de verificação de segurança. Use o Verificador de Driver para verificar se há vulnerabilidades

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Verifique o código com os testes do programa de compatibilidade de hardware

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Verificar os drivers prontos para enviar com ferramentas como BinSkim e SignTool

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Não assine o código do driver de teste para produção

Caixa de seleção não marcada representando um item na checklist de segurança. Execute a assinatura adequada do driver de versão e distribua o pacote de driver usando o Windows Update

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Compreenda como os drivers são reportados usando o Centro de Relatórios de Drivers Vulneráveis e Mal-Intencionados da Microsoft

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Reveja recursos de codificação seguros

Caixa de seleção não marcada que representa um item na lista de verificação de segurança. Revise o Resumo das principais conclusões

Confirme se um driver de kernel é necessário

Item #1 da lista de verificação de segurança:Confirme se um driver de kernel é necessário e se uma abordagem de menor risco, como serviço ou aplicativo do Windows, não é uma opção melhor.

Os drivers do kernel vivem no kernel do Windows e ter um problema ao executar no kernel expõe todo o sistema operacional. Se qualquer outra opção estiver disponível, provavelmente será menor custo e terá menos risco associado do que criar um novo driver kernel.

Para obter mais informações sobre como usar os drivers internos do Windows, consulte Você precisa escrever um driver?.

Para obter informações sobre como usar tarefas em segundo plano, consulte Dar suporte ao seu aplicativo com tarefas em segundo plano.

Para obter informações sobre como usar os Serviços do Windows, consulte Services.

Usar as estruturas de driver

Item #2 da lista de verificação de segurança:Use as estruturas de driver para reduzir o tamanho do seu código e aumentar sua confiabilidade e segurança.

Use as Estruturas de Driver do Windows para reduzir o tamanho do seu código e aumentar a sua confiabilidade e segurança. Para começar, revise Usando o WDF para criar um controlador. Para obter informações sobre como usar o UMDF (User Mode Driver Framework) de menor risco, consulte Escolhendo um modelo de driver.

Escrever um driver WDM (Windows Driver Model) antigo é mais demorado, dispendioso e envolve a recriação de código disponível nas estruturas de drivers.

O código-fonte do Windows Driver Framework (WDF) é de código aberto e está disponível no GitHub. Este é o mesmo código-fonte WDF que é fornecido no Windows. Você pode depurar seu driver de forma mais eficaz quando puder acompanhar as interações entre o driver e o WDF. Faça o download de https://github.com/Microsoft/Windows-Driver-Frameworks.

DMF - Estrutura de Módulo de Condutor

Considere o uso do Driver Module Framework (DMF) em seu projeto de driver. Desenvolvido pela equipe do Microsoft Surface, o DMF é uma estrutura que permite a criação de objetos WDF chamados módulos DMF. O código para esses módulos DMF pode ser compartilhado entre diferentes drivers. Além disso, o DMF fornece uma biblioteca de módulos DMF que foram desenvolvidos para drivers e oferecem reutilização de código para tarefas como gerenciamento de threads e E/S. Um módulo DMF é usado para encapsular tarefas de driver em unidades menores. Cada módulo é independente e tem seu próprio código, contexto e retornos de chamada, facilitando a reutilização. Para obter mais informações, consulte Introducing Driver Module Framework e a documentação do site GitHub.

Gerenciar controle de acesso do motorista

Item #3 da lista de verificação de segurança:Revise seu driver para certificar-se de que você está controlando corretamente o acesso.

Gestão do controlo de acesso dos controladores - WDF

Os drivers devem trabalhar para evitar que os usuários acessem inadequadamente os dispositivos e arquivos de um computador. Para impedir o acesso não autorizado a dispositivos e ficheiros, deve:

  • Nomeie objetos de dispositivo somente quando necessário. Os objetos de dispositivo nomeados geralmente só são necessários por motivos herdados, por exemplo, se você tiver um aplicativo que espera abrir o dispositivo usando um nome específico ou se estiver usando um dispositivo/dispositivo de controle não PNP. Os drivers WDF não precisam dar um nome ao seu dispositivo PnP FDO para criar um link simbólico usando WdfDeviceCreateSymbolicLink.

  • Acesso seguro a objetos e interfaces do dispositivo.

Para permitir que aplicativos ou outros drivers WDF acessem o PDO do dispositivo PnP, você deve usar interfaces de dispositivo. Para obter mais informações, consulte Usando interfaces de dispositivo. Uma interface de dispositivo serve como um link simbólico para o PDO da pilha de dispositivos.

Uma das melhores maneiras de controlar o acesso ao PDO é especificando uma cadeia de caracteres SDDL no seu INF. Se a cadeia de caracteres SDDL não estiver no arquivo INF, o Windows aplicará um descritor de segurança padrão. Para obter mais informações, consulte Protegendo objetos de dispositivo e SDDL para objetos de dispositivo.

Para obter mais informações sobre como controlar o acesso, consulte:

Controlando o acesso a dispositivos em drivers KMDF

Nomes, Descritores de Segurança e Classes de Dispositivos - Tornando os Objetos de Dispositivo Acessíveis... e SEGURO de janeiro e fevereiro de 2017 o NT Insider Newsletter publicado por OSR.

Gerir o controlo de acesso do controlador - WDM

Se você estiver trabalhando com um driver WDM e tiver usado um objeto de dispositivo nomeado, poderá usar IoCreateDeviceSecure e especificar um SDDL para protegê-lo. Quando implementar IoCreateDeviceSecure, especifique sempre um GUID de classe personalizada para o DeviceClassGuid. Você não deve especificar um GUID de classe existente aqui. Isso tem o potencial de quebrar as configurações de segurança ou compatibilidade para outros dispositivos pertencentes a essa classe. Para obter mais informações, consulte WdmlibIoCreateDeviceSecure.

Para mais informações, consulte:

Controlando o acesso ao dispositivo

Controlando o acesso ao namespace do dispositivo

modelo de segurança do Windows para desenvolvedores de drivers

Hierarquia de risco dos identificadores de segurança (SIDs)

A seção a seguir descreve a hierarquia de risco dos SIDs comuns usados no código do driver. Para obter informações gerais sobre SDDL, consulte SDDL for Device Objects, SID Stringse SDDL String Syntax.

É importante entender que, se chamadores com privilégios mais baixos tiverem permissão para acessar o kernel, o risco de código será aumentado. Neste diagrama de resumo, o risco aumenta à medida que você permite que SIDs com privilégios mais baixos acessem a funcionalidade do driver.

SY (System)
     \/
BA (Built-in Administrators)
     \/
LS (Local Service)
     \/
BU (Built-in User)
     \/
AC (Application Container)

Seguindo o princípio geral de segurança de privilégios mínimos, configure apenas o nível mínimo de acesso necessário para que o driver funcione.

Controle de segurança IOCTL granular WDM

Um IOCTL (Input/Output Control) no Windows é uma chamada do sistema para operações de entrada/saída específicas do dispositivo. IOCTLs são usados por aplicativos para se comunicar com drivers de dispositivo, permitindo que eles enviem comandos ou solicitem informações do hardware. Para obter mais informações, consulte Introdução aos códigos de controle de E/S e Exemplo de solicitação de E/S - uma visão geral.

Para gerenciar ainda mais a segurança quando IOCTLs são enviadas por chamadores de modo de usuário, o código do driver pode incluir a função IoValidateDeviceIoControlAccess. Esta função permite que um condutor verifique os direitos de acesso. Ao receber um IOCTL, um driver pode chamar IoValidateDeviceIoControlAccess, especificando FILE_READ_ACCESS, FILE_WRITE_ACCESS ou ambos.

A implementação do controle de segurança IOCTL granular não substitui a necessidade de gerenciar o acesso do driver usando as técnicas discutidas acima.

Para mais informações, consulte Definição de códigos de controlo de E/S e Questões de Segurança para códigos de controlo de E/S.

Controle o acesso apenas aos drivers de software

Item #4 da lista de verificação de segurança:Se um driver somente de software vai ser criado, controle de acesso adicional deve ser implementado.

Os controladores de núcleo baseados apenas em software não utilizam o plug-and-play (PnP) para se associarem a IDs de hardware específicos e podem ser executados em qualquer PC. Tal driver poderia ser usado para fins diferentes do originalmente pretendido, criando um vetor de ataque.

Como os drivers de kernel somente de software contêm risco adicional, eles devem ser limitados para serem executados em hardware específico, por exemplo, usando um ID PnP exclusivo para habilitar a criação de um driver PnP ou verificando a tabela SMBIOS quanto à presença de hardware específico.

Por exemplo, imagine que a Fabrikam OEM deseja distribuir um driver que habilita um utilitário de overclocking para seus sistemas. Se este driver somente de software fosse executado em um sistema de um OEM diferente, a instabilidade do sistema ou danos poderiam resultar. Os sistemas da Fabrikam devem incluir um ID PnP exclusivo para permitir a criação de um driver PnP que também seja atualizável através do Windows Update. Se isso não for possível, e a Fabrikam criar um driver herdado, esse driver deverá encontrar outro método para verificar se está sendo executado em um sistema da Fabrikam, por exemplo, examinando a tabela SMBIOS antes de habilitar quaisquer recursos.

Siga as diretrizes de codificação segura do driver

Item #5 da lista de verificação de segurança:Revise seu código e remova todas as vulnerabilidades de código conhecidas.

A principal atividade da criação de drivers seguros é identificar áreas no código que precisam ser alteradas para evitar vulnerabilidades de software conhecidas. Muitas dessas vulnerabilidades de software conhecidas lidam com o controle estrito do uso da memória para evitar problemas com outras pessoas substituindo ou comprometendo os locais de memória que seu driver usa.

Ferramentas de verificação de código, como CodeQL e testes específicos de driver, podem ser usadas para ajudar a localizar algumas, mas não todas, dessas vulnerabilidades. Essas ferramentas e testes são descritos posteriormente neste tópico.

Buffers de memória

Use o método apropriado para acessar buffers de dados com IOCTLs

Uma das principais responsabilidades de um driver do Windows é a transferência de dados entre aplicativos de modo de usuário e dispositivos de um sistema. Os três métodos para acessar buffers de dados são mostrados na tabela a seguir.

Tipo de buffer IOCTL Resumo Para mais informações
Método com Buffer Recomendado para a maioria das situações Usando E/S bufferizada
METHOD_IN_DIRECT ou METHOD_OUT_DIRECT Usado em algumas operações de entrada/saída de hardware de alta velocidade Usando E/S Direta
METHOD_NEITHER Evite, se possível usando de E/S direta ou em buffer

Em geral, a E/S em buffer é recomendada, pois fornece os métodos de buffer mais seguros. Mas, mesmo ao usar E/S em buffer, há riscos, como ponteiros incorporados que devem ser mitigados.

Para obter mais informações sobre como trabalhar com buffers em IOCTLs, consulte Métodos para Aceder Buffers de Dados.

Erros na utilização de E/S em modo de buffer IOCTL

  • Verifique o tamanho dos buffers relacionados à IOCTL. Para obter mais informações, consulte Falha ao verificar o tamanho dos buffers.

  • Inicialize corretamente os buffers de saída. Para obter mais informações, consulte Falha ao Inicializar Buffers de Saída.

  • Valide corretamente buffers de comprimento variável. Para obter mais informações, consulte Falha ao validar buffers de Variable-Length.

  • Ao usar E/S em buffer, certifique-se de retornar o comprimento adequado para o OutputBuffer no campo Informação da estrutura IO_STATUS_BLOCK. Não retorne apenas diretamente o comprimento de uma solicitação READ. Por exemplo, considere uma situação em que os dados retornados do espaço de utilizador indicam que há um buffer de 4K. Se o driver realmente deve retornar apenas 200 bytes, mas em vez disso apenas retorna 4K no campo Informações, ocorreu uma vulnerabilidade de divulgação não autorizada de informações. Esse problema ocorre porque em versões anteriores do Windows, o buffer que o Gerenciador de E/S usa para E/S em buffer não é zero. Assim, o aplicativo do usuário recebe de volta os 200 bytes originais de dados mais 4K-200 bytes do que estava no buffer (conteúdo do pool não paginado). Esse cenário pode ocorrer com todos os usos de E/S em buffer e não apenas com IOCTLs.

Erros na E/S direta IOCTL

Lide corretamente com buffers de comprimento zero. Para obter mais informações, consulte Erros de no Direct I/O.

Erros na referência a endereços de espaço do usuário

O código do driver deve fazer uso correto da memória

  • Todas as alocações de pool de drivers devem estar no pool não executável (NX). O uso de pools de memória NX é inerentemente mais seguro do que o uso de pools executáveis não paginados (NP) e fornece melhor proteção contra ataques de estouro.

  • Para permitir que os drivers suportem a virtualização HVCI, há requisitos adicionais de memória. Para obter mais informações, consulte Implementar código compatível com HVCI mais adiante neste artigo.

Vulnerabilidades do TOCTOU

Há uma vulnerabilidade potencial de tempo de verificação ao tempo de uso (TOCTOU) ao usar E/S direto (para IOCTLs ou para Leitura/Gravação). Lembre-se de que, como o driver está acessando o buffer de dados do usuário, o aplicativo do usuário pode estar acessando simultaneamente o mesmo buffer de dados.

Para gerenciar esse risco, copie todos os parâmetros que precisam ser validados do buffer de dados do usuário para a memória acessível exclusivamente no modo kernel, como a pilha ou o pool. Em seguida, uma vez que os dados não podem ser acessados pelo aplicativo do usuário, valide e opere com base nos dados que foram passados.

O registro específico do modelo MSR lê e grava

Intrínsecos do compilador, como __readmsr e __writemsr podem ser usados para acessar os registros específicos do modelo. Se esse acesso for necessário, o motorista deve sempre verificar se o registro para ler ou gravar está restrito ao índice ou intervalo esperado.

Para mais informações e exemplos de código, consulte Fornecer a capacidade de ler/escrever MSRs em Práticas recomendadas para restringir o comportamento de alto privilégio em drivers de modo kernel.

Puxadores

Objetos de dispositivo

IRPs

Os IRPs (Pacotes de Solicitação de E/S) do Windows são usados para comunicar solicitações de E/S entre o sistema operacional e os drivers de modo kernel, encapsulando todas as informações necessárias no pacote. Os IRPs facilitam a transferência assíncrona de dados, a sincronização e o tratamento de erros, garantindo uma comunicação eficiente e confiável com dispositivos de hardware. Para obter mais informações, consulte Pacotes de Solicitação de E/S e Visão Geral do Modelo de E/S do Windows .

WDF e IRPs

Uma vantagem de usar WDF é que os drivers WDF normalmente não acessam diretamente IRPs. Por exemplo, a estrutura converte os IRPs WDM que representam operações de controle de E/S de leitura, gravação e dispositivo em objetos de solicitação de estrutura que KMDF/UMDF recebem em filas de E/S. Sempre que possível, recomenda-se vivamente a utilização de WDF.

Se você precisar escrever um driver WDM, revise as orientações a seguir.

Gerencie corretamente os buffers de E/S de IRP

Analise estes tópicos que abordam como validar valores de entrada IRP:

DispatchReadWrite usando E/S em modo bufferizado

Erros na E/S em buffer

DispatchReadWrite utilizando I/O direto

Erros de de E/S direta

Valide valores associados a um IRP, como endereços e comprimentos de buffer.

Se você optar por usar Nenhuma E/S, esteja ciente de que, ao contrário de Leitura e Gravação, e ao contrário de E/S em buffer e E/S direta, ao usar Nenhuma E/S IOCTL os ponteiros e comprimentos de buffer não são validados pelo Gerenciador de E/S.

Lidar com operações de conclusão de IRP corretamente

Um driver nunca deve completar um IRP com um valor de status de STATUS_SUCCESS a menos que ele realmente suporte e processe o IRP. Para obter informações sobre as maneiras corretas de lidar com operações de conclusão de IRP, consulte Concluindo IRPs.

Gerenciar o estado pendente do IRP do driver

O driver deve marcar o IRP como pendente antes de salvar o IRP e deve considerar incluir a chamada para IoMarkIrpPending e a atribuição numa sequência sincronizada. Para obter mais informações, consulte Falha ao verificar o estado de um driver e Retenção de IRPs de entrada quando um dispositivo está em pausa.

Lidar com operações de cancelamento de IRP corretamente

As operações de cancelamento podem ser difíceis de codificar corretamente porque normalmente são executadas de forma assíncrona. Problemas no código que lida com operações de cancelamento podem passar despercebidos por um longo tempo, porque esse código normalmente não é executado com freqüência em um sistema em execução. Certifique-se de ler e entender todas as informações fornecidas em Cancelando IRPs. Preste especial atenção à sincronização do cancelamento de IRP e aos pontos a considerar ao cancelar IRPs.

Uma maneira recomendada de minimizar os problemas de sincronização associados às operações de cancelamento é implementar uma fila de IRP segura para cancelamento .

Garanta o tratamento adequado das operações de limpeza e encerramento de IRP.

Certifique-se de que compreende a diferença entre IRP_MJ_CLEANUP e IRP_MJ_CLOSE requisições. As solicitações de limpeza chegam depois que um aplicativo fecha todas as alças em um objeto de arquivo, mas às vezes antes de todas as solicitações de E/S serem concluídas. As solicitações de fechamento chegam depois que todas as solicitações de E/S para o objeto de arquivo foram concluídas ou canceladas. Para obter mais informações, consulte o seguinte:

DispatchCreate, DispatchClose e DispatchCreateClose rotinas

Rotinas de Limpeza de Despacho

Erros na Manipulação de Operações de Limpeza e Fechamento

Para obter mais informações sobre como manipular IRPs corretamente, consulte Erros adicionais no tratamento de IRPs.

Use funções seguras

Outras questões de segurança

  • Use um bloqueio ou uma sequência intertravada para evitar condições de corrida. Para obter mais informações, consulte erros em um ambiente multiprocessador.

  • Certifique-se de que nenhum filtro TDI (Transport Driver Interface) de rede ou LSPs (Layered Service Providers) sejam instalados pelo driver ou por pacotes de software associados durante a instalação ou o uso. Em vez disso, use APIs modernas, como o Windows Filtering Platform (WFP) .

Vulnerabilidades de código adicionais

Além das possíveis vulnerabilidades abordadas aqui, este artigo fornece informações adicionais sobre como melhorar a segurança do código do driver do modo kernel: Criando drivers Kernel-Mode confiáveis.

Para obter informações adicionais sobre codificação segura C e C++, consulte Recursos de codificação segura no final deste artigo.

Implementar código compatível com HVCI

Item #6 da lista de verificação de segurança:Valide se o driver usa memória para que seja compatível com HVCI.

Integridade da memória e compatibilidade com HVCI

A integridade da memória, também conhecida como HVCI (Integridade de Código Protegida por Hipervisor), usa tecnologia de hardware e virtualização para isolar a função de tomada de decisão de Integridade de Código (CI) do resto do sistema operacional. Ao usar a segurança baseada em virtualização para isolar a CI, a única maneira pela qual a memória do kernel pode se tornar executável é por meio de uma verificação de CI. Isso significa que as páginas de memória do kernel nunca podem ser graváveis e executáveis (W+X) e o código executável não pode ser modificado diretamente.

Para implementar o código compatível com HVCI, certifique-se de que o código do driver faça o seguinte:

  • Opta pelo NX por padrão
  • Usa APIs/sinalizadores NX para alocação de memória (NonPagedPoolNx)
  • Não usa seções que são graváveis e executáveis
  • Não tenta modificar diretamente a memória executável do sistema
  • Não usa código dinâmico no kernel
  • Não carrega arquivos de dados como executáveis
  • O alinhamento da seção é um múltiplo de 0x1000 (PAGE_SIZE). Por exemplo, DRIVER_ALIGNMENT=0x1000

Para obter mais informações sobre como usar a ferramenta e uma lista de chamadas de memória incompatíveis, consulte Implementar código compatível com HVCI.

Para obter mais informações sobre o teste de segurança dos fundamentos do sistema, consulte o teste de prontidão de integridade de código do HyperVisor e a integridade de código (HVCI) Hypervisor-Protected.

Melhore a segurança da instalação do dispositivo

Item #7 da lista de verificação de segurança:Revise as diretrizes de criação e instalação do driver inf para garantir que você esteja seguindo as práticas recomendadas.

Quando você cria o código que instala o pacote de driver, você deve certificar-se de que a instalação do seu dispositivo será sempre realizada de forma segura. Uma instalação segura de dispositivo é aquela que faz o seguinte:

  • Limita o acesso ao dispositivo e suas classes de interface de dispositivo
  • Limita o acesso aos serviços de driver que foram criados para o dispositivo
  • Protege os arquivos do driver contra modificação ou exclusão
  • Limita o acesso às entradas de registo do dispositivo
  • Limita o acesso às classes WMI do dispositivo
  • Usa funções SetupAPI corretamente

Para obter mais informações, consulte o seguinte:

Criação de instalações seguras de dispositivos

Diretrizes para usar o SetupAPI

Utilização de funções para instalação de dispositivos

Tópicos avançados de instalação de dispositivos e drivers

Siga as melhores práticas de código específicas para a tecnologia

Item #8 da lista de verificação de segurança:Reveja as seguintes orientações específicas da tecnologia para o seu motorista.

Sistemas de arquivos

Para obter mais informações, sobre a segurança do driver do sistema de arquivos, consulte o seguinte:

Introdução à Segurança dos Sistemas de Ficheiros

Problemas de segurança do sistema de arquivos

recursos de segurança para sistemas de arquivos

Coexistência com outros drivers de filtro do sistema de arquivos

Iniciativa de vírus da Microsoft

A Microsoft Virus Initiative (MVI) ajuda as organizações a melhorar as soluções de segurança em que nossos clientes confiam para mantê-los seguros. A Microsoft fornece ferramentas, recursos e conhecimento para oferecer suporte a experiências melhores em conjunto com ótimo desempenho, confiabilidade e compatibilidade. A Microsoft colabora com parceiros MVI para definir e seguir Práticas de Implantação Segura (SDP) para oferecer suporte à segurança e resiliência de nossos clientes em comum.

Se você for um fornecedor de antivírus, consulte Microsoft Virus Initiative para saber como ingressar no MVI para obter mais assistência na implantação de software. Para obter informações sobre como os fornecedores de segurança podem aproveitar melhor os recursos de segurança integrados do Windows para aumentar a segurança e a confiabilidade, consulte práticas recomendadas de segurança do Windows para integrar e gerenciar ferramentas de segurança.

NDIS - Rede

Para obter informações sobre a segurança do driver NDIS, consulte Problemas de segurança para drivers de rede.

Impressoras

Para obter informações relacionadas à segurança do driver de impressora, consulte V4 Printer Driver Security Considerations.

Problemas de segurança para drivers do Windows Image Acquisition (WIA)

Para obter informações sobre segurança WIA, consulte Problemas de Segurança para Controladores de Aquisição de Imagem do Windows (WIA).

Adicionar anotações SAL ao seu código de driver

Item #9 da lista de verificação de segurança:Adicione anotações SAL ao seu código de driver.

A linguagem de anotação de código-fonte (SAL) fornece um conjunto de anotações que você pode usar para descrever como uma função usa seus parâmetros, as suposições que faz sobre eles e as garantias que faz quando termina. As anotações são definidas no arquivo de cabeçalho sal.h. A análise de código do Visual Studio para C++ usa anotações SAL para modificar sua análise de funções. Para obter mais informações sobre o desenvolvimento de drivers SAL 2.0 para Windows, consulte Anotações SAL 2.0 para drivers do Windows e Usando anotações SAL para reduzir defeitos de código C/C++.

Para obter informações gerais sobre SAL, consulte este artigo disponível em OSR. Anotações SAL: Não me odeie porque sou bonita

Fazer revisão de código por pares

Item #10 da lista de verificação de segurança:Executar revisão de código de mesmo nível, para procurar problemas não surgidos pelas outras ferramentas e processos

Procura revisores de código experientes para identificar problemas que possas ter perdido. Um segundo conjunto de olhos muitas vezes verá problemas que você pode ter ignorado.

Se você não tiver uma equipe adequada para revisar seu código internamente, considere contratar ajuda externa para essa finalidade.

Realizar análise de ameaças

Item #11 da lista de verificação de segurança:Modifique um modelo de ameaça de driver existente ou crie um modelo de ameaça personalizado para seu driver.

Ao considerar a segurança, uma metodologia comum é criar modelos de ameaça específicos que tentam descrever os tipos de ataques possíveis. Essa técnica é útil ao projetar um driver porque força o desenvolvedor a considerar os potenciais vetores de ataque contra um driver com antecedência. Tendo identificado ameaças potenciais, um desenvolvedor de driver pode considerar meios de se defender contra essas ameaças, a fim de reforçar a segurança geral do componente de driver.

Este artigo fornece orientação específica para drivers na criação de um modelo de ameaça leve: Modelagem de ameaças para drivers. O artigo fornece um exemplo de diagrama de modelo de ameaça de controlador que pode ser usado como um ponto de partida para o seu controlador.

Diagrama de fluxo de dados de exemplo ilustrando um driver hipotético de modo kernel.

As práticas recomendadas do Security Development Lifecycle (SDL) e as ferramentas associadas podem ser usadas por IHVs e OEMs para melhorar a segurança de seus produtos. Para obter mais informações, consulte as recomendações SDL para OEMs.

Use o CodeQL para verificar o código do driver

Item #12 da lista de verificação de segurança:Use o CodeQL para verificar vulnerabilidades no código do driver.

CodeQL, por GitHub, é um mecanismo de análise de código semântico, e a combinação de um extenso conjunto de consultas de segurança, juntamente com uma plataforma robusta, torna-a uma ferramenta valiosa para proteger o código do controlador. Para obter mais informações, consulte CodeQL e o Teste de Logotipo de Ferramentas Estáticas.

Use o Verificador de Driver para verificar vulnerabilidades

Item #13 da lista de verificação de segurança:Use o Verificador de Driver para verificar se há vulnerabilidades no código do driver.

Driver Verifier usa um conjunto de regras de interface e um modelo do sistema operacional para determinar se o driver interage corretamente com o sistema operacional Windows. Driver Verifier encontra defeitos no código do driver que podem apontar para possíveis bugs nos drivers.

Driver Verifier permite o teste ao vivo do motorista. Driver Verifier monitora drivers do Windows em modo núcleo e drivers gráficos para detetar chamadas de função ilegais ou ações que podem corromper o sistema. Um depurador anexado, permite a visualização da execução do sistema operacional e do código do driver em tempo real. Driver Verifier pode sujeitar os drivers do Windows a uma variedade de tensões e testes para encontrar um comportamento inadequado. Para obter mais informações, consulte Verificador de Controlador.

O Driver Verifer funciona com drivers WDM e KMDF. Para obter os detalhes do que ele pode verificar, consulte os tópicos a seguir.

Para mais informações sobre os drivers com os quais o Driver Verifier pode trabalhar, consulte Regras de Conformidade DDI e Drivers Suportados. Para obter as regras do verificador adicional para controladores de tipos específicos, consulte:

Para te familiarizares com o DV, podes usar um dos drivers de exemplo (por exemplo, o exemplo de torradeira destacado: https://github.com/Microsoft/Windows-driver-samples/tree/main/general/toaster/toastDrv/kmdf/func/featured).

Verifique o código com os testes do programa de compatibilidade de hardware

Item #14 da lista de verificação de segurança:Use os testes do programa de compatibilidade de hardware relacionados à segurança para verificar se há problemas de segurança.

O programa de compatibilidade de hardware inclui testes relacionados à segurança que podem ser usados para procurar vulnerabilidades de código. O Programa de Compatibilidade de Hardware do Windows aproveita os testes no Windows Hardware Lab Kit (HLK). Os testes HLK Device Fundamentals podem ser usados na linha de comando para exercitar o código do driver e investigar pontos fracos. Para obter informações gerais sobre os testes de fundamentos do dispositivo e o programa de compatibilidade de hardware, consulte Windows Hardware Lab Kit.

Os testes a seguir são exemplos de testes que podem ser úteis para verificar o código do driver para alguns comportamentos associados a vulnerabilidades de código:

DF - Teste IOCTL aleatório Fuzz (Confiabilidade)

DF - Teste de subabertura difusa (Confiabilidade)

DF - Teste FSCTL de buffer de comprimento zero Fuzz (Confiabilidade)

DF - Teste FSCTL aleatório Fuzz (Confiabilidade)

DF - Teste Fuzz Misc API (Confiabilidade)

Você também pode usar o difusor de atraso de sincronização do kernel incluído no Verificador de Driver.

Os testes CHAOS (Concurrent Hardware and Operating System) executam vários testes de driver PnP, testes de difusão de driver de dispositivo e testes de sistema de energia simultaneamente. Para obter mais informações, consulte CHAOS Tests (Device Fundamentals).

Os testes de penetração de fundamentos de dispositivo executam várias formas de ataques de entrada, que são um componente crítico dos testes de segurança. Os testes de ataque e penetração podem ajudar a identificar vulnerabilidades em interfaces de software. Para obter mais informações, consulte Testes de Intrusão (Fundamentos de Dispositivos).

Use o Device Guard - Teste de conformidade, juntamente com as outras ferramentas descritas neste artigo, para confirmar se o driver é compatível com HVCI.

Ferramentas de teste personalizadas e específicas do domínio

Considere o desenvolvimento de testes de segurança personalizados específicos do domínio. Para desenvolver testes adicionais, reúna informações dos designers originais do software, bem como recursos de desenvolvimento não relacionados familiarizados com o tipo específico de driver que está sendo desenvolvido e uma ou mais pessoas familiarizadas com análise e prevenção de invasões de segurança.

Verifique os drivers prontos para enviar com ferramentas como BinSkim e SignTool

Item #15 da lista de verificação de segurança:Verifique o código compilado com as ferramentas como BinSkim e SignTool antes de ser carregado no Partner Center.

Use ferramentas como BinSkim e SignTool para examinar arquivos binários para verificar o código compilado antes que ele seja carregado no centro de parceiros para ser distribuído usando o Windows Update. Ter ferramentas para verificar binários compilados, antes de serem enviados para distribuição, adiciona outra camada de proteção.

BinSkim

BinSkim pode identificar práticas de codificação e construção que podem potencialmente tornar o binário vulnerável. BinSkim verifica:

  • Uso de conjuntos de ferramentas de compilador desatualizados - Os binários devem ser compilados em relação aos conjuntos de ferramentas de compilador mais recentes sempre que possível para maximizar o uso de mitigações de segurança atuais no nível do compilador e fornecidas pelo sistema operacional.
  • Configurações de compilação inseguras - Os binários devem ser compilados com as configurações mais seguras possíveis para permitir mitigações de segurança fornecidas pelo sistema operacional, maximizar erros do compilador e relatórios de avisos acionáveis, entre outras coisas.
  • Problemas de assinatura - Os binários assinados devem ser assinados com algoritmos criptograficamente fortes.

BinSkim é uma ferramenta de código aberto e gera arquivos de saída que usam o formato Static Analysis Results Interchange Format (SARIF). BinSkim substitui a antiga ferramenta BinScope.

Para obter mais informações sobre BinSkim, consulte Utilize o BinSkim para verificar binários e o Guia do Usuário BinSkim.

SignTool

Use o SignTool para verificar os ficheiros de drivers assinados para lançamento. Para obter mais informações, consulte Verificando a assinatura de um arquivo de driver de Release-Signed e Verificando a assinatura de um arquivo de catálogo assinado por um certificado de liberação comercial.

Não enviar código de teste para produção

Item #16 da lista de verificação de segurança:Não produza código de código de desenvolvimento, teste e fabricação de código de driver do kernel.

O código do driver do kernel usado para desenvolvimento, teste ou fabricação pode incluir recursos perigosos que representam um risco de segurança. Esse código perigoso nunca deve ser assinado com um certificado confiável pelo Windows. O mecanismo correto para executar código de driver perigoso é desabilitar a Inicialização Segura UEFI, habilitar o BCD "TESTSIGNING" e assinar o código de desenvolvimento, teste e fabricação usando um certificado não confiável (por exemplo, um gerado por makecert.exe).

O código assinado por um certificado de editores de software confiável (SPC) ou assinatura do Windows Hardware Quality Labs (WHQL) não deve facilitar o desconhecimento da integridade do código do Windows e das tecnologias de segurança. Antes de o código ser assinado por uma assinatura confiável SPC ou WHQL, primeiro verifique se está em conformidade com as orientações de Criar Drivers Confiáveis Kernel-Mode. Além disso, o código não deve conter quaisquer comportamentos perigosos, descritos abaixo.

Exemplos de comportamento perigoso incluem o seguinte:

  • Fornecendo a capacidade de mapear o kernel arbitrário, memória física ou de dispositivo para o modo de utilizador.
  • Fornecer a capacidade de ler ou escrever no núcleo, memória física ou de dispositivo de forma arbitrária, incluindo entrada/saída de porta (E/S).
  • Fornecer acesso ao armazenamento que ignora o controle de acesso do Windows.
  • Fornecer a capacidade de modificar hardware ou firmware que o driver não foi projetado para gerenciar.

Execute a assinatura adequada de driver de lançamento e distribua o seu pacote de driver usando o Windows Update

Item #17 da lista de verificação de segurança:Use o portal de parceiros do Windows para enviar seu pacote de driver para ser assinado e distribuído por meio do Windows Update.

Antes de lançar um pacote de driver para o público, você envia o pacote para certificação. Para obter mais informações, consulte Teste de desempenho e compatibilidade e Introdução ao programa de hardware.

O uso do Windows Update é altamente recomendado para a distribuição de pacotes de driver. O Windows Update fornece um sistema de distribuição robusto, seguro, dimensionado globalmente e em conformidade com a regulamentação que deve ser usado para fornecer atualizações de driver. Para obter mais informações, consulte Distribuição de um pacote de controlador.

Use a distribuição gradual e de voo do Driver no Partner Center for Windows Hardware para distribuir seu pacote de driver em anéis definidos do Windows Insider, ao mesmo tempo em que fornece monitoramento e avaliação automáticos. Monitore a implantação do driver usando as medidas de driver Microsoft, como porcentagem de máquinas sem um de falha do modo kernel para manter a qualidade.

Para obter uma descrição das práticas seguras de implantação de software, consulte o documento da CISA "Implantação Segura de Software: Como os Fabricantes de Software Podem Garantir Confiabilidade aos Clientes".

Entenda como os drivers são relatados usando o Central de Relatórios de Drivers Vulneráveis e Mal-Intencionados da Microsoft

Item #18 da lista de verificação de segurança: Entenda como os drivers são relatados usando o Microsoft Vulnerable and Malicious Driver Reporting Center

Qualquer pessoa pode enviar um driver questionável usando o Microsoft Vulnerable and Malicious Driver Reporting Center. Consulte esta entrada de blog para obter informações sobre como os drivers são enviados para análise - Melhore a segurança do kernel com o novo Microsoft Vulnerable and Malicious Driver Reporting Center

A Central de Relatórios pode verificar e analisar drivers do Windows criados para arquiteturas x86 e x64. Drivers verificados vulneráveis e mal-intencionados são sinalizados para análise e investigação pela equipe de drivers vulneráveis da Microsoft. Depois que os drivers vulneráveis são confirmados, uma notificação apropriada ocorre, eles são adicionados à lista de bloqueio de drivers vulneráveis. Para obter mais informações sobre isso, consulte regras de bloqueio de driver recomendadas pela Microsoft. Essas regras são aplicadas por padrão a dispositivos habilitados para HVCI (integridade de código protegido pelo hipervisor) e ao Windows 10 no modo S.

Revise os recursos de codificação seguros

Item #19 da lista de verificação de segurança:Revise esses recursos para expandir sua compreensão das práticas recomendadas de codificação segura aplicáveis aos desenvolvedores de drivers.

Orientação do Microsoft NISTIR 8397

A publicação do governo dos Estados Unidos NISTIR 8397: Diretrizes sobre Padrões Mínimos para Verificação de Software pelo Programador pelo National Institute of Standards and Technology (NIST) contém orientações sobre como construir software confiável e seguro em qualquer linguagem de programação.

Crie programas C++ confiáveis e seguros resume como usar produtos de desenvolvedor da Microsoft para C++ e outras linguagens para seguir as diretrizes NISTIR 8397.

Base de dados de vulnerabilidades de software conhecido do NIST

O National Vulnerability Database (NVD) é um repositório pesquisável de falhas de software relacionadas à segurança, incluindo drivers do Windows.

Pesquisa na Base de Dados de Vulnerabilidades do NIST

Visão geral do banco de dados nacional de vulnerabilidades

Padrões de codificação seguros

Universidade Carnegie Mellon SEI CERT - C Coding Standard: Regras para o desenvolvimento de sistemas seguros, confiáveis e protegidos (PDF).

MITRE - pontos fracos abordados pelo CERT C Secure Coding Standard

Microsoft Visual Studio - Usar os verificadores de diretrizes principais do C++

Organizações de codificação seguras

Agência para a Cibersegurança e a Segurança das Infraestruturas (CISA)

Recursos da CISA

Universidade Carnegie Mellon SEI CERT

SAFECode

OSR

OSR fornece treinamento de desenvolvimento de motoristas e serviços de consultoria. Os artigos do boletim informativo da OSR destacam problemas de segurança dos drivers.

Nomes, Descritores de Segurança e Classes de Dispositivos - Tornando os Objetos de Dispositivo Acessíveis... e SEGURO

Você tem que usar a proteção -- Inside Driver & Device Security

Locking Down Drivers - Um Levantamento de Técnicas

Meltdown e Spectre: E os motoristas?

Estudo de caso de vulnerabilidade do motorista

Do alerta à vulnerabilidade do driver: a investigação do Microsoft Defender ATP revela falha de escalonamento de privilégios

Segurança da cadeia de suprimentos de software e lista de materiais de software (SBOMs)

Os SBOMs fornecem uma lista de ingredientes usados na criação de um software, como software de código aberto, componentes e, potencialmente, até ferramentas de construção. Isso permite que produtores e consumidores façam um melhor inventário e avaliem o risco de licença e vulnerabilidade. A Microsoft está usando o SPDX (Software Package Data Exchange) como o formato de documento SBOM. Para obter mais informações, consulte Gerando listas de materiais de software (SBOMs) com SPDX no Microsoft e a Microsoft abre códigos-fonte sua ferramenta de geração de lista de materiais de software (SBOM).

A iniciativa Supply Chain Integrity, Transparency and Trust (SCITT) é um conjunto de padrões de internet IETF para gerenciar a conformidade de bens e serviços em cadeias de suprimentos de ponta a ponta. O SCITT apoia a verificação contínua de bens e serviços onde a autenticidade de entidades, evidências, políticas e artefatos pode ser assegurada e as ações das entidades podem ser garantidas como autorizadas, não repudiáveis, imutáveis e auditáveis.

Livros

24 Pecados Mortais da Segurança de Software: Falhas de Programação e Como Corrigi-las por Michael Howard, David LeBlanc e John Viega

Escrevendo Software Seguro Segunda Edição, Michael Howard e David LeBlanc

A Arte da Avaliação de Segurança de Software: Identificando e Prevenindo Vulnerabilidades de Software, Mark Dowd, John McDonald e Justin Schuh

Codificação Segura em C e C++ (Série SEI em Engenharia de Software) 2ª Edição, Robert C. Seacord

Programação do Microsoft Windows Driver Model (2ª Edição), Walter Oney

Desenvolvendo drivers com o Windows Driver Foundation (Referência do desenvolvedor), Penny Orwick e Guy Smith

Formação

O treinamento em sala de aula de drivers do Windows está disponível em fornecedores como os seguintes:

O treinamento on-line de codificação segura está disponível em uma variedade de fontes. Por exemplo, este curso está disponível no Coursera.

Identificação de vulnerabilidades de segurança node programação C/C++.

O SAFECode também oferece formação gratuita:

SAFECode.org/training

Certificação Profissional

A CERT oferece uma certificação Secure Coding Professional.

Resumo das principais conclusões

A segurança dos motoristas é uma tarefa complexa que contém muitos elementos, mas aqui estão alguns pontos-chave a considerar:

  • Os drivers vivem no kernel do Windows, e ter um problema ao executar no kernel expõe todo o sistema operacional. Por isso, preste muita atenção à segurança do motorista e ao design com a segurança em mente.

  • Aplicar o princípio do menor privilégio:

    um. Use uma cadeia de caracteres SDDL estrita para restringir o acesso ao driver

    b. Restringir ainda mais as IOCTL individuais

  • Crie um modelo de ameaça para identificar vetores de ataque e considere se algo pode ser restringido ainda mais.

  • Tenha cuidado com relação aos ponteiros incorporados que estão a ser passados do modo utilizador. Eles precisam ser sondados e acessados num bloco try except, e são propensos a problemas de tempo de verificação de tempo de uso (ToCToU), a menos que o valor do buffer seja capturado e comparado.

  • Se não tiveres certeza, usa METHOD_BUFFERED como método de buffer de IOCTL.

  • Use utilitários de verificação de código, como o CodeQL, para procurar vulnerabilidades de código conhecidas e corrigir quaisquer problemas identificados.

  • Procura revisores de código experientes para identificar problemas que possas ter perdido.

  • Use verificadores de controladores e teste o seu controlador com várias entradas, incluindo casos limite.