Detect Process Argument Spoofing in Splunk
Adversaries may attempt to hide process command-line arguments by overwriting the Process Environment Block (PEB) in memory. The PEB is a Windows data structure that stores process metadata, including command-line arguments referenced at execution time. When a process is created, defensive tools and EDR sensors typically capture command-line arguments from the PEB at process creation. Adversaries exploit this monitoring window by first spawning a target process in a suspended state with innocuous-looking arguments (e.g., 'svchost.exe -k netsvcs'), allowing the arguments to be logged by monitoring tools. While the process is suspended, the adversary uses the WriteProcessMemory() Windows API — accessed via NtWriteVirtualMemory — to overwrite the RTL_USER_PROCESS_PARAMETERS structure inside the PEB with malicious arguments. The process is then resumed, executing with the malicious payload while all telemetry shows only the spoofed benign arguments. Cobalt Strike implements this capability as the 'argue' feature, allowing operators to mask beacon-spawned process arguments. SombRAT uses the same mechanism to hide its own command-line parameters from post-execution memory analysis. This technique is commonly chained with Parent PID Spoofing (T1134.004) to further blend injected processes into the legitimate process tree.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Technique
- T1564 Hide Artifacts
- Sub-technique
- T1564.010 Process Argument Spoofing
- Canonical reference
- https://attack.mitre.org/techniques/T1564/010/
SPL Detection Query
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
(EventCode=10 OR EventCode=8)
// ---- EventCode=10: ProcessAccess — filter to write-capable GrantedAccess values ----
// Values that include PROCESS_VM_WRITE (0x0020) and/or PROCESS_VM_OPERATION (0x0008)
// enabling WriteProcessMemory() calls needed to overwrite the PEB
| eval HasWriteAccess=if(
EventCode=10 AND GrantedAccess IN (
"0x1fffff", "0x001fffff",
"0x1f3fff", "0x1f0fff",
"0x143a", "0x1438", "0x143b",
"0x0028", "0x0038", "0x003c",
"0x0030", "0x0020", "0x0820"
), 1, 0
)
// ---- EventCode=8: CreateRemoteThread — always suspicious cross-process ----
| eval IsRemoteThread=if(EventCode=8, 1, 0)
| where HasWriteAccess=1 OR IsRemoteThread=1
// Normalize basenames for matching
| eval TargetBasename=lower(replace(TargetImage, ".*\\\\", ""))
| eval SourceBasename=lower(replace(SourceImage, ".*\\\\", ""))
// Filter out known security tool sources
| eval IsKnownSecTool=if(
match(SourceBasename, "(?i)^(msmpeng|mssense|sensenir|sensedr|cylancesvc|cb\.exe|cbdaemon|csfalcon|sentinelagent|elastic.endpoint|carbonblack)"),
1, 0
)
| where IsKnownSecTool=0
// Filter benign system self-injection: services.exe → svchost.exe
| where NOT (SourceBasename="services.exe" AND TargetBasename="svchost.exe")
| where NOT (SourceBasename="wininit.exe")
| where NOT (SourceBasename="csrss.exe")
// Detect LOLBin targets (high-value spoofing candidates)
| eval IsLolbinTarget=if(
TargetBasename IN (
"svchost.exe","rundll32.exe","dllhost.exe","regsvr32.exe",
"msiexec.exe","conhost.exe","notepad.exe","cmd.exe",
"wscript.exe","cscript.exe","werfault.exe","taskhostw.exe"
), 1, 0
)
// Detect suspicious source processes (Office apps, script hosts as injectors)
| eval IsSuspiciousSource=if(
match(SourceBasename, "(?i)^(excel|winword|powerpnt|outlook|msaccess|onenote|mshta|wscript|cscript|msbuild|csc|installutil)\.exe$"),
1, 0
)
// Cobalt Strike argument spoofing patterns: CallTrace showing direct syscalls or unbacked memory
| eval HasSuspiciousCallTrace=if(
match(CallTrace, "(?i)(UNKNOWN|ntdll\.dll\+0x[0-9a-f]+\|UNKNOWN|\\\\Device\\\\HarddiskVolume[0-9]+\\\\Windows\\\\SYSTEM32\\\\ntdll)") AND
NOT match(CallTrace, "(?i)\\\\WINDOWS\\\\System32\\\\"),
1, 0
)
// Composite suspicion scoring
| eval SuspicionScore=HasWriteAccess + IsRemoteThread + IsLolbinTarget + IsSuspiciousSource + coalesce(HasSuspiciousCallTrace, 0)
| table _time, host, User, SourceBasename, SourceImage, SourceCommandLine,
TargetBasename, TargetImage, GrantedAccess, CallTrace,
EventCode, HasWriteAccess, IsRemoteThread, IsLolbinTarget,
IsSuspiciousSource, SuspicionScore
| sort - SuspicionScore, - _time Detects process argument spoofing prerequisites using Sysmon. EventCode=10 (ProcessAccess) with write-capable GrantedAccess values (those including PROCESS_VM_WRITE 0x0020 or PROCESS_VM_OPERATION 0x0008) identifies when a process opens another process with permissions required to call WriteProcessMemory() — the API used to overwrite the PEB. EventCode=8 (CreateRemoteThread) captures the thread-injection variant. Composite scoring weights LOLBin targets, suspicious source processes (Office applications, script hosts), and Cobalt Strike-characteristic unbacked memory CallTrace patterns. Exclusions suppress known security tool behavior and well-understood system parent-child patterns.
Data Sources
Required Sourcetypes
False Positives & Tuning
- Security and endpoint protection tools (AV, EDR, DLP) that require process memory access for scanning and protection
- Anti-cheat software in gaming environments (EasyAntiCheat, BattlEye) that use cross-process memory access
- Debuggers and profiling tools (WinDbg, Visual Studio Debugger, Intel VTune, Process Hacker) generating high volumes of process access events
- Windows system operations: DWM compositing engine, accessibility tools (narrator.exe), COM+ infrastructure making cross-process calls
- Some legitimate endpoint automation platforms using process injection for monitoring or telemetry collection
Other platforms for T1564.010
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1PEB Argument Spoofing via PowerShell P/Invoke WriteProcessMemory
Expected signal: Sysmon Event ID 1: Process Create for notepad.exe with CommandLine='notepad.exe legitimate-document.txt' (the spoofed benign argument — this is what SIEM captures). Sysmon Event ID 10: ProcessAccess from powershell.exe targeting notepad.exe PID with GrantedAccess=0x1fffff. Security Event ID 4688 (if command line auditing enabled): shows same benign argument. Memory forensics on the notepad.exe process after the call will show 'malicious-payload --connect 192.0.2.1:4444' in the PEB RTL_USER_PROCESS_PARAMETERS.CommandLine.Buffer.
- Test 2Process Hollowing with Argument Spoofing using Sysinternals Procdump Validation
Expected signal: Sysmon Event ID 1: Process Create for cmd.exe with CommandLine='cmd.exe /c echo legitimate-task'. Sysmon Event ID 10: ProcessAccess from the PowerShell parent process to the spawned cmd.exe PID during the 3-second suspension window with GrantedAccess reflecting the handle used in CreateProcess (typically 0x1fffff for the hProcess handle). Security Event 4688 captures creation time. The 3-second gap between creation and resume is the PEB modification window — during this period, a real attacker would be calling WriteProcessMemory.
- Test 3Cobalt Strike Argue Simulation using AtomicTestHarnesses
Expected signal: Sysmon Event ID 1: Process Create for notepad.exe with CommandLine containing the decoy 'C:\Users\Public\legit.txt' — this is the argument visible in all SIEM logs. Sysmon Event ID 10: ProcessAccess from the test harness process to notepad.exe with GrantedAccess=0x1fffff during the modification window. The TestSuccess field from Invoke-ATHProcessArgSpoofing confirms the PEB was successfully modified — the in-memory CommandLine buffer now contains 'malicious-payload.exe --backdoor' while the process creation log shows only the decoy.
- Test 4Manual PEB Inspection with WinDbg to Validate Spoofing Artifact
Expected signal: Sysmon Event ID 1: Process Create for calc.exe with logged CommandLine. If CDB attaches: Sysmon Event ID 10 with SourceImage=cdb.exe and GrantedAccess reflecting debug access (0x1fffff or 0x0410). The !peb WinDbg output shows the RTL_USER_PROCESS_PARAMETERS structure including the CommandLine unicode string — in a spoofed process, this value would differ from the Win32_Process.CommandLine WMI query (which reads from the PEB at query time and may reflect the post-modification value) versus Sysmon/4688 logged at creation time.
References (10)
- https://attack.mitre.org/techniques/T1564/010/
- https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb
- https://blog.xpnsec.com/how-to-argue-like-cobalt-strike/
- https://blog.cobaltstrike.com/2019/01/02/cobalt-strike-3-13-why-do-we-argue/
- https://blog.nviso.eu/2020/02/04/the-return-of-the-spoof-part-2-command-line-spoofing/
- https://www.fireeye.com/blog/threat-research/2021/04/unc2447-sombrat-and-fivehands-ransomware-sophisticated-financial-threat.html
- https://www.mandiant.com/resources/staying-hidden-on-the-endpoint-evading-detection-with-shellcode
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1564.010/T1564.010.md
- https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory
- https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-rtl_user_process_parameters
Unlock Pro Content
Get the full detection package for T1564.010 including response playbook, investigation guide, and atomic red team tests.