mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 21:49:40 +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,68 @@
|
||||
# API Reference: Securing Kubernetes on Cloud
|
||||
|
||||
## kubernetes Python Client
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
pip install kubernetes
|
||||
```
|
||||
|
||||
### Configuration
|
||||
```python
|
||||
from kubernetes import client, config
|
||||
config.load_kube_config(context="my-cluster")
|
||||
```
|
||||
|
||||
### Core API (v1)
|
||||
```python
|
||||
v1 = client.CoreV1Api()
|
||||
```
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `list_namespace()` | List all namespaces with labels |
|
||||
| `list_pod_for_all_namespaces()` | List all pods across namespaces |
|
||||
| `read_namespaced_service_account()` | Get service account details |
|
||||
| `create_namespace()` | Create namespace with PSA labels |
|
||||
|
||||
### RBAC API
|
||||
```python
|
||||
rbac = client.RbacAuthorizationV1Api()
|
||||
```
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `list_cluster_role_binding()` | List all ClusterRoleBindings |
|
||||
| `list_cluster_role()` | List all ClusterRoles |
|
||||
| `list_namespaced_role_binding()` | List RoleBindings in a namespace |
|
||||
| `list_namespaced_role()` | List Roles in a namespace |
|
||||
|
||||
### Networking API
|
||||
```python
|
||||
net = client.NetworkingV1Api()
|
||||
```
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `list_namespaced_network_policy()` | List network policies in a namespace |
|
||||
| `create_namespaced_network_policy()` | Create a network policy |
|
||||
|
||||
### Pod Security Context Fields
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `privileged` | Run container in privileged mode |
|
||||
| `run_as_user` | UID to run the container as |
|
||||
| `run_as_non_root` | Require non-root UID |
|
||||
| `read_only_root_filesystem` | Mount root filesystem as read-only |
|
||||
| `allow_privilege_escalation` | Allow setuid/capabilities |
|
||||
| `capabilities.drop` | Linux capabilities to drop |
|
||||
| `seccomp_profile.type` | Seccomp profile (RuntimeDefault) |
|
||||
|
||||
### Pod Security Admission Labels
|
||||
| Label | Values |
|
||||
|-------|--------|
|
||||
| `pod-security.kubernetes.io/enforce` | privileged, baseline, restricted |
|
||||
| `pod-security.kubernetes.io/audit` | privileged, baseline, restricted |
|
||||
| `pod-security.kubernetes.io/warn` | privileged, baseline, restricted |
|
||||
|
||||
## References
|
||||
- kubernetes-client/python: https://github.com/kubernetes-client/python
|
||||
- Pod Security Standards: https://kubernetes.io/docs/concepts/security/pod-security-standards/
|
||||
- Network Policies: https://kubernetes.io/docs/concepts/services-networking/network-policies/
|
||||
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for auditing Kubernetes cluster security posture on managed cloud platforms."""
|
||||
|
||||
from kubernetes import client, config
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def load_kube_config(context=None):
|
||||
"""Load kubeconfig for cluster access."""
|
||||
try:
|
||||
config.load_kube_config(context=context)
|
||||
print("[*] Kubeconfig loaded successfully")
|
||||
except Exception as e:
|
||||
print(f"[-] Failed to load kubeconfig: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def check_pod_security_standards():
|
||||
"""Audit namespaces for Pod Security Standards enforcement labels."""
|
||||
v1 = client.CoreV1Api()
|
||||
namespaces = v1.list_namespace().items
|
||||
findings = []
|
||||
print("\n[*] Checking Pod Security Standards enforcement...")
|
||||
for ns in namespaces:
|
||||
name = ns.metadata.name
|
||||
labels = ns.metadata.labels or {}
|
||||
enforce = labels.get("pod-security.kubernetes.io/enforce", "NOT SET")
|
||||
audit = labels.get("pod-security.kubernetes.io/audit", "NOT SET")
|
||||
warn = labels.get("pod-security.kubernetes.io/warn", "NOT SET")
|
||||
if enforce == "NOT SET" and name not in ("kube-system", "kube-public", "kube-node-lease"):
|
||||
findings.append({"namespace": name, "issue": "No PSA enforcement", "severity": "HIGH"})
|
||||
print(f" [!] {name}: enforce={enforce}")
|
||||
elif enforce in ("baseline", "restricted"):
|
||||
print(f" [+] {name}: enforce={enforce}, audit={audit}, warn={warn}")
|
||||
print(f"[*] {len(findings)} namespaces without PSA enforcement")
|
||||
return findings
|
||||
|
||||
|
||||
def check_rbac_clusterroles():
|
||||
"""Audit ClusterRoleBindings for overly permissive access."""
|
||||
rbac = client.RbacAuthorizationV1Api()
|
||||
findings = []
|
||||
print("\n[*] Checking RBAC ClusterRoleBindings...")
|
||||
bindings = rbac.list_cluster_role_binding().items
|
||||
for binding in bindings:
|
||||
role_ref = binding.role_ref.name
|
||||
subjects = binding.subjects or []
|
||||
if role_ref in ("cluster-admin", "admin"):
|
||||
for subj in subjects:
|
||||
if subj.kind in ("User", "Group") and subj.name not in ("system:masters",):
|
||||
findings.append({
|
||||
"binding": binding.metadata.name, "role": role_ref,
|
||||
"subject": f"{subj.kind}/{subj.name}", "severity": "CRITICAL",
|
||||
})
|
||||
print(f" [!] CRITICAL: {subj.kind}/{subj.name} -> {role_ref}")
|
||||
print(f"[*] {len(findings)} overprivileged ClusterRoleBindings found")
|
||||
return findings
|
||||
|
||||
|
||||
def check_service_account_tokens():
|
||||
"""Find pods with auto-mounted service account tokens."""
|
||||
v1 = client.CoreV1Api()
|
||||
findings = []
|
||||
print("\n[*] Checking for auto-mounted service account tokens...")
|
||||
pods = v1.list_pod_for_all_namespaces().items
|
||||
for pod in pods:
|
||||
ns = pod.metadata.namespace
|
||||
if ns in ("kube-system", "kube-public"):
|
||||
continue
|
||||
auto_mount = pod.spec.automount_service_account_token
|
||||
if auto_mount is None or auto_mount is True:
|
||||
sa = pod.spec.service_account_name or "default"
|
||||
if sa == "default":
|
||||
findings.append({
|
||||
"pod": pod.metadata.name, "namespace": ns,
|
||||
"service_account": sa, "severity": "MEDIUM",
|
||||
})
|
||||
if findings:
|
||||
print(f" [!] {len(findings)} pods with default SA token auto-mounted")
|
||||
for f in findings[:10]:
|
||||
print(f" {f['namespace']}/{f['pod']} (SA: {f['service_account']})")
|
||||
return findings
|
||||
|
||||
|
||||
def check_privileged_pods():
|
||||
"""Find pods running with privileged security context."""
|
||||
v1 = client.CoreV1Api()
|
||||
findings = []
|
||||
print("\n[*] Checking for privileged containers...")
|
||||
pods = v1.list_pod_for_all_namespaces().items
|
||||
for pod in pods:
|
||||
ns = pod.metadata.namespace
|
||||
if ns in ("kube-system",):
|
||||
continue
|
||||
for container in pod.spec.containers:
|
||||
sc = container.security_context
|
||||
if sc:
|
||||
if sc.privileged:
|
||||
findings.append({
|
||||
"pod": pod.metadata.name, "namespace": ns,
|
||||
"container": container.name, "issue": "privileged=true",
|
||||
"severity": "CRITICAL",
|
||||
})
|
||||
print(f" [!] CRITICAL: {ns}/{pod.metadata.name}/{container.name} is PRIVILEGED")
|
||||
if sc.run_as_user == 0:
|
||||
findings.append({
|
||||
"pod": pod.metadata.name, "namespace": ns,
|
||||
"container": container.name, "issue": "running as root (UID 0)",
|
||||
"severity": "HIGH",
|
||||
})
|
||||
print(f"[*] {len(findings)} privileged/root container findings")
|
||||
return findings
|
||||
|
||||
|
||||
def check_network_policies():
|
||||
"""Check if namespaces have network policies applied."""
|
||||
v1 = client.CoreV1Api()
|
||||
net_v1 = client.NetworkingV1Api()
|
||||
findings = []
|
||||
print("\n[*] Checking network policy coverage...")
|
||||
namespaces = v1.list_namespace().items
|
||||
for ns in namespaces:
|
||||
name = ns.metadata.name
|
||||
if name in ("kube-system", "kube-public", "kube-node-lease"):
|
||||
continue
|
||||
policies = net_v1.list_namespaced_network_policy(name).items
|
||||
if not policies:
|
||||
findings.append({"namespace": name, "issue": "No network policies", "severity": "HIGH"})
|
||||
print(f" [!] {name}: NO network policies")
|
||||
else:
|
||||
deny_all = any(not p.spec.pod_selector.match_labels for p in policies
|
||||
if p.spec.pod_selector)
|
||||
print(f" [+] {name}: {len(policies)} policies (default-deny: {'Yes' if deny_all else 'No'})")
|
||||
return findings
|
||||
|
||||
|
||||
def check_image_registries():
|
||||
"""Audit images to ensure they come from approved registries."""
|
||||
v1 = client.CoreV1Api()
|
||||
print("\n[*] Checking container image sources...")
|
||||
pods = v1.list_pod_for_all_namespaces().items
|
||||
registries = {}
|
||||
issues = []
|
||||
for pod in pods:
|
||||
for container in pod.spec.containers:
|
||||
image = container.image or ""
|
||||
registry = image.split("/")[0] if "/" in image else "docker.io"
|
||||
registries[registry] = registries.get(registry, 0) + 1
|
||||
if "@sha256:" not in image and ":latest" in image:
|
||||
issues.append({
|
||||
"pod": pod.metadata.name, "namespace": pod.metadata.namespace,
|
||||
"image": image, "issue": "Using :latest tag",
|
||||
})
|
||||
print(" Image registries in use:")
|
||||
for reg, count in sorted(registries.items(), key=lambda x: -x[1]):
|
||||
print(f" {reg}: {count} containers")
|
||||
if issues:
|
||||
print(f" [!] {len(issues)} containers using :latest tag")
|
||||
return issues
|
||||
|
||||
|
||||
def full_audit(output_path="k8s_security_audit.json"):
|
||||
"""Run a complete Kubernetes security audit."""
|
||||
print("[*] Starting Kubernetes security audit...\n")
|
||||
report = {
|
||||
"audit_date": datetime.now().isoformat(),
|
||||
"psa_findings": check_pod_security_standards(),
|
||||
"rbac_findings": check_rbac_clusterroles(),
|
||||
"sa_token_findings": check_service_account_tokens(),
|
||||
"privileged_findings": check_privileged_pods(),
|
||||
"network_policy_findings": check_network_policies(),
|
||||
"image_findings": check_image_registries(),
|
||||
}
|
||||
total = sum(len(v) for v in report.values() if isinstance(v, list))
|
||||
report["total_findings"] = total
|
||||
with open(output_path, "w") as f:
|
||||
json.dump(report, f, indent=2, default=str)
|
||||
print(f"\n[*] Audit complete: {total} total findings")
|
||||
print(f"[*] Report saved to {output_path}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Kubernetes Cloud Security Audit Agent")
|
||||
parser.add_argument("action", choices=["full-audit", "psa", "rbac", "privileged",
|
||||
"network-policies", "images", "sa-tokens"])
|
||||
parser.add_argument("--context", help="Kubeconfig context name")
|
||||
parser.add_argument("-o", "--output", default="k8s_security_audit.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
load_kube_config(args.context)
|
||||
if args.action == "full-audit":
|
||||
full_audit(args.output)
|
||||
elif args.action == "psa":
|
||||
check_pod_security_standards()
|
||||
elif args.action == "rbac":
|
||||
check_rbac_clusterroles()
|
||||
elif args.action == "privileged":
|
||||
check_privileged_pods()
|
||||
elif args.action == "network-policies":
|
||||
check_network_policies()
|
||||
elif args.action == "images":
|
||||
check_image_registries()
|
||||
elif args.action == "sa-tokens":
|
||||
check_service_account_tokens()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user