Windows Memory Forensics: Identifying Rogue Processes

 


Processes constitute a logical point of departure for memory analysis, serving as one of the principal building blocks of a Windows memory image. They reveal the set of programs that were executing at the moment of acquisition and frequently furnish the most actionable evidence in malware investigations. In conceptual terms familiar to practitioners of traditional disk forensics, processes may be regarded as analogous to files within a file system: some remain allocated (actively resident in the kernel’s tracking structures), while others exist in an unallocated or residual state pending reuse or overwriting.


Process metadata is maintained by the kernel within the executive process block (_EPROCESS). This structure encapsulates the majority of forensically relevant attributes, including:


  • the executable image name (ImageFileName),
  • the process identifier (PID),
  • the parent-process identifier (PPID),
  • the virtual address (offset) of the block itself,
  • creation and exit timestamps,
  • the list of associated threads,
  • the handle table referencing other kernel objects,
  • the root of the Virtual Address Descriptor (VAD) tree,
  • and a pointer to the Process Environment Block (PEB).


Because multiple processes execute concurrently, the kernel organizes active _EPROCESS instances into a circular doubly-linked list via the ActiveProcessLinks member (comprising Flink and Blink pointers). Under normal conditions, only processes still regarded as live appear in this list; upon termination, the corresponding block is eventually unlinked and becomes eligible for reuse. The same linkage mechanism, however, is a classic target of Direct Kernel Object Manipulation (DKOM): malware possessing kernel-mode privileges can remove its own _EPROCESS from the list while leaving the object itself intact and schedulable.



Consequently, memory-forensic frameworks cannot rely solely on traversal of the active-process list. Comprehensive enumeration requires complementary pool-scanning techniques that locate residual or deliberately unlinked _EPROCESS structures throughout the physical memory image.


Memory-analysis frameworks readily produce an inventory of processes together with their associated metadata. The greater analytical challenge lies in interpreting that inventory and discriminating anomalous entries. When examining processes recovered from a memory image, attention should be concentrated on the following six attributes:

  • Image name: The executable name itself frequently supplies an initial signal. Experienced responders can often recognize names that are atypical for a standard Windows installation. Adversaries routinely adopt legitimate or near-legitimate names in an attempt to blend into the process list. Subtle misspellings, or the presence of a legitimate binary in an unexpected operational context (for example, firefox.exe on a server rather than a workstation), warrant heightened scrutiny.
  • Full path: Malware commonly masquerades under familiar image names while executing from atypical locations. Canonical system binaries such as explorer.exe are expected to reside under the Windows directory, and browser executables under Program Files. Observation of these names originating from \Windows\System32, temporary folders, or especially the Recycle Bin constitutes a strong indicator for further investigation, as few legitimate processes are launched from such paths.
  • Parent process: Process lineage supplies critical contextual information. Most interactive user applications are parented by explorer.exe. A system-named binary (e.g., svchost.exe) whose parent is explorer.exe is therefore anomalous. Parentage also situates a process within the boot or logon hierarchy: a process parented by services.exe is more likely to have been started early and may possess a persistence mechanism, whereas one parented by explorer.exe typically appears after interactive logon. Processes lacking a living parent are likewise noteworthy; while certain system processes (e.g., smss.exe) are commonly orphaned, the absence of a parent can also signal advanced techniques such as process hollowing or injection.
  • Command line: The Process Environment Block records the complete command line used at process creation. This field permits verification that the on-disk executable path is consistent with the reported image name and enables detection of unusual or suspicious arguments.
  • Start time: Creation timestamps remain an under-utilized yet highly informative artifact. When the approximate time of an intrusion is known, processes instantiated after that point deserve priority examination. Clusters of ostensibly identical processes (for example, multiple svchost.exe instances) in which one outlier exhibits a markedly different start time merit closer inspection. Comparison of a candidate’s timestamp against those of known early-boot processes such as smss.exe or winlogon.exe further assists in distinguishing boot-time from post-logon activity.
  • Security identifiers: The access-token SIDs associated with a process reveal the privilege context under which it was launched. User SIDs are readily distinguishable by length from the shorter well-known system SIDs. More granular analysis can determine whether a process expected to run as LocalService or NetworkService was instead started under the SYSTEM account, or vice versa—an inconsistency that may indicate privilege escalation or misconfiguration.

Systematic evaluation of these six attributes supplies a structured methodology for isolating processes that deviate from expected system behavior and therefore warrant deeper forensic scrutiny.


