NtAccessCheckByTypeResultListAndAuditAlarm
Contrôle d'accès typé renvoyant une liste de résultats par type, tout en écrivant des entrées d'alarme d'audit dans le journal Sécurité.
Prototype
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 );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| SubsystemName | PUNICODE_STRING | in | Identifiant de sous-système, ex. L"Security". Stocké dans chaque événement d'audit émis. |
| HandleId | PVOID | in | Identifiant de handle opaque de corrélation exposé dans l'événement d'audit. |
| ObjectTypeName | PUNICODE_STRING | in | Nom de type d'objet de plus haut niveau, ex. L"DS-Object", L"File". |
| ObjectName | PUNICODE_STRING | in | Nom d'instance d'objet (DN, chemin, nom d'objet kernel) enregistré dans l'événement d'audit. |
| SecurityDescriptor | PSECURITY_DESCRIPTOR | in | Descripteur de sécurité avec DACL + SACL — les deux sont consultés (DACL pour l'accès, SACL pour l'audit). |
| PrincipalSelfSid | PSID | in | SID optionnel substitué aux placeholders PRINCIPAL_SELF dans la DACL/SACL. |
| DesiredAccess | ACCESS_MASK | in | Droits d'accès à évaluer par entrée d'object-type-list. |
| AuditType | AUDIT_EVENT_TYPE | in | AuditEventObjectAccess ou AuditEventDirectoryServiceAccess — choisit la catégorie d'audit. |
| Flags | ULONG | in | Réservé / modificateurs de comportement (ex. AUDIT_ALLOW_NO_PRIVILEGE). |
| ObjectTypeList | POBJECT_TYPE_LIST | in | Liste aplatie de la hiérarchie de types (objet + property sets + propriétés). |
| ObjectTypeListLength | ULONG | in | Nombre d'entrées ObjectTypeList ; dimensionne les deux tableaux de sortie. |
| GenericMapping | PGENERIC_MAPPING | in | Mapping par type GENERIC_* -> droits spécifiques. |
| ObjectCreation | BOOLEAN | in | TRUE pour création d'objet (journalisé comme création), FALSE pour ouverture d'un objet existant. |
| GrantedAccessList | PACCESS_MASK | out | Masques d'accès accordés par entrée. |
| AccessStatusList | PNTSTATUS | out | NTSTATUS par entrée (STATUS_SUCCESS / STATUS_ACCESS_DENIED). |
| GenerateOnClose | PBOOLEAN | out | TRUE si l'appelant doit ensuite invoquer NtCloseObjectAuditAlarm pour émettre l'événement de fermeture associé. |
IDs de syscalls par version de Windows
| Version 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 |
Module noyau
APIs liées
Stub du 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
Notes non documentées
Parmi les syscalls à prototype le plus long de la Native API — 15 arguments, du fait de la combinaison du contrôle d'accès typé (hiérarchie objet + property sets) avec l'émission d'audit. C'est l'union de NtAccessCheckByTypeResultList (vecteur de résultats) et NtAccessCheckByTypeAndAuditAlarm (émission d'audit). Utilisé presque exclusivement par ntdsa.dll dans lsass.exe pour évaluer les lectures/écritures d'objets Active Directory quand le résultat doit être à la fois par-property-set ET journalisé. La SACL de l'objet AD pilote l'émission éventuelle d'un événement Sécurité 4662 ("Une opération a été effectuée sur un objet") ; la décision par entrée pilote le rejet ou non de l'opération. Le SSN `0x65` est stable depuis Windows 10 1507.
Usage courant par les malwares
Essentiellement nul. La fonction est trop spécialisée — l'appelant doit fournir un OBJECT_TYPE_LIST valide, détenir SeAuditPrivilege, et tout appel réussi génère un 4662 dans le journal Sécurité. Les malwares grand public font l'inverse : ils contournent entièrement les contrôles d'accès (vol de jeton via NtImpersonateThread + SeDebugPrivilege) ou, sur un DC, abusent de Replication Get-Changes-All via des chemins RPC légitimes (DCSync) pour que l'évaluation SACL se fasse au nom de ntdsa avec les logs allant chez les *défenseurs*. Aucune famille de malware connue n'invoque ce syscall directement en environnement réel.
Opportunités de détection
Ce syscall est le moteur de l'audit d'accès aux objets Active Directory (événements 4662, 4663, 4690). Les défenseurs doivent s'assurer que les politiques d'audit avancées `Audit Directory Service Access` et `Audit Directory Service Changes` sont activées sur chaque contrôleur de domaine, avec des SACL configurées sur les conteneurs sensibles (tête du NC de domaine, AdminSDHolder, compte krbtgt). Une chute soudaine du volume de 4662 sur un DC, en particulier pendant des heures par ailleurs chargées, est un signal fort d'altération du sous-système d'audit (T1562.002) — possiblement via NtFlushKey sur la ruche Eventlog, des éditions registre sur les SACL, ou des hooks SRM par pilote.
Exemples de syscalls directs
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,
);
}Mappings MITRE ATT&CK
Last verified: 2026-05-20