Protección de servicios antimalware

Windows 8.1 introdujo un nuevo concepto de servicios protegidos para proteger los servicios antimalware, que son un objetivo frecuente de ataque por malware.

Descubra cómo proteger los servicios de modo usuario antimalware (AM) y cómo puede incluir esta característica en el servicio antimalware.

Esta información se aplica a los siguientes sistemas operativos y sus sucesores:

  • Windows 8.1
  • Windows Server 2012 R2

Al final de este tema se enumeran las referencias y los recursos que se describen aquí.

Introducción

La mayoría de las soluciones antimalware incluyen un servicio de modo usuario que realiza operaciones especializadas para detectar y quitar malware del sistema. Este servicio de modo usuario también es responsable con frecuencia de descargar las últimas definiciones y firmas de virus. Este servicio de modo usuario se convierte en un objetivo frecuente de malware porque es el único punto de error para deshabilitar la protección en un sistema. Para defenderse contra ataques en el servicio de modo usuario, los proveedores de antimalware tienen que agregar una gran cantidad de funcionalidades e heurística a su software. Sin embargo, estas técnicas no son completamente infalibles y tienden a ser propensas a errores porque tienen que identificar la funcionalidad que Windows realiza en su servicio y habilitar de forma selectiva esa funcionalidad.

En Windows 8.1, se ha introducido un nuevo concepto de servicio protegido para permitir que los servicios de modo usuario antimalware se inicien como un servicio protegido. Una vez que el servicio se inicia como protegido, Windows usa la integridad del código para permitir que el código de confianza se cargue en el servicio protegido. Windows también protege estos procesos frente a la inyección de código y otros ataques de procesos de administración.

En este documento se describe cómo un proveedor de antimalware con un controlador Early Launch Anti-Malware (ELAM) puede optar a esta característica e iniciar su servicio antimalware como servicio protegido.

Proceso protegido por el sistema

A partir de Windows 8.1, se ha implementado un nuevo modelo de seguridad en el kernel para defenderse mejor contra ataques malintencionados en componentes críticos del sistema. Este nuevo modelo de seguridad amplía las versiones anteriores de Windows de la infraestructura de procesos protegidos usadas para escenarios específicos, como la reproducción de contenido DRM, en un modelo de uso general que los proveedores de antimalware de terceros pueden usar. La infraestructura de procesos protegidos solo permite cargar código firmado de confianza y tiene defensa integrada contra ataques por inyección de código.

Nota:

CodeIntegrity prohíbe los siguientes archivos DLL de scripting dentro de un proceso protegido (cargado directa e indirectamente), por ejemplo, a través de WinVerifyTrust o WinVerifyTrustEx para comprobar las firmas de script mediante AuthentiCode: scrobj.dll, scrrun.dll, jscript.dll, jscript9.dll y vbscript.dll.

Consulte Procesos protegidos en Windows Vista para más información sobre los procesos protegidos.

El nuevo modelo de seguridad usa una variante ligeramente diferente de la infraestructura de procesos de protección llamada proceso protegido del sistema, que es más adecuada para esta característica, ya que el contenido DRM se mantiene aparte. Cada proceso protegido del sistema tiene un nivel o atributo asociado, que indica la directiva de firma del código firmado que se permite cargar dentro del proceso. Después de que los servicios antimalware hayan optado por el modo de servicio protegido, solo se permite cargar en ese proceso código de Windows o código firmado con los certificados del proveedor de antimalware. Del mismo modo, otros niveles de proceso protegido tienen directivas de código diferentes aplicadas por Windows.

Requisitos

Para que un servicio de modo usuario antimalware se ejecute como un servicio protegido, el proveedor antimalware debe tener instalado un controlador antimalware de inicio temprano en la máquina Windows. Además de los requisitos existentes de certificación del controlador antimalware de inicio temprano, el controlador debe tener una sección de recursos insertada que contenga la información de los certificados usados para firmar los archivos binarios del servicio de modo usuario.