Identifying Rogue Processes With Volatility

Processes constitute the principal building blocks of a Windows memory image and therefore form a logical starting point for analysis. Volatility adopts a modular architecture in which discrete plugins address specific investigative questions. The following plugins are particularly relevant to the initial phase of the analysis checklist—identification of rogue processes—each supplying complementary perspectives on the process inventory:

  • windows.pslist: Enumerates processes present in the active _EPROCESS doubly-linked list (i.e., those still regarded as live by the kernel).
  • windows.psscan: Performs a pool-tag and structure-signature scan of physical memory to recover both linked and unlinked (or residual) _EPROCESS allocations, thereby detecting processes concealed by Direct Kernel Object Manipulation.
  • windows.pstree: Reconstructs the process hierarchy as a tree, preserving parent–child relationships derived from the active-process list and thereby facilitating rapid assessment of lineage anomalies.
  • Memory Baseliner: Compares the process and loaded-module inventories of the subject image against a known-good baseline, highlighting deviations that may indicate unauthorized or malicious activity.

Collectively, these plugins enable both list-based and scan-based enumeration, hierarchical visualization, and differential analysis—forming a robust first-stage methodology for isolating anomalous processes.


Identify Rogue Processes: windows.pslist.PsList

Enumeration of running processes constitutes one of the earliest and most routinely performed steps in memory examination. The Volatility 3 plugin windows.pslist.PsList (The functional equivalent in Volatility 2 is the pslist plugin) provides a rapid and reliable means of obtaining this inventory. It locates the head of the active _EPROCESS doubly-linked list within the kernel, traverses the chain, and extracts structured metadata for each process object encountered. For every identified process, the plugin reports, among other fields:

  • Process Identifier (PID)
  • Parent Process Identifier (PPID)
  • Image file name
  • Virtual address of the _EPROCESS block (Offset(V))
  • Thread count
  • Handle count
  • Session identifier
  • Architecture indicator—64- or 32-bit code (Wow64)
  • Creation timestamp
  • Exit timestamp

Each of these attributes may be scrutinized for anomalies. Consistent with Volatility’s design philosophy, the plugin surfaces the maximum volume of data recoverable from the underlying structures. While certain fields—such as session identifier or handle count—may prove superfluous for routine triage, they can become diagnostically valuable when comparative analysis against peer processes suggests inconsistency.

Output rendering may be controlled via the -r (or --renderer) option. The pretty renderer is well suited to interactive console review, whereas the CSV and JSON renderers facilitate subsequent import into spreadsheets, databases, or other analytical platforms.



When examining a memory image, the active process list is often the first artifact an analyst reviews. The windows.pslist.PsList plugin walks the doubly-linked list of _EPROCESS structures maintained by the Windows kernel and presents a concise inventory of processes that were considered “alive” at the time of acquisition.


In the case of the wcry.raw memory image, the output appears largely unremarkable at first glance. The usual system processes are present—System, smss.exe, csrss.exe, winlogon.exe, services.exe, lsass.exe, and multiple instances of svchost.exe. User-mode activity is limited, with explorer.exe and a handful of supporting processes visible. Two entries, however, immediately stand out from the rest of the list:


PIDPPIDImageFileNameCreate Time (UTC)Notes
19401636tasksche.exe2017-05-12 21:22:14Spawned by explorer.exe
7401940@WanaDecryptor@2017-05-12 21:22:22Spawned by tasksche.exe


Why These Processes Are Suspicious

1. Unusual Process Names
Neither tasksche.exe nor @WanaDecryptor@ belongs to any legitimate Windows component or commonly installed application. The second name in particular is highly distinctive and has been associated with WannaCry ransomware since the May 2017 outbreak.

2. Suspicious Parent-Child Relationship
tasksche.exe was launched by explorer.exe, indicating it was started in a user session rather than as a service. Eight seconds later, it spawned @WanaDecryptor@. This rapid parent-child relationship is characteristic of malware that deploys an initial dropper/orchestrator and then launches a secondary payload (in this case, the ransom note and decryption interface).

3. Timing
Both processes were created very early in the system’s uptime (approximately one minute after boot). This timing is consistent with WannaCry’s known behaviour of executing quickly after initial infection.


Although the pslist output alone does not show the full file path, the process names and relationships already provide strong grounds for further investigation. In real-world WannaCry infections, tasksche.exe is typically found in a randomly named directory under C:\Intel\ (or a similar location), and @WanaDecryptor@.exe is launched from the same folder.


