Initial commit - 611 cybersecurity skills across all subdomains

This commit is contained in:
mukul975
2026-02-25 10:47:44 +01:00
commit 22a7ab1462
1765 changed files with 280648 additions and 0 deletions
@@ -0,0 +1,90 @@
---
name: detecting-process-hollowing-technique
description: Detect process hollowing (T1055.012) by analyzing memory-mapped sections, hollowed process indicators, and parent-child process anomalies in EDR telemetry.
domain: cybersecurity
subdomain: threat-hunting
tags: [threat-hunting, mitre-attack, process-hollowing, process-injection, edr, t1055, proactive-detection]
version: "1.0"
author: mahipal
license: MIT
---
# Detecting Process Hollowing Technique
## When to Use
- When investigating suspected fileless malware or in-memory threats
- After EDR alerts on process injection or suspicious memory operations
- When hunting for defense evasion techniques in a compromised environment
- When threat intel reports indicate process hollowing in active campaigns
- During purple team exercises validating T1055.012 detection coverage
## Prerequisites
- EDR with memory protection monitoring (CrowdStrike, MDE, SentinelOne)
- Sysmon with Event IDs 1 (Process Create), 8 (CreateRemoteThread), 25 (ProcessTampering)
- Windows ETW providers for process hollowing (Microsoft-Windows-Kernel-Process)
- Memory forensics capabilities (Volatility, WinDbg)
- Process integrity monitoring tools
## Workflow
1. **Understand Hollowing Mechanics**: Process hollowing involves creating a legitimate process in suspended state, unmapping its memory, writing malicious code, then resuming execution.
2. **Monitor Suspended Process Creation**: Hunt for processes created with CREATE_SUSPENDED flag followed by memory writes and thread resumption.
3. **Detect Memory Section Anomalies**: Identify processes where the in-memory image differs from the on-disk binary (image mismatch).
4. **Analyze Parent-Child Process Trees**: Flag processes whose behavior does not match their binary name (e.g., svchost.exe making unusual network connections).
5. **Check Process Integrity**: Compare process memory sections against the legitimate binary on disk.
6. **Correlate with Network Activity**: Hollowed processes often establish C2 connections - correlate suspicious process behavior with network logs.
7. **Document and Contain**: Report findings, isolate affected endpoints, and update detection rules.
## Key Concepts
| Concept | Description |
|---------|-------------|
| T1055.012 | Process Injection: Process Hollowing |
| T1055 | Process Injection (parent technique) |
| T1055.001 | DLL Injection |
| T1055.003 | Thread Execution Hijacking |
| T1055.004 | Asynchronous Procedure Call |
| CREATE_SUSPENDED | Windows flag to create a process in suspended state |
| NtUnmapViewOfSection | API to unmap process memory sections |
| WriteProcessMemory | API to write into another process's memory |
| ResumeThread | API to resume a suspended thread |
| Image Mismatch | Process memory content differs from on-disk binary |
| Process Doppelganging | Related technique using NTFS transactions (T1055.013) |
## Tools & Systems
| Tool | Purpose |
|------|---------|
| CrowdStrike Falcon | Memory protection and hollowing detection |
| Microsoft Defender for Endpoint | ProcessTampering alerts |
| Sysmon v13+ | Event ID 25 ProcessTampering detection |
| Volatility | Memory forensics - malfind plugin |
| pe-sieve | Process memory scanner for hollowed processes |
| Hollows Hunter | Automated hollowed process detection |
| Process Hacker | Live process memory inspection |
| API Monitor | Monitor NtUnmapViewOfSection calls |
## Common Scenarios
1. **Svchost.exe Hollowing**: Malware creates svchost.exe suspended, hollows it, injects backdoor code - process appears legitimate but behaves maliciously.
2. **Explorer.exe Hollowing**: Attacker hollows explorer.exe to inherit its network permissions and trusted process context.
3. **Rundll32 Hollowing**: Malicious loader creates rundll32.exe, replaces its memory with implant code for C2 beaconing.
4. **Multi-Stage Hollowing**: Loader uses process hollowing as first stage, then performs additional injection into services.
## Output Format
```
Hunt ID: TH-HOLLOW-[DATE]-[SEQ]
Technique: T1055.012
Hollowed Process: [Process name and PID]
Original Binary: [Expected on-disk path]
Parent Process: [Parent name and PID]
Memory Mismatch: [Yes/No]
Suspicious APIs: [NtUnmapViewOfSection, WriteProcessMemory, etc.]
Network Activity: [C2 connections if any]
Host: [Hostname]
User: [Account context]
Risk Level: [Critical/High/Medium/Low]
```
@@ -0,0 +1,29 @@
# Process Hollowing Hunt Template
## Hunt Metadata
| Field | Value |
|-------|-------|
| Hunt ID | TH-HOLLOW-YYYY-MM-DD-NNN |
| Analyst | |
| Date | |
| Status | [ ] In Progress / [ ] Complete |
## Hypothesis
> [e.g., "Adversaries have used process hollowing to inject malicious code into svchost.exe instances to evade detection."]
## Findings
| # | Host | Process | Parent | Expected Parent | Network Activity | Risk | Verdict |
|---|------|---------|--------|----------------|-----------------|------|---------|
| 1 | | | | | | | |
## Memory Analysis Results
| Process (PID) | Image Mismatch | Injected Code | VAD Anomaly | Verdict |
|--------------|----------------|---------------|-------------|---------|
| | | | | |
## Recommendations
1. **Memory Dump**: [Collect memory from affected hosts]
2. **Containment**: [Isolate compromised endpoints]
3. **Detection**: [Deploy Sysmon v13+ with Event ID 25]
4. **Prevention**: [Enable Attack Surface Reduction rules]
@@ -0,0 +1,79 @@
# Standards and References - Process Hollowing Detection
## MITRE ATT&CK Mappings
### T1055.012 - Process Injection: Process Hollowing
- **Tactic**: Defense Evasion (TA0005), Privilege Escalation (TA0004)
- **Platforms**: Windows
- **Data Sources**: Process modification, OS API execution, Process access
### Related Process Injection Sub-Techniques
| Sub-Technique | Name |
|---------------|------|
| T1055.001 | Dynamic-link Library Injection |
| T1055.002 | Portable Executable Injection |
| T1055.003 | Thread Execution Hijacking |
| T1055.004 | Asynchronous Procedure Call |
| T1055.005 | Thread Local Storage |
| T1055.008 | Ptrace System Calls |
| T1055.009 | Proc Memory |
| T1055.011 | Extra Window Memory Injection |
| T1055.012 | Process Hollowing |
| T1055.013 | Process Doppelganging |
| T1055.014 | VDSO Hijacking |
| T1055.015 | ListPlanting |
## Process Hollowing API Call Sequence
```
1. CreateProcess(CREATE_SUSPENDED) -> Create target in suspended state
2. NtQueryInformationProcess -> Get PEB address
3. ReadProcessMemory(PEB) -> Read image base from PEB
4. NtUnmapViewOfSection(ImageBase) -> Unmap original image
5. VirtualAllocEx(ImageBase, size) -> Allocate memory at same base
6. WriteProcessMemory(PE headers) -> Write malicious PE headers
7. WriteProcessMemory(PE sections) -> Write malicious code sections
8. SetThreadContext(EntryPoint) -> Set new entry point
9. ResumeThread -> Resume execution with malicious code
```
## Detection Data Sources
| Source | Event/Indicator | Description |
|--------|----------------|-------------|
| Sysmon Event 1 | Process Create | Process created with suspicious parent |
| Sysmon Event 8 | CreateRemoteThread | Remote thread in target process |
| Sysmon Event 25 | ProcessTampering | Image file replaced (Sysmon v13+) |
| ETW | Microsoft-Windows-Kernel-Process | Kernel-level process events |
| MDE | ProcessTampering | AlertType for hollowing detection |
| Memory | Malfind | Volatility plugin for injected code |
| Memory | VAD analysis | Virtual Address Descriptor anomalies |
## Volatility Forensic Commands
```bash
# Detect injected/hollowed processes
volatility -f memory.dmp --profile=Win10x64 malfind
# Compare process memory to disk image
volatility -f memory.dmp --profile=Win10x64 procdump -p <PID> -D ./dump/
# Analyze process memory sections
volatility -f memory.dmp --profile=Win10x64 vadinfo -p <PID>
# Check process image path vs loaded modules
volatility -f memory.dmp --profile=Win10x64 dlllist -p <PID>
```
## Known Malware Using Process Hollowing
| Malware | Target Process | Notes |
|---------|---------------|-------|
| Emotet | Multiple | Uses hollowing for persistence |
| TrickBot | svchost.exe | Hollows svchost for C2 |
| Dridex | explorer.exe | Financial trojan |
| FormBook | Various | Infostealer using hollowing |
| AgentTesla | RegAsm.exe, MSBuild.exe | Targets .NET processes |
| Remcos | Common utilities | RAT using hollowing |
| NanoCore | Various | RAT with hollowing capability |
| AsyncRAT | Various .NET processes | Open-source RAT |
@@ -0,0 +1,121 @@
# Detailed Hunting Workflow - Process Hollowing Detection
## Phase 1: Sysmon-Based Detection
### Step 1.1 - Process Tampering Events (Sysmon v13+)
```spl
index=sysmon EventCode=25
| table _time Computer User Image Type
| sort -_time
```
### Step 1.2 - Suspicious Process Creation Patterns
```spl
index=sysmon EventCode=1
| where match(Image, "(?i)(svchost|explorer|rundll32|dllhost|conhost|taskhost)\.exe$")
| where NOT match(ParentImage, "(?i)(services\.exe|explorer\.exe|svchost\.exe|userinit\.exe|winlogon\.exe)")
| table _time Computer User Image ParentImage CommandLine
```
### Step 1.3 - KQL for MDE ProcessTampering
```kql
DeviceEvents
| where ActionType == "ProcessTampering"
| project Timestamp, DeviceName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, AdditionalFields
| order by Timestamp desc
```
## Phase 2: Parent-Child Process Validation
### Step 2.1 - Invalid Parent-Child Relationships
Known legitimate parent-child pairs:
- services.exe -> svchost.exe
- explorer.exe -> user applications
- winlogon.exe -> userinit.exe
- svchost.exe -> specific service children
```spl
index=sysmon EventCode=1
| eval expected_parent=case(
match(Image,"(?i)svchost\.exe$"), "services.exe",
match(Image,"(?i)taskhost\.exe$"), "svchost.exe",
match(Image,"(?i)userinit\.exe$"), "winlogon.exe",
match(Image,"(?i)smss\.exe$"), "System",
1=1, "any"
)
| eval parent_name=mvindex(split(ParentImage,"\\"),-1)
| where expected_parent!="any" AND NOT match(parent_name, expected_parent)
| table _time Computer Image ParentImage expected_parent parent_name CommandLine
```
## Phase 3: Memory Analysis
### Step 3.1 - pe-sieve Scanning
```powershell
# Scan all processes for hollowing
Get-Process | ForEach-Object {
$pid = $_.Id
& pe-sieve64.exe /pid $pid /shellc /dmode 1 /json
}
```
### Step 3.2 - Hollows Hunter Full Scan
```powershell
# Run Hollows Hunter for automated detection
hollows_hunter64.exe /loop /json /dir C:\hunt_output
```
### Step 3.3 - Volatility Malfind
```bash
# Detect injected/modified process memory
python vol.py -f memory.raw windows.malfind
# Dump suspicious processes
python vol.py -f memory.raw windows.pslist --dump
```
## Phase 4: Behavioral Analysis
### Step 4.1 - Process Behavior Mismatches
Look for processes whose network/file behavior contradicts their identity:
```spl
index=sysmon EventCode=3
| where match(Image, "(?i)(svchost|dllhost|taskhost|conhost)\.exe$")
| where NOT match(DestinationIp, "^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)")
| where DestinationPort NOT IN (53, 80, 443, 123)
| stats count by Image DestinationIp DestinationPort Computer
```
### Step 4.2 - Hollowed Process C2 Indicators
```spl
index=sysmon EventCode=3
| where match(Image, "(?i)(svchost|explorer|rundll32)\.exe$")
| bin _time span=1s
| streamstats current=f last(_time) as prev by Image Computer DestinationIp
| eval interval=_time-prev
| stats count avg(interval) as avg_interval stdev(interval) as sd by Image Computer DestinationIp
| eval cv=sd/avg_interval
| where cv < 0.3 AND count > 20
```
## Phase 5: API Call Monitoring
### Step 5.1 - Critical API Sequences
Monitor for this specific API call chain:
1. `CreateProcessW` / `CreateProcessA` with `CREATE_SUSPENDED` (0x00000004)
2. `NtUnmapViewOfSection` / `ZwUnmapViewOfSection`
3. `VirtualAllocEx` with `PAGE_EXECUTE_READWRITE`
4. `WriteProcessMemory`
5. `SetThreadContext` / `NtSetContextThread`
6. `ResumeThread` / `NtResumeThread`
### Step 5.2 - ETW Process Hollowing Detection
```powershell
# Monitor for suspicious API patterns via ETW
# Requires elevated privileges
$session = New-EtwTraceSession -Name "ProcessHollowHunt"
Add-EtwTraceProvider -SessionName "ProcessHollowHunt" `
-Guid "{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}" `
-Level 5
```
@@ -0,0 +1,320 @@
#!/usr/bin/env python3
"""
Process Hollowing Detection Script
Analyzes process creation, memory events, and parent-child relationships
to detect process hollowing (T1055.012) indicators.
"""
import json
import csv
import argparse
import datetime
import re
from collections import defaultdict
from pathlib import Path
# Legitimate parent-child process relationships on Windows
VALID_PARENT_CHILD = {
"smss.exe": {"parents": ["system", "smss.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"csrss.exe": {"parents": ["smss.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"wininit.exe": {"parents": ["smss.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"winlogon.exe": {"parents": ["smss.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"services.exe": {"parents": ["wininit.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"lsass.exe": {"parents": ["wininit.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"svchost.exe": {"parents": ["services.exe", "MsMpEng.exe"], "user": "NT AUTHORITY\\*"},
"taskhost.exe": {"parents": ["svchost.exe"], "user": "*"},
"taskhostw.exe": {"parents": ["svchost.exe"], "user": "*"},
"userinit.exe": {"parents": ["winlogon.exe"], "user": "*"},
"explorer.exe": {"parents": ["userinit.exe", "explorer.exe"], "user": "*"},
"dllhost.exe": {"parents": ["svchost.exe", "services.exe"], "user": "*"},
"conhost.exe": {"parents": ["csrss.exe"], "user": "*"},
"RuntimeBroker.exe": {"parents": ["svchost.exe"], "user": "*"},
"SearchIndexer.exe": {"parents": ["services.exe"], "user": "NT AUTHORITY\\SYSTEM"},
"spoolsv.exe": {"parents": ["services.exe"], "user": "NT AUTHORITY\\SYSTEM"},
}
# Common hollowing target processes
HOLLOWING_TARGETS = {
"svchost.exe", "explorer.exe", "rundll32.exe", "dllhost.exe",
"conhost.exe", "taskhost.exe", "taskhostw.exe", "RuntimeBroker.exe",
"RegAsm.exe", "MSBuild.exe", "RegSvcs.exe", "vbc.exe",
"AppLaunch.exe", "InstallUtil.exe", "aspnet_compiler.exe",
}
# Process behavior indicators that suggest hollowing
ANOMALOUS_BEHAVIORS = {
"svchost.exe": {
"no_cmdline_flag": True, # svchost should have -k flag
"required_arg": "-k",
"no_external_network": True, # unusual ports
},
"explorer.exe": {
"no_cmdline_flag": False,
"no_external_network": False,
"single_instance": True,
},
"dllhost.exe": {
"no_cmdline_flag": True,
"required_arg": "/Processid:",
},
}
def parse_logs(input_path: str) -> list[dict]:
"""Parse log files."""
path = Path(input_path)
if path.suffix == ".json":
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
return data if isinstance(data, list) else data.get("events", [])
elif path.suffix == ".csv":
with open(path, "r", encoding="utf-8-sig") as f:
return [dict(row) for row in csv.DictReader(f)]
return []
def normalize_event(event: dict) -> dict:
"""Normalize process event fields."""
field_map = {
"event_id": ["EventCode", "EventID", "event_id"],
"image": ["Image", "FileName", "image", "process.executable"],
"command_line": ["CommandLine", "ProcessCommandLine", "command_line"],
"parent_image": ["ParentImage", "InitiatingProcessFileName", "parent_image"],
"parent_cmd": ["ParentCommandLine", "InitiatingProcessCommandLine", "parent_command_line"],
"user": ["User", "AccountName", "user.name"],
"hostname": ["Computer", "DeviceName", "host.name"],
"timestamp": ["UtcTime", "Timestamp", "@timestamp"],
"pid": ["ProcessId", "ProcessId", "process.pid"],
"parent_pid": ["ParentProcessId", "ppid", "process.parent.pid"],
"integrity": ["IntegrityLevel", "integrity_level"],
"hashes": ["Hashes", "SHA256", "hashes"],
"action_type": ["ActionType", "event_type"],
"dest_ip": ["DestinationIp", "RemoteIP"],
"dest_port": ["DestinationPort", "RemotePort"],
}
normalized = {}
for target, sources in field_map.items():
for src in sources:
if src in event and event[src]:
normalized[target] = str(event[src])
break
if target not in normalized:
normalized[target] = ""
return normalized
def get_process_name(path: str) -> str:
"""Extract process name from full path."""
if not path:
return ""
return path.split("\\")[-1].split("/")[-1].lower()
def check_parent_child(event: dict) -> dict | None:
"""Check for invalid parent-child process relationships."""
image = get_process_name(event.get("image", ""))
parent = get_process_name(event.get("parent_image", ""))
if image not in VALID_PARENT_CHILD:
return None
expected = VALID_PARENT_CHILD[image]
valid_parents = [p.lower() for p in expected["parents"]]
if parent and parent not in valid_parents:
return {
"detection_type": "INVALID_PARENT_CHILD",
"technique": "T1055.012",
"process": image,
"parent": parent,
"expected_parents": expected["parents"],
"full_image_path": event.get("image", ""),
"full_parent_path": event.get("parent_image", ""),
"command_line": event.get("command_line", ""),
"hostname": event.get("hostname", "unknown"),
"user": event.get("user", "unknown"),
"timestamp": event.get("timestamp", "unknown"),
"risk_score": 70,
"risk_level": "HIGH",
"indicators": [
f"Invalid parent: {parent} (expected: {', '.join(expected['parents'])})"
],
}
return None
def check_process_tampering(event: dict) -> dict | None:
"""Check for Sysmon Event ID 25 (ProcessTampering)."""
if event.get("event_id") != "25":
return None
return {
"detection_type": "PROCESS_TAMPERING",
"technique": "T1055.012",
"process": get_process_name(event.get("image", "")),
"full_image_path": event.get("image", ""),
"hostname": event.get("hostname", "unknown"),
"user": event.get("user", "unknown"),
"timestamp": event.get("timestamp", "unknown"),
"risk_score": 90,
"risk_level": "CRITICAL",
"indicators": ["Sysmon ProcessTampering event detected - image replaced in memory"],
}
def check_behavioral_anomaly(event: dict) -> dict | None:
"""Check for behavioral mismatches suggesting hollowing."""
if event.get("event_id") != "1":
return None
image = get_process_name(event.get("image", ""))
cmd = event.get("command_line", "")
if image not in ANOMALOUS_BEHAVIORS:
return None
behavior = ANOMALOUS_BEHAVIORS[image]
indicators = []
if behavior.get("required_arg") and behavior["required_arg"] not in cmd:
indicators.append(f"Missing required argument '{behavior['required_arg']}'")
if image in HOLLOWING_TARGETS:
# Check if process path is from unexpected location
expected_paths = ["\\windows\\system32\\", "\\windows\\syswow64\\"]
image_path = event.get("image", "").lower()
if not any(ep in image_path for ep in expected_paths):
indicators.append(f"Process running from unexpected path: {image_path}")
if not indicators:
return None
return {
"detection_type": "BEHAVIORAL_ANOMALY",
"technique": "T1055.012",
"process": image,
"full_image_path": event.get("image", ""),
"command_line": cmd,
"parent_process": get_process_name(event.get("parent_image", "")),
"hostname": event.get("hostname", "unknown"),
"user": event.get("user", "unknown"),
"timestamp": event.get("timestamp", "unknown"),
"risk_score": 50,
"risk_level": "MEDIUM",
"indicators": indicators,
}
def check_hollowing_target_network(event: dict) -> dict | None:
"""Detect hollowing targets making unusual network connections."""
if event.get("event_id") != "3":
return None
image = get_process_name(event.get("image", ""))
if image not in HOLLOWING_TARGETS:
return None
dest_ip = event.get("dest_ip", "")
dest_port = event.get("dest_port", "")
# Check for external connections from commonly hollowed processes
if dest_ip and not re.match(r"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)", dest_ip):
suspicious_ports = {"4444", "5555", "6666", "8888", "9090", "1234", "31337", "50050"}
risk = 40
indicators = [f"Hollowing target {image} connecting externally to {dest_ip}:{dest_port}"]
if dest_port in suspicious_ports:
risk += 20
indicators.append(f"Suspicious port: {dest_port}")
return {
"detection_type": "HOLLOWED_PROCESS_NETWORK",
"technique": "T1055.012",
"process": image,
"dest_ip": dest_ip,
"dest_port": dest_port,
"hostname": event.get("hostname", "unknown"),
"timestamp": event.get("timestamp", "unknown"),
"risk_score": risk,
"risk_level": "HIGH" if risk >= 50 else "MEDIUM",
"indicators": indicators,
}
return None
def run_hunt(input_path: str, output_dir: str) -> None:
"""Execute process hollowing hunt."""
print(f"[*] Process Hollowing Hunt - {datetime.datetime.now().isoformat()}")
events = parse_logs(input_path)
print(f"[*] Loaded {len(events)} events")
findings = []
stats = defaultdict(int)
detectors = [
check_process_tampering,
check_parent_child,
check_behavioral_anomaly,
check_hollowing_target_network,
]
for raw_event in events:
event = normalize_event(raw_event)
for detector in detectors:
result = detector(event)
if result:
findings.append(result)
stats[result["detection_type"]] += 1
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
with open(output_path / "hollowing_findings.json", "w", encoding="utf-8") as f:
json.dump({
"hunt_id": f"TH-HOLLOW-{datetime.date.today().isoformat()}",
"total_events": len(events),
"total_findings": len(findings),
"statistics": dict(stats),
"findings": sorted(findings, key=lambda x: x["risk_score"], reverse=True),
}, f, indent=2)
with open(output_path / "hunt_report.md", "w", encoding="utf-8") as f:
f.write(f"# Process Hollowing Hunt Report\n\n")
f.write(f"**Date**: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"**Findings**: {len(findings)}\n\n")
for finding in sorted(findings, key=lambda x: x["risk_score"], reverse=True)[:20]:
f.write(f"### [{finding['risk_level']}] {finding['detection_type']}\n")
f.write(f"- **Process**: {finding.get('process', '')}\n")
f.write(f"- **Host**: {finding['hostname']}\n")
f.write(f"- **Indicators**: {', '.join(finding['indicators'])}\n\n")
print(f"[+] {len(findings)} findings written to {output_dir}")
def main():
parser = argparse.ArgumentParser(description="Process Hollowing Detection")
subparsers = parser.add_subparsers(dest="command")
hunt_p = subparsers.add_parser("hunt")
hunt_p.add_argument("--input", "-i", required=True)
hunt_p.add_argument("--output", "-o", default="./hollowing_output")
subparsers.add_parser("queries")
args = parser.parse_args()
if args.command == "hunt":
run_hunt(args.input, args.output)
elif args.command == "queries":
print("=== Sysmon Queries ===")
print("--- Process Tampering ---")
print('index=sysmon EventCode=25\n| table _time Computer User Image Type')
print("\n--- Invalid Parent-Child ---")
print('index=sysmon EventCode=1 Image="*\\\\svchost.exe"\n| where NOT match(ParentImage, "(?i)services\\.exe")\n| table _time Computer Image ParentImage CommandLine')
else:
parser.print_help()
if __name__ == "__main__":
main()