Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-SkillsFramework mappings
MITRE ATT&CK
NIST CSF 2.0
When to Use
- When proactively hunting for indicators of detecting insider threat behaviors in the environment
- After threat intelligence indicates active campaigns using these techniques
- During incident response to scope compromise related to these techniques
- When EDR or SIEM alerts trigger on related indicators
- During periodic security assessments and purple team exercises
Prerequisites
- EDR platform with process and network telemetry (CrowdStrike, MDE, SentinelOne)
- SIEM with relevant log data ingested (Splunk, Elastic, Sentinel)
- Sysmon deployed with comprehensive configuration
- Windows Security Event Log forwarding enabled
- Threat intelligence feeds for IOC correlation
Workflow
- Formulate Hypothesis: Define a testable hypothesis based on threat intelligence or ATT&CK gap analysis.
- Identify Data Sources: Determine which logs and telemetry are needed to validate or refute the hypothesis.
- Execute Queries: Run detection queries against SIEM and EDR platforms to collect relevant events.
- Analyze Results: Examine query results for anomalies, correlating across multiple data sources.
- Validate Findings: Distinguish true positives from false positives through contextual analysis.
- Correlate Activity: Link findings to broader attack chains and threat actor TTPs.
- Document and Report: Record findings, update detection rules, and recommend response actions.
Key Concepts
| Concept | Description |
|---|---|
| T1078 | Valid Accounts |
| T1530 | Data from Cloud Storage Object |
| T1567 | Exfiltration Over Web Service |
Tools & Systems
| Tool | Purpose |
|---|---|
| CrowdStrike Falcon | EDR telemetry and threat detection |
| Microsoft Defender for Endpoint | Advanced hunting with KQL |
| Splunk Enterprise | SIEM log analysis with SPL queries |
| Elastic Security | Detection rules and investigation timeline |
| Sysmon | Detailed Windows event monitoring |
| Velociraptor | Endpoint artifact collection and hunting |
| Sigma Rules | Cross-platform detection rule format |
Common Scenarios
- Scenario 1: Employee downloading bulk files before resignation
- Scenario 2: IT admin accessing HR data outside job function
- Scenario 3: Service account used for unauthorized data queries
- Scenario 4: Contractor copying source code to personal cloud storage
Output Format
Hunt ID: TH-DETECT-[DATE]-[SEQ]
Technique: T1078
Host: [Hostname]
User: [Account context]
Evidence: [Log entries, process trees, network data]
Risk Level: [Critical/High/Medium/Low]
Confidence: [High/Medium/Low]
Recommended Action: [Containment, investigation, monitoring]Source materials
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.9 KB
API Reference: Detecting Insider Threat Behaviors
Risk Indicator Weights
| Indicator | Weight | Description |
|---|---|---|
| resignation_correlated | 35 | Activity after resignation notice |
| privilege_escalation | 30 | Unauthorized privilege use |
| usb_mass_copy | 30 | Mass copy to removable media |
| mass_download | 25 | Bulk file download/copy (>50 files) |
| unusual_destination | 20 | Data sent to unusual destination |
| cloud_upload | 20 | Upload to personal cloud storage |
| off_hours_access | 15 | Activity outside 8am-6pm |
| email_to_personal | 15 | Forwarding to personal email |
UEBA Data Sources
| Source | Indicators |
|---|---|
| DLP logs | File downloads, USB copies, email attachments |
| Proxy logs | Cloud storage uploads, personal email |
| VPN logs | Off-hours access, unusual locations |
| AD logs | Privilege changes, group modifications |
| Endpoint logs | Application usage, screen captures |
Splunk SPL - Mass Download Detection
index=dlp action IN ("download", "copy", "export")
| bin _time span=1h
| stats count by user, _time
| where count > 50
| sort -countMicrosoft Sentinel - Off-Hours Access
SigninLogs
| where TimeGenerated between (datetime(22:00)..datetime(06:00))
| where ResultType == 0
| summarize count() by UserPrincipalName, bin(TimeGenerated, 1h)
| where count_ > 5Personal Cloud Domains
CLOUD_STORAGE = {
"dropbox.com", "drive.google.com",
"onedrive.live.com", "box.com",
"mega.nz", "wetransfer.com"
}Risk Score Calculation
score = sum(RISK_INDICATORS[ind]["weight"] for ind in detected_indicators)
risk = "CRITICAL" if score >= 80 else "HIGH" if score >= 50 else "MEDIUM"CLI Usage
python agent.py --activity-log user_activity.jsonl
python agent.py --activity-log events.csv --download-threshold 100standards.md1.5 KB
Standards and References - Detecting Insider Threat Behaviors
MITRE ATT&CK Mappings
| Technique | Name | Description |
|---|---|---|
| T1078 | Valid Accounts | See attack.mitre.org/techniques/T1078 |
| T1530 | Data from Cloud Storage Object | See attack.mitre.org/techniques/T1530 |
| T1567 | Exfiltration Over Web Service | See attack.mitre.org/techniques/T1567 |
Detection Data Sources
| Source | Event ID | Purpose |
|---|---|---|
| Sysmon | 1 | Process creation with command line |
| Sysmon | 3 | Network connection initiated |
| Sysmon | 7 | Image loaded (DLL) |
| Sysmon | 10 | Process access (LSASS) |
| Sysmon | 11 | File creation |
| Sysmon | 12/13 | Registry create/set |
| Sysmon | 22 | DNS query |
| Sysmon | 25 | Process tampering |
| Windows Security | 4624 | Successful logon |
| Windows Security | 4625 | Failed logon |
| Windows Security | 4648 | Explicit credential logon |
| Windows Security | 4672 | Special privileges assigned |
| Windows Security | 4688 | Process creation |
| Windows Security | 4697 | Service installed |
| Windows Security | 4698 | Scheduled task created |
| Windows Security | 4769 | Kerberos TGS requested |
| Windows Security | 5140 | Network share accessed |
References
- MITRE ATT&CK Framework: https://attack.mitre.org/
- Sigma Detection Rules: https://github.com/SigmaHQ/sigma
- LOLBAS Project: https://lolbas-project.github.io/
- Atomic Red Team Tests: https://github.com/redcanaryco/atomic-red-team
- Red Canary Threat Detection Report
- SANS Threat Hunting Summit Resources
workflows.md2.9 KB
Detailed Hunting Workflow - Detecting Insider Threat Behaviors
Phase 1: Data Collection and Querying
Splunk SPL Query
index=wineventlog EventCode=5145
| where match(Share_Name, "(?i)(finance|hr|legal|confidential|executive)")
| stats count dc(Relative_Target_Name) as unique_files by Account_Name Source_Address
| where unique_files > 100
| sort -unique_filesKQL Query (Microsoft Defender for Endpoint)
CloudAppEvents
| where ActionType in ("FileDownloaded","FileCopied","FileShared")
| summarize FileCount=count(), UniqueFiles=dcount(ObjectName) by AccountObjectId, IPAddress
| where FileCount > 100Phase 2: Baseline and Anomaly Detection
Step 2.1 - Establish Normal Behavior Baseline
- Collect 30 days of historical data for the targeted technique
- Document expected patterns, frequencies, and legitimate use cases
- Identify known false positive sources and document exceptions
- Build statistical baseline (mean, standard deviation) for key metrics
Step 2.2 - Identify Anomalies
- Compare current activity against the 30-day baseline
- Flag events exceeding 3 standard deviations from normal
- Prioritize anomalies by risk score and potential business impact
- Cross-reference with threat intelligence for known IOCs
Phase 3: Investigation and Correlation
Step 3.1 - Deep Dive Analysis
- For each anomaly, collect full process tree context
- Correlate with network activity, file operations, and authentication events
- Check binary signatures, file hashes, and certificate validity
- Review user account context and access patterns
Step 3.2 - Attack Chain Reconstruction
- Map findings to MITRE ATT&CK kill chain stages
- Identify initial access vector if applicable
- Trace lateral movement and privilege escalation paths
- Determine data access and potential exfiltration
Phase 4: Validation and Response
Step 4.1 - True/False Positive Determination
- Verify findings with system owners and IT operations
- Check change management records for authorized activities
- Validate user context (authorized actions vs. compromised account)
- Document determination rationale for each finding
Step 4.2 - Response Actions
- For confirmed threats: initiate incident response procedures
- For detection gaps: create or update detection rules
- For false positives: tune existing rules and update exclusions
- Update threat hunting playbook with lessons learned
Phase 5: Documentation and Reporting
Step 5.1 - Hunt Report
- Summarize hypothesis, methodology, and findings
- Include all queries executed and their results
- Document IOCs discovered and detection rules created
- Provide recommendations for security improvements
Step 5.2 - Knowledge Base Update
- Add findings to threat intelligence platform
- Update MITRE ATT&CK coverage heatmap
- Share detection rules via Sigma format
- Schedule follow-up hunts for related techniques
Scripts 2
agent.py6.1 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Insider threat behavior detection agent using UEBA indicators.
Analyzes user activity logs to detect anomalous behaviors: off-hours access,
mass file downloads, unusual data access patterns, and privilege abuse.
"""
import argparse
import json
from collections import defaultdict
from datetime import datetime
RISK_INDICATORS = {
"off_hours_access": {"weight": 15, "desc": "Activity outside business hours"},
"mass_download": {"weight": 25, "desc": "Bulk file download/copy"},
"privilege_escalation": {"weight": 30, "desc": "Unauthorized privilege use"},
"unusual_destination": {"weight": 20, "desc": "Data sent to unusual destination"},
"resignation_correlated": {"weight": 35, "desc": "Activity correlated with resignation"},
"usb_mass_copy": {"weight": 30, "desc": "Mass copy to removable media"},
"cloud_upload": {"weight": 20, "desc": "Large upload to personal cloud"},
"email_to_personal": {"weight": 15, "desc": "Forwarding to personal email"},
}
BUSINESS_HOURS = (8, 18)
PERSONAL_DOMAINS = {"gmail.com", "yahoo.com", "hotmail.com", "outlook.com",
"protonmail.com", "icloud.com", "aol.com"}
CLOUD_STORAGE = {"dropbox.com", "drive.google.com", "onedrive.live.com",
"box.com", "mega.nz", "wetransfer.com"}
def parse_activity_log(filepath):
events = []
with open(filepath, "r", encoding="utf-8", errors="replace") as f:
for line in f:
line = line.strip()
if not line:
continue
try:
evt = json.loads(line)
events.append(evt)
except json.JSONDecodeError:
parts = line.split(",")
if len(parts) >= 4:
events.append({
"timestamp": parts[0], "user": parts[1],
"action": parts[2], "detail": ",".join(parts[3:]),
})
return events
def detect_off_hours(events):
findings = []
for evt in events:
ts = evt.get("timestamp", "")
try:
dt = datetime.fromisoformat(ts.replace("Z", "+00:00"))
hour = dt.hour
if hour < BUSINESS_HOURS[0] or hour >= BUSINESS_HOURS[1]:
findings.append({
"indicator": "off_hours_access",
"user": evt.get("user", ""),
"timestamp": ts,
"hour": hour,
"action": evt.get("action", ""),
})
except (ValueError, TypeError):
continue
return findings
def detect_mass_download(events, threshold=50):
user_downloads = defaultdict(list)
for evt in events:
action = evt.get("action", "").lower()
if any(kw in action for kw in ("download", "copy", "export", "fileaccessed")):
user_downloads[evt.get("user", "")].append(evt)
findings = []
for user, downloads in user_downloads.items():
if len(downloads) >= threshold:
findings.append({
"indicator": "mass_download",
"user": user,
"file_count": len(downloads),
"time_range": f"{downloads[0].get('timestamp', '')} - {downloads[-1].get('timestamp', '')}",
"severity": "HIGH" if len(downloads) > 100 else "MEDIUM",
})
return findings
def detect_data_exfil_destinations(events):
findings = []
for evt in events:
detail = evt.get("detail", "").lower()
dest = evt.get("destination", "").lower()
target = detail + " " + dest
for domain in PERSONAL_DOMAINS:
if domain in target:
findings.append({
"indicator": "email_to_personal",
"user": evt.get("user", ""),
"destination": domain,
"timestamp": evt.get("timestamp", ""),
})
for cloud in CLOUD_STORAGE:
if cloud in target:
findings.append({
"indicator": "cloud_upload",
"user": evt.get("user", ""),
"destination": cloud,
"timestamp": evt.get("timestamp", ""),
})
if any(kw in target for kw in ("usb", "removable", "external drive", "e:")):
findings.append({
"indicator": "usb_mass_copy",
"user": evt.get("user", ""),
"timestamp": evt.get("timestamp", ""),
})
return findings
def calculate_risk_score(user_findings):
score = 0
indicators = set()
for f in user_findings:
ind = f.get("indicator", "")
if ind in RISK_INDICATORS:
score += RISK_INDICATORS[ind]["weight"]
indicators.add(ind)
risk = "CRITICAL" if score >= 80 else "HIGH" if score >= 50 else \
"MEDIUM" if score >= 25 else "LOW"
return {"score": min(score, 100), "risk_level": risk, "indicators": list(indicators)}
def main():
parser = argparse.ArgumentParser(description="Insider Threat Behavior Detector")
parser.add_argument("--activity-log", required=True, help="User activity log (JSON lines or CSV)")
parser.add_argument("--download-threshold", type=int, default=50)
args = parser.parse_args()
events = parse_activity_log(args.activity_log)
all_findings = []
all_findings.extend(detect_off_hours(events))
all_findings.extend(detect_mass_download(events, args.download_threshold))
all_findings.extend(detect_data_exfil_destinations(events))
user_findings = defaultdict(list)
for f in all_findings:
user_findings[f.get("user", "unknown")].append(f)
user_risks = {}
for user, findings in user_findings.items():
user_risks[user] = calculate_risk_score(findings)
user_risks[user]["finding_count"] = len(findings)
results = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"total_events": len(events),
"total_findings": len(all_findings),
"user_risk_scores": user_risks,
"findings": all_findings,
}
print(json.dumps(results, indent=2))
if __name__ == "__main__":
main()
process.py3.5 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Insider Threat Detection - Analyzes logs for T1078 indicators."""
import json, csv, argparse, datetime, re
from collections import defaultdict
from pathlib import Path
DETECTION_PATTERNS = [
r'bulk.*download',
r'mass.*copy',
r'sensitive.*access',
]
def parse_logs(path):
p = Path(path)
if p.suffix == ".json":
with open(p, encoding="utf-8") as f:
data = json.load(f)
return data if isinstance(data, list) else data.get("events", [])
elif p.suffix == ".csv":
with open(p, encoding="utf-8-sig") as f:
return [dict(r) for r in csv.DictReader(f)]
return []
def analyze_event(event):
cmd = event.get("CommandLine", event.get("command_line", event.get("ProcessCommandLine", "")))
content = event.get("Task_Content", event.get("Parameters", event.get("RawEventData", "")))
search_text = f"{cmd} {content}"
risk = 0
indicators = []
for pattern in DETECTION_PATTERNS:
if re.search(pattern, search_text, re.IGNORECASE):
risk += 25
indicators.append(f"Pattern match: {pattern}")
if not indicators:
return None
risk = min(risk, 100)
return {
"technique": "T1078",
"command_line": cmd[:500] if cmd else content[:500],
"hostname": event.get("Computer", event.get("DeviceName", event.get("hostname", "unknown"))),
"user": event.get("User", event.get("AccountName", event.get("UserId", "unknown"))),
"timestamp": event.get("_time", event.get("timestamp", event.get("UtcTime", event.get("Timestamp", "")))),
"risk_score": risk,
"risk_level": "CRITICAL" if risk >= 75 else "HIGH" if risk >= 50 else "MEDIUM" if risk >= 25 else "LOW",
"indicators": indicators,
}
def run_hunt(input_path, output_dir):
print(f"[*] Insider Threat Hunt - {datetime.datetime.now().isoformat()}")
events = parse_logs(input_path)
findings = [f for f in (analyze_event(e) for e in events) if f]
Path(output_dir).mkdir(parents=True, exist_ok=True)
slug = "detecting_insider_th"
with open(Path(output_dir) / f"{slug}_findings.json", "w", encoding="utf-8") as f:
json.dump({"hunt_id": f"TH-{datetime.date.today()}", "total_events": len(events), "findings": findings}, f, indent=2)
with open(Path(output_dir) / "hunt_report.md", "w", encoding="utf-8") as f:
f.write(f"# Insider Threat 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['technique']}\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():
p = argparse.ArgumentParser(description="Insider Threat Detection")
sp = p.add_subparsers(dest="cmd")
h = sp.add_parser("hunt"); h.add_argument("--input", "-i", required=True); h.add_argument("--output", "-o", default="./detecting_insid_output")
sp.add_parser("queries")
args = p.parse_args()
if args.cmd == "hunt": run_hunt(args.input, args.output)
elif args.cmd == "queries":
print("=== Detection Queries ===")
print("See references/workflows.md for platform-specific queries")
else: p.print_help()
if __name__ == "__main__": main()
Assets 1
template.mdtext/markdown · 2.6 KBKeep exploring