> Windows Syscalls
ntoskrnl.exeT1112T1070.001T1070.009

NtDeleteKey

Elimina una clave del registro al cerrar el handle — usado para borrar persistencia y artefactos de auditoría tras la ejecución.

Prototipo

NTSTATUS NtDeleteKey(
  HANDLE KeyHandle
);

Argumentos

NameTypeDirDescription
KeyHandleHANDLEinHandle previamente abierto con el derecho de acceso DELETE (o KEY_ALL_ACCESS).

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070xC5win10-1507
Win10 16070xC8win10-1607
Win10 17030xCBwin10-1703
Win10 17090xCCwin10-1709
Win10 18030xCDwin10-1803
Win10 18090xCEwin10-1809
Win10 19030xCFwin10-1903
Win10 19090xCFwin10-1909
Win10 20040xD3win10-2004
Win10 20H20xD3win10-20h2
Win10 21H10xD3win10-21h1
Win10 21H20xD4win10-21h2
Win10 22H20xD4win10-22h2
Win11 21H20xD9win11-21h2
Win11 22H20xDAwin11-22h2
Win11 23H20xDAwin11-23h2
Win11 24H20xDCwin11-24h2
Server 20160xC8winserver-2016
Server 20190xCEwinserver-2019
Server 20220xD8winserver-2022
Server 20250xDCwinserver-2025

Módulo del kernel

ntoskrnl.exeNtDeleteKey

APIs relacionadas

RegDeleteKeyWRegDeleteKeyExWRegDeleteTreeWNtDeleteValueKeyNtEnumerateKeyNtClose

Stub del syscall

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

Syscall de un único argumento, pero con semántica sutil: la clave queda *marcada* para borrar y solo se retira al cerrar el handle — lectores concurrentes conservan acceso hasta liberar sus handles. La clave debe ser **hoja** (sin subclaves), o el call retorna `STATUS_CANNOT_DELETE`; las herramientas de evasión que limpian un árbol deben recurrir en profundidad, llamando a `NtEnumerateKey` y `NtDeleteKey` de abajo arriba. El SSN deriva notablemente entre builds (0xC5 en 1507 → 0xDC en 24H2), resolución dinámica obligatoria.

Uso común por malware

Pura **evasión defensiva (T1112 + T1070)**. Dos patrones recurrentes. (1) **Limpieza de persistencia tras la ejecución**: una vez puesto el payload o vuelto inútil el autorun, el implante retira su propio footprint en Run / RunOnce / IFEO / scheduled-task cache para romper la reconstrucción forense. Los stubs de auto-borrado emiten típicamente `NtDeleteKey` sobre `\Registry\Machine\Software\Microsoft\Windows\CurrentVersion\Run\<implant>` y sobre la clave de hijack CLSID COM colocada antes. (2) **Manipulación indirecta del Event Log (T1070.001)**: mientras el ataque canónico es `wevtutil cl` o detener el servicio EventLog, varios stealers (variantes LummaC2, port Windows de Atomic Stealer) anulan en su lugar las claves de suscripción de auditoría bajo `\Registry\Machine\System\CurrentControlSet\Services\EventLog\Security\Channels\*` vía NtDeleteKey, rompiendo el logging posterior sin disparar el audible Event-ID 1102 (audit log cleared).

Oportunidades de detección

ETW Microsoft-Windows-Kernel-Registry emite evento de borrado con ruta completa y PID. Sysmon Event ID 12 con type=DeleteKey es la captura directa. Crucialmente, un EDR que registre `CmRegisterCallbackEx` recibe notificaciones `RegNtPreDeleteKey` y `RegNtPostDeleteKey` aun cuando los hooks de usuario sean esquivados por syscall directo — los callbacks de kernel ven la operación post-dispatch. Cazas: borrado de cualquier ruta bajo `\Microsoft\Windows\CurrentVersion\Run*`, `\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*`, `\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\*`, o `\Services\EventLog\*`. La tamper protection de Defender marca escrituras/borrados en árboles de registro asociados al AV; correlacionar con el CreateKey/SetValue original del mismo hash SHA-256 de imagen aporta un grafo staging-luego-cleanup de extremo a extremo.

Ejemplos de syscalls directos

cRemove our own Run-key persistence entry

// Open the value's parent key with DELETE access, then NtDeleteKey on the leaf.
UNICODE_STRING name;
RtlInitUnicodeString(&name,
    L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Updater");

OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);

HANDLE hKey = NULL;
if (NT_SUCCESS(NtOpenKey(&hKey, DELETE, &oa))) {
    NtDeleteKey(hKey);     // marks for deletion
    NtClose(hKey);          // actually deletes
}

asmDirect stub (SSN 0xDC, Win11 24H2)

; SSN drifts heavily; resolve dynamically before targeting multiple builds.
NtDeleteKey PROC
    mov  r10, rcx
    mov  eax, 0DCh         ; Win11 24H2
    syscall
    ret
NtDeleteKey ENDP

rustDepth-first key-tree wipe helper

use ntapi::ntregapi::{NtDeleteKey, NtEnumerateKey, NtOpenKey, KEY_BASIC_INFORMATION};
use winapi::shared::ntdef::HANDLE;

pub unsafe fn delete_tree(h_root: HANDLE) {
    let mut buf = vec![0u8; 0x400];
    let mut len = 0u32;
    loop {
        let s = NtEnumerateKey(
            h_root, 0,
            0 /* KeyBasicInformation */,
            buf.as_mut_ptr() as *mut _, buf.len() as u32, &mut len);
        if s != 0 { break; }
        let bi = &*(buf.as_ptr() as *const KEY_BASIC_INFORMATION);
        // open subkey here, recurse, then delete the leaf
    }
    NtDeleteKey(h_root);
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20