Compartir a través de


Lista de verificación de seguridad del conductor

En este artículo se proporciona una lista de comprobación de seguridad de controladores para que los desarrolladores de controladores ayuden a reducir el riesgo de que los controladores se vean comprometidos. La seguridad del controlador es fundamental y afecta directamente a la confiabilidad. Cuando Windows detecta que se está produciendo un acceso incorrecto a la memoria, apagará el sistema operativo y mostrará una pantalla de error azul. Como asociado de Windows, debes trabajar para reducir el impacto significativo que tiene un controlador con errores en nuestras vidas de los clientes.

Para obtener más información sobre las ventajas de proporcionar un controlador seguro y confiable, consulte Guía de seguridad del controlador.

Introducción a la seguridad del controlador

Un error de seguridad es cualquier error que permite a un atacante hacer que un controlador funcione mal de forma que permita a un atacante obtener acceso no autorizado, manipular el sistema o poner en peligro los datos, lo que podría provocar que el sistema se bloquee o se vuelva inutilizable. Además, las vulnerabilidades en el código del controlador pueden permitir que un atacante obtenga acceso al kernel, creando la posibilidad de comprometer todo el sistema operativo.

Cuando la mayoría de los desarrolladores trabajan en sus controladores, su atención se centra en logar que el controlador funcione correctamente y no en si un atacante malintencionado intentará aprovechar vulnerabilidades dentro de su código. Sin embargo, una vez que se lanza un controlador, los atacantes pueden intentar investigar e identificar errores de seguridad. Los desarrolladores deben tener en cuenta estas cuestiones durante la fase de diseño e implementación para minimizar la probabilidad de que se produzcan dichas vulnerabilidades. El objetivo es eliminar todos los errores de seguridad conocidos antes de que se lance el controlador.

La creación de controladores más seguros requiere la cooperación del arquitecto del sistema (pensando conscientemente en posibles amenazas al controlador), del desarrollador que implementa el código (codificando de forma defensiva las operaciones comunes que pueden ser fuente de vulnerabilidades de seguridad) y del equipo de prueba (intentando encontrar de forma proactiva puntos débiles y vulnerabilidades). Al coordinar adecuadamente todas estas actividades, la seguridad del controlador se mejora considerablemente.

Además de evitar los problemas asociados con un controlador atacado, muchos de los pasos descritos, como el uso más preciso de la memoria del kernel, aumentarán la confiabilidad del controlador. Esto reduce los costos de soporte técnico y aumenta la satisfacción del cliente con su producto. Completar las tareas de la lista de comprobación siguiente le ayudará a lograr todos estos objetivos.

Lista de comprobación de seguridad: complete la tarea de seguridad descrita en cada uno de los temas siguientes.

casilla sin marcar que representa un elemento en la lista de verificación de seguridad.Confirme que se requiere un controlador de núcleo

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad. Usar los marcos del controlador

casilla sin marcar que representa un elemento en la lista de comprobación de seguridad.Administrar el control de acceso del controlador

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Controlar el acceso solo a los controladores del software

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Seguir las directrices de codificación segura del controlador

casilla de verificación sin marcar que representa un elemento en la lista de comprobación de seguridad.Implementar código compatible con HVCI

casilla sin marcar que representa un elemento en la lista de comprobación de seguridad.Seguir las mejores prácticas de codificación específicas de la tecnología

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Agregar anotaciones SAL al código del controlador

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Realizar una revisión del código del mismo nivel

casilla sin marcar que representa un elemento en la lista de verificación de seguridad.Realizar análisis de amenazas

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Utilizar CodeQL para comprobar el código del controlador

casilla sin marcar que representa un elemento en la lista de comprobación de seguridad.Utilice el verificador de controladores para verificar vulnerabilidades

Casilla sin marcar que representa un elemento en la lista de comprobación de seguridad.Verificar código con las pruebas del programa de compatibilidad de hardware

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad. Compruebe los controladores listos para enviar con las herramientas como BinSkim y SignTool

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad. No firmar el código del controlador de prueba de producción

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad. Casilla de verificación sin marcar que representa un elemento de la lista de comprobación de seguridad

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad.Comprender cómo se notifican los controladores mediante el Centro de informes de controladores vulnerables y malintencionados de Microsoft

Casilla sin marcar que representa un elemento en la lista de comprobación de seguridad.Revisar recursos seguros de codificación

Casilla de comprobación sin marcar que representa un elemento en la lista de comprobación de seguridad. Revisar el Resumen de conclusiones clave

Confirmar que se requiere un controlador de kernel

elemento de lista de comprobación de seguridad n.º 1:Confirmar que se requiere un controlador de kernel y que un enfoque de menor riesgo, como el servicio o la aplicación de Windows, no es una opción mejor.

Los controladores de kernel residen en el kernel de Windows y si surge un problema al ejecutarse en el kernel, queda expuesto todo el sistema operativo. Si hay alguna otra opción disponible, es probable que sea más económica y tenga menos riesgos asociados que crear un nuevo controlador de kernel.

Para obtener más información sobre el uso de los controladores de Windows integrados, consulte ¿Necesita escribir un controlador?.

Para obtener información sobre el uso de tareas en segundo plano, consulte Como apoyar su aplicación con tareas en segundo plano.

Para obtener información sobre el uso de los servicios de Windows, consulte Servicios.

Usar los marcos del controlador

Elemento de la lista de comprobación de seguridad n.º 2:Utiliza los frameworks de controladores para reducir el tamaño del código y aumentar su fiabilidad y seguridad.

Usa el Windows Driver Frameworks para reducir el tamaño de tu código y aumentar su confiabilidad y seguridad. Para empezar, revise Uso de WDF para desarrollar un controlador. Para obtener información sobre el uso del marco de controlador del modo de usuario (UMDF) de menor riesgo, consulte Elección de un modelo de controlador.