While the majority of processes in this memory image appear legitimate, the presence of tasksche.exe and @WanaDecryptor@ constitutes a high-confidence indicator of WannaCry ransomware activity. These two processes should be prioritized for deeper analysis—including command-line arguments, loaded modules, network connections, and file-system artifacts—in subsequent stages of the investigation.


It is essential to remember that windows.pslist.PsList is the most basic of Volatility’s process enumeration plugins. It simply walks the active _EPROCESS doubly-linked list maintained by the Windows kernel (via PsActiveProcessHead). While this method is fast and reliable under normal conditions, it is also the most easily subverted. Rootkits and advanced malware that employ Direct Kernel Object Manipulation (DKOM) can unlink their _EPROCESS structures from this list, rendering the malicious processes invisible to pslist. Consequently, the absence of a process in the pslist output does not prove that the process was not running at the time of acquisition. For this reason, any thorough memory examination must include complementary techniques—most notably windows.psscan.PsScan—which locates _EPROCESS objects by pool-tag and structure scanning rather than by following the active process list. Only by comparing the results of both plugins can an analyst gain reasonable confidence that hidden or unlinked processes have not been overlooked.


Identify Rogue Processes: windows.psscan.PsScan

The windows.psscan.PsScan plugin collects process information using a fundamentally different approach from windows.pslist.PsList. The inclusion of the word “scan” in its name is deliberate and reflects a broader design pattern within Volatility. Scanning plugins do not rely on the operating system’s normal data structures—such as the doubly-linked list of active processes—to locate objects. Instead, they systematically search the entire memory image for characteristic signatures of specific kernel objects, a technique conceptually similar to data carving on a disk image.

This methodological difference gives psscan several important analytical advantages. Because it does not depend on the integrity of the active process list, it is capable of recovering terminated processes whose _EPROCESS structures still reside in unallocated or residual memory. It is also significantly more resilient against rootkit techniques that employ Direct Kernel Object Manipulation (DKOM) to unlink malicious processes from the kernel’s active list. As a result, psscan frequently reveals processes that are invisible to pslist.

The trade-off for this deeper visibility is performance: the exhaustive scanning process makes psscan considerably slower than its list-walking counterpart. The information it returns, however, is largely the same and includes:

  • Process Identifier (PID)
  • Parent Process Identifier (PPID)
  • Image file name
  • Virtual offset of the _EPROCESS block
  • Thread and handle counts
  • Session ID
  • Wow64 status
  • Process creation time
  • Process exit time

A populated ExitTime field is a reliable indicator that the process has terminated. This timestamp can be particularly valuable, as it allows the analyst to calculate how long a process remained active and may offer insight into the operational behaviour of the executable. It should be noted, however, that not every terminated process receives an updated exit timestamp. Analysts should therefore also watch for processes that report zero threads and zero handles, as the absence of threads generally indicates that no code is currently executing.

Comparing the output of psscan with that of pslist remains a best practice. Processes that appear only in the scan results—or that are present in both but show an exit time—warrant closer scrutiny. It is also worth observing that, particularly on Windows 10 and later systems, exited processes frequently remain linked in the active process list for extended periods before the kernel removes them. Consequently, the presence of an ExitTime value does not automatically mean the process has been unlinked from the list. By combining the results of both plugins, investigators gain a more complete and resilient view of process activity, significantly improving their ability to detect both terminated and deliberately concealed malware.


While windows.pslist provides a clean view of processes that remain linked in the kernel’s active process list, it is inherently limited. Malware that employs Direct Kernel Object Manipulation (DKOM) can unlink its _EPROCESS structures, and processes that have already exited will normally disappear from the list once the kernel reclaims their memory. To overcome these limitations, analysts turn to windows.psscan.PsScan. Unlike pslist, the psscan plugin does not follow any linked list. Instead, it scans the entire memory dump for pool allocations that match the characteristics of an _EPROCESS object (pool tags, structure size, and internal consistency checks). This approach allows it to recover both active processes and residual (terminated or unlinked) process objects that would otherwise be invisible.



When psscan was run against the WannaCry memory image, it returned several important results that were absent from the active process list. All of the newly discovered processes share the same parent: PID 1940 (tasksche.exe).


PIDPPIDImageFileNameCreate Time (UTC)Exit Time (UTC)Status
7401940@WanaDecryptor@2017-05-12 21:22:22Still runningActive
4241940@WanaDecryptor@2017-05-12 21:25:522017-05-12 21:25:53Terminated
5761940@WanaDecryptor@2017-05-12 21:26:222017-05-12 21:26:23Terminated
5361940taskse.exe2017-05-12 21:26:222017-05-12 21:26:23Terminated
8601940taskdl.exe2017-05-12 21:26:232017-05-12 21:26:23Terminated

The presence of multiple short-lived child processes spawned by tasksche.exe provides valuable insight into WannaCry’s runtime behaviour:

  • The malware did not launch the ransom interface only once. It repeatedly created new instances of @WanaDecryptor@.
  • Additional helper binaries (taskse.exe and taskdl.exe) were also executed. These components are known to assist with file enumeration, encryption, and cleanup operations.
  • Most of these helper processes existed for only one second before terminating. Their _EPROCESS objects remained in memory long enough to be recovered by pool scanning, but they had already been removed from the active process list.

This pattern is characteristic of WannaCry. The primary orchestrator (tasksche.exe) remains resident while it continuously launches short-lived helper processes to carry out encryption and display the ransom note.

If the investigation had relied solely on pslist, the analyst would have seen only one instance of @WanaDecryptor@ and would have completely missed taskse.exe and taskdl.exe. By comparing the output of both plugins, we obtain a much more complete picture of the malware’s activity in the minutes following the initial infection. In summary, windows.psscan proved essential in this case. It not only confirmed the presence of the primary WannaCry processes but also revealed a series of terminated helper processes that significantly enriched the timeline and behavioural understanding of the infection.


Identify Rogue Processes: windows.pstree.PsTree

Viewing parent-child process relationships in a hierarchical format can greatly assist in identifying anomalous behaviour. The windows.pstree.PsTree plugin provides this capability within the Volatility framework. Like pslist, it enumerates processes by walking the kernel’s active _EPROCESS doubly-linked list and then presents the results as a structured process tree. Because it relies on the same linked-list mechanism, pstree primarily visualizes processes that are still considered active by the operating system, although terminated processes that have not yet been unlinked from the list may also appear. The information returned by the plugin is consistent with other process-related plugins and includes:

  • Process Identifier (PID)
  • Parent Process Identifier (PPID)
  • Image file name
  • Virtual offset of the _EPROCESS block
  • Thread and handle counts
  • Session ID
  • Wow64 status
  • Process creation time
  • Process exit time

By rendering these relationships in a tree structure, pstree makes inheritance patterns immediately visible, allowing analysts to quickly spot unusual parent-child pairings, unexpected process lineages or malware that has been spawned from legitimate system processes.


While pslist and psscan are excellent for discovering processes, they present information in a flat list. Understanding how processes relate to one another—particularly parent-child relationships—is often critical for reconstructing an attack. The windows.pstree.PsTree plugin addresses this need by displaying processes in a hierarchical tree format based on the InheritedFromUniqueProcessId field (PPID).



In the wcry.raw memory image, the process tree immediately highlights the WannaCry infection chain:


explorer.exe (PID 1636)
 └── tasksche.exe (PID 1940)
      └── @WanaDecryptor@ (PID 740)

This simple hierarchy tells a clear story:

  1. explorer.exe (the Windows shell) launched tasksche.exe.
  2. tasksche.exe then launched @WanaDecryptor@.exe.


Beyond the basic parent-child relationship, the plugin also recovers valuable path and command-line information:

ProcessFull PathCommand Line
tasksche.exeC:\Intel\ivecuqmanpnirkt615\tasksche.exe"C:\Intel\ivecuqmanpnirkt615\tasksche.exe"
@WanaDecryptor@C:\Intel\ivecuqmanpnirkt615\@WanaDecryptor@.exe@WanaDecryptor@.exe

Several forensic observations stand out:

  • Both malicious binaries are located in the same non-standard directory: C:\Intel\ivecuqmanpnirkt615\.
  • The directory name appears randomly generated—a classic WannaCry behaviour used to evade simple signature-based detection and to blend in with legitimate software folders.
  • The processes were executed from a user context (spawned by explorer.exe) rather than as a Windows service.

Seeing the relationship in tree form makes the attack progression obvious. An analyst can instantly recognize that:

  • The initial execution was interactive (or at least occurred within a user session).
  • tasksche.exe acted as the primary orchestrator.
  • @WanaDecryptor@ was a secondary payload launched shortly afterward (only eight seconds later).

