Odd Command Lines
The command line is what a process was told to do. Windows gives its own processes the arguments they expect, so a service host, svchost.exe, always names the group of services it runs. SigmaHQ calls a service host with no arguments extremely abnormal, because with nothing to host it is either a likely home for injected code or not a service host at all. An encoded command or a hidden window often conceals what runs, though management tools use both too. Read the command line from the creation record first, then from the running process, since the two can differ.
Normal and Suspicious
A clean machine sits beside a suspicious one, and the pointer marks where to look.
Normal
A clean Windows 11 install
| Name | Parent | Command Line |
|---|---|---|
svchost.exe | services.exe | svchost.exe -k Dcom |
Suspicious
ws-042,
| Name | Parent | Command Line |
|---|---|---|
scvhost.exe | updsvc64.exe | C:\ |
| Command LineNo arguments after its path: a genuine svchost.exe names the service group it loads with -k. Odd Command Lines | ||
Look Inside
Why It Matters
The command line says what a process was told to do, so a hidden or encoded one is a sign in itself. A service host or proxy started with no arguments has nothing to run, which published rules read as a likely home for injected code.
How to Confirm It
Work through these in order. Each step names the page that shows how.
- Read the command line from the creation record, in event 4688 in the Security log with its command line policy, Sysmon event 1 or DeviceProcessEvents. It shows how the process was started.Command Line and Environment
- Read it again from the running process or a memory image, with Win32_Process or windows.cmdline. A difference means it was rewritten after start.Command Line and Environment
- Decode an encoded command, and never run it. Event 4104 in the Microsoft-Windows-PowerShell/Operational log, where script block logging is on, records what PowerShell actually ran.Command Line and Environment
- Follow the parent, because a hidden or encoded command from an Office program, a script host or explorer.exe at sign-in points to a document, a script or a Run key.Process Trees and Call Chains
What Defenders See
Each record names its log and what must be switched on to get it.
| Record and Where It Lands | What to Read | How to Turn It On |
|---|---|---|
4688 A new process has been created (opens in a new tab)SecurityIt is written on the computer the process ran on. | Process Command Line, which stays empty unless Include command line in process creation events is on.Process Trees and Call Chains shows how to read it. | Turn on Audit Process Creation. For the command line, also turn on Include command line in process creation events. |
1 Process creation (opens in a new tab)Microsoft-Windows-Sysmon/OperationalIt is written on any Windows computer running Sysmon. | CommandLine and Parent | Run Sysmon with ProcessCreate events in its configuration. |
| Device | Process | The Defender for Endpoint sensor on the device |
4104 Script Block Logging (opens in a new tab)Microsoft-Windows-PowerShell/OperationalIt is written on the computer that ran Windows PowerShell. PowerShell 7 writes the same event to PowerShellCore/Operational. | The script block PowerShell actually ran, decoded, where script block logging is on.Command Line and Environment shows how to read it. | Turn on PowerShell Script Block Logging through Group Policy or the Registry. |
AsrDeviceEventsDefender XDR, advanced hunting | The ASR rule against potentially obfuscated scripts fired, in audit or block mode. | The Defender for Endpoint sensor on the device |
What It Looks Like
This record is decoded field by field, with what each value means.
| Field, as the Record Writes It | What It Tells You |
|---|---|
ImageC:\ | Windows PowerShell, genuine and in its home folder. The program is fine, so read what it was told to do. |
CommandLinepowershell | A hidden window and a Base64 command, cut short here, so what runs cannot be read off the line. Where script block logging is on, event 4104 in the Microsoft-Windows-PowerShell/Operational log records it decoded. |
ParentImageC:\ | Started by the shell at sign-in, which is how a Run key or Startup folder entry runs. Check those for the entry that holds this command. |
- False Positives
Management and deployment tools pass encoded commands and hidden windows to PowerShell to avoid quoting problems, so know which of yours do.
- Blind Spots
Without the policy Include command line in process creation events, event 4688 in the Security log holds no command line, and a live read shows only what the PEB holds now.
PowerShell 7 writes script blocks to its own PowerShellCore/Operational channel, which a search of the Windows PowerShell log misses.
Hunt It
The same hunt is written for four tools, so pick the one you use. Defender XDR and Sentinel queries are in KQL, which you paste into Advanced hunting in the Defender portal or into Sentinel's Logs page. Splunk queries are in SPL, for its Search page, and Velociraptor queries are in VQL, which you run as a hunt.
Needs Defender for Endpoint. Management tools send encoded commands too, so read the parent and account. Splunk's encoded command rule matches more forms of the switch, so compare with it before trusting a clean result.
// Encoded or hidden PowerShell, and service hosts or proxies started with no argumentsDeviceProcessEvents| where Timestamp > ago( 30d)| where isnotempty( ProcessCommandLine)| extend Name = tolower( FileName)| where ( Name in ( "powershell.exe", "pwsh.exe") and ProcessCommandLine matches regex @"( ?i)( ^|\ s)( / |--?)( e|ec|en|enc|enco|encod|encode|encoded|encodedc|encodedco|encodedcom|encodedcomm|encodedcomma|encodedcomman|encodedcommand)\ s") or ( Name in ( "powershell.exe", "pwsh.exe") and ProcessCommandLine matches regex @"( ?i)\ s[-/ ]w[a-z]*\ s+( hidden|1)( \ s|$)") or ( Name matches regex @"^[svchot]{6, 8}\ .exe$" and not( ProcessCommandLine matches regex @"( ?i)\ s-k\ s")) or ( Name in ( "rundll32.exe", "dllhost.exe") and ProcessCommandLine matches regex @"( ?i)( rundll32|dllhost)( \ .exe)?\ W*$")| project Timestamp, DeviceName, FileName, FolderPath, InitiatingProcessFileName, AccountName, ProcessCommandLine| order by Timestamp descIn a Memory Image
Volatility 3 reads a memory image, and each of its plugins below shows part of this sign.
windows.cmdline(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. cmdline means command line. The command line as the PEB held it at capture, to compare with the creation record.windows.(documentation, opens in a new tab)Memory Image A Volatility 3 plugin from its malware group. It checks a memory image for code that hides, or code put into a process. Flags a PEB whose recorded string lengths disagree with its text, a sign the command line or path was rewritten. Read the two flags together.malware. pebmasquerade windows.consoles(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. Console buffers held by conhost.exe, which hold commands typed at a prompt and their output.windows.cmdscan(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. cmdscan means command scan. Command history lists left in memory.
Rules to Compare With
Security vendors publish detection rules anyone can read. These look for the same thing, so compare your own with them.
Show the 6 Public Rules
- Malicious PowerShell Process - Encoded Command (opens in a new tab) Splunk: Flags PowerShell started with the EncodedCommand parameter, in any of its shortened forms.
- Suspect Svchost Activity (opens in a new tab) SigmaHQ: Flags svchost.exe started with no arguments, which the rule reads as a likely injection target.
- Dllhost.EXE Execution Anomaly (opens in a new tab) SigmaHQ: Flags dllhost.exe started with no command-line arguments.
- Suspicious DLLHost no Command Line Arguments (opens in a new tab) Splunk: Flags dllhost.exe running with no command-line arguments.
- Unusual Child Processes of RunDLL32 (opens in a new tab) Elastic: Flags rundll32.exe launched with no arguments, or malformed ones, that then starts a child process.
- Potential Homoglyph Attack Using Lookalike Characters (opens in a new tab) SigmaHQ: Flags command lines holding Cyrillic letters that look like Latin ones.
How to Prevent It
Each control helps prevent it, and its line says what it does here.
- ASR: Block execution of potentially obfuscated scripts (opens in a new tab) Blocks scripts that show the properties of obfuscation.
- PowerShell Script Block Logging (opens in a new tab) Records every script block as event 4104 in the Microsoft-Windows-PowerShell/Operational log, so an encoded command can be read decoded. Check it in the Registry: PowerShell Logging Policy
- Include command line in process creation events (opens in a new tab) Fills Process Command Line in event 4688 in the Security log, without which the command is lost.
Sources
- Microsoft Learn: about_PowerShell_exe (the EncodedCommand switch) (opens in a new tab)
- Microsoft Learn: about_Logging_Windows (script block logging) (opens in a new tab)
- Microsoft Learn: Command line process auditing (opens in a new tab)
- Microsoft Learn: 4688(S) A new process has been created (opens in a new tab)
- SigmaHQ: Conhost Spawned By Uncommon Parent Process (a clean system's DcomLaunch command line) (opens in a new tab)
- Microsoft Learn: Service host grouping in Windows 10 (one service per host above 3.5 GB) (opens in a new tab)
- Elastic: Execution of Persistent Suspicious Program (startup programs run under explorer.exe) (opens in a new tab)
- Volatility 3: windows.cmdline (opens in a new tab)
MITRE ATT&CK is a free public catalogue of the techniques attackers use. Each technique has an ID, such as T1055 for Process Injection, so defenders can name the same behaviour the same way. This red flag can point to these techniques.
- T1059.001 (opens in a new tab) Command and Scripting Interpreter: PowerShell
- T1059.003 (opens in a new tab) Command and Scripting Interpreter: Windows Command Shell
- T1027.010 (opens in a new tab) Obfuscated Files or Information: Command Obfuscation
- T1564.003 (opens in a new tab) Hide Artifacts: Hidden Window
- T1564.010 (opens in a new tab) Hide Artifacts: Process Argument Spoofing