Importante

En Windows 8.1, la cadena de certificación debe ser una raíz conocida determinada por la comprobación del controlador, o se debe incluir el certificado raíz.

Durante el proceso de arranque, esta sección de recursos se extraerá del controlador antimalware de inicio temprano para validar la información del certificado y registrar el servicio antimalware. El servicio antimalware también se puede registrar durante el proceso de instalación del software antimalware llamando a una API especial, como se describe más adelante en este documento.

Una vez que la sección de recursos se extrae correctamente del controlador antimalware de inicio temprano y se registra el servicio de modo usuario, el servicio puede iniciarse como servicio protegido. Después de que el servicio se inicia como protegido, otros procesos no protegidos del sistema no podrán insertar subprocesos y no podrán escribir en la memoria virtual del proceso protegido.

Además, los archivos DLL que no sean de Windows que se carguen en el proceso protegido deben estar firmados con un certificado adecuado.

Consulte Antimalware de inicio temprano para más información sobre los controladores antimalware de inicio temprano.

Requisitos de firma del servicio antimalware

El servicio de modo usuario que debe iniciarse como protegido debe estar firmado con certificados válidos. El archivo EXE del servicio debe estar firmado con hash de página y los archivos DLL que no sean de Windows que se carguen en el servicio también deben estar firmados con los mismos certificados. El hash de estos certificados debe agregarse al archivo de recursos, que se vinculará al controlador antimalware de inicio temprano.

Nota:

Aunque se deben usar valores hash de página o archivo SHA256, los certificados pueden seguir siendo SHA1.

Se recomienda que los proveedores de antimalware usen su certificado Authenticode existente para firmar sus archivos binarios del servicio antimalware y que el hash de este certificado Authenticode se incluya en la sección de recursos para indicar el certificado que se usará para firmar los archivos binarios del servicio. Si actualiza este certificado, se debe liberar una versión más reciente del controlador antimalware de inicio temprano con los valores hash de certificado actualizados.

Firma secundaria (opcional)

Los proveedores de antimalware tienen la opción de configurar una entidad de certificación privada y usar certificados de esta entidad para firmar el código de los archivos binarios del servicio antimalware como una firma secundaria. La principal ventaja de usar la entidad de certificación privada es que permite a los proveedores crear certificados con una propiedad EKU especializada, que se puede usar para diferenciar entre varios productos del mismo proveedor. También reduce la necesidad de actualizar el controlador antimalware de inicio temprano debido a la expiración del certificado, ya que los certificados de entidad de certificación privada suelen tener fechas de expiración más largas.

Tenga en cuenta que, si los archivos binarios del servicio están firmados con los certificados de entidad de certificación privada, también deben estar doblemente firmados con los certificados Authenticode existentes. Si los archivos binarios no están firmados por una entidad de certificación de confianza conocida (por ejemplo, VeriSign), el usuario de la máquina no tiene confianza en los archivos binarios porque no puede confiar en la entidad de certificación privada. La firma doble de los archivos binarios con el certificado Authenticode existente también permite que los archivos binarios se ejecuten en sistemas operativos de nivel inferior.

Para más información sobre cómo configurar e instalar la entidad de certificación, consulte Configuración de una entidad de certificación e Instalación de la entidad de certificación.

Nota:

Para la compatibilidad con Windows Vista o Windows XP (o Windows 7 sin la revisión SHA2), puede usar el modificador "/as" al firmar los archivos binarios con SignTool.exe con los valores hash de archivo o página SHA256. De esta forma, la firma se agregará al archivo como una firma secundaria. SHA1 firma primero el archivo, ya que Windows XP, Windows Vista y Windows 7 solo verán la primera firma.

Requisitos de firma de DLL

Como se mencionó anteriormente, los archivos DLL que no son de Windows que se cargan en el servicio protegido deben estar firmados con el mismo certificado que se usó para firmar el servicio antimalware.

