mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 13:44:56 +03:00
234 lines
9.3 KiB
Python
234 lines
9.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Windows Defender Configuration Auditor
|
|
|
|
Collects and audits Microsoft Defender for Endpoint settings across endpoints,
|
|
identifies configuration gaps, and generates compliance reports.
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
from datetime import datetime
|
|
|
|
|
|
RECOMMENDED_SETTINGS = {
|
|
"RealTimeProtectionEnabled": True,
|
|
"BehaviorMonitoringEnabled": True,
|
|
"IoavProtectionEnabled": True,
|
|
"AntispywareEnabled": True,
|
|
"AntivirusEnabled": True,
|
|
"MAPSReporting": 2, # Advanced
|
|
"SubmitSamplesConsent": 3, # SendAllSamples
|
|
"PUAProtection": 1, # Enabled
|
|
"DisableBlockAtFirstSeen": False,
|
|
"CloudBlockLevel": 2, # High
|
|
"CloudExtendedTimeout": 50,
|
|
"EnableNetworkProtection": 1, # Enabled
|
|
"EnableControlledFolderAccess": 1, # Enabled
|
|
"SignatureUpdateInterval": 1, # Hourly
|
|
}
|
|
|
|
RECOMMENDED_ASR_RULES = {
|
|
"BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550": {"name": "Block executable content from email", "mode": 1},
|
|
"D4F940AB-401B-4EFC-AADC-AD5F3C50688A": {"name": "Block Office child processes", "mode": 1},
|
|
"3B576869-A4EC-4529-8536-B80A7769E899": {"name": "Block Office executable creation", "mode": 1},
|
|
"75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84": {"name": "Block Office code injection", "mode": 1},
|
|
"D3E037E1-3EB8-44C8-A917-57927947596D": {"name": "Block JS/VBS launching executables", "mode": 1},
|
|
"5BEB7EFE-FD9A-4556-801D-275E5FFC04CC": {"name": "Block obfuscated scripts", "mode": 1},
|
|
"92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B": {"name": "Block Win32 API from macros", "mode": 1},
|
|
"9E6C4E1F-7D60-472F-BA1A-A39EF669E4B2": {"name": "Block LSASS credential stealing", "mode": 1},
|
|
"D1E49AAC-8F56-4280-B9BA-993A6D77406C": {"name": "Block PSExec/WMI processes", "mode": 1},
|
|
"B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4": {"name": "Block untrusted USB processes", "mode": 1},
|
|
"E6DB77E5-3DF2-4CF1-B95A-636979351E5B": {"name": "Block WMI persistence", "mode": 1},
|
|
"56A863A9-875E-4185-98A7-B882C64B5CE5": {"name": "Block vulnerable signed drivers", "mode": 1},
|
|
}
|
|
|
|
|
|
def collect_defender_settings() -> dict:
|
|
"""Collect current Defender settings via PowerShell."""
|
|
ps_cmd = """
|
|
$prefs = Get-MpPreference
|
|
$status = Get-MpComputerStatus
|
|
$result = @{
|
|
Preferences = @{
|
|
RealTimeProtectionEnabled = $prefs.DisableRealtimeMonitoring -eq $false
|
|
BehaviorMonitoringEnabled = $prefs.DisableBehaviorMonitoring -eq $false
|
|
IoavProtectionEnabled = $prefs.DisableIOAVProtection -eq $false
|
|
AntispywareEnabled = $status.AntispywareEnabled
|
|
AntivirusEnabled = $status.AntivirusEnabled
|
|
MAPSReporting = $prefs.MAPSReporting
|
|
SubmitSamplesConsent = $prefs.SubmitSamplesConsent
|
|
PUAProtection = $prefs.PUAProtection
|
|
DisableBlockAtFirstSeen = $prefs.DisableBlockAtFirstSeen
|
|
CloudBlockLevel = $prefs.CloudBlockLevel
|
|
CloudExtendedTimeout = $prefs.CloudExtendedTimeout
|
|
EnableNetworkProtection = $prefs.EnableNetworkProtection
|
|
EnableControlledFolderAccess = $prefs.EnableControlledFolderAccess
|
|
SignatureUpdateInterval = $prefs.SignatureUpdateInterval
|
|
}
|
|
ASRRules = @{}
|
|
Status = @{
|
|
AMEngineVersion = $status.AMEngineVersion
|
|
AMProductVersion = $status.AMProductVersion
|
|
AntispywareSignatureVersion = $status.AntispywareSignatureVersion
|
|
AntivirusSignatureVersion = $status.AntivirusSignatureVersion
|
|
AntivirusSignatureLastUpdated = $status.AntivirusSignatureLastUpdated.ToString('o')
|
|
FullScanEndTime = if($status.FullScanEndTime) { $status.FullScanEndTime.ToString('o') } else { 'Never' }
|
|
QuickScanEndTime = if($status.QuickScanEndTime) { $status.QuickScanEndTime.ToString('o') } else { 'Never' }
|
|
RealTimeProtectionEnabled = $status.RealTimeProtectionEnabled
|
|
TamperProtectionSource = $status.IsTamperProtected
|
|
}
|
|
}
|
|
$ids = $prefs.AttackSurfaceReductionRules_Ids
|
|
$actions = $prefs.AttackSurfaceReductionRules_Actions
|
|
if ($ids -and $actions) {
|
|
for ($i=0; $i -lt $ids.Count; $i++) {
|
|
$result.ASRRules[$ids[$i].ToString().ToUpper()] = $actions[$i]
|
|
}
|
|
}
|
|
$result | ConvertTo-Json -Depth 3
|
|
"""
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
["powershell", "-NoProfile", "-Command", ps_cmd],
|
|
capture_output=True, text=True, timeout=30,
|
|
)
|
|
if result.returncode == 0 and result.stdout.strip():
|
|
return json.loads(result.stdout)
|
|
else:
|
|
return {"error": result.stderr or "Failed to collect Defender settings"}
|
|
except FileNotFoundError:
|
|
return {"error": "PowerShell not available (requires Windows)"}
|
|
except subprocess.TimeoutExpired:
|
|
return {"error": "PowerShell command timed out"}
|
|
except json.JSONDecodeError as e:
|
|
return {"error": f"Failed to parse PowerShell output: {e}"}
|
|
|
|
|
|
def audit_settings(settings: dict) -> dict:
|
|
"""Audit collected settings against recommended baseline."""
|
|
findings = {
|
|
"compliant": [],
|
|
"non_compliant": [],
|
|
"asr_rules": {
|
|
"enabled_block": [],
|
|
"enabled_audit": [],
|
|
"disabled": [],
|
|
"missing": [],
|
|
},
|
|
"score": 0.0,
|
|
}
|
|
|
|
prefs = settings.get("Preferences", {})
|
|
total_checks = 0
|
|
passed_checks = 0
|
|
|
|
for setting, expected in RECOMMENDED_SETTINGS.items():
|
|
total_checks += 1
|
|
actual = prefs.get(setting)
|
|
|
|
if actual == expected:
|
|
passed_checks += 1
|
|
findings["compliant"].append({
|
|
"setting": setting,
|
|
"expected": expected,
|
|
"actual": actual,
|
|
})
|
|
else:
|
|
findings["non_compliant"].append({
|
|
"setting": setting,
|
|
"expected": expected,
|
|
"actual": actual,
|
|
"severity": "high" if setting in (
|
|
"RealTimeProtectionEnabled", "AntivirusEnabled",
|
|
"EnableNetworkProtection", "MAPSReporting",
|
|
) else "medium",
|
|
})
|
|
|
|
asr_rules = settings.get("ASRRules", {})
|
|
for rule_guid, rule_info in RECOMMENDED_ASR_RULES.items():
|
|
total_checks += 1
|
|
mode = asr_rules.get(rule_guid)
|
|
|
|
if mode == 1:
|
|
passed_checks += 1
|
|
findings["asr_rules"]["enabled_block"].append({
|
|
"guid": rule_guid, "name": rule_info["name"],
|
|
})
|
|
elif mode == 2:
|
|
findings["asr_rules"]["enabled_audit"].append({
|
|
"guid": rule_guid, "name": rule_info["name"],
|
|
})
|
|
elif mode == 0:
|
|
findings["asr_rules"]["disabled"].append({
|
|
"guid": rule_guid, "name": rule_info["name"],
|
|
})
|
|
else:
|
|
findings["asr_rules"]["missing"].append({
|
|
"guid": rule_guid, "name": rule_info["name"],
|
|
})
|
|
|
|
if total_checks > 0:
|
|
findings["score"] = round((passed_checks / total_checks) * 100, 2)
|
|
|
|
return findings
|
|
|
|
|
|
def generate_report(settings: dict, findings: dict, output_path: str) -> None:
|
|
"""Generate configuration audit report."""
|
|
report = {
|
|
"report_generated": datetime.utcnow().isoformat() + "Z",
|
|
"defender_status": settings.get("Status", {}),
|
|
"compliance_score": findings["score"],
|
|
"total_compliant": len(findings["compliant"]),
|
|
"total_non_compliant": len(findings["non_compliant"]),
|
|
"asr_summary": {
|
|
"block_mode": len(findings["asr_rules"]["enabled_block"]),
|
|
"audit_mode": len(findings["asr_rules"]["enabled_audit"]),
|
|
"disabled": len(findings["asr_rules"]["disabled"]),
|
|
"not_configured": len(findings["asr_rules"]["missing"]),
|
|
},
|
|
"non_compliant_settings": findings["non_compliant"],
|
|
"asr_details": findings["asr_rules"],
|
|
}
|
|
|
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
json.dump(report, f, indent=2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
output_dir = sys.argv[1] if len(sys.argv) > 1 else "."
|
|
|
|
print("Collecting Microsoft Defender settings...")
|
|
settings = collect_defender_settings()
|
|
|
|
if "error" in settings:
|
|
print(f"Error: {settings['error']}")
|
|
print("This tool requires Windows with Microsoft Defender for Endpoint.")
|
|
sys.exit(1)
|
|
|
|
print("Auditing against recommended baseline...")
|
|
findings = audit_settings(settings)
|
|
|
|
report_path = os.path.join(output_dir, "defender_audit_report.json")
|
|
generate_report(settings, findings, report_path)
|
|
print(f"Audit report: {report_path}")
|
|
|
|
print(f"\n--- Defender Configuration Audit ---")
|
|
print(f"Compliance Score: {findings['score']}%")
|
|
print(f"Compliant settings: {len(findings['compliant'])}")
|
|
print(f"Non-compliant: {len(findings['non_compliant'])}")
|
|
print(f"\nASR Rules:")
|
|
print(f" Block mode: {len(findings['asr_rules']['enabled_block'])}")
|
|
print(f" Audit mode: {len(findings['asr_rules']['enabled_audit'])}")
|
|
print(f" Disabled: {len(findings['asr_rules']['disabled'])}")
|
|
print(f" Not configured: {len(findings['asr_rules']['missing'])}")
|
|
|
|
if findings["non_compliant"]:
|
|
print(f"\nNon-compliant settings requiring remediation:")
|
|
for item in findings["non_compliant"]:
|
|
print(f" [{item['severity'].upper()}] {item['setting']}: expected={item['expected']}, actual={item['actual']}")
|