Files
mukul975 c21af3347e Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills
- Update all 648 LICENSE files: copyright now reads 'Mahipal'
- Add implementing-security-monitoring-with-datadog (new skill with full anatomy)
- All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
2026-03-11 00:22:12 +01:00

161 lines
6.4 KiB
Python

#!/usr/bin/env python3
"""Agent for auditing and managing BitLocker disk encryption across endpoints."""
import json
import argparse
import subprocess
import re
from datetime import datetime
from pathlib import Path
def get_bitlocker_status():
"""Get BitLocker status on local machine via manage-bde."""
try:
result = subprocess.run(
["manage-bde", "-status"], capture_output=True, text=True, timeout=30)
volumes = []
current = {}
for line in result.stdout.splitlines():
line = line.strip()
if line.startswith("Volume"):
if current:
volumes.append(current)
current = {"volume": line}
elif ":" in line:
key, _, value = line.partition(":")
current[key.strip()] = value.strip()
if current:
volumes.append(current)
return volumes
except (subprocess.TimeoutExpired, FileNotFoundError):
return []
def parse_bitlocker_report(report_path):
"""Parse BitLocker compliance report (CSV or JSON)."""
entries = []
if report_path.endswith(".json"):
with open(report_path) as f:
entries = json.load(f)
else:
import csv
with open(report_path, newline="", encoding="utf-8-sig") as f:
entries = list(csv.DictReader(f))
return entries
def audit_bitlocker_compliance(devices):
"""Audit BitLocker compliance across fleet."""
findings = []
for device in devices:
hostname = device.get("hostname", device.get("ComputerName", ""))
protection = device.get("protection_status", device.get("ProtectionStatus", ""))
encryption = device.get("encryption_method", device.get("EncryptionMethod", ""))
key_protector = device.get("key_protector", device.get("KeyProtector", ""))
recovery_key = device.get("recovery_key_escrowed",
device.get("RecoveryKeyEscrowed", ""))
if "off" in str(protection).lower() or protection == "0":
findings.append({
"hostname": hostname, "issue": "bitlocker_disabled",
"severity": "CRITICAL",
})
if encryption and "aes" not in str(encryption).lower():
findings.append({
"hostname": hostname, "issue": "weak_encryption_method",
"value": encryption, "severity": "HIGH",
})
if "128" in str(encryption):
findings.append({
"hostname": hostname, "issue": "aes_128_not_256",
"severity": "MEDIUM",
"recommendation": "Upgrade to AES-256",
})
if not key_protector or "tpm" not in str(key_protector).lower():
findings.append({
"hostname": hostname, "issue": "no_tpm_protector",
"severity": "HIGH",
})
if str(recovery_key).lower() in ("no", "false", "0", ""):
findings.append({
"hostname": hostname, "issue": "recovery_key_not_escrowed",
"severity": "HIGH",
"recommendation": "Escrow recovery key to Active Directory",
})
return findings
def generate_gpo_recommendations():
"""Generate Group Policy recommendations for BitLocker."""
return {
"Computer Configuration": {
"path": "Administrative Templates > Windows Components > BitLocker Drive Encryption",
"settings": [
{"name": "Choose drive encryption method (OS)",
"value": "AES-256", "policy": "Enabled"},
{"name": "Require additional authentication at startup",
"value": "Allow BitLocker without compatible TPM: Disabled",
"policy": "Enabled"},
{"name": "Choose how BitLocker-protected OS drives can be recovered",
"value": "Save to AD DS, Do not enable until stored",
"policy": "Enabled"},
{"name": "Enforce drive encryption type on OS drives",
"value": "Full encryption", "policy": "Enabled"},
],
},
}
def calculate_compliance_metrics(devices, findings):
"""Calculate fleet encryption compliance metrics."""
total = len(devices)
encrypted = total - sum(1 for f in findings if f["issue"] == "bitlocker_disabled")
strong_enc = encrypted - sum(1 for f in findings if f["issue"] in
("weak_encryption_method", "aes_128_not_256"))
escrowed = total - sum(1 for f in findings if f["issue"] == "recovery_key_not_escrowed")
return {
"total_devices": total,
"encrypted": encrypted,
"encryption_rate": round(encrypted / total * 100, 1) if total else 0,
"strong_encryption": strong_enc,
"recovery_keys_escrowed": escrowed,
"escrow_rate": round(escrowed / total * 100, 1) if total else 0,
}
def main():
parser = argparse.ArgumentParser(description="BitLocker Disk Encryption Agent")
parser.add_argument("--report", help="BitLocker report CSV/JSON")
parser.add_argument("--local", action="store_true", help="Check local machine")
parser.add_argument("--output", default="bitlocker_audit_report.json")
parser.add_argument("--action", choices=["audit", "local", "gpo", "full"], default="full")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "findings": {}}
if args.action in ("local", "full") and args.local:
status = get_bitlocker_status()
report["findings"]["local_status"] = status
print(f"[+] Local volumes: {len(status)}")
if args.action in ("audit", "full") and args.report:
devices = parse_bitlocker_report(args.report)
findings = audit_bitlocker_compliance(devices)
metrics = calculate_compliance_metrics(devices, findings)
report["findings"]["compliance_audit"] = findings
report["findings"]["metrics"] = metrics
print(f"[+] Devices: {metrics['total_devices']}, Encrypted: {metrics['encryption_rate']}%")
if args.action in ("gpo", "full"):
gpo = generate_gpo_recommendations()
report["findings"]["gpo_recommendations"] = gpo
print("[+] GPO recommendations generated")
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()