Firma de catálogo

Los proveedores de antimalware pueden incluir paquetes desarrollados por otras empresas sin actualizar las firmas binarias. Para ello, se pueden incluir los archivos binarios en un catálogo firmado con su certificado Authenticode, lo que se consigue siguiendo estos pasos:

  1. Genere un catálogo mediante MakeCat.
  2. Agregue al catálogo todos los archivos binarios sin una firma adecuada.
  3. Firme el catálogo con el certificado Authenticode, como lo haría con cualquier otro archivo binario.
  4. Use la función add catalog para incluir el catálogo con la aplicación.

Cuando la integridad del código encuentre los paquetes sin una firma adecuada, buscará un catálogo con una firma aprobada. Este catálogo lo encontrará siempre que se sigan estos pasos y se instale con la aplicación.

Información del archivo de recursos

Se debe crear y vincular un archivo de recursos al controlador antimalware de inicio temprano. El hash del certificado, junto con otra información del certificado, debe agregarse al archivo de recursos.

La sección de recursos debe estar dispuesta de esta manera para que el sistema extraiga correctamente los recursos de la imagen binaria y valide la información del certificado insertado.

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

Para más información sobre el archivo de recursos definido por el usuario, consulte Recurso definido por el usuario.

CertHash

Hash del certificado que se usa para firmar el servicio antimalware. La herramienta CertUtil.exe, que se incluye en Windows SDK, se puede usar para obtener el hash.

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

Por ejemplo:

anti-malware protected service certificate hash (certhash)

Algoritmo

El valor del algoritmo representa el algoritmo del certificado. Se admiten estos valores de algoritmo:

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

Recuerde incluir el valor del algoritmo (como se muestra anteriormente) y no el nombre real del algoritmo. Por ejemplo, si el certificado se basa en el algoritmo SHA256, incluya 0x800c en la sección de recursos.

EKU

El objeto EKU representa una única propiedad de uso mejorado de clave (EKU) de un certificado. Es opcional y se debe especificar "\0" si no hay ningún EKU asociado al certificado. En caso de que haya varios productos y servicios de un único proveedor de antimalware ejecutándose en el mismo sistema, el proveedor de antimalware puede usar la propiedad EKU del certificado de entidad de certificación privada para diferenciar un servicio de otro. Por ejemplo, si hay dos servicios que se ejecutan en el sistema desde el mismo proveedor de antimalware y firmados por la misma entidad de certificación, el servicio que debe iniciarse como protegido se puede firmar con un certificado emitido por la entidad de certificación que contenga un EKU especial. Este EKU debe agregarse a la sección de recursos. A continuación, el sistema registra el EKU y se empareja con el hash de certificado para validar e iniciar el servicio como protegido.

Tenga en cuenta que la cadena de certificados debe incluir el EKU de firma de código (1.3.6.1.5.5.7.3.3), pero este EKU no debe incluirse en la sección de recursos del controlador antimalware de inicio temprano.

Nota:

Si la información de EKU se incluye en la información del certificado para el controlador antimalware de inicio temprano, se debe usar el mismo EKU al firmar los archivos binarios.

Nota:

La representación de cadena de la integridad del código de Windows de un OID en un EKU tiene una longitud máxima de 64 caracteres, incluido el carácter de terminación cero.  

Nota:

Si especifica varios EKU, se evalúan con la lógica AND. El certificado de entidad final debe satisfacer todos los EKU especificados en la sección de recursos de ELAM para la entrada especificada.

Count

Si el binario del servicio antimalware está firmado con el certificado Authenticode, así como con el certificado de entidad de certificación privada, solo se debe agregar la información del certificado de entidad de certificación privada en la sección de recursos.

Inicio de servicios antimalware como protegidos

Registrar el servicio