This visual representation is particularly useful when writing reports or explaining the infection timeline to stakeholders who may not be familiar with raw process lists.

The windows.pstree.PsTree output provides the clearest view of the WannaCry execution flow in this memory image. By combining process hierarchy with full path information, it confirms that the ransomware was launched from a suspicious directory under C:\Intel\ and followed the classic parent-child pattern of explorer.exe → tasksche.exe → @WanaDecryptor@. This relationship forms one of the strongest behavioural indicators of WannaCry activity in the image.


Effective memory forensics depends heavily on the analyst’s ability to distinguish normal system activity from anomalous behaviour. Knowing what legitimate processes should look like on a Windows host—their expected parent-child relationships, typical command-line arguments, standard execution paths, and usual privilege levels—dramatically reduces noise and allows investigators to focus on true outliers.

One of the most practical resources for building this baseline knowledge is the SANS “Hunt Evil” poster. Specifically designed for threat hunting and incident response, the poster provides a clear visual reference of core Windows processes, their normal relationships, and common indicators of abuse. By keeping this resource close at hand during analysis, investigators can rapidly assess whether a process tree, parent-child relationship, or execution path deviates from expected behaviour.

In the context of memory analysis, this baseline approach is particularly powerful. When reviewing the output of plugins such as pslist, psscan, and pstree, the analyst can quickly dismiss the majority of legitimate system processes and concentrate attention on those that fall outside established norms—exactly as demonstrated in the WannaCry case, where tasksche.exe and @WanaDecryptor@ stood out precisely because they violated multiple expectations of normal Windows process behaviour.


Orphan Processes

In both Windows and Unix-like operating systems, it is uncommon to observe child processes running without a corresponding parent. Such processes are referred to as orphan processes. This situation is unusual because child processes are typically spawned to perform a specific task or a subset of work on behalf of a parent process. Consequently, it is rare for a parent to terminate while its child processes are still active. A practical example is dllhost.exe, which is frequently used as a surrogate process to host software extensions. Its purpose is to isolate potential failures so that a crash in the extension does not bring down the parent application. In normal operation, therefore, the continued presence of dllhost.exe without an identifiable parent is unexpected and warrants closer examination.

The absence of a parent process is a useful investigative lead. Malware loaders commonly produce this pattern: they launch their intended payload and then exit, leaving the malicious process orphaned. A similar artefact can also appear during certain code-injection attacks, in which a process is deliberately created as an injection target, and the parent is no longer required once the injected code is executing. Many Metasploit Meterpreter payloads, for instance, exhibit this behaviour. Because of its investigative value, the identification of orphan processes has been highlighted as a high-priority hunting technique. Hiroshi Suzuki and Hisao Nashiwa notably included it among their top recommended methods in the presentation Super Easy Memory Forensics, delivered at the FIRST Conference in Dublin in June 2022.



In the process tree illustrated above, an initial Amadey infection is visible through the presence of three malicious processes, all of which appear as orphans. Although the System process (PID 4) is also shown without a parent, this is expected and legitimate behaviour. The remaining three processes, however, warrant closer scrutiny.

The process named Sun07610e6b216 is sufficiently anomalous in naming convention that most analysts would flag it immediately. In contrast, setup_install.exe and tkools.exe employ more generic names that could easily escape casual notice. What elevates them as suspicious is the absence of a living parent process—indicated in pstree output by a single asterisk (*) at the start of a new branch. This lack of an active parent provides a strong reason to prioritize these processes for further investigation. In this particular case, all three proved to be components of the Amadey malware family.

It is important to recognize that a small number of well-known legitimate processes routinely appear as orphans. These include System (the root of the process hierarchy), explorer.exe, csrss.exe, and wininit.exe. In the example shown, explorer.exe is correctly positioned beneath its expected parent, userinit.exe; however, userinit.exe itself has already terminated and carries an exit timestamp. This illustrates a key point: while Windows generally maintains parent-child relationships by convention, it does not strictly enforce them. The absence of active enforcement creates opportunities for more sophisticated techniques, including parent process ID (PID) spoofing, in which malware deliberately fabricates a plausible parent to evade detection.


Recognizing Persistence and Lateral Movement Through Process Trees

