Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-SkillsFramework mappings
MITRE ATT&CK
T1003 on the official MITRE ATT&CK siteT1005 on the official MITRE ATT&CK siteT1059 on the official MITRE ATT&CK siteT1068 on the official MITRE ATT&CK siteT1525 on the official MITRE ATT&CK siteT1609 on the official MITRE ATT&CK siteT1610 on the official MITRE ATT&CK siteT1611 on the official MITRE ATT&CK site
NIST CSF 2.0
MITRE D3FEND
Overview
Falco is a CNCF-graduated runtime security tool that monitors Linux syscalls to detect anomalous container behavior. It uses a rules engine to identify container escape techniques such as mounting host filesystems, accessing sensitive host paths, loading kernel modules, and exploiting privileged container capabilities.
When to Use
- When investigating security incidents that require detecting container escape with falco rules
- When building detection rules or threat hunting queries for this domain
- When SOC analysts need structured procedures for this analysis type
- When validating security monitoring coverage for related attack techniques
Prerequisites
- Linux host with kernel 5.8+ (for eBPF driver) or kernel module support
- Kubernetes cluster (v1.24+) or standalone Docker/containerd
- Helm 3 for Kubernetes deployment
- Root or privileged access for driver installation
Installing Falco
Kubernetes Deployment with Helm
# Add Falco Helm chart
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
# Install Falco with eBPF driver
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true \
--set driver.kind=ebpf \
--set collectors.containerd.enabled=true \
--set collectors.containerd.socket=/run/containerd/containerd.sock
# Verify
kubectl get pods -n falco
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=20Standalone Installation (Debian/Ubuntu)
# Add Falco GPG key and repo
curl -fsSL https://falco.org/repo/falcosecurity-packages.asc | \
sudo gpg --dearmor -o /usr/share/keyrings/falco-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" | \
sudo tee /etc/apt/sources.list.d/falcosecurity.list
sudo apt-get update
sudo apt-get install -y falco
# Start Falco
sudo systemctl enable falco
sudo systemctl start falcoContainer Escape Detection Rules
Rule 1: Detect Host Mount from Container
- rule: Container Mounting Host Filesystem
desc: Detect a container attempting to mount the host filesystem
condition: >
spawned_process and container and
proc.name = mount and
(proc.args contains "/host" or proc.args contains "nsenter")
output: >
Container mounting host filesystem
(user=%user.name container_id=%container.id container_name=%container.name
image=%container.image.repository command=%proc.cmdline %evt.args)
priority: CRITICAL
tags: [container, escape, T1611]Rule 2: Detect nsenter Usage (Namespace Escape)
- rule: Nsenter Execution in Container
desc: Detect nsenter being used to escape container namespaces
condition: >
spawned_process and container and proc.name = nsenter
output: >
nsenter executed in container - potential escape attempt
(user=%user.name container_id=%container.id image=%container.image.repository
command=%proc.cmdline parent=%proc.pname)
priority: CRITICAL
tags: [container, escape, namespace, T1611]Rule 3: Detect Privileged Container Launch
- rule: Launch Privileged Container
desc: Detect a privileged container being launched
condition: >
container_started and container and container.privileged=true
output: >
Privileged container started
(user=%user.name container_id=%container.id container_name=%container.name
image=%container.image.repository)
priority: WARNING
tags: [container, privileged, T1610]Rule 4: Detect /proc/sysrq-trigger Write
- rule: Write to Sysrq Trigger
desc: Detect writes to /proc/sysrq-trigger which can crash or control the host
condition: >
open_write and container and fd.name = /proc/sysrq-trigger
output: >
Write to /proc/sysrq-trigger from container
(user=%user.name container_id=%container.id image=%container.image.repository
command=%proc.cmdline)
priority: CRITICAL
tags: [container, escape, host-manipulation]Rule 5: Detect Kernel Module Loading from Container
- rule: Container Loading Kernel Module
desc: Detect a container attempting to load a kernel module
condition: >
spawned_process and container and
(proc.name in (insmod, modprobe) or
(proc.name = init_module))
output: >
Kernel module loading from container
(user=%user.name container_id=%container.id image=%container.image.repository
command=%proc.cmdline)
priority: CRITICAL
tags: [container, escape, kernel, T1611]Rule 6: Detect Container Breakout via cgroups
- rule: Write to Cgroup Release Agent
desc: Detect writes to cgroup release_agent which is a known container escape vector
condition: >
open_write and container and
fd.name endswith release_agent
output: >
Container writing to cgroup release_agent - escape attempt
(user=%user.name container_id=%container.id image=%container.image.repository
file=%fd.name command=%proc.cmdline)
priority: CRITICAL
tags: [container, escape, cgroup, CVE-2022-0492]Rule 7: Detect Access to Host /etc/shadow
- rule: Container Reading Host Shadow File
desc: Detect a container reading /etc/shadow on the host via mounted volume
condition: >
open_read and container and
(fd.name = /etc/shadow or fd.name startswith /host/etc/shadow)
output: >
Container reading host shadow file
(user=%user.name container_id=%container.id image=%container.image.repository
file=%fd.name command=%proc.cmdline)
priority: CRITICAL
tags: [container, credential-access, T1003]Rule 8: Detect Docker Socket Access
- rule: Container Accessing Docker Socket
desc: Detect a container accessing the Docker socket which allows host control
condition: >
(open_read or open_write) and container and
fd.name = /var/run/docker.sock
output: >
Container accessing Docker socket
(user=%user.name container_id=%container.id image=%container.image.repository
command=%proc.cmdline)
priority: CRITICAL
tags: [container, escape, docker-socket, T1610]Complete Custom Rules File
# /etc/falco/rules.d/container-escape.yaml
- list: escape_binaries
items: [nsenter, chroot, unshare, mount, umount, pivot_root]
- macro: container_escape_attempt
condition: >
spawned_process and container and
proc.name in (escape_binaries)
- rule: Container Escape Binary Execution
desc: Detect execution of binaries commonly used for container escape
condition: container_escape_attempt
output: >
Escape-related binary executed in container
(user=%user.name container=%container.name image=%container.image.repository
command=%proc.cmdline parent=%proc.pname pid=%proc.pid)
priority: CRITICAL
tags: [container, escape, mitre_T1611]
- rule: Sensitive File Access from Container
desc: Detect container access to sensitive host files
condition: >
(open_read or open_write) and container and
(fd.name startswith /proc/1/ or
fd.name = /etc/shadow or
fd.name = /etc/kubernetes/admin.conf or
fd.name startswith /var/lib/kubelet/)
output: >
Sensitive file accessed from container
(container=%container.name image=%container.image.repository
file=%fd.name command=%proc.cmdline user=%user.name)
priority: CRITICAL
tags: [container, sensitive-file, mitre_T1005]Falco Configuration
# /etc/falco/falco.yaml (key settings)
rules_files:
- /etc/falco/falco_rules.yaml
- /etc/falco/rules.d/container-escape.yaml
json_output: true
json_include_output_property: true
json_include_tags_property: true
log_stderr: true
log_syslog: true
log_level: info
priority: WARNING
stdout_output:
enabled: true
syslog_output:
enabled: true
http_output:
enabled: true
url: http://falcosidekick:2801
insecure: true
grpc:
enabled: true
bind_address: "unix:///run/falco/falco.sock"
threadiness: 8
grpc_output:
enabled: trueAlert Integration
Forward to Slack via Falcosidekick
# Falcosidekick values.yaml
config:
slack:
webhookurl: "https://hooks.slack.com/services/XXXXX"
minimumpriority: "warning"
messageformat: |
*{{.Priority}}* - {{.Rule}}
Container: {{.OutputFields.container_name}}
Image: {{.OutputFields.container_image_repository}}
Command: {{.OutputFields.proc_cmdline}}Testing Rules
# Simulate container escape attempt (in a test container)
kubectl run test-escape --image=alpine --restart=Never -- sh -c "cat /etc/shadow"
# Simulate nsenter
kubectl run test-nsenter --image=alpine --restart=Never --overrides='{"spec":{"hostPID":true}}' -- nsenter -t 1 -m -u -i -n -- cat /etc/hostname
# Check Falco alerts
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=50 | grep -i escapeBest Practices
- Deploy Falco as DaemonSet to ensure coverage on all nodes
- Use eBPF driver over kernel module for safer operation
- Start with default rules (maturity_stable) then add custom rules
- Forward alerts to SIEM/SOAR via Falcosidekick
- Tag rules with MITRE ATT&CK technique IDs for correlation
- Test rules in permissive mode before enforcing
- Tune false positives by adding exception lists for known good processes
- Monitor Falco health with Prometheus metrics endpoint
Source materials
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md2.3 KB
API Reference: Detecting Container Escape with Falco Rules
Falco CLI
falco --version # check version
falco --validate /path/to/rules.yaml # validate rules syntax
falco -r /etc/falco/rules.d/escape.yaml # load specific rules
falco --list # list all available fields
falco --list-events # list supported syscallsFalco Rule Syntax
- rule: <name>
desc: <description>
condition: <filter expression>
output: <alert message with fields>
priority: <Emergency|Alert|Critical|Error|Warning|Notice|Informational|Debug>
tags: [tag1, tag2]
enabled: trueKey Falco Filter Fields
| Field | Description |
|---|---|
container |
True if event is from a container |
spawned_process |
True if new process spawned |
proc.name |
Process name |
proc.cmdline |
Full command line |
proc.pname |
Parent process name |
fd.name |
File descriptor name/path |
container.name |
Container name |
container.image.repository |
Image repository |
container.privileged |
True if privileged |
proc.is_exe_upper_layer |
Binary not in original image |
evt.type |
Syscall type (setns, unshare, mount) |
Falco JSON Output Format
{
"time": "2024-01-15T10:30:00.000Z",
"rule": "Container Escape Binary Execution",
"priority": "Critical",
"source": "syscall",
"output": "Escape binary in container...",
"output_fields": {
"user.name": "root",
"proc.cmdline": "nsenter -t 1 -m -u -i -n",
"container.name": "attacker-pod"
},
"tags": ["container", "escape", "T1611"]
}Falcosidekick Alert Routing
config:
slack:
webhookurl: "https://hooks.slack.com/services/XXX"
minimumpriority: "critical"
elasticsearch:
hostport: "https://es:9200"
index: "falco-alerts"Helm Deployment
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set driver.kind=ebpf \
--set falcosidekick.enabled=trueCLI Usage
python agent.py --check-status
python agent.py --validate-rules /etc/falco/rules.d/escape.yaml
python agent.py --parse-alerts /var/log/falco/events.json --min-priority Warning
python agent.py --generate-rules > escape-rules.yamlstandards.md2.6 KB
Standards and References - Container Escape Detection with Falco
Industry Standards
NIST SP 800-190: Application Container Security Guide
- Section 4.3: Container Runtime - Monitor containers for anomalous behavior at runtime
- Section 5.4: Container Runtime Security - Implement runtime monitoring and alerting
- Recommends syscall-level monitoring for escape detection
CIS Kubernetes Benchmark v1.8
- 5.7.1: Create administrative boundaries between resources using namespaces
- 5.7.2: Ensure that the seccomp profile is set to docker/default
- 5.7.3: Apply Security Context to pods and containers
- 5.7.4: The default namespace should not be used
MITRE ATT&CK for Containers
| Technique ID | Name | Falco Detection |
|---|---|---|
| T1611 | Escape to Host | nsenter, mount, chroot detection |
| T1610 | Deploy Container | Privileged container launch detection |
| T1003 | OS Credential Dumping | /etc/shadow access from container |
| T1005 | Data from Local System | Sensitive file read detection |
| T1059 | Command and Scripting Interpreter | Shell spawn in container |
| T1068 | Exploitation for Privilege Escalation | Kernel exploit indicators |
NSA/CISA Kubernetes Hardening Guide v1.2
- Section 5: Audit Logging and Threat Detection
- Enable runtime security monitoring
- Detect anomalous container behavior in real-time
- Monitor for privilege escalation attempts
Falco Rule Maturity Levels
| Level | Description | Count |
|---|---|---|
| maturity_stable | Production-ready, low false positives | 25 rules |
| maturity_incubating | Proven useful, may need tuning | ~30 rules |
| maturity_sandbox | Experimental, high false positive rate | ~38 rules |
| maturity_deprecated | Scheduled for removal | Variable |
Known Container Escape CVEs
| CVE | Description | Falco Rule |
|---|---|---|
| CVE-2024-21626 | runc process.cwd container breakout | Detect use of /proc/self/fd to access host |
| CVE-2022-0492 | cgroup v1 release_agent escape | Write to Cgroup Release Agent |
| CVE-2022-0185 | File system context exploit | Detect unshare in container |
| CVE-2020-15257 | containerd-shim API access | Detect abstract socket connections |
| CVE-2019-5736 | runc overwrite host binary | Detect writes to /proc/self/exe |
Compliance Mappings
PCI DSS v4.0
- Requirement 10.6.1: Review logs for anomalies at least daily
- Requirement 11.5: Deploy change-detection mechanisms
SOC 2 Type II
- CC7.2: Monitor system components for anomalies
- CC7.3: Evaluate security events to determine impact
workflows.md2.9 KB
Workflow - Detecting Container Escape with Falco Rules
Phase 1: Deploy Falco
Install on Kubernetes
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set driver.kind=ebpf \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true \
--set collectors.containerd.enabled=true
kubectl -n falco rollout status daemonset/falco --timeout=120sVerify Deployment
kubectl get pods -n falco -o wide
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=10Phase 2: Deploy Custom Escape Detection Rules
Create ConfigMap with Custom Rules
kubectl create configmap falco-escape-rules -n falco \
--from-file=container-escape.yaml=/path/to/container-escape.yaml
# Restart Falco to load new rules
kubectl rollout restart daemonset/falco -n falcoValidate Rules Loaded
kubectl exec -n falco $(kubectl get pod -n falco -l app.kubernetes.io/name=falco -o jsonpath='{.items[0].metadata.name}') -- \
falco --list | grep -i escapePhase 3: Test Detection
Test 1 - Privileged Container
kubectl run escape-test-priv --image=alpine --restart=Never \
--overrides='{"spec":{"containers":[{"name":"test","image":"alpine","command":["sleep","30"],"securityContext":{"privileged":true}}]}}'
# Check alert
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=5 | grep -i privileged
kubectl delete pod escape-test-privTest 2 - Sensitive File Access
kubectl run escape-test-shadow --image=alpine --restart=Never -- cat /etc/shadow
kubectl logs -n falco -l app.kubernetes.io/name=falco --tail=5 | grep -i shadow
kubectl delete pod escape-test-shadowTest 3 - Shell Spawn
kubectl exec -it deploy/some-app -- /bin/sh
# In Falco logs, should see "Terminal shell in container"Phase 4: Integrate Alerting
Configure Falcosidekick Outputs
# values-sidekick.yaml
config:
slack:
webhookurl: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
minimumpriority: "warning"
elasticsearch:
hostport: "https://elasticsearch:9200"
index: "falco"
minimumpriority: "notice"
prometheus:
enabled: truehelm upgrade falco falcosecurity/falco -n falco \
-f values-sidekick.yamlPhase 5: Tune and Maintain
Handle False Positives
# Add exceptions to rules
- rule: Terminal shell in container
append: true
exceptions:
- name: known_shell_spawners
fields: [container.image.repository]
comps: [in]
values:
- [my-debug-image, kubectl-debug]Regular Maintenance
- Update Falco rules weekly:
falcoctl artifact install falco-rules - Review new maturity_stable rules after each Falco release
- Correlate Falco alerts with Kubernetes audit logs
- Run escape simulation exercises monthly
Scripts 2
agent.py6.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Falco-based container escape detection agent.
Manages Falco rules, parses Falco alert output, and generates
escape detection reports from Falco JSON event streams.
"""
import argparse
import json
import subprocess
import sys
from datetime import datetime
ESCAPE_RULE_TAGS = ["container", "escape", "T1611", "T1610", "namespace",
"docker_socket", "cgroup", "kernel_module", "privileged"]
SEVERITY_MAP = {
"Emergency": 0, "Alert": 1, "Critical": 2, "Error": 3,
"Warning": 4, "Notice": 5, "Informational": 6, "Debug": 7
}
def check_falco_status():
try:
result = subprocess.run(["falco", "--version"],
capture_output=True, text=True, timeout=10)
if result.returncode == 0:
version = result.stdout.strip()
return {"installed": True, "version": version}
except FileNotFoundError:
pass
try:
result = subprocess.run(["systemctl", "is-active", "falco"],
capture_output=True, text=True, timeout=5)
return {"installed": True, "service_status": result.stdout.strip()}
except FileNotFoundError:
pass
return {"installed": False}
def validate_rules_file(rules_path):
try:
result = subprocess.run(
["falco", "--validate", rules_path],
capture_output=True, text=True, timeout=30)
return {
"valid": result.returncode == 0,
"output": result.stdout.strip() if result.returncode == 0
else result.stderr.strip(),
}
except (FileNotFoundError, subprocess.TimeoutExpired) as e:
return {"valid": False, "error": str(e)}
def parse_falco_alerts(filepath, min_priority="Warning"):
min_level = SEVERITY_MAP.get(min_priority, 4)
alerts = []
escape_alerts = []
with open(filepath, "r") as f:
for line in f:
line = line.strip()
if not line:
continue
try:
evt = json.loads(line)
except json.JSONDecodeError:
continue
priority = evt.get("priority", "Informational")
if SEVERITY_MAP.get(priority, 6) > min_level:
continue
alert = {
"time": evt.get("time", ""),
"rule": evt.get("rule", ""),
"priority": priority,
"source": evt.get("source", "syscall"),
"output": evt.get("output", ""),
"fields": evt.get("output_fields", {}),
"tags": evt.get("tags", []),
}
alerts.append(alert)
tags = set(evt.get("tags", []))
if tags & set(ESCAPE_RULE_TAGS):
escape_alerts.append(alert)
return {"total_alerts": len(alerts), "escape_alerts": escape_alerts}
def generate_escape_rules_yaml():
rules = """# Container Escape Detection Rules for Falco
# Deploy to /etc/falco/rules.d/container-escape.yaml
- list: escape_binaries
items: [nsenter, unshare, mount, umount, pivot_root, chroot, modprobe, insmod]
- macro: container_escape_binary
condition: spawned_process and container and proc.name in (escape_binaries)
- rule: Container Escape Binary Execution
desc: Detect execution of binaries commonly used for container escape
condition: container_escape_binary
output: "Escape binary in container (user=%user.name cmd=%proc.cmdline container=%container.name image=%container.image.repository)"
priority: CRITICAL
tags: [container, escape, T1611]
- rule: Docker Socket Access from Container
desc: Container accessing Docker socket enables full host control
condition: (open_read or open_write) and container and fd.name = /var/run/docker.sock
output: "Docker socket accessed (user=%user.name container=%container.name cmd=%proc.cmdline)"
priority: CRITICAL
tags: [container, escape, docker_socket, T1610]
- rule: Cgroup Release Agent Write
desc: Writing to cgroup release_agent is a known container escape vector
condition: open_write and container and fd.name endswith release_agent
output: "Cgroup escape attempt (user=%user.name container=%container.name file=%fd.name)"
priority: CRITICAL
tags: [container, escape, cgroup]
- rule: Kernel Module Load from Container
desc: Container attempting to load kernel module
condition: spawned_process and container and proc.name in (modprobe, insmod, rmmod)
output: "Kernel module load (user=%user.name container=%container.name cmd=%proc.cmdline)"
priority: CRITICAL
tags: [container, escape, kernel_module]
- rule: Sensitive Proc Access from Container
desc: Container accessing sensitive /proc or /sys paths
condition: open_read and container and (fd.name startswith /proc/sysrq-trigger or fd.name startswith /proc/kcore or fd.name startswith /proc/kallsyms)
output: "Sensitive proc access (container=%container.name path=%fd.name cmd=%proc.cmdline)"
priority: CRITICAL
tags: [container, escape, proc_access]
"""
return rules
def main():
parser = argparse.ArgumentParser(description="Falco Container Escape Detection")
parser.add_argument("--check-status", action="store_true", help="Check Falco installation")
parser.add_argument("--validate-rules", help="Validate a Falco rules file")
parser.add_argument("--parse-alerts", help="Parse Falco JSON alert log")
parser.add_argument("--min-priority", default="Warning",
choices=list(SEVERITY_MAP.keys()))
parser.add_argument("--generate-rules", action="store_true",
help="Output escape detection rules YAML")
args = parser.parse_args()
results = {"timestamp": datetime.utcnow().isoformat() + "Z"}
if args.check_status:
results["falco_status"] = check_falco_status()
if args.validate_rules:
results["validation"] = validate_rules_file(args.validate_rules)
if args.parse_alerts:
parsed = parse_falco_alerts(args.parse_alerts, args.min_priority)
results["alert_summary"] = {
"total_alerts": parsed["total_alerts"],
"escape_alerts_count": len(parsed["escape_alerts"]),
}
results["escape_alerts"] = parsed["escape_alerts"]
if args.generate_rules:
print(generate_escape_rules_yaml())
return
print(json.dumps(results, indent=2))
if __name__ == "__main__":
main()
process.py8.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Falco Container Escape Rule Manager - Generate, validate, and deploy
custom Falco rules for container escape detection.
"""
import json
import subprocess
import sys
import argparse
from pathlib import Path
from datetime import datetime
# Container escape detection rule templates
ESCAPE_RULES = {
"mount_host_fs": {
"rule": "Container Mounting Host Filesystem",
"desc": "Detect a container attempting to mount the host filesystem",
"condition": 'spawned_process and container and proc.name = mount and (proc.args contains "/host" or proc.args contains "nsenter")',
"priority": "CRITICAL",
"tags": ["container", "escape", "T1611"],
},
"nsenter_usage": {
"rule": "Nsenter Execution in Container",
"desc": "Detect nsenter being used to escape container namespaces",
"condition": "spawned_process and container and proc.name = nsenter",
"priority": "CRITICAL",
"tags": ["container", "escape", "namespace", "T1611"],
},
"privileged_container": {
"rule": "Launch Privileged Container",
"desc": "Detect a privileged container being launched",
"condition": "container_started and container and container.privileged=true",
"priority": "WARNING",
"tags": ["container", "privileged", "T1610"],
},
"cgroup_escape": {
"rule": "Write to Cgroup Release Agent",
"desc": "Detect writes to cgroup release_agent - known escape vector",
"condition": "open_write and container and fd.name endswith release_agent",
"priority": "CRITICAL",
"tags": ["container", "escape", "cgroup", "CVE-2022-0492"],
},
"docker_socket": {
"rule": "Container Accessing Docker Socket",
"desc": "Detect container accessing Docker socket for host control",
"condition": "(open_read or open_write) and container and fd.name = /var/run/docker.sock",
"priority": "CRITICAL",
"tags": ["container", "escape", "docker-socket", "T1610"],
},
"kernel_module": {
"rule": "Container Loading Kernel Module",
"desc": "Detect a container attempting to load a kernel module",
"condition": "spawned_process and container and proc.name in (insmod, modprobe)",
"priority": "CRITICAL",
"tags": ["container", "escape", "kernel", "T1611"],
},
"shadow_file": {
"rule": "Container Reading Host Shadow File",
"desc": "Detect container reading /etc/shadow",
"condition": 'open_read and container and (fd.name = /etc/shadow or fd.name startswith /host/etc/shadow)',
"priority": "CRITICAL",
"tags": ["container", "credential-access", "T1003"],
},
"sysrq_trigger": {
"rule": "Write to Sysrq Trigger from Container",
"desc": "Detect writes to /proc/sysrq-trigger from container",
"condition": "open_write and container and fd.name = /proc/sysrq-trigger",
"priority": "CRITICAL",
"tags": ["container", "escape", "host-manipulation"],
},
}
def generate_rule_yaml(rule_key: str, rule_data: dict) -> str:
"""Generate a single Falco rule in YAML format."""
tags_str = ", ".join(rule_data["tags"])
output_fields = (
"user=%user.name container_id=%container.id "
"container_name=%container.name image=%container.image.repository "
"command=%proc.cmdline"
)
return f"""- rule: {rule_data['rule']}
desc: {rule_data['desc']}
condition: >
{rule_data['condition']}
output: >
{rule_data['desc']}
({output_fields})
priority: {rule_data['priority']}
tags: [{tags_str}]
"""
def generate_all_rules() -> str:
"""Generate complete Falco rules file for container escape detection."""
header = f"""# Container Escape Detection Rules for Falco
# Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')}
# Deploy to: /etc/falco/rules.d/container-escape.yaml
- list: escape_binaries
items: [nsenter, chroot, unshare, mount, umount, pivot_root]
- macro: container_escape_binary
condition: spawned_process and container and proc.name in (escape_binaries)
"""
rules = ""
for key, data in ESCAPE_RULES.items():
rules += generate_rule_yaml(key, data) + "\n"
return header + rules
def parse_falco_alerts(log_file: str) -> list:
"""Parse Falco JSON alerts from log file."""
alerts = []
path = Path(log_file)
if not path.exists():
print(f"Log file not found: {log_file}", file=sys.stderr)
return alerts
for line in path.read_text().splitlines():
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", ""),
"tags": alert.get("tags", []),
"container_name": alert.get("output_fields", {}).get("container.name", ""),
"container_image": alert.get("output_fields", {}).get("container.image.repository", ""),
})
except json.JSONDecodeError:
continue
return alerts
def summarize_alerts(alerts: list) -> dict:
"""Summarize Falco alerts by rule and severity."""
summary = {"total": len(alerts), "by_priority": {}, "by_rule": {}, "escape_attempts": []}
for alert in alerts:
pri = alert["priority"]
rule = alert["rule"]
summary["by_priority"][pri] = summary["by_priority"].get(pri, 0) + 1
summary["by_rule"][rule] = summary["by_rule"].get(rule, 0) + 1
if any(tag in alert.get("tags", []) for tag in ["escape", "T1611", "T1610"]):
summary["escape_attempts"].append(alert)
return summary
def check_falco_health() -> dict:
"""Check if Falco is running and healthy."""
result = subprocess.run(
["kubectl", "get", "pods", "-n", "falco", "-l", "app.kubernetes.io/name=falco",
"-o", "json"],
capture_output=True, text=True,
)
if result.returncode != 0:
return {"healthy": False, "error": result.stderr}
pods = json.loads(result.stdout)
pod_status = []
for pod in pods.get("items", []):
name = pod["metadata"]["name"]
phase = pod["status"]["phase"]
node = pod["spec"].get("nodeName", "unknown")
pod_status.append({"name": name, "phase": phase, "node": node})
all_running = all(p["phase"] == "Running" for p in pod_status)
return {"healthy": all_running, "pods": pod_status}
def main():
parser = argparse.ArgumentParser(description="Falco Container Escape Rule Manager")
subparsers = parser.add_subparsers(dest="command")
subparsers.add_parser("generate", help="Generate container escape detection rules")
parse_cmd = subparsers.add_parser("parse-alerts", help="Parse Falco alert logs")
parse_cmd.add_argument("--log-file", required=True, help="Path to Falco JSON log file")
subparsers.add_parser("health", help="Check Falco deployment health")
deploy_cmd = subparsers.add_parser("deploy", help="Deploy rules to Kubernetes")
deploy_cmd.add_argument("--namespace", default="falco", help="Falco namespace")
args = parser.parse_args()
if args.command == "generate":
print(generate_all_rules())
elif args.command == "parse-alerts":
alerts = parse_falco_alerts(args.log_file)
summary = summarize_alerts(alerts)
print(json.dumps(summary, indent=2))
elif args.command == "health":
health = check_falco_health()
print(json.dumps(health, indent=2))
elif args.command == "deploy":
rules_yaml = generate_all_rules()
proc = subprocess.run(
["kubectl", "create", "configmap", "falco-escape-rules",
"-n", args.namespace, "--from-literal=container-escape.yaml=" + rules_yaml,
"--dry-run=client", "-o", "yaml"],
capture_output=True, text=True,
)
apply = subprocess.run(
["kubectl", "apply", "-f", "-"],
input=proc.stdout, capture_output=True, text=True,
)
print(apply.stdout)
if apply.returncode == 0:
print("Rules deployed. Restart Falco to load:")
print(f" kubectl rollout restart daemonset/falco -n {args.namespace}")
else:
parser.print_help()
if __name__ == "__main__":
main()
Assets 1
template.mdtext/markdown · 1.9 KBKeep exploring