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:
mukul975
2026-03-11 00:22:12 +01:00
parent 27c6414ca5
commit c21af3347e
1244 changed files with 61622 additions and 723 deletions
@@ -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()