NtSetSecurityObject
Escribe un nuevo SECURITY_DESCRIPTOR (propietario / DACL / SACL / etiqueta) sobre un objeto del kernel por handle.
Prototipo
NTSTATUS NtSetSecurityObject( HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| Handle | HANDLE | in | Handle al objeto objetivo. El acceso requerido depende de los bits de SecurityInformation: WRITE_DAC para DACL, WRITE_OWNER para OWNER, ACCESS_SYSTEM_SECURITY para SACL. |
| SecurityInformation | SECURITY_INFORMATION | in | Máscara de bits de partes a escribir — debe coincidir con los componentes presentes en SecurityDescriptor. |
| SecurityDescriptor | PSECURITY_DESCRIPTOR | in | Puntero al descriptor de seguridad auto-relativo o absoluto a aplicar. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x18B | win10-1507 |
| Win10 1607 | 0x194 | win10-1607 |
| Win10 1703 | 0x19A | win10-1703 |
| Win10 1709 | 0x19D | win10-1709 |
| Win10 1803 | 0x19F | win10-1803 |
| Win10 1809 | 0x1A0 | win10-1809 |
| Win10 1903 | 0x1A1 | win10-1903 |
| Win10 1909 | 0x1A1 | win10-1909 |
| Win10 2004 | 0x1A7 | win10-2004 |
| Win10 20H2 | 0x1A7 | win10-20h2 |
| Win10 21H1 | 0x1A7 | win10-21h1 |
| Win10 21H2 | 0x1A9 | win10-21h2 |
| Win10 22H2 | 0x1A9 | win10-22h2 |
| Win11 21H2 | 0x1B2 | win11-21h2 |
| Win11 22H2 | 0x1B6 | win11-22h2 |
| Win11 23H2 | 0x1B6 | win11-23h2 |
| Win11 24H2 | 0x1B9 | win11-24h2 |
| Server 2016 | 0x194 | winserver-2016 |
| Server 2019 | 0x1A0 | winserver-2019 |
| Server 2022 | 0x1AF | winserver-2022 |
| Server 2025 | 0x1B9 | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 B9 01 00 00 mov eax, 0x1B9 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
Mitad de escritura del par security-descriptor. El kernel fusiona, reemplaza o quita ACEs según las banderas de control puestas en el descriptor proporcionado (SE_DACL_PROTECTED, SE_SACL_PROTECTED, …). SeAssignSecurityEx realiza la fusión real, con reglas de herencia aplicadas si el objeto es un contenedor. Devuelve STATUS_INVALID_OWNER si el SID propietario provisto no está habilitado en el token del llamador, y STATUS_PRIVILEGE_NOT_HELD cuando se solicita la SACL sin SE_SECURITY_NAME.
Uso común por malware
T1222 *Permissions Modification* es el uso canónico. Dominan dos escenarios. (1) **Endurecimiento de persistencia en registro**: debilitar la DACL de `HKLM\SYSTEM\CurrentControlSet\Services\<implante>` para que un usuario de bajo privilegio pueda reescribir ImagePath / Parameters sin admin (T1222.001). (2) **Auto-protección de implante en archivos**: endurecer la DACL del propio EXE/DLL para que la remediación AV nivel SYSTEM encuentre ACCESS_DENIED, o incluso quitar Administrators de la DACL tras tomar propiedad — así sobreviven algunas notas de rescate (y el propio encriptador) a los intentos de eliminación (T1222.002). Carbanak / FIN7 han usado ambos patrones contra servicios y archivos de tareas programadas.
Oportunidades de detección
Señal de alta fidelidad cuando el *objeto objetivo* es sensible. El Event 4670 de auditoría de acceso a objetos (Permisos sobre un objeto fueron cambiados) dispara si la SACL de auditoría está configurada sobre el objetivo — pero las SACL sobre `HKLM\System\...` raramente están puestas por defecto. Sysmon Event 4 (estado del servicio Sysmon) no cubre esto; los hooks *EDR* sobre NtSetSecurityObject o sobre el RtlSetSecurityObject de más alto nivel son la detección práctica. Buscar: cualquier proceso distinto de `services.exe`, `TrustedInstaller`, `msiexec` o binarios dirigidos por GPO que escriba una DACL sobre una clave de servicio del registro o sobre un fichero bajo Program Files. Una DACL debilitada que conceda `Everyone:F` o `Authenticated Users:F` a un ImagePath de servicio es esencialmente una pista fumante.
Ejemplos de syscalls directos
cWeaken DACL on a service registry key (skeleton)
// Add an explicit Allow-Full-Control ACE for Authenticated Users on the
// service's registry key, enabling later config rewrite without admin.
PSECURITY_DESCRIPTOR sd = NULL;
ULONG sdLen = 0;
ConvertStringSecurityDescriptorToSecurityDescriptorW(
L"D:(A;OICI;GA;;;AU)", // Authenticated Users : Generic All, container+object inherit
SDDL_REVISION_1, &sd, &sdLen);
NTSTATUS st = NtSetSecurityObject(hSvcKey, DACL_SECURITY_INFORMATION, sd);
// hSvcKey must have been opened with WRITE_DAC.
LocalFree(sd);asmx64 direct stub (Win11 24H2 SSN 0x1B9)
NtSetSecurityObject PROC
mov r10, rcx
mov eax, 1B9h
syscall
ret
NtSetSecurityObject ENDPrustTake ownership of own binary, then deny Administrators
// Cargo: windows-sys = "0.59", ntapi = "0.4"
// Step 1: take ownership (requires SeTakeOwnershipPrivilege enabled).
unsafe {
NtSetSecurityObject(h_file,
OWNER_SECURITY_INFORMATION,
owner_sd_with_self_sid.as_ptr() as _);
}
// Step 2: now write a DACL that denies Administrators Delete/WriteAttrib.
unsafe {
NtSetSecurityObject(h_file,
DACL_SECURITY_INFORMATION,
deny_admins_dacl.as_ptr() as _);
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20