NtDeleteKey
Löscht einen Registrierungsschlüssel beim Schließen des Handles — wird verwendet, um Persistenz und Audit-Key-Artefakte nach Ausführung zu beseitigen.
Prototyp
NTSTATUS NtDeleteKey( HANDLE KeyHandle );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| KeyHandle | HANDLE | in | Zuvor mit DELETE-Recht (oder KEY_ALL_ACCESS) geöffnetes Handle. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0xC5 | win10-1507 |
| Win10 1607 | 0xC8 | win10-1607 |
| Win10 1703 | 0xCB | win10-1703 |
| Win10 1709 | 0xCC | win10-1709 |
| Win10 1803 | 0xCD | win10-1803 |
| Win10 1809 | 0xCE | win10-1809 |
| Win10 1903 | 0xCF | win10-1903 |
| Win10 1909 | 0xCF | win10-1909 |
| Win10 2004 | 0xD3 | win10-2004 |
| Win10 20H2 | 0xD3 | win10-20h2 |
| Win10 21H1 | 0xD3 | win10-21h1 |
| Win10 21H2 | 0xD4 | win10-21h2 |
| Win10 22H2 | 0xD4 | win10-22h2 |
| Win11 21H2 | 0xD9 | win11-21h2 |
| Win11 22H2 | 0xDA | win11-22h2 |
| Win11 23H2 | 0xDA | win11-23h2 |
| Win11 24H2 | 0xDC | win11-24h2 |
| Server 2016 | 0xC8 | winserver-2016 |
| Server 2019 | 0xCE | winserver-2019 |
| Server 2022 | 0xD8 | winserver-2022 |
| Server 2025 | 0xDC | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
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
Undokumentierte Hinweise
Einargumentiger Syscall, aber mit subtiler Semantik: der Key wird zur Löschung *markiert* und erst beim Schließen des Handles tatsächlich entfernt — gleichzeitige Leser behalten Zugriff, bis sie ihre Handles freigeben. Der Key muss **Leaf** sein (keine Subkeys), sonst liefert der Aufruf `STATUS_CANNOT_DELETE`; Defense-Evasion-Tools, die einen Baum aufräumen, müssen depth-first rekursieren, abwechselnd `NtEnumerateKey` und `NtDeleteKey` von unten nach oben. Die SSN driftet über Builds spürbar (0xC5 auf 1507 → 0xDC auf 24H2), dynamische Auflösung ist Pflicht.
Häufige Malware-Nutzung
Reine **Defense Evasion (T1112 + T1070)**. Zwei wiederkehrende Muster. (1) **Persistenz-Cleanup nach Ausführung**: Sobald die Payload abgesetzt ist oder der Autorun nicht mehr gebraucht wird, entfernt das Implant seinen eigenen Run-/RunOnce-/IFEO-/Scheduled-Task-Cache-Footprint, um die forensische Rekonstruktion zu sabotieren. Self-Destruct-Stubs feuern typischerweise `NtDeleteKey` auf `\Registry\Machine\Software\Microsoft\Windows\CurrentVersion\Run\<implant>` und auf den zuvor gesetzten COM-CLSID-Hijack-Key. (2) **Indirekte Event-Log-Manipulation (T1070.001)**: Während der kanonische Angriff `wevtutil cl` oder ein EventLog-Service-Stop ist, nullen mehrere Stealer (LummaC2-Varianten, Atomic Stealer Win-Port) stattdessen die Audit-Subscription-Keys unter `\Registry\Machine\System\CurrentControlSet\Services\EventLog\Security\Channels\*` via NtDeleteKey und brechen so nachfolgendes Logging, ohne das auffällige Event-ID 1102 (Audit Log Cleared) auszulösen.
Erkennungsmöglichkeiten
Microsoft-Windows-Kernel-Registry-ETW emittiert ein Delete-Event mit vollem Pfad und PID. Sysmon Event ID 12 mit type=DeleteKey ist der direkte Catch. Entscheidend: ein EDR, der `CmRegisterCallbackEx` registriert, erhält `RegNtPreDeleteKey`- und `RegNtPostDeleteKey`-Benachrichtigungen auch dann, wenn User-Mode-Hooks per direktem Syscall umgangen werden — Kernel-Callbacks sehen die Operation post-dispatch. Hochwertige Hunts: Löschung jedes Pfades unter `\Microsoft\Windows\CurrentVersion\Run*`, `\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\*`, `\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\*` oder `\Services\EventLog\*`. Defender's Tamper Protection markiert Writes/Deletes auf AV-relevanten Registry-Bäumen; Korrelation mit dem ursprünglichen CreateKey/SetValue desselben SHA-256-Image-Hashs liefert einen End-to-End-Graphen Staging→Cleanup.
Direkte Syscall-Beispiele
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 ENDPrustDepth-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);
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20