NtAccessCheckByTypeResultListAndAuditAlarm
Comprobación de acceso tipada que devuelve una lista de resultados por tipo y registra entradas de alarma de auditoría en el log de Seguridad.
Prototipo
NTSTATUS NtAccessCheckByTypeResultListAndAuditAlarm( PUNICODE_STRING SubsystemName, PVOID HandleId, PUNICODE_STRING ObjectTypeName, PUNICODE_STRING ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType, ULONG Flags, POBJECT_TYPE_LIST ObjectTypeList, ULONG ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, BOOLEAN ObjectCreation, PACCESS_MASK GrantedAccessList, PNTSTATUS AccessStatusList, PBOOLEAN GenerateOnClose );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| SubsystemName | PUNICODE_STRING | in | Identificador del subsistema, p. ej. L"Security". Almacenado en cada evento de auditoría emitido. |
| HandleId | PVOID | in | ID de handle opaco de correlación expuesto en el evento de auditoría. |
| ObjectTypeName | PUNICODE_STRING | in | Nombre de tipo de objeto de nivel superior, p. ej. L"DS-Object", L"File". |
| ObjectName | PUNICODE_STRING | in | Nombre de instancia del objeto (DN, ruta, nombre de objeto kernel) registrado en el evento de auditoría. |
| SecurityDescriptor | PSECURITY_DESCRIPTOR | in | Descriptor de seguridad con DACL + SACL — ambos se consultan (DACL para acceso, SACL para auditoría). |
| PrincipalSelfSid | PSID | in | SID opcional sustituido por los marcadores PRINCIPAL_SELF en la DACL/SACL. |
| DesiredAccess | ACCESS_MASK | in | Derechos de acceso a evaluar por entrada de object-type-list. |
| AuditType | AUDIT_EVENT_TYPE | in | AuditEventObjectAccess o AuditEventDirectoryServiceAccess — escoge la categoría de auditoría. |
| Flags | ULONG | in | Reservado / modificadores de comportamiento (p. ej. AUDIT_ALLOW_NO_PRIVILEGE). |
| ObjectTypeList | POBJECT_TYPE_LIST | in | Lista aplanada de jerarquía de tipos (objeto + property sets + propiedades). |
| ObjectTypeListLength | ULONG | in | Número de entradas de ObjectTypeList; dimensiona los dos arreglos de salida. |
| GenericMapping | PGENERIC_MAPPING | in | Mapeo por tipo GENERIC_* -> derechos específicos. |
| ObjectCreation | BOOLEAN | in | TRUE para creación de objeto (registrado como creación), FALSE para apertura de objeto existente. |
| GrantedAccessList | PACCESS_MASK | out | Máscaras de acceso concedido por entrada. |
| AccessStatusList | PNTSTATUS | out | NTSTATUS por entrada (STATUS_SUCCESS / STATUS_ACCESS_DENIED). |
| GenerateOnClose | PBOOLEAN | out | TRUE si el llamante debe invocar después NtCloseObjectAuditAlarm para emitir el evento de cierre asociado. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x65 | win10-1507 |
| Win10 1607 | 0x65 | win10-1607 |
| Win10 1703 | 0x65 | win10-1703 |
| Win10 1709 | 0x65 | win10-1709 |
| Win10 1803 | 0x65 | win10-1803 |
| Win10 1809 | 0x65 | win10-1809 |
| Win10 1903 | 0x65 | win10-1903 |
| Win10 1909 | 0x65 | win10-1909 |
| Win10 2004 | 0x65 | win10-2004 |
| Win10 20H2 | 0x65 | win10-20h2 |
| Win10 21H1 | 0x65 | win10-21h1 |
| Win10 21H2 | 0x65 | win10-21h2 |
| Win10 22H2 | 0x65 | win10-22h2 |
| Win11 21H2 | 0x65 | win11-21h2 |
| Win11 22H2 | 0x65 | win11-22h2 |
| Win11 23H2 | 0x65 | win11-23h2 |
| Win11 24H2 | 0x65 | win11-24h2 |
| Server 2016 | 0x65 | winserver-2016 |
| Server 2019 | 0x65 | winserver-2019 |
| Server 2022 | 0x65 | winserver-2022 |
| Server 2025 | 0x65 | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 65 00 00 00 mov eax, 0x65 F6 04 25 08 03 FE 7F 01 test byte ptr [0x7FFE0308], 1 75 03 jne short +3 0F 05 syscall C3 ret CD 2E int 2Eh C3 ret
Notas no documentadas
Entre los syscalls de prototipo más largo de la Native API — 15 argumentos, debido a la combinación de comprobación de acceso tipada (jerarquía objeto + property sets) con emisión de auditoría. Es la unión de NtAccessCheckByTypeResultList (vector de resultados) y NtAccessCheckByTypeAndAuditAlarm (emisión de auditoría). Lo usa casi exclusivamente ntdsa.dll dentro de lsass.exe para evaluar lecturas/escrituras de objetos de Active Directory donde el resultado debe ser tanto por-property-set COMO registrado. La SACL del objeto AD impulsa si se emite un evento de Seguridad 4662 ("Se realizó una operación sobre un objeto"); la decisión por entrada impulsa si la operación se rechaza. El SSN `0x65` ha sido estable desde Windows 10 1507.
Uso común por malware
Esencialmente cero. La función es demasiado especializada — el llamante debe marshalizar un OBJECT_TYPE_LIST válido, poseer SeAuditPrivilege, y cada llamada exitosa genera un 4662 en el log de Seguridad. El malware commodity hace lo contrario: o evita por completo las comprobaciones de acceso (robo de token vía NtImpersonateThread + SeDebugPrivilege), o en un DC abusa de Replication Get-Changes-All vía rutas RPC legítimas (DCSync) para que la evaluación SACL ocurra en nombre de ntdsa con los logs yendo a los *defensores*. Ninguna familia in-the-wild se sabe que invoque este syscall directamente.
Oportunidades de detección
Este syscall es el motor detrás de la auditoría de acceso a objetos de Active Directory (eventos 4662, 4663, 4690). Los defensores deben asegurar que las políticas de auditoría avanzada `Audit Directory Service Access` y `Audit Directory Service Changes` estén habilitadas en cada controlador de dominio, con SACLs configuradas en contenedores sensibles (cabeza del NC de dominio, AdminSDHolder, cuenta krbtgt). Una caída repentina del volumen de 4662 en un DC, especialmente en horas de carga, es señal fuerte de manipulación del subsistema de auditoría (T1562.002) — posiblemente vía NtFlushKey sobre la hive Eventlog, edits de registro sobre SACL, o hooks SRM basados en driver.
Ejemplos de syscalls directos
asmx64 direct stub
; Direct syscall stub for NtAccessCheckByTypeResultListAndAuditAlarm (SSN 0x65)
NtAccessCheckByTypeResultListAndAuditAlarm PROC
mov r10, rcx ; syscall convention
mov eax, 65h ; SSN
syscall
ret
NtAccessCheckByTypeResultListAndAuditAlarm ENDPcWin32 wrapper (advapi32)
// AccessCheckByTypeResultListAndAuditAlarmW marshals OBJECT_TYPE_LIST_W and
// dispatches to the Nt-level entry point.
UNICODE_STRING sub = RTL_CONSTANT_STRING(L"Security");
UNICODE_STRING tname= RTL_CONSTANT_STRING(L"DS-Object");
UNICODE_STRING oname= RTL_CONSTANT_STRING(L"CN=krbtgt,CN=Users,DC=contoso,DC=com");
ACCESS_MASK granted[2] = {0};
NTSTATUS statuses[2] = {STATUS_ACCESS_DENIED, STATUS_ACCESS_DENIED};
BOOLEAN gen_on_close = FALSE;
NTSTATUS rc = NtAccessCheckByTypeResultListAndAuditAlarm(
&sub,
(PVOID)0xABCD1234,
&tname, &oname,
pSd, NULL,
READ_CONTROL | ADS_RIGHT_DS_READ_PROP,
AuditEventDirectoryServiceAccess,
0,
pObjectTypeList, 2,
&g_DsGenericMapping,
FALSE,
granted, statuses,
&gen_on_close);
// Each successful entry emits a 4662 carrying the object DN and the GUID
// of the property set evaluated.rustwindows-sys Win32 advapi32 wrapper
// AccessCheckByTypeResultListAndAuditAlarmW in windows-sys::Win32::Security::Authorization.
use windows_sys::Win32::Security::Authorization::*;
use windows_sys::Win32::Security::*;
unsafe {
let mut granted = [0u32; 2];
let mut status = [0i32; 2];
let mut gen_on_close: i32 = 0;
let rc = AccessCheckByTypeResultListAndAuditAlarmW(
windows_sys::w!("Security"),
handle_id as *mut _,
windows_sys::w!("DS-Object"),
windows_sys::w!("CN=krbtgt,CN=Users,DC=contoso,DC=com"),
sd_ptr, std::ptr::null_mut(),
ADS_RIGHT_DS_READ_PROP.0 as u32 | READ_CONTROL,
otl.as_ptr(), otl.len() as u32,
0, // ObjectCreation == FALSE
granted.as_mut_ptr(), status.as_mut_ptr(),
&mut gen_on_close,
);
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20