> Windows Syscalls
ntoskrnl.exeT1069T1087T1106

NtQuerySecurityObject

Récupère un SECURITY_DESCRIPTOR auto-relatif depuis tout objet noyau exposé via un handle.

Prototype

NTSTATUS NtQuerySecurityObject(
  HANDLE               Handle,
  SECURITY_INFORMATION SecurityInformation,
  PSECURITY_DESCRIPTOR SecurityDescriptor,
  ULONG                Length,
  PULONG               LengthNeeded
);

Arguments

NameTypeDirDescription
HandleHANDLEinHandle vers tout objet sécurisable (fichier, clé registre, processus, token, pipe nommé, etc.) ouvert avec READ_CONTROL.
SecurityInformationSECURITY_INFORMATIONinMasque binaire des parties à récupérer : OWNER_SECURITY_INFORMATION | GROUP_ | DACL_ | SACL_ | LABEL_ | ATTRIBUTE_.
SecurityDescriptorPSECURITY_DESCRIPTORoutBuffer alloué par l'appelant recevant le security descriptor auto-relatif.
LengthULONGinTaille de SecurityDescriptor en octets.
LengthNeededPULONGoutReçoit la taille réellement écrite, ou la taille requise en cas de STATUS_BUFFER_TOO_SMALL.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x142win10-1507
Win10 16070x148win10-1607
Win10 17030x14Ewin10-1703
Win10 17090x151win10-1709
Win10 18030x153win10-1803
Win10 18090x154win10-1809
Win10 19030x155win10-1903
Win10 19090x155win10-1909
Win10 20040x15Bwin10-2004
Win10 20H20x15Bwin10-20h2
Win10 21H10x15Bwin10-21h1
Win10 21H20x15Cwin10-21h2
Win10 22H20x15Cwin10-22h2
Win11 21H20x163win11-21h2
Win11 22H20x166win11-22h2
Win11 23H20x166win11-23h2
Win11 24H20x168win11-24h2
Server 20160x148winserver-2016
Server 20190x154winserver-2019
Server 20220x161winserver-2022
Server 20250x168winserver-2025

Module noyau

ntoskrnl.exeNtQuerySecurityObject

APIs liées

GetSecurityInfoGetKernelObjectSecurityGetUserObjectSecurityGetFileSecurityWNtSetSecurityObjectNtAccessCheck

Stub du syscall

4C 8B D1            mov r10, rcx
B8 68 01 00 00      mov eax, 0x168
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

Accesseur universel aux security descriptors de tous les types d'objets. Lire la SACL nécessite SE_SECURITY_NAME (ACCESS_SYSTEM_SECURITY) — la plupart des appelants omettent donc SACL_SECURITY_INFORMATION. Renvoie STATUS_BUFFER_TOO_SMALL avec la taille requise dans LengthNeeded ; le motif standard est un appel sonde avec Length=0 suivi d'une allocation. Les wrappers Win32 GetSecurityInfo / GetKernelObjectSecurity / GetUserObjectSecurity y aboutissent tous.

Usage courant par les malwares

Étape de reconnaissance qui précède presque toujours un SetSecurityObject — l'implant lit le SDDL courant d'une cible (clé registre de service, fichier de tâche planifiée, répertoire d'installation EDR) pour savoir quoi fusionner ou retirer. Utilisé aussi par les outils de découverte de privilèges comme l'équivalent de Get-DomainObjectAcl de PowerSploit pour repérer des ACL faibles (par ex. une clé registre de service inscriptible par Authenticated Users) exploitables sans rien toucher. Dans les chaînes de vol de credentials, NtQuerySecurityObject sur un handle LSASS confirme les privilèges et bits d'accès réellement obtenus.

Opportunités de détection

Pris seul, volumétrie extrêmement haute — chaque boîte de dialogue Ouvrir, chaque fenêtre Propriétés, chaque invite UAC l'appelle. La barre de détection est le *contexte* : NtQuerySecurityObject sur `HKLM\SYSTEM\CurrentControlSet\Services\<EDR>` ou sur `lsass.exe` depuis un processus non fiable est intéressant. L'audit d'accès aux objets (Event 4663 avec `Accesses: Read SD`) couvre la plupart des cas mais reste bruyant jusqu'à réglage. Les EDR qui médiatisent les ouvertures fichier/processus voient le READ_CONTROL sur le handle dont NtQuerySecurityObject dépend. La détection style Bluespawn se concentre sur le SetSecurityObject *apparié* qui suit.

Exemples de syscalls directs

cProbe-then-alloc pattern

// Read the DACL of a service registry key in two calls.
ULONG needed = 0;
NTSTATUS st = NtQuerySecurityObject(hSvcKey, DACL_SECURITY_INFORMATION,
                                    NULL, 0, &needed);
if (st == STATUS_BUFFER_TOO_SMALL) {
    PVOID sd = RtlAllocateHeap(RtlProcessHeap(), 0, needed);
    st = NtQuerySecurityObject(hSvcKey, DACL_SECURITY_INFORMATION,
                               sd, needed, &needed);
    // Now walk the DACL and decide what to weaken.
}

asmx64 direct stub (Win11 24H2 SSN 0x168)

NtQuerySecurityObject PROC
    mov  r10, rcx
    mov  eax, 168h
    syscall
    ret
NtQuerySecurityObject ENDP

rustRead DACL of EDR install dir before tampering

// Cargo: ntapi = "0.4", windows-sys = "0.59"
let mut needed: u32 = 0;
let st = unsafe {
    NtQuerySecurityObject(h_dir,
        DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
        null_mut(), 0, &mut needed)
};
assert_eq!(st, STATUS_BUFFER_TOO_SMALL as i32);
let mut buf = vec![0u8; needed as usize];
unsafe {
    NtQuerySecurityObject(h_dir,
        DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
        buf.as_mut_ptr() as _, buf.len() as u32, &mut needed);
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20