Resources Blog Detection and response

Better know a data source: Process command line

In the first entry in our new series highlighting different endpoint data sources, we explore how process command line often reveals telling information about malicious activity.

Matt Graeber
Originally published . Last modified .

Command line refers to the arguments that are passed to an executable process in Windows. It is useful information for defenders as it can reveal contextual clues about the execution of a suspicious process. For example, adversaries regularly supply malicious PowerShell code as command-line arguments via the -Command and -EncodedCommand parameters. For executables that support arguments, command-line context is incredibly valuable to defenders looking to identify malicious behavior and/or aid incident response.

Any user-mode process, even if it isn’t a dedicated console application (for example, a GUI application) can have associated command-line arguments. And while it is generally the case that if an application implements command-line parameters that they will be documented accordingly, this is not always the case. Many applications have undocumented command-line parameters.

Why focus on process command line?

Defenders and vendors rely on process command line to discern benign from suspicious or malicious activity because it is among the most omnipresent data sources on an endpoint. Process command line can tell us how an application was intended to be used and in some cases can supply us directly with adversary payloads. For example, adversaries often supply malicious encoded PowerShell commands directly at the command line using any of the -EncodedCommand parameter variations. The way in which PowerShell eases post-exploitation abuse for adversaries also creates a unique and straightforward means of detecting malicious behavior based on process command line alone.

But this begs the question: what does legitimate PowerShell command-line activity look like?, which begs the follow-on question an adversary may pose: to what extent can I blend in with seemingly legitimate looking PowerShell command-line activity? So while you can be generally confident that known malicious evidence in the command line is malicious, you can’t always trust that non-malicious looking command line is not malicious activity in hiding.

What data sources are available to retrieve process command line?

The following data sources are either built into the operating system or are freely available to collect process command line. Note: This is a non-exhaustive list of data sources.

Windows Management Instrumentation (WMI)

Data source: Win32_Process Class
Relevant field[s]: CommandLine

Example retrieval: 

 

Get-CimInstance -ClassName Win32_Process | Select-Object -Property CommandLine
wmic process list /format:csv

Example data: 

 

PS C:\> Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine = "Foo"' | Select ProcessId, ExecutablePath, CommandLine | Format-List

ProcessId      : 2648
ExecutablePath : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
CommandLine    : Foo

Windows Process Auditing

Data source: Windows Security Log Event ID 4688
Relevant field[s]: CommandLine

Example data:

 

A new process has been created.
 
Creator Subject:
	Security ID:		<REDACTED>
	Account Name:		<REDACTED>
	Account Domain:		<REDACTED>
	Logon ID:		0x1103DA2
 
Target Subject:
	Security ID:		NULL SID
	Account Name:		-
	Account Domain:		-
	Logon ID:		0x0
 
Process Information:
	New Process ID:	0x1a40
	New Process Name:	C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
	Token Elevation Type:	%%1938
	Mandatory Label:	Mandatory Label\Medium Mandatory Level
	Creator Process ID:	0x270
	Creator Process Name:	C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
	Process Command Line:	Foo

Sysmon

Data source: Event ID 1: Process creation
Relevant field[s]: CommandLine, ParentCommandLine

Example data:

 

Process Create:
RuleName: 
UtcTime: 2021-03-09 21:15:45.985
ProcessGuid: {79703954-e581-6047-0000-0010cb1b2601}
ProcessId: 4516
Image: C:\Windows\System32\conhost.exe
FileVersion: 10.0.19041.746 (WinBuild.160101.0800)
Description: Console Window Host
Product: Microsoft® Windows® Operating System
Company: Microsoft Corporation
OriginalFileName: CONHOST.EXE
CommandLine: \??\C:\WINDOWS\system32\conhost.exe 0xffffffff -ForceV1
CurrentDirectory: C:\WINDOWS
User: <REDACTED>
LogonGuid: {79703954-e15d-6047-0000-0020a23d1001}
LogonId: 0x1103DA2
TerminalSessionId: 4
IntegrityLevel: Medium
Hashes: SHA1=9D48D4B78CBBFB22C9EE9070F713B35CD2A6A6EB
ParentProcessGuid: {79703954-e581-6047-0000-00105f1b2601}
ParentProcessId: 6720
ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ParentCommandLine: Foo

Where is process command line stored and how do adversaries retrieve it?

Process command-line information is stored within the ProcessParameters field of the process environment block (PEB), a user-mode data structure present in all processes. Because it is a user-mode data structure, it is readily susceptible to adversary modification. Even kernel drivers responsible for populating security events have to retrieve the command line from the PEB in user mode.

There are no APIs for directly retrieving process command line from another process. The following APIs are often used to access the PEB directly:

Under what conditions does an adversary have control over the process command line?

If an adversary has already achieved arbitrary code execution, they have the ability to spawn a new process with the command-line arguments of their choosing. An adversary may supply custom command-line arguments with the following intentions:

  • to supply legitimate command-line arguments to an executable that expects and will process the arguments
  • to evade naive detection logic that might look for specific command-line strings