El servicio antimalware debe registrarse con el sistema para poder iniciarlo como protegido. Durante la instalación del software antimalware, el instalador puede instalar el controlador antimalware de inicio temprano y reiniciar el sistema para registrar automáticamente el servicio. El sistema registrará el servicio en tiempo de arranque extrayendo la información del certificado del archivo de recursos antes mencionado que está vinculado al controlador antimalware de inicio temprano.

Durante la fase de instalación, se recomienda encarecidamente reiniciar el sistema para que el controlador antimalware de inicio temprano se cargue y valide el estado del sistema. Sin embargo, en los casos en los que se deba evitar un reinicio, Windows también expone un mecanismo para que el instalador antimalware registre el servicio como protegido mediante una API.

Registro del servicio sin reiniciar el sistema

Durante la instalación, un instalador de software antimalware puede llamar a la API InstallELAMCertificateInfo y proporcionar un identificador al archivo del controlador antimalware de inicio temprano. El sistema abre el controlador antimalware de inicio temprano, llama a rutinas internas para asegurarse de que dicho controlador está firmado correctamente y extrae la información del certificado de la sección de recursos asociada a él. Para ver la sintaxis de función, consulte InstallELAMCertificateInfo.

Ejemplo de código

HANDLE FileHandle = NULL;

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

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

Inicio del servicio como protegido

El instalador puede seguir estos pasos para crear, configurar e iniciar el servicio como protegido:

  1. Llame a la API CreateService para crear un objeto de servicio y agregarlo a la base de datos del API del administrador de controles de servicio (SCM).

  2. Llame a la API SetServiceObjectSecurity para establecer el descriptor de seguridad del objeto de servicio creado en el paso 1.

  3. Llame a la API ChangeServiceConfig2 para marcar el servicio como protegido, y especifique el nuevo valor de enumeración SERVICE_CONFIG_LAUNCH_PROTECTED, que se ha agregado en Winsvc.h (a partir de Windows 8.1).

    Ejemplo de código

    SERVICE_LAUNCH_PROTECTED_INFO Info;
    SC_HANDLE hService;
    
    Info.dwLaunchProtected = SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT;
    
    hService = CreateService (/* ... */);
    
    if (ChangeServiceConfig2(hService,
                             SERVICE_CONFIG_LAUNCH_PROTECTED,
                             &Info) == FALSE)
    {
        Result = GetLastError();
    }
    
  4. Llame a la API StartService para iniciar el servicio. Al iniciar el servicio como protegido, SCM lo comprueba con el subsistema de integridad de código (CI) para validar la información del certificado. Después de que el CI valida la información del certificado, SCM inicia el servicio como protegido.

    1. Tenga en cuenta que este paso da error si no ha registrado el servicio mediante una llamada a la API InstallELAMCertificateInfo.
    2. Si el servicio se ha configurado para iniciarse automáticamente durante la fase de inicio del sistema, puede evitar este paso y simplemente reiniciar el sistema. Durante un reinicio, el sistema registra automáticamente el servicio (si el controlador antimalware de inicio temprano se inicia correctamente) e inicia el servicio en modo protegido.
    3. Si el servicio no se inicia, consulte la información en Registro de eventos de integridad de código y auditoría del sistema y temas siguientes. Allí encontrará mensajes de error más detallados que explican por qué el sistema de integridad de código ha impedido que el servicio se inicie. Esos registros también pueden ayudarle a identificar los archivos DLL que el servicio intentó cargar, pero no pudo hacerlo.

Inicio de un proceso secundario como protegido

El nuevo modelo de seguridad también permite que los servicios protegidos antimalware inicien procesos secundarios como protegidos. Estos procesos secundarios se ejecutarán en el mismo nivel de protección que el servicio primario y sus archivos binarios deben estar firmados con el mismo certificado que se ha registrado a través de la sección de recursos de ELAM.