Escribir un controlador Windows Driver Model (WDM) antiguo requiere más tiempo, es más costoso y casi siempre implica volver a crear el código que esté disponible en los marcos del controlador.

El código fuente de Windows Driver Framework (WDF) es de código abierto y está disponible en GitHub. Este es el mismo código fuente de WDF que se incluye en Windows. Puede depurar el controlador de forma más efectiva si puede seguir las interacciones entre el controlador y WDF. Descárguelo desde https://github.com/Microsoft/Windows-Driver-Frameworks.

DMF: marco de módulo de controlador

Considere el uso de Driver Module Framework (DMF) en el proyecto de controlador. Desarrollado por el equipo de Microsoft Surface, DMF es un marco que permite la creación de objetos WDF denominados módulos DMF. El código de estos módulos DMF se puede compartir entre distintos controladores. Además, DMF proporciona una biblioteca de módulos DMF que se han desarrollado para controladores y ofrecen reutilización de código para tareas como la administración de subprocesos y E/S. Un módulo DMF se usa para encapsular las tareas del controlador en unidades más pequeñas. Cada módulo es autónomo y tiene su propio código, contexto y funciones de retrollamada, lo que facilita la reutilización. Para obtener más información, consulte la sección "Introducción al Marco de Módulos de Controladores" y la documentación del sitio de GitHub .

Administrar el control de acceso del controlador

Elemento de la lista de comprobación de seguridad n.º 3:revise el controlador para asegurarse de que controla el acceso correctamente.

Administración del control de acceso del controlador: WDF

Los controladores deben funcionar para evitar que los usuarios accedan de forma inapropiada a los dispositivos y archivos de un equipo. Para evitar el acceso no autorizado a dispositivos y archivos, debe:

  • Asignar un nombre a los objetos de dispositivo solo cuando sea necesario. Los objetos de dispositivo con nombre generalmente solo son necesarios por motivos heredados, por ejemplo, si tiene una aplicación que espera abrir el dispositivo con un nombre en particular o si está utilizando un dispositivo que no sea PNP o un dispositivo de control. Tenga en cuenta que los controladores WDF no necesitan asignar un nombre FDO al dispositivo PnP para crear un vínculo simbólico mediante WdfDeviceCreateSymbolicLink.

  • Proteja el acceso a los objetos e interfaces del dispositivo.

Para permitir que las aplicaciones u otros controladores WDF accedan al PDO del dispositivo PnP, debe usar interfaces de dispositivo. Para obtener más información, consulte Uso de interfaces de dispositivos. Una interfaz de dispositivo actúa como un vínculo simbólico al PDO de la pila de dispositivos.

Una de las mejores formas de controlar el acceso al PDO es especificar una cadena SDDL en el INF. Si la cadena SDDL no está en el archivo INF, Windows aplicará un descriptor de seguridad predeterminado. Para obtener más información, consulte Protección de objetos de dispositivo y SDDL para objetos de dispositivo.

Para obtener más información sobre el control del acceso, consulte lo siguiente:

Control del acceso a dispositivos en controladores KMDF

Nombres, descriptores de seguridad y clases de dispositivo: cómo hacer que los objetos de dispositivo sean accesibles... and SAFE desde enero, febrero 2017 The NT Insider Newsletter publicado por OSR.

Administración del control de acceso del controlador: WDM

Si está trabajando con un controlador WDM y ha usado un objeto de dispositivo con nombre, puede usar IoCreateDeviceSecure y especificar un SDDL para protegerlo. Al implementar IoCreateDeviceSecure, especifique siempre un GUID de clase personalizado para DeviceClassGuid. No debe especificar aquí un GUID de clase existente. Hacerlo, podría interrumpir la configuración de seguridad o la compatibilidad con otros dispositivos que pertenecen a esa clase. Para obtener más información, consulte WdmlibIoCreateDeviceSecure.

Para obtener más información, consulte lo siguiente:

Control del acceso al dispositivo

Control del acceso al espacio de nombres del dispositivo

Modelo de seguridad de Windows para desarrolladores de controladores

Jerarquía de riesgos de identificadores de seguridad (SID)

En la sección siguiente se describe la jerarquía de riesgos de los SID comunes que se usan en el código de controlador. Para obtener información general sobre SDDL, consulte SDDL para objetos de dispositivo, Cadenas SID y la sintaxis de cadenas SDDL.

Es importante saber que si se permite que autores de llamada con menos privilegios accedan al kernel, el riesgo del código aumenta. En este diagrama de resumen, el riesgo aumenta a medida que se permite el acceso de los SIDs de menor privilegio a la funcionalidad de su controlador.

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

Siguiendo el principio general de seguridad de mínimo privilegio, configure solo el nivel mínimo de acceso requerido para que su controlador funcione.

Control de seguridad IOCTL pormenorizado de WDM

Un IOCTL (Control de entrada/salida) en Windows es una llamada del sistema para las operaciones de entrada y salida específicas del dispositivo. Las aplicaciones usan ICTL para comunicarse con controladores de dispositivo, lo que les permite enviar comandos o solicitar información del hardware. Para obtener más información, vea Introducción a los Códigos de Control de E/S y Solicitud de E/S de Ejemplo: Información General.

Para administrar aún más la seguridad cuando los autores de llamadas en modo de usuario envían IOCTL, el código de controlador puede incluir la función IoValidateDeviceIoControlAccess. Esta función permite a un controlador comprobar los derechos de acceso. Al recibir un IOCTL, un controlador puede llamar a IoValidateDeviceIoControlAccess, especificando FILE_READ_ACCESS, FILE_WRITE_ACCESS o ambos.

La implementación de un control de seguridad IOCTL pormenorizado no reemplaza la necesidad de administrar el acceso de los controladores mediante las técnicas descritas anteriormente.