So in the scenario where an adversary already has arbitrary code execution, they have a large amount of control over the command line of the processes they spawn. You should never assume that an adversary is not tampering with command-line logging.

Under what conditions does an adversary not have control over process command line?

An adversary will not have direct control over process command line under the following conditions, among many others:

  • A file is executed using its default file handler. For example, getting a victim to download and double click on a MSHTA .hta file would invoke the default file handler for that extension: mshta.exe <path to HTA file>
  • An executable starts as a side effect of certain actions. For example, when the Add-Type cmdlet is called in PowerShell, assuming it is C# code being compiled, the C# compiler csc.exe is spawned as a child process with a predictable command line.

How can I simulate generation of process command line in order to perform sensor and detection validation?

Influencing process command line at process start

There are multiple APIs available to start a process with a custom command line, CreateProcess being one of the more common functions available. In order to test starting an executable with a command line, we developed a simple PowerShell wrapper to make testing easy.

 

PS C:\> Start-ProcessWithCommandLine -ApplicationName 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -CommandLine 'Foo'
 
ProcessId ExecutablePath                                            CommandLine
--------- --------------                                            -----------
     7032 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Foo

 

In the above example, what would have been a command line of C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe is Foo instead. The ability to specify the command line at process start may not always be useful to an adversary because it would prevent their ability to supply legitimate command-line arguments. In the example above, while a powershell.exe is masqueraded in the command line, no relevant arguments like -Command or –EncodedCommand were supplied, potentially limiting the value to an adversary.

Modifying process command line after process start

In order to modify process command line after process start, an adversary would need to directly access and modify the PEB of a running process. The Masquerade-PEB PowerShell function written by Ruben Boonen is available to perform test command-line modification via the PEB.

 

> . .\Masquerade-PEB.ps1
> $CurrentPowerShellProcess = Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = $PID"
> $CurrentPowerShellProcess.CommandLine
powershell.exe  -NoProfile
> Masquerade-PEB -BinPath C:\Windows\explorer.exe
 
[?] PID 6236
[+] PebBaseAddress: 0x000000049470E000
[!] RtlEnterCriticalSection --> &Peb->FastPebLock
[>] Overwriting &Peb->ProcessParameters.ImagePathName: 0x0000014B554C2120
[>] Overwriting &Peb->ProcessParameters.CommandLine: 0x0000014B554C2130
[?] Traversing &Peb->Ldr->InLoadOrderModuleList doubly linked list
[>] Overwriting _LDR_DATA_TABLE_ENTRY.FullDllName: 0x0000014B554C2AF8
[>] Overwriting _LDR_DATA_TABLE_ENTRY.BaseDllName: 0x0000014B554C2B08
[!] RtlLeaveCriticalSection --> &Peb->FastPebLock
 
> $CurrentPowerShellProcess = Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = $PID"
> $CurrentPowerShellProcess.CommandLine
C:\Windows\explorer.exe

 

In the example above, powershell.exe -NoProfile was replaced with C:\Windows\explorer.exe. In this scenario, an adversary would have benefited from a process accepting the command-line arguments they supplied, but their evidence was then later concealed. While this scenario has the potential to buy additional evasion for an adversary, most process command-line log sources—including 4688 and Sysmon Event ID 1 events documented above—will capture the original command line prior to an adversary making modifications.

What can process command line reveal in isolation?

  • It can offer a clue about the functionality of the running executable assuming the command line was not altered by an adversary.
  • It can reveal the use of undocumented or underutilized command-line arguments that could potentially stand on their own as detection logic.
  • Adversaries will sometimes start a process with no command-line arguments and use it as a target for process injection. For executables that expect command-line arguments, such an anomaly could serve as sufficient indication of suspicious behavior.

What can process command line reveal in relation to other data sources?

  • The executable path of the process: Is the process executable filename present in the command line? Is it a full path, relative path, or just the filename? Does such a distinction tell us something? How often does the process command line not have the filename of the running executable? Could there be an opportunity to detect certain instances of adversary command line tampering?
  • Binary metadata of the process executable: Does the command line correspond to the expected command-line arguments implemented in the process executable?

Conclusion

Just because an adversary can exert influence over command-line parameters does not mean that process command-line logging cannot be trusted. And just because an adversary can exert influence over command-line parameters doesn’t mean that they will. There are still plenty of opportunities to leverage process command line to detect suspicious and malicious behavior while also using it to baseline expected, legitimate behavior. Also, command-line logging that occurs at process start has the benefit of winning the race and retrieving the original process command line before an adversary can come around and cover their tracks after the fact, as is the case in the Masquerade-PEB example above.

Our hope is that you now have a better understanding of what process command line looks like under the hood and how adversaries think about it in terms of evasion. Stay tuned for more deep dives into data sources in the coming months!

 

ProxyShell exploitation leads to BlackByte ransomware

 

Plan ahead with Red Canary’s new Incident Response and Preparedness guide

 

Intelligence Insights: November 2021

 

The dark side of Microsoft Remote Procedure Call protocols

Subscribe to our blog