Initial commit - 611 cybersecurity skills across all subdomains

This commit is contained in:
mukul975
2026-02-25 10:47:44 +01:00
commit 22a7ab1462
1765 changed files with 280648 additions and 0 deletions
@@ -0,0 +1,205 @@
---
name: None
description: Kubernetes Role-Based Access Control (RBAC) auditing systematically reviews roles, cluster roles, bindings, and service account permissions to identify overly permissive access, privilege escalation p
domain: cybersecurity
subdomain: container-security
tags: [containers, kubernetes, security, RBAC, access-control]
version: "1.0"
author: mahipal
license: MIT
---
# Auditing Kubernetes RBAC Permissions
## Overview
Kubernetes Role-Based Access Control (RBAC) auditing systematically reviews roles, cluster roles, bindings, and service account permissions to identify overly permissive access, privilege escalation paths, and violations of least-privilege principles. Tools like rbac-tool, KubiScan, and rakkess automate discovery of dangerous permission combinations.
## Prerequisites
- Kubernetes cluster with RBAC enabled (default since 1.6)
- kubectl with cluster-admin access for full audit
- rbac-tool, rakkess, or KubiScan installed
## Core Concepts
### RBAC Components
| Resource | Scope | Purpose |
|----------|-------|---------|
| Role | Namespace | Grants permissions within a namespace |
| ClusterRole | Cluster | Grants permissions cluster-wide |
| RoleBinding | Namespace | Binds Role/ClusterRole to subjects in namespace |
| ClusterRoleBinding | Cluster | Binds ClusterRole to subjects cluster-wide |
### Dangerous Permission Combinations
| Permission | Risk | Impact |
|-----------|------|--------|
| `*` on `*` resources | Critical | Equivalent to cluster-admin |
| create pods | High | Can deploy privileged pods |
| create pods/exec | High | Can exec into any pod |
| get secrets | High | Can read all secrets |
| create clusterrolebindings | Critical | Can escalate to cluster-admin |
| impersonate users | Critical | Can act as any user |
| escalate on roles | Critical | Can grant permissions beyond own |
| bind on roles | High | Can create new role bindings |
## Implementation Steps
### Step 1: Enumerate All RBAC Resources
```bash
# List all ClusterRoles
kubectl get clusterroles -o name | wc -l
kubectl get clusterroles --no-headers | grep -v "system:"
# List all ClusterRoleBindings
kubectl get clusterrolebindings -o wide
# List all Roles per namespace
kubectl get roles -A
# List all RoleBindings per namespace
kubectl get rolebindings -A -o wide
# Export all RBAC for offline analysis
kubectl get clusterroles,clusterrolebindings,roles,rolebindings -A -o yaml > rbac-export.yaml
```
### Step 2: Identify Wildcard Permissions
```bash
# Find ClusterRoles with wildcard verbs on all resources
kubectl get clusterroles -o json | jq -r '
.items[] |
select(.rules[]? |
(.verbs | index("*")) and
(.resources | index("*"))
) |
.metadata.name'
# Find roles that can create pods
kubectl get clusterroles -o json | jq -r '
.items[] |
select(.rules[]? |
(.verbs | index("create") or index("*")) and
(.resources | index("pods") or index("*"))
) |
.metadata.name'
# Find roles that can read secrets
kubectl get clusterroles -o json | jq -r '
.items[] |
select(.rules[]? |
(.verbs | index("get") or index("list") or index("*")) and
(.resources | index("secrets") or index("*"))
) |
.metadata.name'
```
### Step 3: Check Service Account Permissions
```bash
# List all service accounts
kubectl get serviceaccounts -A
# Check permissions for default service accounts
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "=== $ns/default ==="
kubectl auth can-i --list --as=system:serviceaccount:$ns:default 2>/dev/null | grep -v "no"
done
# Check for service accounts with cluster-admin
kubectl get clusterrolebindings -o json | jq -r '
.items[] |
select(.roleRef.name == "cluster-admin") |
{binding: .metadata.name, subjects: [.subjects[]? | {kind, name, namespace}]}'
```
### Step 4: Use rbac-tool for Automated Analysis
```bash
# Install rbac-tool
kubectl krew install rbac-tool
# Visualize RBAC
kubectl rbac-tool viz --outformat dot | dot -Tpng > rbac-graph.png
# Find who can perform specific actions
kubectl rbac-tool who-can get secrets -A
kubectl rbac-tool who-can create pods -A
kubectl rbac-tool who-can '*' '*'
# Analyze all permissions
kubectl rbac-tool analysis
# Generate RBAC policy report
kubectl rbac-tool auditgen > rbac-audit.yaml
```
### Step 5: Check for Privilege Escalation Paths
```bash
# Check if any role can escalate privileges
kubectl get clusterroles -o json | jq -r '
.items[] |
select(.rules[]? |
(.verbs | index("escalate") or index("bind") or index("impersonate")) and
(.resources | index("clusterroles") or index("roles") or index("clusterrolebindings") or index("rolebindings") or index("users") or index("groups") or index("serviceaccounts"))
) |
.metadata.name'
# Check for impersonation permissions
kubectl get clusterroles -o json | jq -r '
.items[] |
select(.rules[]? |
(.verbs | index("impersonate"))
) |
{name: .metadata.name, rules: .rules}'
```
### Step 6: Audit with KubiScan
```bash
# Install KubiScan
pip install kubiscan
# Find risky roles
kubiscan --risky-roles
# Find risky ClusterRoles
kubiscan --risky-clusterroles
# Find risky subjects
kubiscan --risky-subjects
# Find pods with risky service accounts
kubiscan --risky-pods
# Full report
kubiscan --all
```
## Validation Commands
```bash
# Verify specific permission
kubectl auth can-i create pods --as=system:serviceaccount:default:myapp
# Check all permissions for a user
kubectl auth can-i --list --as=developer@example.com
# Validate RBAC with kubescape
kubescape scan framework nsa --controls-config rbac-controls.json
# Test least privilege
kubectl auth can-i delete nodes --as=system:serviceaccount:app:web-server
# Expected: no
```
## References
- [Kubernetes RBAC Documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
- [rbac-tool GitHub](https://github.com/alcideio/rbac-tool)
- [KubiScan - Risky Permissions Scanner](https://github.com/cyberark/KubiScan)
- [CIS Kubernetes Benchmark - Section 5.1](https://www.cisecurity.org/benchmark/kubernetes)
@@ -0,0 +1,25 @@
# RBAC Audit Report Template
## Cluster Information
| Field | Value |
|-------|-------|
| Cluster Name | |
| Audit Date | |
| Total ClusterRoles | |
| Total Roles | |
| Total Bindings | |
## High-Risk Bindings
| Binding | Role | Subject | Severity | Action |
|---------|------|---------|----------|--------|
| | | | | |
## Service Account Review
| Namespace | SA Name | Bound Roles | Risk | Recommendation |
|-----------|---------|-------------|------|---------------|
| | | | | |
## Remediation Plan
| Priority | Finding | Action | Owner | Status |
|----------|---------|--------|-------|--------|
| | | | | |
@@ -0,0 +1,34 @@
# Standards Reference - RBAC Auditing
## CIS Kubernetes Benchmark v1.8 - Section 5.1
- 5.1.1: Ensure cluster-admin role is only used where required
- 5.1.2: Minimize access to secrets
- 5.1.3: Minimize wildcard use in Roles and ClusterRoles
- 5.1.4: Minimize access to create pods
- 5.1.5: Ensure default service accounts are not actively used
- 5.1.6: Ensure Service Account Tokens are not mounted when not needed
- 5.1.7: Avoid use of system:masters group
- 5.1.8: Limit use of the Bind, Impersonate and Escalate permissions
## NIST SP 800-53 AC Controls
- AC-2: Account Management
- AC-3: Access Enforcement
- AC-6: Least Privilege
- AC-6(1): Authorize Access to Security Functions
- AC-6(5): Privileged Accounts
## Dangerous RBAC Combinations
| Verbs | Resources | Risk Level |
|-------|-----------|-----------|
| * | * | CRITICAL - cluster-admin equivalent |
| create | pods | HIGH - can deploy privileged pods |
| create | pods/exec | HIGH - can exec into any pod |
| get, list | secrets | HIGH - can read all secrets |
| create | clusterrolebindings | CRITICAL - privilege escalation |
| impersonate | users, groups, serviceaccounts | CRITICAL - identity theft |
| escalate | roles, clusterroles | CRITICAL - RBAC escalation |
| bind | roles, clusterroles | HIGH - can create bindings |
| create | deployments | MEDIUM - can deploy workloads |
| delete | pods, nodes | HIGH - denial of service |
@@ -0,0 +1,60 @@
# Workflows - RBAC Auditing
## Workflow 1: Comprehensive RBAC Audit
```
[Export all RBAC] --> [Identify cluster-admin bindings] --> [Check wildcard permissions]
| | |
v v v
kubectl get all Flag non-system Flag * verbs, * resources
RBAC resources cluster-admin users Find excessive permissions
| | |
+----------+------------+------------------------------------+
|
v
[Check service account permissions]
|
v
[Identify privilege escalation paths]
|
v
[Generate remediation report]
```
## Workflow 2: Least Privilege Implementation
```
Step 1: Inventory current permissions per team/service
Step 2: Document actual required operations
Step 3: Create minimal Role/ClusterRole
Step 4: Test with auth can-i dry-run
Step 5: Apply new bindings
Step 6: Remove overly permissive bindings
Step 7: Validate with automated audit
```
## Workflow 3: Continuous RBAC Monitoring
```yaml
# CronJob for weekly RBAC audit
apiVersion: batch/v1
kind: CronJob
metadata:
name: rbac-audit
spec:
schedule: "0 2 * * 1" # Weekly Monday 2am
jobTemplate:
spec:
template:
spec:
containers:
- name: audit
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name' > /audit/cluster-admin-bindings.txt
kubectl get clusterroles -o json | jq '.items[] | select(.rules[]? | (.verbs | index("*")) and (.resources | index("*"))) | .metadata.name' > /audit/wildcard-roles.txt
restartPolicy: Never
```
@@ -0,0 +1,257 @@
#!/usr/bin/env python3
"""
Kubernetes RBAC Permissions Auditor
Audits RBAC configurations for overly permissive roles,
dangerous permission combinations, and privilege escalation paths.
"""
import subprocess
import json
import sys
from dataclasses import dataclass, field
DANGEROUS_VERBS = {"*", "escalate", "bind", "impersonate"}
DANGEROUS_RESOURCES = {"*", "secrets", "pods", "clusterroles", "clusterrolebindings", "roles", "rolebindings"}
HIGH_RISK_COMBINATIONS = [
({"*"}, {"*"}, "CRITICAL", "Wildcard access on all resources (cluster-admin equivalent)"),
({"create", "update", "patch"}, {"clusterrolebindings", "rolebindings"}, "CRITICAL", "Can create role bindings for privilege escalation"),
({"escalate"}, {"clusterroles", "roles"}, "CRITICAL", "Can escalate role permissions beyond own level"),
({"impersonate"}, {"users", "groups", "serviceaccounts"}, "CRITICAL", "Can impersonate any identity"),
({"get", "list", "watch"}, {"secrets"}, "HIGH", "Can read all secrets in scope"),
({"create"}, {"pods"}, "HIGH", "Can create pods (deploy workloads)"),
({"create"}, {"pods/exec"}, "HIGH", "Can exec into pods (command execution)"),
({"delete"}, {"pods", "nodes", "namespaces"}, "HIGH", "Can delete critical resources"),
]
@dataclass
class RBACFinding:
resource_type: str
resource_name: str
namespace: str
severity: str
issue: str
details: str
remediation: str
@dataclass
class RBACAuditReport:
findings: list = field(default_factory=list)
cluster_roles: int = 0
roles: int = 0
cluster_role_bindings: int = 0
role_bindings: int = 0
service_accounts: int = 0
def run_kubectl_json(args: list):
cmd = ["kubectl"] + args + ["-o", "json"]
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode != 0:
return None
return json.loads(result.stdout)
except (subprocess.TimeoutExpired, json.JSONDecodeError, FileNotFoundError):
return None
def check_role_rules(rules: list, role_name: str, role_type: str, namespace: str, report: RBACAuditReport):
"""Analyze role rules for dangerous permissions."""
for rule in rules:
verbs = set(rule.get("verbs", []))
resources = set(rule.get("resources", []))
api_groups = rule.get("apiGroups", [])
for req_verbs, req_resources, severity, description in HIGH_RISK_COMBINATIONS:
verb_match = "*" in verbs or bool(verbs & req_verbs)
resource_match = "*" in resources or bool(resources & req_resources)
if verb_match and resource_match:
report.findings.append(RBACFinding(
resource_type=role_type,
resource_name=role_name,
namespace=namespace,
severity=severity,
issue=description,
details=f"verbs={list(verbs)}, resources={list(resources)}, apiGroups={api_groups}",
remediation=f"Restrict {role_type} '{role_name}' to minimum required permissions"
))
break
def audit_cluster_roles(report: RBACAuditReport):
"""Audit all ClusterRoles."""
print("[*] Auditing ClusterRoles...")
data = run_kubectl_json(["get", "clusterroles"])
if not data:
return
items = data.get("items", [])
report.cluster_roles = len(items)
for cr in items:
name = cr["metadata"]["name"]
# Skip well-known system roles
if name.startswith("system:") and name not in ("system:aggregate-to-admin", "system:aggregate-to-edit"):
continue
rules = cr.get("rules", [])
check_role_rules(rules, name, "ClusterRole", "cluster-wide", report)
def audit_roles(report: RBACAuditReport):
"""Audit all namespace Roles."""
print("[*] Auditing Roles...")
data = run_kubectl_json(["get", "roles", "-A"])
if not data:
return
items = data.get("items", [])
report.roles = len(items)
for role in items:
name = role["metadata"]["name"]
namespace = role["metadata"]["namespace"]
rules = role.get("rules", [])
check_role_rules(rules, name, "Role", namespace, report)
def audit_bindings(report: RBACAuditReport):
"""Audit ClusterRoleBindings for dangerous subject assignments."""
print("[*] Auditing ClusterRoleBindings...")
data = run_kubectl_json(["get", "clusterrolebindings"])
if not data:
return
items = data.get("items", [])
report.cluster_role_bindings = len(items)
dangerous_subjects = {"system:anonymous", "system:unauthenticated"}
admin_roles = {"cluster-admin", "admin", "edit"}
for crb in items:
name = crb["metadata"]["name"]
role_ref = crb.get("roleRef", {}).get("name", "")
subjects = crb.get("subjects", []) or []
for subject in subjects:
s_name = subject.get("name", "")
s_kind = subject.get("kind", "")
if s_name in dangerous_subjects and role_ref in admin_roles:
report.findings.append(RBACFinding(
resource_type="ClusterRoleBinding",
resource_name=name,
namespace="cluster-wide",
severity="CRITICAL",
issue=f"Dangerous subject '{s_name}' bound to '{role_ref}'",
details=f"Subject {s_kind}/{s_name} has {role_ref} access",
remediation=f"Remove or restrict ClusterRoleBinding '{name}'"
))
# Check for system:authenticated bound to admin roles
if s_name == "system:authenticated" and role_ref in admin_roles:
report.findings.append(RBACFinding(
resource_type="ClusterRoleBinding",
resource_name=name,
namespace="cluster-wide",
severity="CRITICAL",
issue=f"All authenticated users have '{role_ref}' access",
details=f"Group system:authenticated bound to {role_ref}",
remediation=f"Remove binding, use specific user/group bindings"
))
def audit_service_accounts(report: RBACAuditReport):
"""Audit service accounts for over-permissioning."""
print("[*] Auditing Service Accounts...")
data = run_kubectl_json(["get", "serviceaccounts", "-A"])
if not data:
return
items = data.get("items", [])
report.service_accounts = len(items)
# Check default SAs that have non-default bindings
crbs = run_kubectl_json(["get", "clusterrolebindings"])
rbs = run_kubectl_json(["get", "rolebindings", "-A"])
if crbs:
for crb in crbs.get("items", []):
for subject in crb.get("subjects", []) or []:
if subject.get("kind") == "ServiceAccount" and subject.get("name") == "default":
report.findings.append(RBACFinding(
resource_type="ServiceAccount",
resource_name=f"default ({subject.get('namespace', 'unknown')})",
namespace=subject.get("namespace", "unknown"),
severity="HIGH",
issue=f"Default SA bound to ClusterRole '{crb['roleRef']['name']}'",
details="Default service account should not have additional permissions",
remediation="Create dedicated service account, remove default SA binding"
))
def print_report(report: RBACAuditReport):
print("\n" + "=" * 70)
print("KUBERNETES RBAC AUDIT REPORT")
print("=" * 70)
print(f"ClusterRoles: {report.cluster_roles}")
print(f"Roles: {report.roles}")
print(f"ClusterRoleBindings: {report.cluster_role_bindings}")
print(f"RoleBindings: {report.role_bindings}")
print(f"ServiceAccounts: {report.service_accounts}")
print(f"Total Findings: {len(report.findings)}")
print("=" * 70)
for severity in ["CRITICAL", "HIGH", "MEDIUM", "LOW"]:
findings = [f for f in report.findings if f.severity == severity]
if findings:
print(f"\n{severity} ({len(findings)}):")
print("-" * 70)
for f in findings:
print(f" [{f.resource_type}] {f.resource_name}")
print(f" Issue: {f.issue}")
print(f" Details: {f.details}")
print(f" Fix: {f.remediation}")
print()
def main():
print("[*] Kubernetes RBAC Permissions Auditor\n")
report = RBACAuditReport()
audit_cluster_roles(report)
audit_roles(report)
audit_bindings(report)
audit_service_accounts(report)
print_report(report)
output = {
"summary": {
"cluster_roles": report.cluster_roles,
"roles": report.roles,
"findings": len(report.findings),
},
"findings": [
{"type": f.resource_type, "name": f.resource_name, "namespace": f.namespace,
"severity": f.severity, "issue": f.issue, "remediation": f.remediation}
for f in report.findings
],
}
with open("rbac_audit_report.json", "w") as f:
json.dump(output, f, indent=2)
print("[*] Report saved to rbac_audit_report.json")
critical = sum(1 for f in report.findings if f.severity == "CRITICAL")
if critical > 0:
print(f"\n[!] {critical} CRITICAL findings found")
sys.exit(1)
if __name__ == "__main__":
main()