Windows is fundamentally designed to execute code within process threads. As a result, common persistence and lateral movement techniques inevitably leave distinctive process artefacts on a compromised system. Because the majority of real-world attacks rely on a relatively small set of these techniques, familiarity with their characteristic process-tree patterns can significantly improve an analyst’s ability to identify malicious activity in memory. The figure below demonstrates four frequently observed techniques, each resulting in the execution of a malicious binary named updater.exe. Understanding the expected parent-child relationships associated with these methods provides a practical framework for spotting anomalies.


Services
Services remain one of the most common mechanisms for executing code on Windows. Consequently, a large number of child processes typically appear beneath services.exe. When hunting for malware, systematic review of this branch is almost always warranted. It is no coincidence that three of the four techniques illustrated ultimately appear under services.exe.

Scheduled Tasks
Modern Windows systems can contain hundreds of scheduled tasks, offering attackers ample opportunity to conceal a single malicious task among legitimate ones. When a scheduled task is triggered, it executes under a specific svchost.exe instance responsible for the Task Scheduler. On Windows 10 and later, this process can be identified by the presence of a child process named taskhostw.exe and the command line:


C:\Windows\system32\svchost.exe -k netsvcs -p -s Schedule

Executables launched by the scheduled task appear as direct children of this svchost.exe process (not under taskhostw.exe).

Registry Run Keys
Registry run keys are designed to execute during user logon and therefore typically appear as child processes of the user desktop process, explorer.exe. Because the majority of user-context applications also reside under this branch, it is a high-value location for detecting not only run-key persistence but a wide range of other user-level attacks.

PsExec (Sysinternals)
Remote execution via the Sysinternals PsExec utility results in the creation of a service on the target system. By default, this service is named PSEXESVC.exe. Any binaries launched through PsExec appear as children of this service process. Analysts should note that the service name can be altered using the tool’s -r parameter. It is also important to distinguish the genuine Sysinternals PsExec from the numerous third-party tools and payloads that adopt the same name. Many of these alternatives—including Cobalt Strike’s psexec payloads—rely on WMI or PowerShell for execution and therefore produce entirely different parent-child process patterns.

By internalising these characteristic process-tree signatures, investigators can more rapidly distinguish legitimate system activity from the artefacts left by common persistence and lateral movement techniques.


Recognizing WMI and PowerShell Activity in Process Trees

As WMI and PowerShell have become ubiquitous in modern enterprise environments, their presence in process trees is both expected and analytically significant. The specific processes observed, together with their parent-child relationships, often reveal a great deal about the nature of activity occurring on a system.


In the top-left of the figure shown above, a WMI-based attack is visible. The primary WMI process, WmiPrvSE.exe, is used to launch PowerShell (powershell.exe). This parent-child relationship is a common precursor in many offensive techniques, including certain Cobalt Strike commands and the abuse of WMI CommandLine Event Consumers. While some legitimate remote administration activity can produce the same pattern, the relationship is almost always worth investigating.

WMI Event Consumers are frequently leveraged for both persistence and code execution. Two consumer types are particularly abused in the wild: CommandLine and ActiveScript. The illustration demonstrates a CommandLineEventConsumer attack; ActiveScriptEventConsumers are equally common. When an ActiveScriptEventConsumer executes, it spawns a process rarely observed on most systems—scrcons.exe. Microsoft officially designates this binary as the “WMI Standard Event Consumer – Scripting Application,” underscoring its narrow purpose. The appearance of scrcons.exe should therefore prompt immediate closer examination.

WMI was designed for remote query and control. The WmiPrvSE.exe process (WMI Provider Host) is responsible for executing WMI commands on the target system and serves as the interface between WMI and the operating system. Because of WMI’s flexibility, attackers have developed numerous methods to run malicious code through it—the classic example being wmic.exe process call create, though far more sophisticated techniques also exist. In some cases, adversaries deliberately prefer WMI over PowerShell remoting precisely because the resulting activity is less conspicuous. Child processes of WmiPrvSE.exe frequently provide the clearest indicators of suspicious behaviour.

The presence of wsmprovhost.exe on a system is a reliable indicator of PowerShell remoting activity. This process executes on the remote (target) system and is associated with capabilities such as Enter-PSSession, Invoke-Command, New-PSSession, and any PowerShell cmdlets that natively support the -ComputerName parameter (for example, Set-Service or Clear-EventLog). This applies specifically to true PowerShell remoting. Older cmdlets such as Get-WmiObject that rely on RPC/DCOM are typically handled by a svchost.exe process and may be identified through suspicious internal network connections instead.

