mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-24 05:30:58 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
kube-bench CIS Benchmark Reporter - Parse kube-bench JSON output
|
||||
and generate compliance reports with trend tracking.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from collections import Counter
|
||||
|
||||
|
||||
def parse_kube_bench_json(filepath: str) -> dict:
|
||||
"""Parse kube-bench JSON output file."""
|
||||
path = Path(filepath)
|
||||
if not path.exists():
|
||||
print(f"File not found: {filepath}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
return json.loads(path.read_text())
|
||||
|
||||
|
||||
def extract_checks(data: dict) -> list:
|
||||
"""Extract all individual checks from kube-bench results."""
|
||||
checks = []
|
||||
for control in data.get("Controls", []):
|
||||
section = control.get("id", "")
|
||||
section_text = control.get("text", "")
|
||||
for group in control.get("tests", []):
|
||||
group_id = group.get("section", "")
|
||||
for result in group.get("results", []):
|
||||
checks.append({
|
||||
"section": section,
|
||||
"section_text": section_text,
|
||||
"group": group_id,
|
||||
"id": result.get("test_number", ""),
|
||||
"description": result.get("test_desc", ""),
|
||||
"status": result.get("status", ""),
|
||||
"scored": result.get("scored", False),
|
||||
"remediation": result.get("remediation", ""),
|
||||
"reason": result.get("reason", ""),
|
||||
})
|
||||
return checks
|
||||
|
||||
|
||||
def generate_summary(checks: list) -> dict:
|
||||
"""Generate summary statistics."""
|
||||
status_counts = Counter(c["status"] for c in checks)
|
||||
section_counts = {}
|
||||
for c in checks:
|
||||
sec = c["section"]
|
||||
if sec not in section_counts:
|
||||
section_counts[sec] = {"section_text": c["section_text"], "PASS": 0, "FAIL": 0, "WARN": 0, "INFO": 0}
|
||||
status = c["status"]
|
||||
if status in section_counts[sec]:
|
||||
section_counts[sec][status] += 1
|
||||
|
||||
total = len(checks)
|
||||
passed = status_counts.get("PASS", 0)
|
||||
score = (passed / total * 100) if total > 0 else 0
|
||||
|
||||
return {
|
||||
"total_checks": total,
|
||||
"pass": status_counts.get("PASS", 0),
|
||||
"fail": status_counts.get("FAIL", 0),
|
||||
"warn": status_counts.get("WARN", 0),
|
||||
"info": status_counts.get("INFO", 0),
|
||||
"score_percent": round(score, 1),
|
||||
"by_section": section_counts,
|
||||
}
|
||||
|
||||
|
||||
def generate_report(data: dict, output_path: str = None) -> str:
|
||||
"""Generate markdown CIS benchmark report."""
|
||||
checks = extract_checks(data)
|
||||
summary = generate_summary(checks)
|
||||
timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
report = f"""# CIS Kubernetes Benchmark Report
|
||||
|
||||
**Date:** {timestamp}
|
||||
**Total Checks:** {summary['total_checks']}
|
||||
**Score:** {summary['score_percent']}%
|
||||
|
||||
## Summary
|
||||
|
||||
| Status | Count |
|
||||
|--------|-------|
|
||||
| PASS | {summary['pass']} |
|
||||
| FAIL | {summary['fail']} |
|
||||
| WARN | {summary['warn']} |
|
||||
| INFO | {summary['info']} |
|
||||
|
||||
## Results by Section
|
||||
|
||||
| Section | Description | Pass | Fail | Warn |
|
||||
|---------|-------------|------|------|------|
|
||||
"""
|
||||
for sec_id, sec in sorted(summary["by_section"].items()):
|
||||
report += f"| {sec_id} | {sec['section_text']} | {sec['PASS']} | {sec['FAIL']} | {sec['WARN']} |\n"
|
||||
|
||||
failed = [c for c in checks if c["status"] == "FAIL"]
|
||||
if failed:
|
||||
report += "\n## Failed Checks (Requires Remediation)\n\n"
|
||||
for c in failed:
|
||||
report += f"### {c['id']} - {c['description']}\n"
|
||||
report += f"- **Status:** FAIL\n"
|
||||
report += f"- **Scored:** {c['scored']}\n"
|
||||
if c['remediation']:
|
||||
report += f"- **Remediation:** {c['remediation']}\n"
|
||||
report += "\n"
|
||||
|
||||
if output_path:
|
||||
Path(output_path).write_text(report)
|
||||
print(f"Report written to {output_path}")
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def compare_scans(current_file: str, previous_file: str):
|
||||
"""Compare two kube-bench scan results."""
|
||||
current = extract_checks(parse_kube_bench_json(current_file))
|
||||
previous = extract_checks(parse_kube_bench_json(previous_file))
|
||||
|
||||
curr_summary = generate_summary(current)
|
||||
prev_summary = generate_summary(previous)
|
||||
|
||||
print("\n=== CIS Benchmark Comparison ===\n")
|
||||
print(f"{'Metric':<20} {'Previous':<12} {'Current':<12} {'Change'}")
|
||||
print("-" * 55)
|
||||
|
||||
for metric in ["pass", "fail", "warn"]:
|
||||
prev_val = prev_summary[metric]
|
||||
curr_val = curr_summary[metric]
|
||||
change = curr_val - prev_val
|
||||
sign = "+" if change > 0 else ""
|
||||
print(f"{metric.upper():<20} {prev_val:<12} {curr_val:<12} {sign}{change}")
|
||||
|
||||
print(f"{'SCORE':<20} {prev_summary['score_percent']}%{'':<7} {curr_summary['score_percent']}%")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="kube-bench CIS Benchmark Reporter")
|
||||
subparsers = parser.add_subparsers(dest="command")
|
||||
|
||||
report_cmd = subparsers.add_parser("report", help="Generate report from kube-bench JSON")
|
||||
report_cmd.add_argument("input", help="kube-bench JSON output file")
|
||||
report_cmd.add_argument("--output", "-o", help="Output markdown report path")
|
||||
|
||||
compare_cmd = subparsers.add_parser("compare", help="Compare two scan results")
|
||||
compare_cmd.add_argument("current", help="Current scan JSON")
|
||||
compare_cmd.add_argument("previous", help="Previous scan JSON")
|
||||
|
||||
summary_cmd = subparsers.add_parser("summary", help="Print summary from JSON")
|
||||
summary_cmd.add_argument("input", help="kube-bench JSON output file")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "report":
|
||||
data = parse_kube_bench_json(args.input)
|
||||
report = generate_report(data, args.output)
|
||||
if not args.output:
|
||||
print(report)
|
||||
|
||||
elif args.command == "compare":
|
||||
compare_scans(args.current, args.previous)
|
||||
|
||||
elif args.command == "summary":
|
||||
data = parse_kube_bench_json(args.input)
|
||||
checks = extract_checks(data)
|
||||
summary = generate_summary(checks)
|
||||
print(json.dumps(summary, indent=2))
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user