Para permitir que el servicio protegido antimalware inicie el proceso secundario como protegido, se ha expuesto una nueva clave de atributo extendida, PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, y se debe usar con la API UpdateProcThreadAttribute. Se debe pasar un puntero al valor de atributo de PROTECTION_LEVEL_SAME a la API UpdateProcThreadAttribute.

Notas:

  • Para poder usar este nuevo atributo, el servicio también debe especificar CREATE_PROTECTED_PROCESS en el parámetro de marcas de creación de procesos de la llamada CreateProcess.
  • Debe tener los archivos binarios del servicio firmados mediante el modificador /ac para incluir el certificado cruzado y encadenarlo a una entidad de certificación conocida. El certificado autofirmado sin encadenarlo correctamente a una entidad de certificación raíz conocida no funcionará.

Ejemplo de código

DWORD ProtectionLevel = PROTECTION_LEVEL_SAME;
SIZE_T AttributeListSize;

STARTUPINFOEXW StartupInfoEx = { 0 };

StartupInfoEx.StartupInfo.cb = sizeof(StartupInfoEx);

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

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

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

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

PROCESS_INFORMATION ProcessInformation = { 0 };

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

Actualizaciones y mantenimiento

Después de iniciar el servicio antimalware como protegido, otros procesos no protegidos (e incluso administradores) no pueden detener el servicio. En el caso de las actualizaciones de los archivos binarios del servicio, el servicio antimalware debe recibir una devolución de llamada del instalador para que se detenga a fin de que se le pueda atender. Una vez detenido el servicio, el instalador antimalware puede realizar actualizaciones y, luego, seguir los pasos descritos anteriormente en las secciones Registro del servicio e Inicio del servicio como protegido para registrar el certificado e iniciar el servicio como protegido.

Tenga en cuenta que el servicio debe asegurarse de que solo autores de llamada de confianza puedan detenerlo. Permitir que lo hagan autores de llamada que no son de confianza contradice el propósito de proteger el servicio.

Anulación del registro del servicio

Al desinstalar un servicio protegido, el servicio debe marcarse a sí mismo como desprotegido llamando a la API ChangeServiceConfig2. Tenga en cuenta que, dado que el sistema no permite que ningún proceso no protegido modifique la configuración de un servicio protegido, la llamada a ChangeServiceConfig2 debe realizarla el propio servicio protegido. Una vez que el servicio se ha reconfigurado para ejecutarse como desprotegido, el desinstalador simplemente puede realizar los pasos adecuados para quitar el software antimalware del sistema.

Depuración de un servicio protegido antimalware

Como parte del modelo de seguridad de procesos protegidos, otros procesos no protegidos no pueden insertar subprocesos ni escribir en la memoria virtual del proceso protegido. Sin embargo, se permite un depurador de kernel (KD) para depurar los procesos protegidos antimalware. El KD también se puede usar para comprobar si el servicio antimalware se está ejecutando como protegido o no:

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

Si el valor del miembro Type es 0y0001, el servicio se ejecuta como protegido.

Además, solo se permiten los siguientes comandos SC en el servicio protegido antimalware:

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

Si el depurador está conectado, utilice la siguiente marca en el Registro para interrumpir el depurador cuando se carguen archivos binarios sin firmar (o firmados de forma inadecuada) en el servicio protegido antimalware.

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

Establezca el valor en 00000400 para interrumpir el depurador cuando se produzca un error en la validación de la firma.

Nota:

Limitaciones del proceso protegido:

  1. Los procesos que tienen una interfaz de usuario o una GUI no se pueden proteger debido a la forma en que el kernel bloquea un proceso en memoria y no permite escribir en él.
  2. Antes de Windows 10, versión 1703 (la actualización Creators), los procesos protegidos no pueden usar los protocolos de comunicación TLS o SSL debido a las limitaciones de uso compartido de certificados entre la autoridad de seguridad local (LSA) y un proceso protegido.

Recursos

Para obtener más información, consulta:

En este artículo se hace referencia a estas funciones de API de Windows: