Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-SkillsFramework mappings
MITRE ATT&CK
T1027 on the official MITRE ATT&CK siteT1046 on the official MITRE ATT&CK siteT1057 on the official MITRE ATT&CK siteT1082 on the official MITRE ATT&CK siteT1083 on the official MITRE ATT&CK siteT1574.001 on the official MITRE ATT&CK siteT1574.002 on the official MITRE ATT&CK siteT1574.006 on the official MITRE ATT&CK siteT1574.008 on the official MITRE ATT&CK siteT1574.009 on the official MITRE ATT&CK siteT1574.011 on the official MITRE ATT&CK siteT1574.012 on the official MITRE ATT&CK site
NIST CSF 2.0
MITRE D3FEND
When to Use
- When investigating potential DLL hijacking in enterprise environments
- After EDR alerts on unsigned DLLs loaded by signed applications
- When hunting for APT persistence using legitimate application wrappers
- During incident response to identify trojanized applications
- When threat intel indicates DLL sideloading campaigns targeting specific software
Prerequisites
- EDR with DLL load monitoring (CrowdStrike, MDE, SentinelOne)
- Sysmon Event ID 7 (Image Loaded) with hash verification
- Application whitelisting or DLL integrity monitoring
- Software inventory of legitimate applications and expected DLL paths
- Code signing verification capabilities
Workflow
- Identify Sideloading Targets: Research known vulnerable applications that load DLLs without full path qualification (LOLBAS, DLL-sideload databases).
- Monitor DLL Load Events: Query Sysmon Event ID 7 for DLL loads where the DLL path differs from the application's expected directory.
- Check DLL Signatures: Flag unsigned or untrusted DLLs loaded by signed executables.
- Detect Path Anomalies: Identify legitimate executables running from unusual locations (Temp, AppData, Public) that may be decoy wrappers.
- Hash Verification: Compare loaded DLL hashes against known-good versions and threat intel feeds.
- Correlate with Process Behavior: Check if the host process exhibits unusual behavior (network connections, child processes) after loading the suspicious DLL.
- Document and Remediate: Report sideloading instances, quarantine malicious DLLs, and update detection rules.
Key Concepts
| Concept | Description |
|---|---|
| T1574.002 | DLL Side-Loading |
| T1574.001 | DLL Search Order Hijacking |
| T1574.006 | Dynamic Linker Hijacking |
| T1574.008 | Path Interception by Search Order Hijacking |
| DLL Search Order | Windows DLL loading priority path |
| Side-Loading | Placing malicious DLL where legitimate app loads it |
| Phantom DLL | DLL that legitimate apps try to load but does not exist |
| DLL Proxying | Malicious DLL forwarding calls to legitimate DLL |
Tools & Systems
| Tool | Purpose |
|---|---|
| Sysmon | Event ID 7 DLL load monitoring |
| CrowdStrike Falcon | DLL load detection with process context |
| Microsoft Defender for Endpoint | DLL load anomaly detection |
| Process Monitor | Real-time DLL load tracing |
| DLL Export Viewer | Verify DLL export functions |
| Sigcheck | Digital signature verification |
| pe-sieve | PE analysis for proxied DLLs |
Common Scenarios
- Legitimate App Wrapper: Adversary copies signed application (e.g., OneDrive updater) to temp folder alongside malicious DLL with same name as expected dependency.
- Phantom DLL Exploitation: Malicious DLL placed in PATH location where legitimate app searches for non-existent DLL.
- DLL Proxy Loading: Malicious version.dll proxies all exports to real version.dll while executing malicious code on DllMain.
- Software Update Hijack: Attacker replaces DLL in update staging directory before legitimate updater loads it.
Output Format
Hunt ID: TH-SIDELOAD-[DATE]-[SEQ]
Technique: T1574.002
Host Application: [Legitimate signed executable]
Sideloaded DLL: [Malicious DLL name and path]
Expected DLL Path: [Where DLL should legitimately be]
DLL Signed: [Yes/No]
App Location: [Expected/Anomalous]
Host: [Hostname]
Risk Level: [Critical/High/Medium/Low]Source materials
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.5 KB
API Reference: Detecting DLL Sideloading Attacks
Sysmon Event ID 7 (Image Loaded)
<EventID>7</EventID>
<Data Name="Image">C:\Users\victim\app\signed.exe</Data>
<Data Name="ImageLoaded">C:\Users\victim\app\malicious.dll</Data>
<Data Name="Signed">false</Data>
<Data Name="SignatureStatus">Unavailable</Data>
<Data Name="Hashes">SHA256=abc123...</Data>python-evtx Usage
import Evtx.Evtx as evtx
with evtx.Evtx("Sysmon.evtx") as log:
for record in log.records():
xml = record.xml()
# Filter EventID 7, check Signed=false, non-standard pathKnown Sideloading Targets
| Legitimate Executable | Vulnerable DLL |
|---|---|
| vmwaretray.exe | vmtools.dll |
| colorcpl.exe | colorui.dll |
| consent.exe | comctl32.dll |
| bginfo.exe | version.dll |
| teams.exe | version.dll |
| winword.exe | wwlib.dll |
Splunk SPL Detection
index=sysmon EventCode=7 Signed=false
| where NOT match(ImageLoaded, "(?i)(System32|SysWOW64|Program Files)")
| stats count by Image, ImageLoaded, SignatureStatus, Computer
| where count > 0Sigma Rule Fields
logsource:
product: windows
category: image_load
detection:
selection:
EventID: 7
Signed: "false"
filter:
ImageLoaded|startswith:
- "C:\\Windows\\System32\\"
- "C:\\Program Files\\"CLI Usage
python agent.py --sysmon-log Sysmon.evtx
python agent.py --scan-dir C:\Users\victim\Downloads\app\
python agent.py --generate-sigmastandards.md1.9 KB
Standards and References - DLL Sideloading Detection
MITRE ATT&CK Mappings
T1574.002 - Hijack Execution Flow: DLL Side-Loading
- Tactic: Persistence (TA0003), Privilege Escalation (TA0004), Defense Evasion (TA0005)
- Platforms: Windows
- Data Sources: File monitoring, DLL monitoring, Process monitoring
Related Techniques
| Technique | Name |
|---|---|
| T1574.001 | DLL Search Order Hijacking |
| T1574.006 | Dynamic Linker Hijacking |
| T1574.008 | Path Interception by Search Order |
| T1574.009 | Path Interception by Unquoted Service Path |
| T1574.011 | Services Registry Permissions Weakness |
| T1574.012 | COR_PROFILER |
Windows DLL Search Order
- Directory of the executable (or directory specified by SetDllDirectory)
- System32 directory
- 16-bit system directory
- Windows directory
- Current working directory
- PATH environment variable directories
Known Vulnerable Applications
| Application | Vulnerable DLL | Vendor | Notes |
|---|---|---|---|
| OneDriveUpdater.exe | version.dll | Microsoft | Frequently abused by APTs |
| Teams.exe | CRYPTSP.dll | Microsoft | Side-loading target |
| DismHost.exe | dismcore.dll | Microsoft | Signed binary side-loading |
| MpCmdRun.exe | mpclient.dll | Microsoft | AV binary abuse |
| WerFault.exe | dbgcore.dll | Microsoft | Error handler abuse |
| Grammarly | Various | Grammarly | User-space application |
| Zoom | Various | Zoom | Meeting application |
Detection Data Sources
| Source | Event | Purpose |
|---|---|---|
| Sysmon Event 7 | Image Loaded | DLL load with hash and signature |
| Sysmon Event 1 | Process Create | Application launch location |
| Windows Security 4688 | Process Create | Command line monitoring |
| ETW | DLL Load Events | Kernel-level DLL tracking |
| MDE | DeviceImageLoadEvents | DLL load telemetry |
workflows.md2.2 KB
Detailed Hunting Workflow - DLL Sideloading
Phase 1: Sysmon DLL Load Analysis
Step 1.1 - Unsigned DLLs Loaded by Signed Applications
index=sysmon EventCode=7 Signed=false
| where match(Image, "(?i)\\\\(Program Files|Windows)\\\\")
| where NOT match(ImageLoaded, "(?i)\\\\(Windows|Program Files)\\\\")
| stats count by Image ImageLoaded Signature Computer
| sort -countStep 1.2 - DLL Loads from Unusual Directories
index=sysmon EventCode=7
| where match(ImageLoaded, "(?i)(\\\\temp\\\\|\\\\appdata\\\\|\\\\public\\\\|\\\\downloads\\\\)")
| where Signed=false OR Signature="?"
| stats count by Image ImageLoaded Computer User
| sort -countStep 1.3 - KQL for MDE DLL Sideloading
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("OneDriveUpdater.exe","DismHost.exe","WerFault.exe")
| where not(FolderPath startswith "C:\\Windows" or FolderPath startswith "C:\\Program Files")
| project Timestamp, DeviceName, InitiatingProcessFileName, FolderPath, FileName, SHA256Phase 2: Legitimate App in Wrong Location
Step 2.1 - Signed Binaries Running Outside Standard Paths
index=sysmon EventCode=1
| where NOT match(Image, "(?i)^(C:\\\\Windows|C:\\\\Program Files)")
| where match(Image, "(?i)(svchost|explorer|rundll32|dllhost|OneDrive|Teams)\.exe$")
| table _time Computer User Image CommandLine ParentImage HashesPhase 3: Hash-Based Detection
Step 3.1 - Known-Bad DLL Hashes
Compare loaded DLL hashes against threat intelligence:
index=sysmon EventCode=7
| rex field=Hashes "SHA256=(?<sha256>[A-Fa-f0-9]{64})"
| lookup threat_intel_hashes sha256 OUTPUT malware_family confidence
| where isnotnull(malware_family)
| table _time Computer Image ImageLoaded sha256 malware_familyPhase 4: Behavioral Correlation
Step 4.1 - Network Activity After DLL Load
Correlate DLL loads with subsequent network connections:
index=sysmon EventCode=7 Signed=false
| rename Image as proc_image
| join proc_image Computer [
search index=sysmon EventCode=3
| rename Image as proc_image
| where NOT match(DestinationIp, "^(10\.|172\.|192\.168\.)")
]
| table _time Computer proc_image ImageLoaded DestinationIp DestinationPortScripts 2
agent.py5.7 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""DLL sideloading detection agent using Sysmon Event ID 7 (Image Loaded) analysis.
Detects unsigned DLLs loaded by signed executables from non-standard paths,
a common APT persistence and defense evasion technique (T1574.002).
"""
import argparse
import json
import re
from datetime import datetime
from pathlib import Path
try:
import Evtx.Evtx as evtx
except ImportError:
evtx = None
KNOWN_SIDELOAD_TARGETS = {
"vmwaretray.exe": ["vmtools.dll"],
"colorcpl.exe": ["colorui.dll"],
"searchprotocolhost.exe": ["msfte.dll"],
"consent.exe": ["comctl32.dll"],
"dxcap.exe": ["d3d9.dll"],
"eventvwr.exe": ["mmc.dll"],
"msdeploy.exe": ["microsoft.web.deployment.dll"],
"bginfo.exe": ["version.dll"],
"winword.exe": ["wwlib.dll"],
"teams.exe": ["version.dll"],
}
STANDARD_DLL_DIRS = {
r"c:\windows\system32", r"c:\windows\syswow64",
r"c:\windows\winsxs", r"c:\program files",
r"c:\program files (x86)",
}
def parse_sysmon_dll_loads(filepath):
if evtx is None:
return {"error": "python-evtx not installed: pip install python-evtx"}
findings = []
with evtx.Evtx(filepath) as log:
for record in log.records():
xml = record.xml()
if "<EventID>7</EventID>" not in xml:
continue
image = re.search(r'<Data Name="Image">([^<]+)', xml)
loaded = re.search(r'<Data Name="ImageLoaded">([^<]+)', xml)
signed = re.search(r'<Data Name="Signed">([^<]+)', xml)
sig_status = re.search(r'<Data Name="SignatureStatus">([^<]+)', xml)
sha256 = re.search(r'<Data Name="Hashes">([^<]+)', xml)
time_created = re.search(r'SystemTime="([^"]+)"', xml)
if not image or not loaded:
continue
image_path = image.group(1).lower()
dll_path = loaded.group(1).lower()
is_signed = signed.group(1) if signed else "unknown"
image_name = image_path.rsplit("\\", 1)[-1]
dll_name = dll_path.rsplit("\\", 1)[-1]
dll_dir = dll_path.rsplit("\\", 1)[0] if "\\" in dll_path else ""
is_standard_dir = any(dll_dir.startswith(d) for d in STANDARD_DLL_DIRS)
is_known_target = (image_name in KNOWN_SIDELOAD_TARGETS and
dll_name in KNOWN_SIDELOAD_TARGETS[image_name])
if is_signed == "false" and not is_standard_dir:
severity = "CRITICAL" if is_known_target else "HIGH"
findings.append({
"timestamp": time_created.group(1) if time_created else "",
"host_process": image_path,
"loaded_dll": dll_path,
"signed": is_signed,
"signature_status": sig_status.group(1) if sig_status else "",
"hash": sha256.group(1) if sha256 else "",
"known_sideload_target": is_known_target,
"non_standard_path": True,
"severity": severity,
"mitre": "T1574.002",
})
return findings
def scan_directory_for_sideloading(directory):
findings = []
dir_path = Path(directory)
if not dir_path.is_dir():
return [{"error": f"Directory not found: {directory}"}]
exe_files = list(dir_path.glob("*.exe"))
dll_files = list(dir_path.glob("*.dll"))
for exe in exe_files:
exe_name = exe.name.lower()
if exe_name in KNOWN_SIDELOAD_TARGETS:
for dll in dll_files:
if dll.name.lower() in KNOWN_SIDELOAD_TARGETS[exe_name]:
findings.append({
"exe_path": str(exe),
"dll_path": str(dll),
"dll_size_bytes": dll.stat().st_size,
"known_sideload_pair": True,
"severity": "CRITICAL",
"mitre": "T1574.002",
"description": f"Known sideloading pair: {exe.name} + {dll.name}",
})
return findings
def generate_sigma_rule():
return {
"title": "DLL Sideloading - Unsigned DLL in Non-Standard Path",
"status": "experimental",
"logsource": {"product": "windows", "category": "image_load"},
"detection": {
"selection": {"EventID": 7, "Signed": "false"},
"filter_standard": {"ImageLoaded|startswith": [
"C:\\Windows\\System32\\", "C:\\Windows\\SysWOW64\\",
"C:\\Program Files\\", "C:\\Program Files (x86)\\"
]},
"condition": "selection and not filter_standard"
},
"level": "high",
"tags": ["attack.defense_evasion", "attack.t1574.002"],
}
def main():
parser = argparse.ArgumentParser(description="DLL Sideloading Detector")
parser.add_argument("--sysmon-log", help="Sysmon EVTX file with Event ID 7")
parser.add_argument("--scan-dir", help="Directory to scan for sideloading pairs")
parser.add_argument("--generate-sigma", action="store_true")
args = parser.parse_args()
results = {"timestamp": datetime.utcnow().isoformat() + "Z", "findings": []}
if args.sysmon_log:
evtx_findings = parse_sysmon_dll_loads(args.sysmon_log)
if isinstance(evtx_findings, dict) and "error" in evtx_findings:
results["error"] = evtx_findings["error"]
else:
results["findings"].extend(evtx_findings)
if args.scan_dir:
dir_findings = scan_directory_for_sideloading(args.scan_dir)
results["findings"].extend(dir_findings)
if args.generate_sigma:
results["sigma_rule"] = generate_sigma_rule()
results["total_findings"] = len(results["findings"])
print(json.dumps(results, indent=2))
if __name__ == "__main__":
main()
process.py6.0 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
DLL Sideloading Detection Script
Analyzes DLL load events for sideloading indicators including unsigned DLLs,
path anomalies, and known vulnerable application abuse.
"""
import json
import csv
import argparse
import datetime
import re
from collections import defaultdict
from pathlib import Path
KNOWN_SIDELOAD_TARGETS = {
"version.dll": ["OneDriveUpdater.exe", "Grammarly.exe"],
"cryptsp.dll": ["Teams.exe"],
"dismcore.dll": ["DismHost.exe"],
"mpclient.dll": ["MpCmdRun.exe"],
"dbgcore.dll": ["WerFault.exe"],
"wbemcomn.dll": ["mmc.exe"],
"comsvcs.dll": ["rundll32.exe"],
"uxtheme.dll": ["Multiple"],
"dwmapi.dll": ["Multiple"],
"winmm.dll": ["Multiple"],
"dxgi.dll": ["Multiple"],
}
LEGITIMATE_DLL_PATHS = [
r"C:\\Windows\\System32\\",
r"C:\\Windows\\SysWOW64\\",
r"C:\\Windows\\WinSxS\\",
r"C:\\Program Files\\",
r"C:\\Program Files \(x86\)\\",
]
SUSPICIOUS_DLL_PATHS = [
r"\\Temp\\", r"\\tmp\\", r"\\AppData\\Local\\Temp\\",
r"\\Users\\Public\\", r"\\Downloads\\", r"\\Desktop\\",
r"\\ProgramData\\(?!Microsoft)",
]
def parse_logs(input_path: str) -> list[dict]:
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:
field_map = {
"event_id": ["EventCode", "EventID"],
"image": ["Image", "InitiatingProcessFileName"],
"dll_loaded": ["ImageLoaded", "FileName", "FolderPath"],
"signed": ["Signed", "IsSigned"],
"signature": ["Signature", "SignatureType"],
"hashes": ["Hashes", "SHA256"],
"hostname": ["Computer", "DeviceName"],
"user": ["User", "AccountName"],
"timestamp": ["UtcTime", "Timestamp"],
}
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 detect_sideloading(event: dict) -> dict | None:
if event.get("event_id") != "7":
return None
dll_path = event.get("dll_loaded", "").lower()
image_path = event.get("image", "").lower()
signed = event.get("signed", "").lower()
dll_name = dll_path.split("\\")[-1] if dll_path else ""
app_name = image_path.split("\\")[-1] if image_path else ""
risk = 0
indicators = []
# Check if DLL is a known sideloading target
if dll_name in KNOWN_SIDELOAD_TARGETS:
# Check if loaded from non-standard path
is_legit_path = any(re.search(p, dll_path, re.IGNORECASE) for p in LEGITIMATE_DLL_PATHS)
if not is_legit_path:
risk += 40
indicators.append(f"Known sideload target DLL: {dll_name}")
# Check for unsigned DLL
if signed in ("false", "0", ""):
risk += 20
indicators.append("Unsigned DLL loaded")
# Check for suspicious DLL path
for pattern in SUSPICIOUS_DLL_PATHS:
if re.search(pattern, dll_path, re.IGNORECASE):
risk += 25
indicators.append(f"DLL in suspicious path: {pattern}")
break
# Check for app running from unusual location
app_in_standard = any(re.search(p, image_path, re.IGNORECASE) for p in LEGITIMATE_DLL_PATHS)
if not app_in_standard and app_name:
for pattern in SUSPICIOUS_DLL_PATHS:
if re.search(pattern, image_path, re.IGNORECASE):
risk += 20
indicators.append(f"Host application in suspicious path")
break
if not indicators:
return None
risk_level = "CRITICAL" if risk >= 70 else "HIGH" if risk >= 50 else "MEDIUM" if risk >= 30 else "LOW"
return {
"detection_type": "DLL_SIDELOADING",
"technique": "T1574.002",
"host_application": image_path,
"sideloaded_dll": dll_path,
"dll_name": dll_name,
"signed": signed,
"hostname": event.get("hostname", "unknown"),
"user": event.get("user", "unknown"),
"timestamp": event.get("timestamp", "unknown"),
"risk_score": risk,
"risk_level": risk_level,
"indicators": indicators,
}
def run_hunt(input_path: str, output_dir: str) -> None:
print(f"[*] DLL Sideloading Hunt - {datetime.datetime.now().isoformat()}")
events = [normalize_event(e) for e in parse_logs(input_path)]
print(f"[*] Loaded {len(events)} events")
findings = [f for f in (detect_sideloading(e) for e in events) if f]
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
with open(output_path / "sideload_findings.json", "w", encoding="utf-8") as f:
json.dump({
"hunt_id": f"TH-SIDELOAD-{datetime.date.today().isoformat()}",
"total_events": len(events),
"findings": sorted(findings, key=lambda x: x["risk_score"], reverse=True),
}, f, indent=2)
print(f"[+] {len(findings)} findings written to {output_dir}")
def main():
parser = argparse.ArgumentParser(description="DLL Sideloading 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="./sideload_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 DLL Load Queries ===")
print('index=sysmon EventCode=7 Signed=false\n| stats count by Image ImageLoaded Computer\n| sort -count')
else:
parser.print_help()
if __name__ == "__main__":
main()
Assets 1
template.mdtext/markdown · 0.7 KBKeep exploring