Local execution of powershell.exe is itself often of interest. As a general rule of thumb:


  • A parent of explorer.exe usually indicates interactive user execution.
  • A parent of svchost.exe commonly suggests the use of an administrative account.
  • A parent of cmd.exe may indicate launch via a backdoor or command shell, although it can also result from a user simply transitioning from a Command Prompt session.
  • Parents such as winword.exe, mshta.exe, or wscript.exe are highly anomalous and warrant immediate investigation.

Detecting malicious WMI and PowerShell activity in memory remains challenging because of the volume of legitimate enterprise usage. As with most forensic analysis, context is critical. Examining both the parent and child processes of suspicious binaries frequently supplies the additional context needed to distinguish benign from malicious behaviour. In the final example on the above figure, PowerShell remoting (wsmprovhost.exe) is observed spawning sc.exe, a tool used to interact with Windows services—common targets of attackers. This combination should prompt a deeper inspection of the process tree with particular attention to service-related activity. Similarly, an application such as Word, Outlook, or the more obscure mshta.exe spawning a PowerShell child process constitutes a clear anomaly that may indicate the execution of a macro or other malicious payload.



Running processes offer an excellent opportunity to identify suspicious WMI activity. Because the relevant structures exist only in live memory, access to memory—and a means of analyzing it—is required. Process data can be examined through an endpoint detection and response (EDR) platform, live-response collection, or offline analysis of a memory dump.

A fundamental principle of process analysis is that every process has (or once had) a parent. By organizing processes into a tree and examining parent-child relationships, analysts can frequently surface anomalous patterns. This approach has proven particularly effective for identifying WMI event consumers and a wide range of other suspicious WMI-related activity. The standard WMI process is WmiPrvSE.exe (often rendered as wmiprvse.exe). On a modern Windows system, multiple instances may be running; their parent process should normally be svchost.exe. Observation of WmiPrvSE.exe with an unexpected parent—such as w3wp.exe (the IIS worker process)—would be anomalous and could indicate webshell activity.

In the figure above, the anomaly lies not with the parent of WmiPrvSE.exe but with its child. The process has spawned cmd.exe, a highly unusual relationship. This exact pattern is produced when a WMI CommandLineEventConsumer executes. In the illustrated case, the WMI-based attack appears to be modifying a Windows registry value associated with protected processes (a feature introduced in Windows 8). One plausible objective of such a modification is to weaken the protection of the LSASS process.

Command-line information stored with each process supplies additional investigative context. The combination of WmiPrvSE.exe launching a command prompt that performs unexpected registry modifications is precisely the type of behaviour an analyst should recognize as a potential indicator of compromise. This particular example is especially instructive because the distinctive command line can be attributed to a known attack tool. Command lines associated with the popular Impacket wmiexec.py utility are memorable and serve as effective hunting indicators. For further reading on this topic, CrowdStrike has published a detailed post on detecting and hunting wmiexec activity.


Baseline Analysis with Memory Baseliner

Baseline analysis is a fundamental technique applicable across a wide range of digital forensics and incident response artefacts. In its simplest form, it involves comparing a suspect data set against a known-good data set in order to identify outliers. Memory Baseliner, developed by Csaba Barta, brings this capability to memory forensics.

Windows memory images routinely contain more than one hundred processes, each associated with hundreds of additional objects, alongside numerous drivers and services. Even experienced analysts can overlook malware concealed among thousands of items that require review. When a baseline from a clean system of comparable type is available, many of the known-good artefacts can be rapidly filtered, allowing attention to be focused on genuine anomalies. To achieve this, Memory Baseliner accepts two memory images: a baseline image (specified with -b) and a suspect image (specified with -i). The current version of the tool is implemented as a stand-alone utility that uses Volatility 3 as a library. It supports baselining of the following categories of memory objects:

  • Processes and their associated DLLs (-proc)
  • Drivers (-drv)
  • Windows services (-svc)

Results can be written to a file (-o) for subsequent analysis in a spreadsheet or other review tool. A useful practice is to include the --showknown option, which outputs both known (present in the baseline) and unknown (absent from the baseline) items in a single file. This combined output can then be filtered flexibly. Analysts should examine the available columns carefully, as they contain substantial contextual information, including process name, command line, parent process, loaded modules, import-table hashes (where available), a KNOWN/UNKNOWN status flag, and frequency-of-occurrence data for both the baseline and the suspect image (“BASELINE FoO” and “IMAGE FoO”).

