NtDeleteFile
Elimina un archivo por ruta sin abrir handle previo — primitiva anti-forense poco común.
Prototipo
NTSTATUS NtDeleteFile( POBJECT_ATTRIBUTES ObjectAttributes );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Ruta del espacio de objetos NT del archivo a borrar, p. ej. \??\C:\ProgramData\loader.bin. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0xC4 | win10-1507 |
| Win10 1607 | 0xC7 | win10-1607 |
| Win10 1703 | 0xCA | win10-1703 |
| Win10 1709 | 0xCB | win10-1709 |
| Win10 1803 | 0xCC | win10-1803 |
| Win10 1809 | 0xCD | win10-1809 |
| Win10 1903 | 0xCE | win10-1903 |
| Win10 1909 | 0xCE | win10-1909 |
| Win10 2004 | 0xD2 | win10-2004 |
| Win10 20H2 | 0xD2 | win10-20h2 |
| Win10 21H1 | 0xD2 | win10-21h1 |
| Win10 21H2 | 0xD3 | win10-21h2 |
| Win10 22H2 | 0xD3 | win10-22h2 |
| Win11 21H2 | 0xD8 | win11-21h2 |
| Win11 22H2 | 0xD9 | win11-22h2 |
| Win11 23H2 | 0xD9 | win11-23h2 |
| Win11 24H2 | 0xDB | win11-24h2 |
| Server 2016 | 0xC7 | winserver-2016 |
| Server 2019 | 0xCD | winserver-2019 |
| Server 2022 | 0xD7 | winserver-2022 |
| Server 2025 | 0xDB | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 DB 00 00 00 mov eax, 0xDB 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
NtDeleteFile es la primitiva rara de borrado por ruta: en lugar de abrir un archivo con acceso `DELETE` y luego emitir `NtSetInformationFile` con `FileDispositionInformation`, hace ambas cosas atómicamente desde un único argumento de ruta. Ningún wrapper Win32 la usa directamente — `DeleteFileW` siempre pasa por `NtOpenFile` + `FileDispositionInformation`, y `SHFileOperation` (en contexto shell) inserta aún más capas, incluida la gestión de la Papelera de reciclaje. Llamar a NtDeleteFile es por tanto una *firma* en sí misma: el software legítimo casi nunca la usa.
Uso común por malware
NtDeleteFile se prefiere en cadenas de **eliminación de indicadores** porque salta tanto `kernel32!DeleteFileW` (frecuentemente hookeada por EDR de user mode) como la redirección a la Papelera del shell. Familias de ransomware que limpian sus propios droppers y logs de staging (LockBit 3.0, Conti, BlackCat/ALPHV) y loaders que se autoeliminan tras pasar a una copia persistida eligen ocasionalmente esta primitiva precisamente por su propiedad de bypass. Nota: `NtDeleteFile` aún falla en archivos con handles abiertos por otros procesos a menos que se hayan abierto con `FILE_SHARE_DELETE` — para esos casos se prefiere la variante `Posix delete` de `FileDispositionInformationEx`.
Oportunidades de detección
Como el uso legítimo es extremadamente raro, *cualquier* llamada a NtDeleteFile es de alta señal. Los drivers mini-filter en kernel ven los borrados vía `IRP_MJ_SET_INFORMATION` con `FileDispositionInformation` independientemente de que el syscall originario fuera NtDeleteFile o NtSetInformationFile — la capa IRP normaliza. ETW `Microsoft-Windows-Kernel-File` expone un evento Delete vinculado al FILE_OBJECT. Sysmon Event 23 (FileDelete con archivado) y Event 26 (FileDeleteDetected, sin archivo) son los principales indicadores host; la captura de archivo es esencial porque el contenido del archivo desaparece inmediatamente después.
Ejemplos de syscalls directos
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtDeleteFile (SSN 0xDB on Win11 24H2 — drifts per build)
NtDeleteFile PROC
mov r10, rcx ; ObjectAttributes
mov eax, 0DBh ; SSN
syscall
ret
NtDeleteFile ENDPcSelf-delete after handoff
// Loader self-deletes its on-disk copy after persisting a clone elsewhere.
// Skips kernel32!DeleteFileW and shell Recycle Bin path.
#include <windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI *pNtDeleteFile)(POBJECT_ATTRIBUTES);
NTSTATUS Vanish(LPCWSTR ntpath) {
UNICODE_STRING us; RtlInitUnicodeString(&us, ntpath);
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &us, OBJ_CASE_INSENSITIVE, NULL, NULL);
pNtDeleteFile fn = (pNtDeleteFile)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtDeleteFile");
return fn(&oa);
}
// Caller: Vanish(L"\\??\\C:\\ProgramData\\loader.bin");rustFFI declaration
// Cargo: windows-sys = { version = "0.59", features = [
// "Wdk_Foundation", "Wdk_Storage_FileSystem",
// ] }
use windows_sys::Wdk::Storage::FileSystem::NtDeleteFile;
use windows_sys::Wdk::Foundation::OBJECT_ATTRIBUTES;
unsafe fn vanish(oa: *mut OBJECT_ATTRIBUTES) -> i32 {
NtDeleteFile(oa)
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20