Para obtener más información, vea Definición de códigos de control de E/S y Problemas de seguridad para códigos de control de E/S.

Controlar el acceso solo a los controladores del software

elemento de lista de comprobación de seguridad n.º 4:Si se va a crear un controlador de solo software, se debe implementar un control de acceso adicional.

Los controladores de kernel de solo software no usan plug-and-play (PnP) para asociarse con identificadores de hardware específicos y pueden ejecutarse en cualquier equipo. Un controlador de este tipo podría usarse para fines distintos a los previstos originalmente, creando un vector de ataque.

Debido a que los controladores de kernel de solo software contienen riesgos adicionales, se debe limitar su ejecución en hardware específico (por ejemplo, utilizando un identificador de PnP único para habilitar la creación de un controlador PnP o comprobando la tabla SMBIOS para detectar la presencia de hardware específico).

Por ejemplo, imaginemos que OEM Fabrikam desea distribuir un controlador que habilite una utilidad de overclocking para sus sistemas. Si este controlador de solo software se ejecutara en un sistema desde un OEM diferente, podría producirse inestabilidad o daños en el sistema. Los sistemas de Fabrikam deben incluir un identificador de PnP único para habilitar la creación de un controlador PnP que también se pueda actualizar a través de Windows Update. Si esto no es posible y Fabrikam crea un controlador heredado, ese controlador debe encontrar otro método para comprobar que se está ejecutando en un sistema Fabrikam (por ejemplo, mediante el examen de la tabla SMBIOS antes de habilitar cualquier funcionalidad).

Seguir las directrices de codificación segura del controlador

elemento de lista de comprobación de seguridad n.º 5:Revise el código y quite las vulnerabilidades de código conocidas.

La actividad principal de la creación de controladores seguros es identificar áreas en el código que deben cambiarse para evitar vulnerabilidades de software conocidas. Muchas de estas vulnerabilidades de software conocidas se ocupan de mantener un seguimiento estricto del uso de la memoria para evitar problemas causados por otros que sobrescriban o comprometan las ubicaciones de memoria que usa su controlador.

Las herramientas de análisis de código, como CodeQL y pruebas específicas del controlador, se pueden usar para ayudar a localizar, algunas, pero no todas, de estas vulnerabilidades. Estas herramientas y pruebas se describen más adelante en este tema.

Búferes de memoria

Uso del método adecuado para acceder a los búferes de datos con IOCTL

Una de las principales responsabilidades de un controlador de Windows es transferir datos entre las aplicaciones en modo de usuario y los dispositivos de un sistema. Los tres métodos para acceder a los búferes de datos se muestran en la tabla siguiente.

Tipo de búfer IOCTL Resumen Para más información
METHOD_BUFFERED Recomendado para la mayoría de las situaciones Uso de E/S almacenada en búfer
METHOD_IN_DIRECT o METHOD_OUT_DIRECT Se utiliza en algunas E/S de hardware de alta velocidad Uso de E/S directa
METHOD_NEITHER Evitar si es posible Sin uso de búfer ni E/S directa

En general, se recomienda la E/S almacenada en búfer, ya que proporciona los métodos de almacenamiento en búfer más seguros. Pero incluso cuando se usa la E/S almacenada en búfer existen riesgos, como punteros integrados, que deben mitigarse.

Para obtener más información sobre cómo trabajar con búferes en IOCTL, consulte Métodos para acceder a a búferes de datos.

Errores en el uso de E/S con búfer IOCTL

  • Compruebe el tamaño de los búferes relacionados con IOCTL. Para obtener más información, consulte Error al comprobar el tamaño de los búferes.

  • Inicialice correctamente los búferes de salida. Para obtener más información, consulte Error al iniciar búferes de salida

  • Valide correctamente los búferes de longitud variable. Para obtener más información, consulte Error al validar búferes de longitud variable

  • Al usar E/S almacenada en búfer, asegúrese de devolver la longitud adecuada para OutputBuffer en el campo Información de estructura IO_STATUS_BLOCK. No solo devuelva directamente la longitud directamente desde una solicitud READ. Por ejemplo, considere una situación en la que los datos devueltos desde el espacio de usuario indican que hay un búfer de 4K. Si el controlador en realidad solo debería devolver 200 bytes, pero en lugar de eso devuelve 4K en el campo Información, se ha producido una vulnerabilidad de divulgación de información. Este problema se produce porque en las versiones anteriores de Windows, el búfer que utiliza el Administrador de E/S para la E/S con almacenamiento en búfer no se pone a cero. Por lo tanto, la aplicación de usuario recupera los 200 bytes de datos originales más 4K-200 bytes de lo que había en el búfer (contenido del grupo no paginado). Este escenario puede producirse con todos los usos de E/S almacenados en búfer y no solo con IOCTL.

Errores en la E/S directa de IOCTL

Maneje correctamente los búferes de longitud cero. Para obtener más información, consulte Errores en E/S directa.

Errores al hacer referencia a direcciones de espacio de usuario

El código del controlador debe hacer un uso correcto de la memoria

  • Todas las asignaciones del grupo de controladores deben estar en un grupo que no sea ejecutable (NX). El uso de grupos de memoria NX es intrínsecamente más seguro que el uso de grupos ejecutables no paginados (NP) y proporciona una mejor protección contra ataques de desbordamiento.

  • Para permitir que los controladores admitan la virtualización de HVCI, existen requisitos de memoria adicionales. Para obtener más información, consulte Implementar código compatible con HVCI más adelante en este artículo.

Vulnerabilidades de TOCTOU

Existe una posible vulnerabilidad de tiempo de verificación a tiempo de uso (TOCTOU) cuando se usa E/S directa (para IOCTL o para lectura y escritura). Tenga en cuenta que, a medida que el controlador accede al búfer de datos de usuario, la aplicación de usuario puede acceder simultáneamente al mismo búfer de datos.

