Memory-Resident and Fileless Malware Architectures

The Myth of the Footprintless Attack

The term "fileless malware" has become dangerously misleading in security discourse. While these techniques avoid writing traditional PE files to disk, they leave substantial evidence in volatile memory, registry hives, prefetch files, and event logs. The distinction matters critically for defenders: fileless does not mean footprintless. A reflective DLL injection leaves allocatable memory regions with suspicious characteristics; process hollowing creates mismatched memory sections; even the most sophisticated in-memory framework requires initialization artifacts that forensic analysis can recover.

Understanding this distinction shapes detection strategy. Memory forensics, ETW (Event Tracing for Windows) telemetry, and behavioral analytics become essential complements to signature-based scanning. The adversary's goal shifts from total invisibility to reducing dwell time before detection—a race measured in minutes rather than months.

Living-off-the-Land: Trusted Platform Abuse

LOLBins (Living-off-the-Land Binaries) represent the foundational technique for fileless operations, leveraging signed, legitimate system executables to perform malicious actions. Microsoft-signed tools like certutil.exe, mshta.exe, regsvr32.exe, and powershell.exe provide execution, download, and encoding capabilities without triggering application whitelisting defenses.

The persistence mechanism often exploits trusted platform features themselves. Consider WMI repository manipulation:

# Creating a WMI event subscription for persistence
$FilterArgs = @{
    Name='WinLogonFilter'
    EventNamespace='root/cimv2'
    QueryLanguage='WQL'
    Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 200 AND TargetInstance.SystemUpTime < 320"
}

$Filter = New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs

$ConsumerArgs = @{
    Name='WinLogonConsumer'
    CommandLineTemplate='powershell.exe -nop -w hidden -e JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8A...'
}

$Consumer = New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs

$BindingArgs = @{
    Filter = [ref]$Filter
    Consumer = [ref]$Consumer
}
New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $BindingArgs

This subscription triggers 200-320 seconds after boot, executing encoded PowerShell through a trusted WMI infrastructure component. Detection requires monitoring WMI-Activity ETW provider events 5857-5861, not traditional file creation alerts.

Reflective Injection and Process Manipulation Techniques

Reflective DLL Injection, pioneered by Stephen Fewer, enables loading a DLL entirely from memory without using the Windows loader. The DLL parses its own headers, performs relocations, and resolves imports manually. Modern implementations like sRDI (Shellcode Reflective DLL Injection) convert DLLs to position-independent shellcode, evading memory scanners looking for MZ headers in private allocations.

Process Hollowing creates a suspended legitimate process, unmaps its original executable, and replaces it with malicious code:

1. CreateProcess("svchost.exe", ..., CREATE_SUSPENDED, ...) → Process handle, thread handle
2. NtUnmapViewOfSection(hProcess, baseAddress) → Hollow original image
3. VirtualAllocEx(hProcess, baseAddress, imageSize, MEM_COMMIT|RESERVE, PAGE_EXECUTE_READWRITE)
4. WriteProcessMemory(hProcess, baseAddress, maliciousImage, imageSize, ...)
5. Relocate image, resolve imports
6. SetThreadContext(hThread, &contextWithNewEntryPoint)
7. ResumeThread(hThread)

Memory forensics detects this via Volatility's malfind or windows.pslist.PsList with VAD analysis—hollowed processes exhibit PAGE_EXECUTE_READWRITE permissions on their primary executable VAD, and the in-memory PE header won't match the on-disk file hash.

Process Doppelgänging, disclosed in 2017 by enSilo researchers, abuses Windows Transactional NTFS (TxF) to create a ghost process:

// Simplified doppelgänging workflow
NTSTATUS doppelgangeInject(WCHAR* targetPath, PVOID payload, DWORD payloadSize) {
    HANDLE hTransaction = CreateTransaction(NULL, NULL, 0, 0, 0, NULL, NULL);
    HANDLE hTransactedFile = CreateFileTransactedW(targetPath, GENERIC_WRITE|GENERIC_READ, 
        0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL, hTransaction, NULL, NULL);
    
    // Write payload into transacted file (isolated from filesystem view)
    WriteFile(hTransactedFile, payload, payloadSize, NULL, NULL);
    
    // Create section from transacted file - appears as legitimate signed binary
    NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, 0, SEC_IMAGE, PAGE_READONLY, hTransactedFile);
    
    // Rollback transaction - file on disk never modified
    RollbackTransaction(hTransaction);
    
    // Map section into new process
    NtCreateProcessEx(&hProcess, PROCESS_ALL_ACCESS, NULL, NtCurrentProcess(), PS_INHERIT_HANDLES, hSection, NULL, NULL, FALSE);
    
    // ... thread creation and execution
}

Transacted Hollowing combines doppelgänging with process hollowing, using the transacted section as the "clean" initial mapping then hollowing it—creating layers of abstraction that confuse memory scanners.

Commercial Adversary Simulation Frameworks

Modern red team frameworks have operationalized these techniques with industrial sophistication, creating asymmetric challenges for defenders.

Framework Evasion Focus Notable Techniques
Cobalt Strike Malleable C2, sleep masks, in-memory evasion User-defined C2 profiles, AES/RC4 sleep encryption, SMB/TCP beacons, BOF/.NET execution
Sliver Cross-platform, DNS canary detection In-memory .NET assemblies, process injection via multiple techniques, DNS/TLS/mTLS C2
Brute Ratel C4 EDR evasion, syscall proxying Badger agents with sleep obfuscation, x64 return address spoofing, hardware breakpoint removal

Cobalt Strike's sleep mask encrypts beacon memory during idle periods, decrypting only briefly for callback. Its Malleable C2 allows complete customization of network indicators—from JA3 TLS fingerprints to HTTP headers mimicking legitimate applications. Detection requires analyzing memory anomalies during active periods or identifying the decryption routine itself via behavioral patterns.

Sliver's DNS canary generates unique DNS queries per binary, allowing operators to detect sandbox execution or analyst detonation. Its in-memory .NET execution leverages CLR hosting without touching disk:

# Sliver .NET assembly execution in remote process
sliver> execute-assembly --in-process /path/to/Rubeus.exe klist

Brute Ratel C4 pushes evasion further with Badger agents that replace standard Windows APIs with direct syscalls, bypassing user-mode hooking. Its x64 return address spoofing manipulates the stack to show legitimate call frames during ETW and stack walking callbacks. Critically, it implements hardware breakpoint clearing to defeat EDR solutions using Dr0-Dr7 debug registers for execution monitoring.

ETW, AMSI, and CLM: The Evasion Arms Race

ETW Bypasses have evolved from crude provider disabling to sophisticated manipulation. Modern techniques include:

  • Patching EtwEventWrite: Redirecting to ret instructions in ntdll.dll, though increasingly detected
  • ETW TI (Threat Intelligence) patchless bypasses: Manipulating registration handles via NtTraceControl with TraceControlStopLogger (class 1) to disable specific providers
  • Synthetic stack frames: Abusing RtlWalkFrameChain limitations with frame pointer omission

AMSI Unhooking neutralizes Windows' script-scanning interface. The classic technique patches AmsiScanBuffer in loaded amsi.dll:

// AMSI patch example (detected by most modern EDRs)
IntPtr asmi = LoadLibrary("amsi.dll");
IntPtr AmsiScanBuffer = GetProcAddress(amsi, "AmsiScanBuffer");

// Original bytes: 4c 8b dc 49 89 5b 08 49 89 6b 10 49 89 73 18
// Patch to: ret (0xC3) or mov eax, 80070057 (AMSIE_INVALID); ret
byte[] patch = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; // mov eax, 0x80070057; ret
VirtualProtect(AmsiScanBuffer, patch.Length, PAGE_EXECUTE_READWRITE, out _);
Marshal.Copy(patch, 0, AmsiScanBuffer, patch.Length);

Modern EDRs detect this via memory integrity checks. Advanced malware now employs AMSI bypasses via CLR profiling or hardware breakpoints on AMSI functions redirected to benign handlers—techniques requiring deeper inspection than simple byte signature scanning.

Constrained Language Mode (CLM) Breakout exploits that CLM only applies to Windows PowerShell, not PowerShell 7, or leverages .NET methods accessible despite language constraints:

# CLM breakout via Add-Type and C# compilation
$Ref = [Ref].Assembly.GetTypes() | ? { $_.Name -like "*iUtils" }
$Field = $Ref.GetFields("NonPublic,Static") | ? { $_.Name -like "*Context" }
$Field.SetValue($null, [IntPtr]::Zero)  # Disables CLM enforcement

