mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-16 21:05:22 +03:00
Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills - Update all 648 LICENSE files: copyright now reads 'Mahipal' - Add implementing-security-monitoring-with-datadog (new skill with full anatomy) - All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
Copyright (c) 2025 Mahipal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# API Reference: Suspicious PowerShell Execution Detection
|
||||
|
||||
## Windows PowerShell Event Logs
|
||||
|
||||
### Event IDs
|
||||
| Event ID | Log | Description |
|
||||
|----------|-----|-------------|
|
||||
| 4104 | PowerShell/Operational | Script block logging |
|
||||
| 4103 | PowerShell/Operational | Module logging |
|
||||
| 800 | PowerShell | Pipeline execution details |
|
||||
| 400 | PowerShell | Engine lifecycle (start) |
|
||||
| 403 | PowerShell | Engine lifecycle (stop) |
|
||||
|
||||
### Script Block Logging Query
|
||||
```powershell
|
||||
Get-WinEvent -FilterHashtable @{
|
||||
LogName = 'Microsoft-Windows-PowerShell/Operational'
|
||||
Id = 4104
|
||||
} -MaxEvents 100
|
||||
```
|
||||
|
||||
### Event 4104 Properties
|
||||
| Index | Field | Description |
|
||||
|-------|-------|-------------|
|
||||
| 0 | MessageNumber | Block sequence number |
|
||||
| 1 | MessageTotal | Total blocks in script |
|
||||
| 2 | ScriptBlockText | Actual script content |
|
||||
| 3 | ScriptBlockId | Unique script ID |
|
||||
| 4 | Path | Script file path |
|
||||
|
||||
## Suspicious PowerShell Patterns
|
||||
|
||||
### Execution Policy Bypass
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File script.ps1
|
||||
powershell -ep bypass -nop -w hidden -enc <base64>
|
||||
```
|
||||
|
||||
### Common Obfuscation Techniques
|
||||
| Technique | Example |
|
||||
|-----------|---------|
|
||||
| Concatenation | `"Inv"+"oke-Ex"+"pression"` |
|
||||
| Variable substitution | `${I`nv`oke-`Ex`pression}` |
|
||||
| Encoded commands | `-enc SQBuAHYAbwBrAGUALQA...` |
|
||||
| Char array | `[char[]]@(73,69,88) -join ''` |
|
||||
|
||||
## Sigma Detection Rules
|
||||
|
||||
### Suspicious PowerShell Command Line
|
||||
```yaml
|
||||
title: Suspicious PowerShell Invocation
|
||||
logsource:
|
||||
product: windows
|
||||
category: process_creation
|
||||
detection:
|
||||
selection:
|
||||
CommandLine|contains:
|
||||
- '-enc'
|
||||
- '-EncodedCommand'
|
||||
- 'FromBase64String'
|
||||
- 'DownloadString'
|
||||
- 'Invoke-Expression'
|
||||
condition: selection
|
||||
level: high
|
||||
```
|
||||
|
||||
## AMSI (Antimalware Scan Interface)
|
||||
|
||||
### AMSI Scan Functions
|
||||
```c
|
||||
HRESULT AmsiScanBuffer(
|
||||
HAMSICONTEXT amsiContext,
|
||||
PVOID buffer,
|
||||
ULONG length,
|
||||
LPCWSTR contentName,
|
||||
HAMSISESSION amsiSession,
|
||||
AMSI_RESULT *result
|
||||
);
|
||||
```
|
||||
|
||||
### AMSI Results
|
||||
| Value | Meaning |
|
||||
|-------|---------|
|
||||
| 0 | Clean |
|
||||
| 1 | Not Detected |
|
||||
| 16384 | Blocked by admin |
|
||||
| 32768 | Detected (malware) |
|
||||
|
||||
## Microsoft Defender ATP API
|
||||
|
||||
### Advanced Hunting Query
|
||||
```http
|
||||
POST https://api.security.microsoft.com/api/advancedqueries/run
|
||||
Authorization: Bearer {token}
|
||||
|
||||
{
|
||||
"Query": "DeviceProcessEvents | where FileName == 'powershell.exe' | where ProcessCommandLine has_any('encodedcommand','downloadstring','invoke-expression') | project Timestamp, DeviceName, ProcessCommandLine | take 100"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for detecting suspicious PowerShell execution patterns."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import Counter
|
||||
from datetime import datetime, timezone
|
||||
|
||||
|
||||
SUSPICIOUS_CMDLETS = [
|
||||
"Invoke-Expression", "IEX", "Invoke-WebRequest", "Invoke-RestMethod",
|
||||
"Start-Process", "New-Object Net.WebClient", "DownloadString",
|
||||
"DownloadFile", "System.Reflection.Assembly", "FromBase64String",
|
||||
"Invoke-Mimikatz", "Invoke-Shellcode", "Invoke-DllInjection",
|
||||
"Invoke-ReflectivePEInjection", "Get-Keystrokes", "Get-GPPPassword",
|
||||
"Invoke-CredentialInjection", "Invoke-TokenManipulation",
|
||||
"Add-Exfiltration", "Get-TimedScreenshot",
|
||||
]
|
||||
|
||||
OBFUSCATION_PATTERNS = [
|
||||
(r'\-[eE][nN][cC]\s', "Encoded command (-enc)"),
|
||||
(r'[Ff][Rr][Oo][Mm][Bb][Aa][Ss][Ee]64', "Base64 decoding"),
|
||||
(r'\$\{[^}]+\}', "Variable obfuscation ${...}"),
|
||||
(r"'[^']*'\s*\+\s*'[^']*'", "String concatenation obfuscation"),
|
||||
(r'\-[Ww]indow[Ss]tyle\s+[Hh]idden', "Hidden window execution"),
|
||||
(r'\-[Nn]o[Pp]rofile', "NoProfile flag"),
|
||||
(r'\-[Ee]xecution[Pp]olicy\s+[Bb]ypass', "Execution policy bypass"),
|
||||
(r'[Ss]et-[Mm]pPreference.*-[Dd]isable', "Defender bypass attempt"),
|
||||
(r'[Aa][Mm][Ss][Ii]', "AMSI reference"),
|
||||
]
|
||||
|
||||
|
||||
def parse_script_block_logs():
|
||||
"""Parse PowerShell script block logging events (Event ID 4104)."""
|
||||
events = []
|
||||
if sys.platform != "win32":
|
||||
return events
|
||||
ps_cmd = (
|
||||
"Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';"
|
||||
"Id=4104} -MaxEvents 200 | Select-Object TimeCreated,"
|
||||
"@{N='ScriptBlock';E={$_.Properties[2].Value}},"
|
||||
"@{N='Path';E={$_.Properties[4].Value}} | ConvertTo-Json -Depth 3"
|
||||
)
|
||||
try:
|
||||
result = subprocess.check_output(
|
||||
["powershell", "-NoProfile", "-Command", ps_cmd],
|
||||
text=True, errors="replace", timeout=30
|
||||
)
|
||||
data = json.loads(result) if result.strip() else []
|
||||
return data if isinstance(data, list) else [data]
|
||||
except (subprocess.SubprocessError, json.JSONDecodeError):
|
||||
return []
|
||||
|
||||
|
||||
def analyze_script_content(script_text):
|
||||
"""Analyze a PowerShell script for suspicious patterns."""
|
||||
findings = []
|
||||
if not script_text:
|
||||
return findings
|
||||
|
||||
for cmdlet in SUSPICIOUS_CMDLETS:
|
||||
if cmdlet.lower() in script_text.lower():
|
||||
findings.append({"type": "suspicious_cmdlet", "cmdlet": cmdlet})
|
||||
|
||||
for pattern, desc in OBFUSCATION_PATTERNS:
|
||||
if re.search(pattern, script_text):
|
||||
findings.append({"type": "obfuscation", "pattern": desc})
|
||||
|
||||
b64_match = re.findall(r'[A-Za-z0-9+/]{40,}={0,2}', script_text)
|
||||
for b64 in b64_match[:3]:
|
||||
try:
|
||||
import base64
|
||||
decoded = base64.b64decode(b64).decode("utf-8", errors="replace")
|
||||
if any(c.lower() in decoded.lower() for c in SUSPICIOUS_CMDLETS[:10]):
|
||||
findings.append({"type": "encoded_payload", "preview": decoded[:100]})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def analyze_log_file(log_path):
|
||||
"""Analyze a text file containing PowerShell commands."""
|
||||
findings = []
|
||||
try:
|
||||
with open(log_path, "r", errors="replace") as f:
|
||||
content = f.read()
|
||||
results = analyze_script_content(content)
|
||||
if results:
|
||||
findings.append({
|
||||
"file": log_path,
|
||||
"indicators": results,
|
||||
"indicator_count": len(results),
|
||||
})
|
||||
except FileNotFoundError:
|
||||
print(f"[!] File not found: {log_path}")
|
||||
return findings
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Detect suspicious PowerShell execution patterns"
|
||||
)
|
||||
parser.add_argument("--event-logs", action="store_true",
|
||||
help="Parse Windows PowerShell event logs")
|
||||
parser.add_argument("--script", help="Analyze a PowerShell script file")
|
||||
parser.add_argument("--log-dir", help="Directory of PS log files to scan")
|
||||
parser.add_argument("--output", "-o", help="Output JSON report")
|
||||
parser.add_argument("--verbose", "-v", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("[*] Suspicious PowerShell Execution Detection Agent")
|
||||
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "findings": []}
|
||||
|
||||
if args.event_logs:
|
||||
events = parse_script_block_logs()
|
||||
for evt in events:
|
||||
script = evt.get("ScriptBlock", "")
|
||||
indicators = analyze_script_content(script)
|
||||
if indicators:
|
||||
report["findings"].append({
|
||||
"source": "event_log",
|
||||
"time": evt.get("TimeCreated", ""),
|
||||
"path": evt.get("Path", ""),
|
||||
"indicators": indicators,
|
||||
"preview": script[:200] if args.verbose else "",
|
||||
})
|
||||
print(f"[*] Analyzed {len(events)} script block events")
|
||||
|
||||
if args.script:
|
||||
findings = analyze_log_file(args.script)
|
||||
report["findings"].extend(findings)
|
||||
|
||||
if args.log_dir and os.path.isdir(args.log_dir):
|
||||
for root, _, files in os.walk(args.log_dir):
|
||||
for f in files:
|
||||
if f.lower().endswith((".ps1", ".psm1", ".psd1", ".log", ".txt")):
|
||||
findings = analyze_log_file(os.path.join(root, f))
|
||||
report["findings"].extend(findings)
|
||||
|
||||
report["total_suspicious"] = len(report["findings"])
|
||||
report["risk_level"] = (
|
||||
"CRITICAL" if len(report["findings"]) >= 10
|
||||
else "HIGH" if len(report["findings"]) >= 5
|
||||
else "MEDIUM" if report["findings"]
|
||||
else "LOW"
|
||||
)
|
||||
print(f"[*] Suspicious findings: {len(report['findings'])}")
|
||||
|
||||
if args.output:
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(f"[*] Report saved to {args.output}")
|
||||
else:
|
||||
print(json.dumps(report, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user