mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-19 05:59:40 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
---
|
||||
name: detecting-dll-sideloading-attacks
|
||||
description: Detect DLL side-loading attacks where adversaries place malicious DLLs alongside legitimate applications to hijack execution flow for defense evasion.
|
||||
domain: cybersecurity
|
||||
subdomain: threat-hunting
|
||||
tags: [threat-hunting, mitre-attack, dll-sideloading, defense-evasion, t1574, edr, proactive-detection]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# Detecting DLL Sideloading Attacks
|
||||
|
||||
## 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
|
||||
|
||||
1. **Identify Sideloading Targets**: Research known vulnerable applications that load DLLs without full path qualification (LOLBAS, DLL-sideload databases).
|
||||
2. **Monitor DLL Load Events**: Query Sysmon Event ID 7 for DLL loads where the DLL path differs from the application's expected directory.
|
||||
3. **Check DLL Signatures**: Flag unsigned or untrusted DLLs loaded by signed executables.
|
||||
4. **Detect Path Anomalies**: Identify legitimate executables running from unusual locations (Temp, AppData, Public) that may be decoy wrappers.
|
||||
5. **Hash Verification**: Compare loaded DLL hashes against known-good versions and threat intel feeds.
|
||||
6. **Correlate with Process Behavior**: Check if the host process exhibits unusual behavior (network connections, child processes) after loading the suspicious DLL.
|
||||
7. **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
|
||||
|
||||
1. **Legitimate App Wrapper**: Adversary copies signed application (e.g., OneDrive updater) to temp folder alongside malicious DLL with same name as expected dependency.
|
||||
2. **Phantom DLL Exploitation**: Malicious DLL placed in PATH location where legitimate app searches for non-existent DLL.
|
||||
3. **DLL Proxy Loading**: Malicious version.dll proxies all exports to real version.dll while executing malicious code on DllMain.
|
||||
4. **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]
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
# DLL Sideloading Hunt Template
|
||||
|
||||
## Hunt Metadata
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Hunt ID | TH-SIDELOAD-YYYY-MM-DD-NNN |
|
||||
| Analyst | |
|
||||
| Date | |
|
||||
|
||||
## Hypothesis
|
||||
> [e.g., "Adversaries are using DLL sideloading with legitimate signed applications to execute malicious payloads while evading detection."]
|
||||
|
||||
## Findings
|
||||
| # | Host | Application | Sideloaded DLL | DLL Path | Signed | Risk | Verdict |
|
||||
|---|------|------------|---------------|----------|--------|------|---------|
|
||||
| 1 | | | | | | | |
|
||||
|
||||
## Recommendations
|
||||
1. **Block**: [Quarantine malicious DLLs]
|
||||
2. **Harden**: [Application directory permissions, DLL safe search mode]
|
||||
3. **Detect**: [Sysmon Event ID 7 rules for known targets]
|
||||
@@ -0,0 +1,49 @@
|
||||
# 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
|
||||
|
||||
1. Directory of the executable (or directory specified by SetDllDirectory)
|
||||
2. System32 directory
|
||||
3. 16-bit system directory
|
||||
4. Windows directory
|
||||
5. Current working directory
|
||||
6. 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 |
|
||||
@@ -0,0 +1,67 @@
|
||||
# Detailed Hunting Workflow - DLL Sideloading
|
||||
|
||||
## Phase 1: Sysmon DLL Load Analysis
|
||||
|
||||
### Step 1.1 - Unsigned DLLs Loaded by Signed Applications
|
||||
```spl
|
||||
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 -count
|
||||
```
|
||||
|
||||
### Step 1.2 - DLL Loads from Unusual Directories
|
||||
```spl
|
||||
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 -count
|
||||
```
|
||||
|
||||
### Step 1.3 - KQL for MDE DLL Sideloading
|
||||
```kql
|
||||
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, SHA256
|
||||
```
|
||||
|
||||
## Phase 2: Legitimate App in Wrong Location
|
||||
|
||||
### Step 2.1 - Signed Binaries Running Outside Standard Paths
|
||||
```spl
|
||||
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 Hashes
|
||||
```
|
||||
|
||||
## Phase 3: Hash-Based Detection
|
||||
|
||||
### Step 3.1 - Known-Bad DLL Hashes
|
||||
Compare loaded DLL hashes against threat intelligence:
|
||||
```spl
|
||||
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_family
|
||||
```
|
||||
|
||||
## Phase 4: Behavioral Correlation
|
||||
|
||||
### Step 4.1 - Network Activity After DLL Load
|
||||
Correlate DLL loads with subsequent network connections:
|
||||
```spl
|
||||
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 DestinationPort
|
||||
```
|
||||
@@ -0,0 +1,181 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user