Alternatively, InstallUtil.exe, Msbuild.exe, and Csc.exe execute full-trust code from XML or source files regardless of CLM status.

UEFI Bootkits and Below-the-OS Persistence

Firmware-level threats represent the most persistent and stealthy attack surface. ESPecter, discovered by ESET in 2021, modifies the EFI System Partition (ESP) to replace legitimate Windows Boot Manager (bootmgfw.efi) with a malicious version that loads additional components before OS initialization.

MoonBounce, attributed to APT41, demonstrates even deeper persistence by infecting the SPI flash memory containing the UEFI firmware itself—not just the ESP partition. This survives OS reinstallation and disk replacement. MoonBounce hooks the CoreDxe image in the firmware, intercepting ExitBootServices to load a malicious driver before Windows kernel initialization.

SPI Flash Memory Layout:
┌─────────────────────────────────────┐
│       Descriptor Region (4KB)       │
├─────────────────────────────────────┤
│          BIOS Region (varies)       │ ← CoreDxe, DXE drivers, MoonBounce hook
├─────────────────────────────────────┤
│       Intel ME Region (varies)      │
├─────────────────────────────────────┤
│    Gigabit Ethernet Region (4KB)    │
├─────────────────────────────────────┤
│     Platform Data Region (varies)   │
└─────────────────────────────────────┘

SPI Flash Analysis Challenges include:

  • Hardware access requirements: Direct SPI programming via Dediprog SF100, Flashrom-compatible programmers, or SoC-specific interfaces
  • Firmware volume parsing: UEFI PI (Platform Initialization) firmware uses Firmware File System (FFS) with GUID-named files in firmware volumes
  • Compression layers: DXE drivers often use LZMA or Tiano compression requiring extraction before analysis
  • Signature verification bypass: Intel Boot Guard and AMD PSP cryptographic protections

Hardware-Assisted Verification provides defense but introduces complexity:

Technology Mechanism Limitations
Intel Boot Guard ACM (Authenticated Code Module) verifies Initial Boot Block (IBB) signature before execution OEM misconfiguration (verify mode vs. measured boot), key escrow risks
AMD PSP ARM Cortex-A5 co-processor verifies BIOS signature Historical vulnerabilities (CVE-2017-2637, CVE-2019-9836), limited transparency
Intel T TXT/TXT Trusted Execution Technology for measured launch Performance overhead, complex attestation infrastructure

Boot Guard's Verified Boot mode prevents execution of modified firmware entirely; Measured Boot only records hashes for remote attestation. Analysis of Boot Guard configuration requires parsing the Flash Descriptor and FMAP regions for the Boot Guard Profile (BGUP) structure, accessible via Intel's Chipsec utility:

# CHIPSEC Boot Guard verification
python chipsec_main.py -m common.bios_wp
python chipsec_main.py -m common.spi_desc
python chipsec_util.py spi dump rom.bin
python chipsec_util.py decode rom.bin  # Extract firmware volumes

Kernel-Level Rootkits and DKOM

Direct Kernel Object Manipulation (DKOM) enables stealth by altering kernel data structures directly, bypassing API monitoring. Rootkits like FudModule (Lazarus Group, 2022) abuse BYOVD (Bring Your Own Vulnerable Driver) to gain kernel execution, then manipulate structures to hide processes, threads, and loaded drivers.

Classic DKOM techniques include:

  • Process hiding: Unlinking EPROCESS from PsActiveProcessHead doubly-linked list; requires fixing Flink/Blink pointers
  • Thread hiding: Similar ETHREAD manipulation or CrossThreadFlags modification
  • Driver hiding: Removing from PsLoadedModuleList
  • Token manipulation: Exchanging process tokens via _EPROCESS.Token pointer swap

Modern EDR detects DKOM via:

  • Integrity rings: Monitoring critical kernel structures with secondary verification
  • Hardware breakpoints on kernel structures: Performance-intensive but effective for high-value targets
  • Hypervisor-based monitoring: Intel VT-x/AMD-V based introspection below kernel level

The arms race continues toward hypervisor-level rootkits (BluePill, Vitriol) and counter-EDR techniques that disable kernel callbacks entirely—requiring defenders to assume breach and emphasize behavioral anomaly detection over integrity verification alone.