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
| Name | Type | Dir | Description |
|---|---|---|---|
| Handle | HANDLE | in | Handle vers tout objet sécurisable (fichier, clé registre, processus, token, pipe nommé, etc.) ouvert avec READ_CONTROL. |
| SecurityInformation | SECURITY_INFORMATION | in | Masque binaire des parties à récupérer : OWNER_SECURITY_INFORMATION | GROUP_ | DACL_ | SACL_ | LABEL_ | ATTRIBUTE_. |
| SecurityDescriptor | PSECURITY_DESCRIPTOR | out | Buffer alloué par l'appelant recevant le security descriptor auto-relatif. |
| Length | ULONG | in | Taille de SecurityDescriptor en octets. |
| LengthNeeded | PULONG | out | Reç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 Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x142 | win10-1507 |
| Win10 1607 | 0x148 | win10-1607 |
| Win10 1703 | 0x14E | win10-1703 |
| Win10 1709 | 0x151 | win10-1709 |
| Win10 1803 | 0x153 | win10-1803 |
| Win10 1809 | 0x154 | win10-1809 |
| Win10 1903 | 0x155 | win10-1903 |
| Win10 1909 | 0x155 | win10-1909 |
| Win10 2004 | 0x15B | win10-2004 |
| Win10 20H2 | 0x15B | win10-20h2 |
| Win10 21H1 | 0x15B | win10-21h1 |
| Win10 21H2 | 0x15C | win10-21h2 |
| Win10 22H2 | 0x15C | win10-22h2 |
| Win11 21H2 | 0x163 | win11-21h2 |
| Win11 22H2 | 0x166 | win11-22h2 |
| Win11 23H2 | 0x166 | win11-23h2 |
| Win11 24H2 | 0x168 | win11-24h2 |
| Server 2016 | 0x148 | winserver-2016 |
| Server 2019 | 0x154 | winserver-2019 |
| Server 2022 | 0x161 | winserver-2022 |
| Server 2025 | 0x168 | winserver-2025 |
Module noyau
APIs liées
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 ENDPrustRead 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