Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills

Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
This commit is contained in:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Anthropic Agent Skills Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,56 @@
# API Reference: Investigating Insider Threat Indicators
## Splunk REST API (SIEM Queries)
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/services/search/jobs` | POST | Submit SPL search for user activity timeline |
| `/services/search/jobs/{sid}/results` | GET | Retrieve search results for DLP and access data |
| `/services/saved/searches` | GET | List saved insider threat correlation searches |
## Microsoft Purview DLP API (Graph)
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/security/alerts_v2` | GET | Retrieve DLP policy violation alerts |
| `/security/incidents` | GET | List incidents with insider threat classification |
| `/compliance/ediscovery/cases` | POST | Create eDiscovery case for evidence preservation |
## Microsoft Graph (O365 Activity)
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/auditLogs/signIns` | GET | Query user sign-in logs with location and device |
| `/auditLogs/directoryAudits` | GET | Directory change audit (role assignments, group changes) |
| `/users/{id}/mailFolders/{id}/messages` | GET | Search mailbox for exfiltration via email |
## Key Libraries
- **splunk-sdk**: Python SDK for submitting SPL queries and retrieving results
- **msgraph-sdk**: Microsoft Graph API for O365 audit logs and DLP alerts
- **hashlib** (stdlib): SHA-256 hashing for chain-of-custody evidence integrity
- **csv** (stdlib): Parse exported DLP alert data and access logs
## Evidence Handling
| Function | Purpose |
|----------|---------|
| `hashlib.sha256()` | Generate file hash for chain-of-custody log |
| `json.dump()` | Serialize evidence metadata with timestamps |
| `os.path.getsize()` | Record evidence file sizes |
## Configuration
| Variable | Description |
|----------|-------------|
| `SPLUNK_HOST` | Splunk search head URL for REST API queries |
| `SPLUNK_TOKEN` | Bearer token for Splunk authentication |
| `GRAPH_CLIENT_ID` | Azure AD app registration for Graph API access |
| `GRAPH_TENANT_ID` | Azure AD tenant ID |
## References
- [Splunk REST API Reference](https://docs.splunk.com/Documentation/Splunk/latest/RESTREF)
- [Microsoft Purview DLP](https://learn.microsoft.com/en-us/purview/dlp-learn-about-dlp)
- [CISA Insider Threat Guide](https://www.cisa.gov/topics/physical-security/insider-threat-mitigation)
- [CERT Insider Threat Center](https://insights.sei.cmu.edu/library/common-sense-guide-to-mitigating-insider-threats/)
@@ -0,0 +1,234 @@
#!/usr/bin/env python3
"""
Insider Threat Investigation Agent
Automates insider threat indicator collection by correlating SIEM data,
DLP alerts, access logs, and HR events to build investigation timelines.
"""
import csv
import hashlib
import json
import os
import sys
from datetime import datetime, timezone, timedelta
def load_dlp_alerts(filepath: str) -> list[dict]:
"""Load DLP alert data from exported CSV."""
alerts = []
if not os.path.exists(filepath):
print(f"[!] DLP alerts file not found: {filepath}")
return alerts
with open(filepath, "r", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
alerts.append({
"timestamp": row.get("timestamp", ""),
"user": row.get("user", ""),
"policy": row.get("policy_name", ""),
"action": row.get("action", ""),
"destination": row.get("destination", ""),
"file_count": int(row.get("file_count", 0)),
"bytes_transferred": int(row.get("bytes_transferred", 0)),
"severity": row.get("severity", "medium"),
})
return alerts
def load_access_logs(filepath: str) -> list[dict]:
"""Load authentication and access logs from exported JSON."""
if not os.path.exists(filepath):
print(f"[!] Access logs file not found: {filepath}")
return []
with open(filepath, "r") as f:
return json.load(f)
def analyze_data_movement(dlp_alerts: list[dict], subject_user: str) -> dict:
"""Analyze data exfiltration indicators for the subject."""
user_alerts = [a for a in dlp_alerts if a["user"].lower() == subject_user.lower()]
total_bytes = sum(a["bytes_transferred"] for a in user_alerts)
total_files = sum(a["file_count"] for a in user_alerts)
destinations = {}
for alert in user_alerts:
dest = alert["destination"]
destinations[dest] = destinations.get(dest, 0) + alert["file_count"]
high_severity = [a for a in user_alerts if a["severity"] == "high"]
return {
"total_alerts": len(user_alerts),
"total_bytes_transferred": total_bytes,
"total_bytes_gb": round(total_bytes / (1024**3), 2),
"total_files": total_files,
"destinations": destinations,
"high_severity_alerts": len(high_severity),
"alert_details": user_alerts,
}
def analyze_access_patterns(access_logs: list[dict], subject_user: str) -> dict:
"""Detect anomalous access patterns for the subject."""
user_logs = [l for l in access_logs if l.get("user", "").lower() == subject_user.lower()]
off_hours_events = []
weekend_events = []
unique_apps = set()
unique_ips = set()
for log in user_logs:
ts = log.get("timestamp", "")
try:
dt = datetime.fromisoformat(ts.replace("Z", "+00:00"))
hour = dt.hour
weekday = dt.weekday()
if hour < 7 or hour > 19:
off_hours_events.append(log)
if weekday >= 5:
weekend_events.append(log)
except (ValueError, AttributeError):
pass
unique_apps.add(log.get("application", "unknown"))
unique_ips.add(log.get("source_ip", "unknown"))
return {
"total_events": len(user_logs),
"off_hours_events": len(off_hours_events),
"off_hours_pct": round(len(off_hours_events) / max(len(user_logs), 1) * 100, 1),
"weekend_events": len(weekend_events),
"weekend_pct": round(len(weekend_events) / max(len(user_logs), 1) * 100, 1),
"unique_applications": sorted(unique_apps),
"unique_source_ips": sorted(unique_ips),
}
def detect_pre_departure_indicators(
data_movement: dict, access_patterns: dict, notice_date: str
) -> list[dict]:
"""Identify pre-departure behavioral indicators."""
indicators = []
if data_movement["total_bytes_gb"] > 1.0:
indicators.append({
"severity": "HIGH",
"indicator": "Bulk data transfer",
"detail": f"{data_movement['total_bytes_gb']} GB transferred across {data_movement['total_files']} files",
})
if data_movement["high_severity_alerts"] > 0:
indicators.append({
"severity": "HIGH",
"indicator": "High-severity DLP violations",
"detail": f"{data_movement['high_severity_alerts']} high-severity DLP alerts triggered",
})
personal_storage = ["dropbox", "drive.google", "onedrive.live", "mega.nz", "wetransfer"]
for dest, count in data_movement["destinations"].items():
if any(ps in dest.lower() for ps in personal_storage):
indicators.append({
"severity": "HIGH",
"indicator": "Transfer to personal cloud storage",
"detail": f"{count} files sent to {dest}",
})
if access_patterns["off_hours_pct"] > 30:
indicators.append({
"severity": "MEDIUM",
"indicator": "Elevated off-hours activity",
"detail": f"{access_patterns['off_hours_pct']}% of activity outside business hours",
})
if access_patterns["weekend_pct"] > 15:
indicators.append({
"severity": "MEDIUM",
"indicator": "Elevated weekend activity",
"detail": f"{access_patterns['weekend_pct']}% of activity on weekends",
})
if len(access_patterns["unique_applications"]) > 15:
indicators.append({
"severity": "MEDIUM",
"indicator": "Broad application access",
"detail": f"Accessed {len(access_patterns['unique_applications'])} unique applications",
})
return indicators
def create_evidence_log(case_id: str, evidence_files: list[str]) -> dict:
"""Create chain-of-custody evidence log with file hashes."""
items = []
for filepath in evidence_files:
if os.path.exists(filepath):
with open(filepath, "rb") as f:
content = f.read()
items.append({
"item_id": f"EV-{len(items)+1:03d}",
"file": filepath,
"sha256": hashlib.sha256(content).hexdigest(),
"size_bytes": len(content),
"collected_at": datetime.now(timezone.utc).isoformat(),
})
return {
"case_id": case_id,
"created_at": datetime.now(timezone.utc).isoformat(),
"investigator": os.getenv("USER", "soc_analyst"),
"evidence_items": items,
}
def generate_report(case_id: str, subject: str, data_mv: dict, access: dict, indicators: list) -> str:
"""Generate insider threat investigation report."""
lines = [
f"INSIDER THREAT INVESTIGATION REPORT - {case_id}",
"=" * 55,
f"Subject: {subject}",
f"Report Generated: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
"",
"DATA MOVEMENT ANALYSIS:",
f" DLP Alerts: {data_mv['total_alerts']}",
f" Data Transferred: {data_mv['total_bytes_gb']} GB ({data_mv['total_files']} files)",
f" High-Severity Alerts: {data_mv['high_severity_alerts']}",
f" Destinations: {json.dumps(data_mv['destinations'], indent=4)}",
"",
"ACCESS PATTERN ANALYSIS:",
f" Total Events: {access['total_events']}",
f" Off-Hours Activity: {access['off_hours_pct']}%",
f" Weekend Activity: {access['weekend_pct']}%",
f" Applications Accessed: {len(access['unique_applications'])}",
"",
f"INDICATORS IDENTIFIED: {len(indicators)}",
"-" * 40,
]
for ind in indicators:
lines.append(f" [{ind['severity']}] {ind['indicator']}: {ind['detail']}")
return "\n".join(lines)
if __name__ == "__main__":
case_id = sys.argv[1] if len(sys.argv) > 1 else "IT-2024-0001"
subject_user = sys.argv[2] if len(sys.argv) > 2 else "jsmith"
dlp_file = sys.argv[3] if len(sys.argv) > 3 else "dlp_alerts.csv"
access_file = sys.argv[4] if len(sys.argv) > 4 else "access_logs.json"
print(f"[*] Starting insider threat investigation: {case_id}")
print(f"[*] Subject: {subject_user}")
dlp_alerts = load_dlp_alerts(dlp_file)
access_logs = load_access_logs(access_file)
data_movement = analyze_data_movement(dlp_alerts, subject_user)
access_patterns = analyze_access_patterns(access_logs, subject_user)
indicators = detect_pre_departure_indicators(data_movement, access_patterns, "2024-03-15")
report = generate_report(case_id, subject_user, data_movement, access_patterns, indicators)
print(report)
output = f"insider_threat_{case_id}_{datetime.now(timezone.utc).strftime('%Y%m%d')}.json"
with open(output, "w") as f:
json.dump({"data_movement": data_movement, "access_patterns": access_patterns, "indicators": indicators}, f, indent=2)
print(f"\n[*] Results saved to {output}")