Para administrar este riesgo, copie todos los parámetros que se deban validar desde el búfer de datos de usuario a una memoria a la que solo se pueda acceder desde el modo kernel (como la pila o el grupo). Una vez que la aplicación de usuario no pueda acceder a los datos, valídelos y opere con ellos.

Lecturas y escrituras de registros específicos del modelo MSR

Las funciones intrínsecas del compilador, como __readmsr y __writemsr se pueden usar para acceder a los registros específicos del modelo. Si se requiere este acceso, el controlador siempre debe comprobar que el registro en el que se va a leer o escribir, está restringido al índice o intervalo esperados.

Para más información, y ejemplos de código, consulte Proporcionando la habilidad de leer/escribir MSRs en Mejores prácticas para restringir el comportamiento de alto privilegio en controladores de modo kernel.

Asas

Objetos de dispositivo

IRP

Los paquetes de solicitud de E/S de Windows (IRP) se usan para comunicar las solicitudes de E/S entre el sistema operativo y los controladores en modo kernel, encapsulando toda la información necesaria en el paquete. Los IRP facilitan la transferencia de datos asincrónica, la sincronización y el control de errores, lo que garantiza una comunicación eficaz y confiable con dispositivos de hardware. Para obtener más información, vea Paquetes de solicitud de E/S y Visión general del modelo de E/S de Windows.

WDF e IRP

Una ventaja de usar WDF es que los controladores WDF normalmente no acceden directamente a los IRP. Por ejemplo, el marco convierte los IRP de WDM que representan operaciones de control de E/S de lectura, escritura y dispositivo a objetos de solicitud de marco que KMDF/UMDF reciben en colas de E/S. Siempre que sea posible, se recomienda encarecidamente el uso de WDF.

Si necesita escribir un controlador WDM, revise las instrucciones siguientes.

Administración correcta de los búferes de E/S de IRP

Revise estos temas que tratan cómo validar los valores de entrada de IRP:

DispatchReadWrite mediante E/S almacenadas en búfer

Errores en E/S almacenada en búfer

DispatchReadWrite mediante E/S directa

Errores en E/S directa

Valide los valores asociados a un IRP, como las direcciones y las longitudes del búfer.

Si elige usar Neither E/S, tenga en cuenta que, a diferencia de Lectura y Escritura, y a diferencia de E/S Almacenada en Búfer y E/S Directa, cuando se utiliza Neither E/S IOCTL, el Administrador de E/S no valida los punteros y longitudes del búfer.

Control correcto de las operaciones de finalización de IRP

Un controlador nunca debe completar un IRP con un valor de estado de STATUS_SUCCESS a menos que realmente admita y procese el IRP. Para obtener información sobre las formas correctas de manejar las operaciones de finalización de IRP, consulte Finalización de IRP.

Administración del estado pendiente del IRP del controlador

El controlador debe marcar el IRP como pendiente antes de almacenarlo y debe asegurarse de incluir tanto la llamada a IoMarkIrpPending como la asignación como parte de una secuencia interbloqueada. Para obtener más información, consulte Error al comprobar el estado de un controlador y Retener los IRP entrantes cuando un dispositivo está en pausa.

Manejar las operaciones de cancelación de IRP adecuadamente

Las operaciones de cancelación pueden ser difíciles de codificar correctamente porque normalmente se ejecutan de forma asincrónica. Los problemas en el código que controla las operaciones de cancelación pueden pasar desapercibidos durante mucho tiempo, ya que este código normalmente no se ejecuta con frecuencia en un sistema en ejecución. Asegúrese de leer y comprender toda la información proporcionada en Cancelación de IRP. Preste especial atención a la sincronización de la cancelación de IRP y a los puntos a tener en cuenta al cancelar IRP.

Una forma recomendada de minimizar los problemas de sincronización asociados con las operaciones de cancelación es implementar una cola IRP segura para la cancelación.

Control correcto de las operaciones de limpieza y cierre de IRP

Asegúrese de comprender la diferencia entre las solicitudes IRP_MJ_CLEANUP e IRP_MJ_CLOSE. Las solicitudes de limpieza llegan después de que una aplicación cierre todos los identificadores de un objeto de archivo, pero a veces antes de que se hayan completado todas las solicitudes de E/S. Las solicitudes de cierre llegan después de que se hayan completado o cancelado todas las solicitudes de E/S para el objeto de archivo. Para obtener más información, consulte lo siguiente:

Rutinas DispatchCreate, DispatchClose y DispatchCreateClose

Rutinas DispatchCleanup

Errores en el Control de las Operaciones de Limpieza y Cierre

Para obtener más información sobre cómo controlar IRP correctamente, consulte Errores adicionales en el control de IRP.

Uso de funciones seguras

Otros problemas de seguridad

  • Use un bloqueo o una secuencia entrelazada para evitar condiciones de carrera. Para obtener más información, consulte Errores en un entorno de varios procesadores.

  • Asegúrese de que ni el controlador ni los paquetes de software asociados instalen filtros de la Interfaz de Controlador de Transporte de Red (TDI) ni proveedores de servicios en capas (LSP) durante la instalación o el uso. En su lugar, use las API modernas, como la Windows Filtering Platform (WFP) .

Vulnerabilidades adicionales de código

Además de las posibles vulnerabilidades que se describen aquí, este artículo proporciona información adicional sobre cómo mejorar la seguridad del código de controlador en modo kernel: Creación de controladores fiables Kernel-Mode.

Para obtener más información sobre la codificación segura de C y C++, consulte Revisar los recursos de codificación segura al final de este artículo.

Implementar código compatible con HVCI