Least Frequency of Occurrence (Stacking)

Memory Baseliner also supports least-frequency-of-occurrence analysis through its stacking features. The underlying principle is that malware artefacts are far rarer than those associated with normal system activity. When executables, drivers, DLLs, or services are aggregated across many systems, items linked to malware tend to appear among the least frequently occurring. A DLL present on only one system is statistically more likely to be malicious than one found on 73 systems.

Stacking is performed by pointing the tool at a directory of memory images with the -d option and selecting the appropriate stacking mode (for example, -drvstack). Processes, DLLs, drivers, and services can then be compared across the collection, allowing the least common items to rise to the top of the output for easier identification.

As with any analytical technique, stacking should not be expected to deliver instantaneous malware identification. Enterprises contain many unique systems even within similar build groups, and a number of legitimate but uncommon artefacts will appear as false positives. Nevertheless, the method is highly effective at reducing the data set and offering an alternative means of surfacing outliers.

The primary practical limitation of Memory Baseliner is execution time. Although the latest version has been optimised, generating baseline output for a large memory image can still require approximately 15 minutes. Subsequent runs can be accelerated significantly by using the --jsonbaseline feature. This capability creates a compact JSON representation of the known-good image that can be loaded in future analyses, eliminating the need to reprocess the original baseline memory dump.

The --savebaseline argument generates the JSON file, while --loadbaseline loads it for later use; both require the --jsonbaseline argument to specify the filename. It is important to note that JSON files are specific to the type of analysis being performed, so separate files are required for process, driver, and service baselining. Once a JSON baseline has been created, the original memory image is no longer needed. Because these JSON files are typically under 1 MB, they are far more portable than full memory dumps, making it practical to maintain a repository of baselines covering the range of system types and operating-system versions likely to be encountered.

An earlier version of the tool existed as a set of Volatility 2 plugins. That implementation is substantially different and less capable than the current stand-alone version. For reference, the older plugins were:

  • processbl – compared processes and loaded DLLs (drawing on functionality similar to pslist and ldrmodules)
  • servicebl – compared services (using svcscan components)
  • driverbl – compared loaded drivers (using modscan functionality)


The modern Memory Baseliner represents a significant evolution of the original concept and remains a valuable addition to the memory-analysis toolkit.




The figure above demonstrates Memory Baseliner applied to a memory image infected with DarkComet, a well-known remote access tool that has been employed by several Middle Eastern-based hacktivist groups. A conventional windows.pslist.PsList enumeration of the infected image identified 43 running processes. After comparison against a baseline image, the number of processes requiring review was reduced to 13 items absent from the baseline (flagged with the UNKNOWN label).

Several of these unknown processes immediately attract attention, including two instances of cmd.exe, runddl32.exe, notepad.exe, and DumpIt.exe (the last of which is a recognised memory-acquisition utility and was likely used to create the dump under analysis). The additional command-line context further sharpens the picture: runddl32.exe was executed from an atypical location within a user-profile Temp folder. Experienced analysts will also notice a critical anomaly in the executable name itself—there is no legitimate Windows binary named runddl32.exe. The genuine system component is rundll32.exe. By substantially reducing the volume of noise an analyst must evaluate, such discrepancies become far more apparent.

Further relationships reinforce the suspicion. notepad.exe lists runddl32.exe as its parent process, making it highly probable that this instance is also malicious. The command lines associated with the two cmd.exe processes reveal attacker tradecraft consistent with attempts to conceal artefacts by modifying folder and file attributes to the hidden-system state.

Even in this condensed view, a considerable amount of investigative value is present. The complete tool output contains still richer data, including loaded DLLs for each process, frequency-of-occurrence statistics, and import hashes that support more granular comparison. Because the volume of information can be substantial, an effective initial filtering strategy is to restrict the data set to process names (as shown in the example) and then filter the DLL NAME column for “.exe”. This works because the primary image binary itself appears in the loaded-module list. Combining that filter with a PROCESS STATUS of UNKNOWN rapidly isolates processes that were not present in the baseline image.

It is worth noting that the baseline used in this demonstration differed significantly from the system on which DarkComet was executed. A more closely matched baseline—aligned to a specific workstation or server build—would be expected to produce an even smaller set of unknown processes, further concentrating analyst effort on genuine outliers.


Post a Comment

Previous Post Next Post