Microsoft WindowsPowerShell

PowerShell for Rapid Incident Response – Process Enumeration (Part One)

“When the dog bites, when the bee stings, when I’m feeling sad…
I simply remember my favourite things and then I don’t feel so bad.”

When a security event takes place within your organisation, swift and direct incident response is required to determine the extent of an attack and the containment and eradication actions that may be required. This can often lead to a scramble by DFIR analysts to gather artefacts and find actions that took place on an affected system. Part one of this blog post series aims to show security analysts how PowerShell can quickly be utilised on compromised hosts to discover running processes that may be associated with malicious activity.

PowerShell features many powerful built-in commands which can be utilised during incident response engagements to quickly return information useful to analysts. One such command is get-process, which can be used to quickly query a host for running processes.

Often, Malware will drop malicious binaries into the user roaming AppData directory, as a form of persistence. Binaries in the ‘users/*/AppData/roaming’ folder are replicated to a user’s Active Directory profile path and can be automatically executed from Registry Run keys, Startup Folder Entries, Scheduled Tasks, Installed Services, and many other Auto-Start Extensibility Point (ASEP) locations.

Using Get-Process in PowerShell

Utilizing PowerShell and its built-in get-process command, you can quickly find instances of such processes.

get-process | ?{$_.Path -like '*appdata*'}

This returns the standard output of get-process, as we didn’t select any properties. It is important to note that the ‘?’ character is shorthand for “where” and that the ‘$_’ variable is the previously piped in object, which in this instance is the array returned by get-process. In short, you are asking PowerShell to retrieve an array of processes on the host, and filter those processes where the Path property of that array is like ‘*appdata*’.

You can use ‘gm’ (shorthand for get-members) to return the members or property and method names contained by the retuned objects, rather than just the name and path, as below:

get-process | ?{$_.Path -like '*appdata*'} | gm

Now that you know the additional properties of the returned process object, you can specify these properties to return some actionable information. We will also pipe to ‘fl’ (shorthand for Format-List) to return the objects in a list format.

get-process | select name, path, starttime, ID | ?{$_.Path -like '*appdata*'} | fl
Retrieving a list of process objects using get-process with specified properties.
Retrieving a list of process objects using get-process with specified properties.

Returned is the name of the process, the path it was started from, the process start time and its process ID. The start time is very useful, as you can look for further events which took place on the host around that timeframe.

Using GWMI (Get-WMIObject)

You can also retrieve information regarding Process Objects stored within Windows Management Instrumentation (WMI), using the command shown below:

gwmi win32_process | ?{$_.Path -match 'appdata'}
Retrieving a list of Win32_Process objects using gwmi.

As you can see, WMI Win32_process objects contain a different set of properties, such as the ID of the Parent Process which initially executed the binary, and the command-line arguments the binary was run with.

The parent process details can show us how the binary where the binary was executed from, such as services.exe for a persistence service, explorer.exe for a registry runkey or startup folder lnk file, or potentially by the malware first stage binary.

Command-Line details can show us if the malware was started with any arguments, which may lead to the discovery of Command and Control configuration or details of additional payloads to retrieve. As recently seen in DeathKitty Ransomware, some malicious binaries are often started with a “key” argument used to unpack the malicious payload, which may be useful for further dynamic analysis of the binary.

Once you know these new property names from the standard output, which can also be retrieved by piping the command to ‘gm’ as previously done with get-process. You can then specify the exact output you would like returned, as in the following example:

Retrieving a list of Win32_Process objects with specified properties.
Retrieving a list of Win32_Process objects with specified properties.

In this post, I have shown how you can quickly retrieve running processes from a specific location. The AppData folder is only one of many locations that malware may execute processes from or setup persistence in. Replacement of the AppData filter in the commands above should be done, in correlation with any SIEM events or other contextual attack data which shows binaries written to disk. Using multiple filters can also enable an analyst to look at multiple common malware locations as part of their initial triage.

Here are also some additional resources in regards to enumerating processes using PowerShell:

I hope this has shown how you can quickly retrieve information about running processes on a host. In the next part, I will be exploring how to gain similar information regarding installed services and how to quickly take action against those services, such as stopping and removing them.


SANS certified security consultant, currently contracting to private and government industry on major projects. Wide ranging skill set including Cyber Security, Networking, Systems Administration and Managed IT Services.
Back to top button