elemento de lista de comprobación de seguridad n.º 6:Validar que el controlador usa memoria para que sea compatible con HVCI.

Integridad de memoria y compatibilidad con HVCI

La integridad de memoria, también conocida como Integridad de código protegida por hipervisor (HVCI) usa tecnología de hardware y virtualización para aislar la función de toma de decisiones de integridad de código (CI) del resto del sistema operativo. Cuando se utiliza la seguridad basada en virtualización para aislar CI, la única forma en que la memoria del kernel se puede convertir en ejecutable es mediante una verificación de CI. Esto significa que las páginas de memoria del kernel nunca pueden ser regrabables y ejecutables (W+X) y el código ejecutable no se puede modificar directamente.

Para implementar código compatible con HVCI, asegúrese de que el código de controlador haga lo siguiente:

  • Participa en NX de forma predeterminada
  • Usa las API o marcas de NX para la asignación de memoria (NonPagedPoolNx)
  • No usa secciones que sean regrabables y ejecutables
  • No intenta modificar directamente la memoria del sistema ejecutable
  • No usa código dinámico en kernel
  • No carga archivos de datos como ejecutables
  • La alineación de sección es un múltiplo de 0x1000 (PAGE_SIZE). Por ejemplo, DRIVER_ALIGNMENT=0x1000

Para obtener más información sobre el uso de la herramienta y una lista de llamadas de memoria incompatibles, consulte Implementación de código compatible con HVCI.

Para obtener más información sobre la prueba de seguridad de los aspectos básicos del sistema relacionados, consulte Prueba de preparación de integridad de código de HyperVisor e Integridad del código protegido por hipervisor (HVCI).

Mejorar la seguridad de la instalación de dispositivos

Elemento de la lista de comprobación de seguridad n.º 7: revise las instrucciones de creación e instalación del controlador para asegurarse de que sigue los procedimientos recomendados.

Al crear el código que instala el paquete de controladores, debe asegurarse de que la instalación del dispositivo siempre se realizará de forma segura. Una instalación segura de dispositivos es aquella que hace lo siguiente:

  • Limita el acceso al dispositivo y a sus clases de interfaz de dispositivo.
  • Limita el acceso a los servicios de controlador que se crearon para el dispositivo.
  • Protege los archivos de controlador de modificaciones o eliminaciones.
  • Limita el acceso a las entradas del registro del dispositivo.
  • Limita el acceso a las clases WMI del dispositivo.
  • Usa las funciones SetupAPI correctamente

Para obtener más información, consulte lo siguiente:

Creación de Instalaciones Seguras de Dispositivos

Directrices para usar SetupAPI

Uso de funciones de instalación de dispositivos

Temas avanzados de instalación de dispositivos y controladores

Seguir prácticas recomendadas de codificación específicas para la tecnología

Elemento de la lista de comprobación de seguridad n.º 8:revise la siguiente guía tecnológica específica para el controlador.

Sistemas de archivos

Para obtener más información, acerca de la seguridad del controlador del sistema de archivos, consulte lo siguiente:

Introducción a la seguridad de los sistemas de archivos

Problemas de seguridad del sistema de archivos

Características de seguridad para sistemas de archivos

Coexistencia con otros controladores de filtro del sistema de archivos

Iniciativa de virus de Microsoft

La Iniciativa de virus de Microsoft (MVI) ayuda a las organizaciones a mejorar las soluciones de seguridad que nuestros clientes confían para mantenerlos seguros. Microsoft proporciona herramientas, recursos y conocimientos para apoyar experiencias integradas con un gran rendimiento, fiabilidad y compatibilidad. Microsoft colabora con asociados de MVI para definir y seguir los procedimientos de implementación seguros (SDP) para respaldar la seguridad y la resistencia de nuestros clientes mutuos.

Si es un proveedor antivirus, consulte Microsoft Virus Initiative para aprender a unirse a MVI para obtener más ayuda sobre la implementación de software. Para obtener información sobre cómo los proveedores de seguridad pueden aprovechar mejor las funcionalidades de seguridad integradas de Windows para obtener una mayor seguridad y confiabilidad, consulte procedimientos recomendados de seguridad de Windows para integrar y administrar herramientas de seguridad.

NDIS - Redes

Para obtener información sobre la seguridad del controlador NDIS, consulte Cuestiones de Seguridad para Controladores de Red.

Impresoras

Para obtener información relacionada con la seguridad del controlador de impresora, consulte Consideraciones de seguridad del controlador de impresora V4.

Problemas de seguridad de los controladores de adquisición de imágenes de Windows (WIA)

Para obtener información sobre la seguridad de WIA, consulta Problemas de seguridad de los controladores WIA de adquisición de imágenes de Windows.

Añade anotaciones SAL a tu código de controlador

Elemento de la lista de comprobación de seguridad n.º 9: agregue anotaciones SAL a en el código de controlador.

El lenguaje de anotación de código fuente (SAL) proporciona un conjunto de anotaciones que puede usar para describir cómo una función usa sus parámetros, las suposiciones que hace sobre ellos y las garantías que ofrece cuando finaliza. Las anotaciones se definen en el archivo de encabezado sal.h. Code Analysis de Visual Studio para C++ usa anotaciones SAL para modificar su análisis de funciones. Para obtener más información sobre el desarrollo de controladores SAL 2.0 para Windows, consulta Anotaciones de SAL 2.0 para controladores de Windows y Usar anotaciones SAL para reducir defectos de código de C/C++.

Para obtener información general sobre SAL, consulte este artículo disponible en OSR. anotaciones SAL: No me odies porque soy hermosa

Realizar una revisión del código del mismo nivel

elemento de lista de comprobación de seguridad n.º 10:Realizar revisión del código del mismo nivel, para buscar problemas no expuestos por las demás herramientas y procesos

