mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-24 13:40:57 +03:00
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:
@@ -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,47 @@
|
||||
---
|
||||
name: performing-cloud-native-forensics-with-falco
|
||||
description: >
|
||||
Uses Falco YAML rules for runtime threat detection in containers and Kubernetes,
|
||||
monitoring syscalls for shell spawns, file tampering, network anomalies, and privilege
|
||||
escalation. Manages Falco rules via the Falco gRPC API and parses Falco alert output.
|
||||
Use when building container runtime security or investigating k8s cluster compromises.
|
||||
---
|
||||
|
||||
# Performing Cloud Native Forensics with Falco
|
||||
|
||||
## Instructions
|
||||
|
||||
Deploy and manage Falco rules for runtime security detection in containerized
|
||||
environments. Parse Falco alerts for incident response.
|
||||
|
||||
```yaml
|
||||
# Custom Falco rule for detecting shell in container
|
||||
- rule: Shell Spawned in Container
|
||||
desc: Detect shell process started in a container
|
||||
condition: >
|
||||
spawned_process and container
|
||||
and proc.name in (bash, sh, zsh, dash, csh)
|
||||
and not proc.pname in (docker-entrypo, supervisord)
|
||||
output: >
|
||||
Shell spawned in container
|
||||
(user=%user.name command=%proc.cmdline container=%container.name
|
||||
image=%container.image.repository)
|
||||
priority: WARNING
|
||||
tags: [container, shell, mitre_execution]
|
||||
```
|
||||
|
||||
Key detection rules:
|
||||
1. Shell spawn in non-interactive containers
|
||||
2. Sensitive file access (/etc/shadow, /etc/passwd)
|
||||
3. Outbound connections from unexpected containers
|
||||
4. Privilege escalation via setuid/setgid
|
||||
5. Container escape via mount or ptrace
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Run Falco with custom rules
|
||||
falco -r /etc/falco/custom_rules.yaml -o json_output=true
|
||||
# Parse JSON alerts
|
||||
cat /var/log/falco/alerts.json | python3 -c "import json,sys; [print(json.loads(l)['output']) for l in sys.stdin]"
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
# API Reference: Performing Cloud Native Forensics with Falco
|
||||
|
||||
## Falco Rule YAML Structure
|
||||
|
||||
```yaml
|
||||
- rule: Shell Spawned in Container
|
||||
desc: Detect shell in container
|
||||
condition: >
|
||||
spawned_process and container
|
||||
and proc.name in (bash, sh, zsh)
|
||||
output: >
|
||||
Shell spawned (user=%user.name command=%proc.cmdline
|
||||
container=%container.name image=%container.image.repository)
|
||||
priority: WARNING
|
||||
tags: [container, shell, mitre_execution]
|
||||
```
|
||||
|
||||
## Falco Condition Fields
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `proc.name` | Process name |
|
||||
| `proc.cmdline` | Full command line |
|
||||
| `proc.pname` | Parent process name |
|
||||
| `user.name` | User running process |
|
||||
| `fd.name` | File descriptor name/path |
|
||||
| `container.name` | Container name |
|
||||
| `container.image.repository` | Container image |
|
||||
| `container.privileged` | Privileged flag |
|
||||
| `evt.type` | Syscall type (execve, open, connect) |
|
||||
|
||||
## Falco Priority Levels
|
||||
|
||||
`EMERGENCY > ALERT > CRITICAL > ERROR > WARNING > NOTICE > INFO > DEBUG`
|
||||
|
||||
## Falco HTTP API
|
||||
|
||||
```python
|
||||
import requests
|
||||
# Health check
|
||||
requests.get("http://localhost:8765/healthz")
|
||||
# Version
|
||||
requests.get("http://localhost:8765/version")
|
||||
```
|
||||
|
||||
## Helm Deployment
|
||||
|
||||
```bash
|
||||
helm repo add falcosecurity https://falcosecurity.github.io/charts
|
||||
helm install falco falcosecurity/falco \
|
||||
--set driver.kind=ebpf \
|
||||
--set falcosidekick.enabled=true
|
||||
```
|
||||
|
||||
### References
|
||||
|
||||
- Falco: https://falco.org/docs/
|
||||
- Falco rules: https://github.com/falcosecurity/rules
|
||||
- Falcosidekick: https://github.com/falcosecurity/falcosidekick
|
||||
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for managing Falco rules and parsing alerts for container forensics."""
|
||||
|
||||
import os
|
||||
import json
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
import requests
|
||||
|
||||
|
||||
FALCO_RULES = [
|
||||
{
|
||||
"rule": "Shell Spawned in Container",
|
||||
"desc": "Detect shell process started in a container",
|
||||
"condition": "spawned_process and container and proc.name in (bash, sh, zsh, dash) "
|
||||
"and not proc.pname in (docker-entrypo, supervisord, crond)",
|
||||
"output": "Shell spawned (user=%user.name command=%proc.cmdline "
|
||||
"container=%container.name image=%container.image.repository)",
|
||||
"priority": "WARNING",
|
||||
"tags": ["container", "shell", "mitre_execution"],
|
||||
},
|
||||
{
|
||||
"rule": "Sensitive File Access in Container",
|
||||
"desc": "Detect read of sensitive files in container",
|
||||
"condition": "open_read and container and fd.name in (/etc/shadow, /etc/passwd, "
|
||||
"/etc/sudoers) and not proc.name in (su, sudo, login)",
|
||||
"output": "Sensitive file read (file=%fd.name user=%user.name "
|
||||
"container=%container.name)",
|
||||
"priority": "WARNING",
|
||||
"tags": ["container", "filesystem", "mitre_credential_access"],
|
||||
},
|
||||
{
|
||||
"rule": "Outbound Connection from Container",
|
||||
"desc": "Detect unexpected outbound network connections from containers",
|
||||
"condition": "evt.type=connect and fd.typechar=4 and fd.ip != 0.0.0.0 "
|
||||
"and container and not fd.snet in (10.0.0.0/8, 172.16.0.0/12, "
|
||||
"192.168.0.0/16)",
|
||||
"output": "Outbound connection (command=%proc.cmdline dest=%fd.name "
|
||||
"container=%container.name)",
|
||||
"priority": "NOTICE",
|
||||
"tags": ["container", "network", "mitre_command_and_control"],
|
||||
},
|
||||
{
|
||||
"rule": "Privilege Escalation in Container",
|
||||
"desc": "Detect setuid/setgid calls in container",
|
||||
"condition": "evt.type in (setuid, setgid) and container "
|
||||
"and not user.name=root",
|
||||
"output": "Privilege escalation attempt (user=%user.name command=%proc.cmdline "
|
||||
"container=%container.name)",
|
||||
"priority": "CRITICAL",
|
||||
"tags": ["container", "privilege_escalation", "mitre_privilege_escalation"],
|
||||
},
|
||||
{
|
||||
"rule": "Container Escape Attempt via Mount",
|
||||
"desc": "Detect mount syscall in container indicating escape attempt",
|
||||
"condition": "evt.type=mount and container",
|
||||
"output": "Mount in container (user=%user.name command=%proc.cmdline "
|
||||
"container=%container.name)",
|
||||
"priority": "CRITICAL",
|
||||
"tags": ["container", "escape", "mitre_privilege_escalation"],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def generate_falco_rules(output_path, custom_rules=None):
|
||||
"""Generate Falco rules YAML file."""
|
||||
rules = custom_rules or FALCO_RULES
|
||||
with open(output_path, "w") as f:
|
||||
yaml.dump(rules, f, default_flow_style=False, sort_keys=False)
|
||||
return len(rules)
|
||||
|
||||
|
||||
def parse_falco_alerts(alert_file):
|
||||
"""Parse Falco JSON alert output file."""
|
||||
alerts = []
|
||||
with open(alert_file) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
alert = json.loads(line)
|
||||
alerts.append({
|
||||
"time": alert.get("time", ""),
|
||||
"rule": alert.get("rule", ""),
|
||||
"priority": alert.get("priority", ""),
|
||||
"output": alert.get("output", ""),
|
||||
"output_fields": alert.get("output_fields", {}),
|
||||
"source": alert.get("source", ""),
|
||||
"tags": alert.get("tags", []),
|
||||
})
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
return alerts
|
||||
|
||||
|
||||
def summarize_alerts(alerts):
|
||||
"""Generate alert summary statistics."""
|
||||
by_rule = defaultdict(int)
|
||||
by_priority = defaultdict(int)
|
||||
by_container = defaultdict(int)
|
||||
for alert in alerts:
|
||||
by_rule[alert["rule"]] += 1
|
||||
by_priority[alert["priority"]] += 1
|
||||
container = alert.get("output_fields", {}).get("container.name", "unknown")
|
||||
by_container[container] += 1
|
||||
return {
|
||||
"total_alerts": len(alerts),
|
||||
"by_rule": dict(by_rule),
|
||||
"by_priority": dict(by_priority),
|
||||
"by_container": dict(sorted(by_container.items(), key=lambda x: -x[1])[:20]),
|
||||
}
|
||||
|
||||
|
||||
def check_falco_health(falco_url="http://localhost:8765"):
|
||||
"""Check Falco health via HTTP endpoint."""
|
||||
try:
|
||||
resp = requests.get(f"{falco_url}/healthz", timeout=5)
|
||||
return {"status": "healthy" if resp.status_code == 200 else "unhealthy",
|
||||
"code": resp.status_code}
|
||||
except requests.RequestException as e:
|
||||
return {"status": "unreachable", "error": str(e)}
|
||||
|
||||
|
||||
def get_falco_version(falco_url="http://localhost:8765"):
|
||||
"""Get Falco version information."""
|
||||
try:
|
||||
resp = requests.get(f"{falco_url}/version", timeout=5)
|
||||
return resp.json()
|
||||
except requests.RequestException as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
|
||||
def correlate_alerts_with_k8s(alerts, suspicious_images=None):
|
||||
"""Correlate Falco alerts with known suspicious container images."""
|
||||
if not suspicious_images:
|
||||
suspicious_images = []
|
||||
correlated = []
|
||||
for alert in alerts:
|
||||
fields = alert.get("output_fields", {})
|
||||
image = fields.get("container.image.repository", "")
|
||||
if any(s in image for s in suspicious_images):
|
||||
alert["correlation"] = "suspicious_image"
|
||||
correlated.append(alert)
|
||||
elif alert["priority"] in ("CRITICAL", "ERROR"):
|
||||
correlated.append(alert)
|
||||
return correlated
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Falco Cloud Native Forensics Agent")
|
||||
parser.add_argument("--alert-file", help="Path to Falco JSON alert log")
|
||||
parser.add_argument("--rules-output", default="custom_falco_rules.yaml")
|
||||
parser.add_argument("--falco-url", default="http://localhost:8765")
|
||||
parser.add_argument("--output", default="falco_report.json")
|
||||
parser.add_argument("--action", choices=[
|
||||
"generate_rules", "parse_alerts", "health", "full_analysis"
|
||||
], default="full_analysis")
|
||||
args = parser.parse_args()
|
||||
|
||||
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
|
||||
|
||||
if args.action in ("generate_rules", "full_analysis"):
|
||||
count = generate_falco_rules(args.rules_output)
|
||||
report["findings"]["rules_generated"] = count
|
||||
print(f"[+] Generated {count} Falco rules to {args.rules_output}")
|
||||
|
||||
if args.action in ("parse_alerts", "full_analysis") and args.alert_file:
|
||||
alerts = parse_falco_alerts(args.alert_file)
|
||||
summary = summarize_alerts(alerts)
|
||||
report["findings"]["alert_summary"] = summary
|
||||
report["findings"]["critical_alerts"] = [
|
||||
a for a in alerts if a["priority"] in ("CRITICAL", "ERROR")
|
||||
]
|
||||
print(f"[+] Parsed {summary['total_alerts']} alerts")
|
||||
print(f" Critical: {summary['by_priority'].get('CRITICAL', 0)}")
|
||||
|
||||
if args.action in ("health", "full_analysis"):
|
||||
health = check_falco_health(args.falco_url)
|
||||
report["findings"]["falco_health"] = health
|
||||
print(f"[+] Falco health: {health['status']}")
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(f"[+] Report saved to {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user