Busque revisores de código expertos para buscar problemas que se puedan haber pasado por alto. Una segunda revisión a menudo detectará problemas que quizás usted haya pasado por alto.

Si no tiene personal adecuado para revisar el código internamente, considere la posibilidad de participar en la ayuda externa para este propósito.

Realizar análisis de amenazas

Elemento de la lista de comprobación de seguridad n.º 11:modifique un modelo de amenazas de controlador existente o cree un modelo de amenazas personalizado para el controlador.

Al considerar la seguridad, una metodología común consiste en crear modelos de amenazas específicos que intenten describir los tipos de ataques que son posibles. Esta técnica es útil al diseñar un controlador porque obliga al desarrollador a considerar de antemano los posibles vectores de ataque contra un controlador de antemano. Una vez identificadas las posibles amenazas, un desarrollador de controladores puede considerar medios de defensa contra estas amenazas a fin de reforzar la seguridad general del componente de controlador.

En este artículo se proporcionan instrucciones específicas del controlador para crear un modelo de amenazas ligero: Modelado de amenazas para controladores. En el artículo se proporciona un diagrama de modelo de amenazas de un controlador de ejemplo que se puede utilizar como punto de partida para su controlador.

Diagrama de flujo de datos de muestra que ilustra un controlador hipotético en modo kernel.

IHV y OEM pueden utilizar los procedimientos recomendados del ciclo de vida de desarrollo de seguridad (SDL) y las herramientas asociadas para mejorar la seguridad de sus productos. Para obtener más información, consulte Recomendaciones de SDL para OEM.

Utilizar CodeQL para comprobar el código del controlador

elemento de lista de comprobación de seguridad n.º 12:Usar CodeQL para comprobar si hay vulnerabilidades en el código de controlador.

CodeQL, de GitHub, es un motor de análisis de código semántico y la combinación de un amplio conjunto de consultas de seguridad junto con una plataforma sólida lo convierten en una herramienta valiosa para proteger el código de controlador. Para obtener más información, consulte CodeQL y Static Tools Logo Test.

Utilizar el comprobador de controladores para comprobar vulnerabilidades

elemento de lista de comprobación de seguridad n.º 13:Usar comprobador de controladores para comprobar si hay vulnerabilidades en el código de controlador.

El comprobador de controladores usa un conjunto de reglas de interfaz y un modelo del sistema operativo para determinar si el controlador interactúa correctamente con el sistema operativo Windows. El comprobador de controladores encuentra defectos en el código de controlador que podrían apuntar a posibles errores en los controladores.

El comprobador de controladores permite realizar pruebas del controlador de por vida. El Comprobador de controladores supervisa los controladores del modo kernel de Windows y los controladores gráficos para detectar llamadas o acciones de función no válidas que podrían dañar el sistema. Un depurador asociado permite ver la ejecución del código del sistema operativo y del controlador en tiempo real. Además, puede someter los controladores de Windows a varias pruebas y tensiones para detectar comportamientos incorrectos. Para obtener más información, consulte Comprobador de controladores.

Driver Verifer funciona con controladores WDM y KMDF. Para conocer los detalles de lo que puede comprobar, consulte los temas siguientes.

Para obtener más información sobre los controladores con los que Driver Verifier puede trabajar, consulte Reglas de cumplimiento DDI y controladores compatibles. Para conocer las reglas adicionales de Driver Verifier para tipos específicos de controladores, consulte:

Para familiarizarse con DV, puede usar uno de los controladores de ejemplo (por ejemplo, el ejemplo de toaster destacado: https://github.com/Microsoft/Windows-driver-samples/tree/main/general/toaster/toastDrv/kmdf/func/featured).

Comprobar el código con las pruebas del programa de compatibilidad de hardware

elemento de lista de comprobación de seguridad n.º 14:Use las pruebas del programa de compatibilidad de hardware relacionadas con la seguridad para comprobar si hay problemas de seguridad.

El programa de compatibilidad de hardware incluye pruebas relacionadas con la seguridad se pueden utilizar para buscar vulnerabilidades en el código. El Programa de compatibilidad de hardware con Windows aprovecha las pruebas de Windows Hardware Lab Kit (HLK). Las pruebas de aspectos básicos del dispositivo HLK se pueden usar en la línea de comandos para ejercitar el código del controlador y detectar puntos débiles. Para obtener información general sobre las pruebas fundamentales del dispositivo y el programa de compatibilidad de hardware, consulte Windows Hardware Lab Kit.

Las siguientes pruebas son ejemplos de pruebas que pueden resultar útiles para comprobar el código de controlador en busca de algunos comportamientos asociados con vulnerabilidades de código:

DF: Prueba aproximada de IOCTL aleatoria (confiabilidad)

DF: Prueba aproximada de aperturas relativas (confiabilidad)

DF: Prueba aproximada FSCTL de búfer de longitud cero (confiabilidad)

DF: Prueba aproximada de FSCTL aleatoria (confiabilidad)

DF: Prueba aproximada de Misc API (confiabilidad)

También puede usar la pruebas de vulnerabilidad ante datos aleatorios o inesperados de demora en la sincronización del kernel que se incluye con el comprobador de controladores.

Las pruebas CHAOS (hardware simultáneo y sistema operativo) ejecutan varias pruebas de controladores PnP, pruebas aproximadas del controlador de dispositivo y pruebas del sistema de energía simultáneamente. Para obtener más información, consulte Pruebas CHAOS (aspectos básicos del dispositivo).

Las pruebas de penetración de los fundamentos del dispositivo realizan varias formas de ataques de entrada, que son un componente crítico de las pruebas de seguridad. Las pruebas de ataque y penetración pueden ayudar a identificar vulnerabilidades en las interfaces de software. Para obtener más información, consulte Pruebas de penetración (aspectos básicos del dispositivo).

Utilice el Device Guard: Prueba de Cumplimiento, junto con las otras herramientas descritas en este artículo, para confirmar que su controlador es compatible con HVCI.

Herramientas de prueba personalizadas y específicas del dominio

Considere el desarrollo de pruebas de seguridad personalizadas y específicas para cada dominio. Para desarrollar pruebas adicionales, recopile información de los diseñadores originales del software, así como de recursos de desarrollo externos familiarizados con el controlador específico que se está desarrollando y de una o más personas que conozcan el análisis y la prevención de intrusiones de seguridad.

Comprobación de controladores listos para su envío con herramientas como BinSkim y SignTool

Punto nº 15 de la lista de comprobación de seguridad: Compruebe el código compilado con herramientas como BinSkim y SignTool antes de cargarlo en el centro de socios.

Usa herramientas como BinSkim y SignTool para examinar los archivos binarios para comprobar el código compilado antes de cargarlo en el Centro de partners para que se distribuya mediante Windows Update. Tener herramientas para comprobar los archivos binarios compilados, antes de que se envíen para su distribución, agrega otra capa de protección.

BinSkim

BinSkim puede identificar prácticas de codificación y construcción que puedan hacer que el binario sea potencialmente vulnerable. BinSkim comprueba si:

  • Se usan conjuntos de herramientas del compilador obsoletos: los archivos binarios deben compilarse con los conjuntos de herramientas de compilación más recientes siempre que sea posible para maximizar el uso de las mitigaciones de seguridad proporcionadas por el sistema operativo y el nivel de compilador actual.
  • Las configuraciones de compilaciones no son seguras: los archivos binarios deben compilarse con las configuraciones más seguras posibles para habilitar las mitigaciones de seguridad proporcionadas por el sistema operativo, maximizar los errores del compilador y los informes de advertencias procesables, entre otras cosas.
  • Hay problemas de firma: los archivos binarios firmados deben firmarse con algoritmos criptográficamente seguros.

BinSkim es una herramienta de código abierto y genera archivos de salida que usan el formato de intercambio de resultados de análisis estáticos (SARIF). BinSkim reemplaza la herramienta anterior BinScope.

Para obtener más información sobre BinSkim, consulte Usar BinSkim para comprobar los binarios y la Guía del Usuario de BinSkim.

SignTool

SignToolUtilice SignTool para comprobar los archivos de controlador firmados. Para obtener más información, consulte Verificación de la firma de un archivo de controlador firmado por la versión y Verificación de la firma de un archivo de catálogo firmado por un certificado de versión comercial.

No firmar el código del controlador de prueba de producción

Elemento de la lista de comprobación de seguridad n.º 16:no firme el código de producción del controlador del kernel para el desarrollo, pruebas y fabricación.

El código del controlador del kernel que se usa para el desarrollo, las pruebas o la fabricación podría incluir funcionalidades peligrosas que supongan un riesgo de seguridad. Este código peligroso nunca debe firmarse con un certificado en el que Windows confíe. El mecanismo correcto para ejecutar código de controlador peligroso es deshabilitar el arranque seguro UEFI, habilitar el BCD "TESTSIGNING" y firmar el código de desarrollo, prueba y fabricación mediante un certificado que no es de confianza (por ejemplo, uno generado por makecert.exe).

El código firmado por un Certificado de los Editores de Software (SPC) de confianza o una firma de Windows Hardware Quality Labs (WHQL) no debe facilitar la elusión de las tecnologías de seguridad e integridad de código de Windows. Antes de firmar el código con una firma SPC o WHQL confiable, primero asegúrese de que cumpla con las pautas de Creación de controladores en modo kernel confiables. Además, el código no debe contener ningún comportamiento peligroso, descrito a continuación.

Entre los ejemplos de comportamiento peligroso se incluyen los siguientes:

  • Proporcionar la capacidad de asignar memoria arbitraria del kernel, física o del dispositivo al modo de usuario.
  • Proporcionar la capacidad de leer o escribir memoria arbitraria del kernel, física o del dispositivo, incluida la entrada y salida del puerto (E/S).
  • Proporcionar acceso al almacenamiento que omite el control de acceso de Windows.
  • Proporcionar la capacidad de modificar el hardware o el firmware para cuya administración el controlador no fue diseñado.

Ejecute la firma correcta del controlador de lanzamiento y distribuya el paquete de controlador a través de Windows Update.

Elemento de la lista de comprobación de seguridad n.º 17:Utilice el portal de socios de Windows para enviar su paquete de controladores para que se firme y distribuya a través de Windows Update.

Antes de lanzar un paquete de controladores al público, envíe el paquete para su certificación. Para obtener más información, consulte Prueba de rendimiento y compatibilidad y Introducción al programa hardware.

Se recomienda encarecidamente usar Windows Update para la distribución de paquetes de controladores. Windows Update proporciona un sistema de distribución sólido, seguro, a escala mundial y que cumple con la normativa, que se debe usar para proporcionar actualizaciones de controladores. Para obtener más información, consulte Distribución de un paquete de controladores.

Utilice la implementación gradual y el vuelo de controladores en el Centro de socios para hardware de Windows para distribuir su paquete de controladores dentro de los anillos definidos de Windows Insider, al tiempo que proporciona supervisión y evaluación automáticas. Supervise el despliegue del controlador utilizando las medidas de controladores de Microsoft, como el Porcentaje de máquinas sin fallos en el modo Kernel, para mantener la calidad.

Para obtener una descripción de los procedimientos de implementación de software seguros, consulte el documento "Implementación Segura de Software de CISA: Cómo los fabricantes de software pueden garantizar la fiabilidad para los clientes".

Comprender cómo se notifican los controladores mediante el Centro de notificación de controladores maliciosos y vulnerables de Microsoft.

Punto 18 de la lista de comprobación de seguridad: Comprenda cómo se informa sobre los controladores mediante el Centro de informes sobre controladores vulnerables y malintencionados de Microsoft.

Cualquiera puede enviar un controlador cuestionable a través del Centro de informes sobre controladores malintencionados y vulnerables de Microsoft. Consulte esta entrada de blog para obtener información sobre cómo se envían los controladores para su análisis: cómo mejorar la seguridad del kernel con el nuevo Centro de informes de controladores vulnerables y malintencionados de Microsoft

El Centro de informes puede examinar y analizar controladores de Windows creados para arquitecturas x86 y x64. Los controladores analizados vulnerables y malintencionados se marcan para su análisis e investigación por parte del equipo de controladores vulnerables de Microsoft. Una vez confirmados los controladores vulnerables, se emite una notificación adecuada y se añaden a la lista de bloqueos de controladores vulnerables. Para obtener más información sobre esto, consulte Reglas de bloqueo de controladores recomendadas por Microsoft. Estas reglas se aplican de forma predeterminada a los dispositivos habilitados para integridad de código protegido por hipervisor (HVCI) y Windows 10 en modo S.

Revisar los recursos de codificación segura

Elemento de la lista de comprobación de seguridad n.º 19:revise estos recursos para ampliar la comprensión de los procedimientos recomendados de codificación segura aplicables a los desarrolladores de controladores.

Base de datos de vulnerabilidades de software conocida de NIST

La base de datos de vulnerabilidades nacionales (NVD) es un repositorio en el que se pueden buscar errores de software relacionados con la seguridad, incluidos los controladores de Windows.

Buscar en la base de datos de vulnerabilidades de NIST

Visión general de la Base de Datos Nacional de Vulnerabilidades

Estándares de codificación seguros

Carnegie Mellon University SEI CERT - Estándar de Codificación C: Reglas para desarrollar sistemas seguros, fiables y confiables (PDF).

MITRE - Debilidades Abordadas por el Estándar de Codificación Segura CERT C

Organizaciones de codificación segura

Agencia de Seguridad de Infraestructura y Ciberseguridad (CISA)

Recursos CISA

SAFECode: https://safecode.org/

Carnegie Mellon University SEI CERT

OSR

OSR proporciona servicios de consultoría y aprendizaje para el desarrollo de controladores. Estos artículos del boletín OSR destacan los problemas de seguridad de los controladores.

Nombres, descriptores de seguridad y clases de dispositivo: cómo hacer que los objetos de dispositivo sean accesibles... and SAFE

Debe usar la protección: seguridad interna del controlador & del dispositivo

Bloqueo de controladores: una encuesta sobre técnicas

Meltdown y Spectre: ¿qué pasa con los controladores?

Caso práctico de vulnerabilidad del controlador

De alerta a vulnerabilidad del controlador: la investigación de ATP de Microsoft Defender descubre el error de elevación de privilegios

Seguridad de la cadena de suministro de software y Lista de materiales de software (SBOM)

la iniciativa integridad de la cadena de suministro, transparencia y confianza (SCITT)

Generar listas de materiales de software (SBOM) con SPDX en Microsoft

Microsoft abre su herramienta de generación de listas de materiales de software (SBOM).

Libros

24 Pecados mortales de seguridad de software: Errores de programación y Cómo corregirlos por Michael Howard, David LeBlanc y John Viega

Escribir Software Seguro Segunda Edición, de Michael Howard y David LeBlanc

The Art of Software Security Assessment: Identificación y prevención de vulnerabilidades de software, Mark Dowd, John McDonald y Justin Schuh

Secure Coding in C and C++ (SEI Series in Software Engineering) 2nd Edition [Codificación segura en C y C++ (Serie SEI en ingeniería de software) 2.ª edición)], Robert C. Seacord

Programar el Modelo de Controlador de Microsoft Windows (2ª Edición), Walter Oney

Desarrollar controladores con Windows Driver Foundation (Referencia del desarrollador), Penny Orwick y Guy Smith

Cursos

La formación en aula para controladores de Windows está disponible a través de proveedores como los siguientes:

La formación en línea sobre codificación segura está disponible en una variedad de fuentes. Por ejemplo, este curso está disponible en:

Identificar vulnerabilidades de seguridad en la programación de C/C++.

SAFECode también ofrece formación gratuita:

SAFECode.org/training

Certificación profesional

CERT ofrece una certificación de Profesional en Codificación Segura .

Revisar el resumen de conclusiones clave

La seguridad del controlador es una tarea compleja que contiene muchos elementos, pero estos son algunos puntos clave a tener en cuenta:

  • Los controladores residen en el kernel de Windows y tener un problema cuando se ejecutan en el kernel expone todo el sistema operativo. Por este motivo, preste mucha atención a la seguridad y al diseño de los controladores teniendo en cuenta la seguridad.

  • Aplique el principio de mínimo privilegio:

    a. Usar una cadena SDDL estricta para restringir el acceso al controlador

    b. Restringir aún más los IOCTL individuales

  • Cree un modelo de amenaza para identificar vectores de ataque y considere si algo se puede restringir aún más.

  • Tenga cuidado con los punteros incrustados que se pasan desde el modo de usuario. Es necesario probarlos, acceder a ellos dentro de try except y son propensos a vulnerabilidad de tiempo de verificación a tiempo de uso (ToCToU) a menos que se capture y compare el valor del búfer.

  • Si no está seguro, use METHOD_BUFFERED como método de almacenamiento en búfer IOCTL.

  • Use utilidades de análisis de código como CodeQL para buscar vulnerabilidades de código conocidas y corregir los problemas identificados.

  • Busque revisores de código expertos para buscar problemas que se puedan haber pasado por alto.

  • Use comprobadores de controladores y pruebe el controlador con varias entradas, incluidos casos extremos.