Loading content...
Patching addresses vulnerabilities you know about. But how do you know what vulnerabilities exist in your environment in the first place? How do you find the unpatched systems, the misconfigured services, the exposed secrets, the deprecated cipher suites, the forgotten systems running end-of-life software?
This is the domain of Vulnerability Management—a continuous program for discovering, assessing, prioritizing, and remediating security weaknesses before adversaries exploit them.
Consider a typical enterprise environment:
Without systematic vulnerability management, security teams are blind to their exposure. They react to breaches rather than prevent them. They don't know which of their thousands of systems are vulnerable to the latest critical CVE. They can't answer basic questions like "Are we vulnerable to Log4Shell?" without days of manual investigation.
Vulnerability management transforms this chaos into visibility. It provides the asset inventory, vulnerability data, and prioritization intelligence needed to focus remediation efforts where they matter most.
By the end of this page, you will understand the vulnerability management lifecycle, master vulnerability scanning tools and techniques for both Linux and Windows systems, comprehend CVSS scoring and its limitations, develop risk-based prioritization strategies, and design vulnerability management programs that scale to enterprise environments.
Vulnerability management is a continuous cycle, not a one-time project. The cycle typically includes five phases that repeat indefinitely:
Phase 1: Asset Discovery and Inventory
You cannot protect what you don't know exists. Asset discovery identifies all systems in the environment—servers, workstations, network devices, cloud resources, containers, and applications. This inventory must be continuously updated as environments change.
Phase 2: Vulnerability Scanning
Automated scanners probe known assets for vulnerabilities. This includes missing patches, misconfigurations, weak credentials, exposed services, and known software flaws. Scanning technologies range from network-based probes to authenticated agent-based assessments.
Phase 3: Vulnerability Assessment
Raw scan results are noisy. Assessment filters false positives, correlates vulnerabilities with threat intelligence, and enriches findings with context: Is this system internet-facing? Does it hold sensitive data? Is there a known exploit?
Phase 4: Prioritization and Planning
Not all vulnerabilities can be fixed immediately. Prioritization ranks vulnerabilities by actual risk—considering severity, exploitability, asset criticality, and compensating controls. Remediation is planned according to priority and resource availability.
Phase 5: Remediation and Verification
Fixes are applied through patching, reconfiguration, architecture changes, or compensating controls. After remediation, rescanning verifies that vulnerabilities were successfully addressed. The cycle then repeats.
| Level | Characteristics | Coverage | Typical Metrics |
|---|---|---|---|
| Ad-Hoc | Reactive scanning after incidents; no regular schedule | < 25% of assets | No formal metrics |
| Managed | Scheduled scans; basic prioritization; manual remediation tracking | 50-75% of assets | Scan coverage, open vulns |
| Defined | Continuous scanning; risk-based prioritization; SLAs defined | 75-90% of assets | MTTR, SLA compliance |
| Measured | Full coverage; integrated with ITSM; metrics-driven improvement | 90% of assets | Risk reduction trending |
| Optimized | Continuous automated remediation; predictive prioritization | 95% of assets | Mean time to remediate < 7 days |
Multiple scanning methodologies exist, each with distinct capabilities and trade-offs. Comprehensive vulnerability management typically employs several approaches.
Network-Based Scanning
Network scanners probe systems remotely, identifying open ports, services, and known vulnerabilities. They simulate an external attacker's view but may miss vulnerabilities not exposed over the network.
Advantages: No agent installation required, can scan any reachable system Limitations: Limited visibility into local configurations, may trigger IDS alerts, incomplete view of patch levels
Authenticated/Credentialed Scanning
Scanners use provided credentials to log into systems and examine configurations, installed software, and patch levels. This provides much deeper visibility than network-only scanning.
Advantages: Detailed software inventory, accurate patch assessment, configuration checks Limitations: Credential management overhead, higher privilege requirements
Agent-Based Scanning
Lightweight agents installed on endpoints continuously collect vulnerability data and report to a central console. This provides the most complete and timely visibility.
Advantages: Continuous visibility, works for mobile/remote devices, lower network impact Limitations: Agent deployment and maintenance overhead, coverage gaps for unmanaged systems
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
#!/bin/bash# Vulnerability Scanning with OpenVAS/GVM (Greenbone Vulnerability Management)# Open-source enterprise vulnerability scanner # === Installation (Debian/Ubuntu) ===apt install gvm -y # Initial setup (creates certificates, downloads NVTs)gvm-setup # Check installationgvm-check-setup # === Command-line scanning with gvm-cli === # Create a target (define what to scan)gvm-cli socket --gmp-username admin --gmp-password admin --xml '<create_target> <name>Production Servers</name> <hosts>192.168.1.0/24</hosts> <port_list id="33d0cd82-57c6-11e1-8ed1-406186ea4fc5"/> <!-- All IANA --> </create_target>' # Get target ID from response, then create taskgvm-cli socket --gmp-username admin --gmp-password admin --xml '<create_task> <name>Weekly Production Scan</name> <target id="TARGET_ID"/> <config id="daba56c8-73ec-11df-a475-002264764cea"/> <!-- Full and fast --> <scanner id="08b69003-5fc2-4037-a479-93b440211c73"/> </create_task>' # Start the taskgvm-cli socket --gmp-username admin --gmp-password admin --xml '<start_task task_id="TASK_ID"/>' # Check task statusgvm-cli socket --gmp-username admin --gmp-password admin --xml '<get_tasks task_id="TASK_ID"/>' # Generate report in PDF formatgvm-cli socket --gmp-username admin --gmp-password admin --xml '<get_reports report_id="REPORT_ID" format_id="c402cc3e-b531-11e1-9163-406186ea4fc5"/>' # === Automating scans with cron ===cat > /usr/local/bin/scheduled-vuln-scan.sh << 'SCANSCRIPT'#!/bin/bash# Weekly vulnerability scan automation SCAN_TARGET="192.168.0.0/16"REPORT_EMAIL="security-team@example.com" # Trigger scan via APIgvm-cli socket --gmp-username admin --gmp-password admin --xml "<start_task task_id="$TASK_ID"/>" # Wait for completion (poll status)while true; do STATUS=$(gvm-cli socket --gmp-username admin --gmp-password admin --xml "<get_tasks task_id="$TASK_ID"/>" | grep -oP 'status="K[^"]+') [ "$STATUS" = "Done" ] && break sleep 300done # Generate and email reportgvm-cli socket --gmp-username admin --gmp-password admin --xml "<get_reports report_id="$REPORT_ID" format_id="c402cc3e-b531-11e1-9163-406186ea4fc5"/>" | base64 -d > /tmp/vuln-report.pdf mail -s "Weekly Vulnerability Report" -a /tmp/vuln-report.pdf $REPORT_EMAIL < /dev/nullSCANSCRIPT chmod +x /usr/local/bin/scheduled-vuln-scan.shecho "0 2 * * 0 root /usr/local/bin/scheduled-vuln-scan.sh" >> /etc/crontabApplication Security Scanning
Beyond infrastructure scanning, application security testing identifies vulnerabilities in custom code:
When selecting vulnerability scanners, consider: (1) Coverage—does it detect OS, application, and configuration vulnerabilities? (2) Accuracy—low false positive rates save analyst time. (3) Scalability—can it handle your environment size? (4) Integration—does it feed into your ticketing, SIEM, and reporting systems? (5) Compliance—does it provide reports for your regulatory requirements?
The Common Vulnerability Scoring System (CVSS) provides standardized severity ratings for vulnerabilities. Understanding CVSS is essential for interpreting scanner output and communicating vulnerability risk.
CVSS Structure (v3.1)
CVSS consists of three metric groups:
Base Score (0-10): Intrinsic characteristics of the vulnerability that are constant over time:
Temporal Score: Characteristics that change over time:
Environmental Score: Organization-specific adjustments:
| Score Range | Severity | Typical Remediation SLA | Example Vulnerabilities |
|---|---|---|---|
| 9.0-10.0 | Critical | 24-72 hours | Remote code execution, authentication bypass |
| 7.0-8.9 | High | 7 days | Privilege escalation, data disclosure |
| 4.0-6.9 | Medium | 30 days | Cross-site scripting, information leak |
| 0.1-3.9 | Low | 90 days | Denial of service, minor info disclosure |
| 0.0 | None/Informational | Best effort | Deprecated protocol, missing header |
CVSS Limitations
While CVSS provides valuable standardization, it has significant limitations for prioritization:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
#!/usr/bin/env python3"""CVSS Analysis and Risk-Adjusted PrioritizationDemonstrates how to enhance CVSS with contextual factors""" from dataclasses import dataclassfrom enum import Enumfrom typing import Optionalimport json class ExploitAvailability(Enum): NONE = 1.0 # No known exploit POC = 1.3 # Proof of concept exists FUNCTIONAL = 1.5 # Functional exploit exists WEAPONIZED = 2.0 # Actively exploited in the wild class AssetCriticality(Enum): LOW = 0.5 # Development, testing systems MEDIUM = 1.0 # Internal business applications HIGH = 1.5 # Customer-facing, business-critical CRITICAL = 2.0 # Core infrastructure, PII/financial data class NetworkExposure(Enum): INTERNAL = 0.7 # Internal network only VPN_ACCESSIBLE = 1.0 # Accessible via VPN DMZ = 1.3 # In DMZ INTERNET_FACING = 1.5 # Directly internet-accessible @dataclassclass Vulnerability: cve_id: str cvss_base: float description: str affected_assets: list exploit_status: ExploitAvailability = ExploitAvailability.NONE compensating_controls: bool = False @dataclassclass Asset: hostname: str ip_address: str criticality: AssetCriticality exposure: NetworkExposure data_classification: str owner: str def calculate_risk_adjusted_score( vuln: Vulnerability, asset: Asset) -> float: """ Calculate risk-adjusted vulnerability score considering context beyond base CVSS. Formula: Risk Score = CVSS Base × Exploit Factor × Asset Criticality × Exposure / Compensating Control Reduction """ base_score = vuln.cvss_base exploit_factor = vuln.exploit_status.value criticality_factor = asset.criticality.value exposure_factor = asset.exposure.value # Compensating controls reduce effective risk by 30% control_reduction = 0.7 if vuln.compensating_controls else 1.0 risk_score = ( base_score * exploit_factor * criticality_factor * exposure_factor * control_reduction ) # Cap at 10.0 for consistent scale return min(10.0, risk_score) def prioritize_vulnerabilities( vulnerabilities: list, assets: dict) -> list: """ Prioritize vulnerabilities by risk-adjusted score. Returns sorted list with remediation recommendations. """ prioritized = [] for vuln in vulnerabilities: for asset_hostname in vuln.affected_assets: asset = assets.get(asset_hostname) if not asset: continue risk_score = calculate_risk_adjusted_score(vuln, asset) # Determine SLA based on risk score if risk_score >= 9.0: sla = "24 hours" priority = "CRITICAL" elif risk_score >= 7.0: sla = "72 hours" priority = "HIGH" elif risk_score >= 5.0: sla = "7 days" priority = "MEDIUM" else: sla = "30 days" priority = "LOW" prioritized.append({ "cve": vuln.cve_id, "asset": asset_hostname, "cvss_base": vuln.cvss_base, "risk_adjusted_score": round(risk_score, 2), "priority": priority, "sla": sla, "exploit_status": vuln.exploit_status.name, "owner": asset.owner, }) # Sort by risk-adjusted score, highest first return sorted(prioritized, key=lambda x: x["risk_adjusted_score"], reverse=True) # Example usageif __name__ == "__main__": # Define assets with context assets = { "web-prod-01": Asset( hostname="web-prod-01", ip_address="10.0.1.10", criticality=AssetCriticality.CRITICAL, exposure=NetworkExposure.INTERNET_FACING, data_classification="PII", owner="web-team@example.com" ), "dev-server-01": Asset( hostname="dev-server-01", ip_address="10.0.100.50", criticality=AssetCriticality.LOW, exposure=NetworkExposure.INTERNAL, data_classification="None", owner="dev-team@example.com" ), } # Define vulnerabilities vulns = [ Vulnerability( cve_id="CVE-2024-1234", cvss_base=7.5, description="Remote code execution via deserialization", affected_assets=["web-prod-01", "dev-server-01"], exploit_status=ExploitAvailability.WEAPONIZED, ), Vulnerability( cve_id="CVE-2024-5678", cvss_base=9.8, description="Authentication bypass in admin interface", affected_assets=["dev-server-01"], exploit_status=ExploitAvailability.POC, ), ] # Prioritize results = prioritize_vulnerabilities(vulns, assets) print("\n=== Prioritized Vulnerability Remediation ===\n") for item in results: print(f"Priority: {item['priority']} | SLA: {item['sla']}") print(f" CVE: {item['cve']} (CVSS: {item['cvss_base']} → Risk: {item['risk_adjusted_score']})") print(f" Asset: {item['asset']}") print(f" Exploit Status: {item['exploit_status']}") print(f" Owner: {item['owner']}") print()Raw vulnerability data without threat context leads to poor prioritization. Integrating threat intelligence transforms vulnerability management from a technical exercise into a risk management function.
Types of Threat Intelligence for Vulnerability Management
1. Exploit Intelligence
2. Attack Pattern Intelligence
3. Indicator Intelligence
4. Patch Intelligence
| Source Type | Examples | Data Provided | Integration Method |
|---|---|---|---|
| Commercial TIP | Recorded Future, Mandiant, CrowdStrike | Exploit availability, threat actor tracking | API integration |
| Open Source | CISA KEV, Exploit-DB, NVD | Known exploited vulns, CVE details | Feed ingestion |
| Vendor Advisories | Microsoft, Red Hat, Cisco | Patch info, severity assessments | Manual/RSS |
| Community | Twitter/X, Reddit, security blogs | Early warning, POC releases | OSINT monitoring |
| Internal | SIEM, IDS, honeypots | Exploitation attempts against your org | Direct correlation |
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
#!/bin/bash# Integrate CISA Known Exploited Vulnerabilities (KEV) Catalog# KEV lists vulnerabilities with confirmed active exploitation KEV_URL="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"KEV_FILE="/var/lib/vuln-mgmt/kev.json"VULN_DB="/var/lib/vuln-mgmt/vulnerabilities.db" # Download latest KEV catalogcurl -sf "$KEV_URL" -o "$KEV_FILE.new" if [ $? -eq 0 ]; then mv "$KEV_FILE.new" "$KEV_FILE" echo "Updated KEV catalog: $(jq '.vulnerabilities | length' $KEV_FILE) entries"fi # Extract CVEs with due datesjq -r '.vulnerabilities[] | [.cveID, .vendorProject, .product, .dueDate] | @tsv' "$KEV_FILE" > /tmp/kev_cves.txt echo "=== CISA KEV Vulnerabilities Requiring Attention ==="echo "These have confirmed active exploitation and federal remediation deadlines"echo "" # Cross-reference with your vulnerability scan resultswhile IFS=$' ' read -r CVE VENDOR PRODUCT DUE_DATE; do # Query your vulnerability database for affected systems AFFECTED=$(sqlite3 "$VULN_DB" "SELECT hostname FROM scan_results WHERE cve='$CVE'") if [ -n "$AFFECTED" ]; then echo "CRITICAL: $CVE ($VENDOR $PRODUCT)" echo " Due Date: $DUE_DATE" echo " Affected Systems:" echo "$AFFECTED" | while read host; do echo " - $host" done echo "" fidone < /tmp/kev_cves.txt # Generate report of KEV vulnerabilities in environmentcat > /tmp/kev_report.json << EOF{ "report_date": "$(date -Iseconds)", "kev_catalog_date": "$(jq -r '.catalogVersion' $KEV_FILE)", "kev_count": $(jq '.vulnerabilities | length' $KEV_FILE), "affected_in_environment": [$(sqlite3 -json "$VULN_DB" " SELECT sr.cve, sr.hostname, sr.cvss, k.dueDate FROM scan_results sr JOIN ( SELECT value->>'cveID' as cve, value->>'dueDate' as dueDate FROM kev_catalog, json_each(vulnerabilities) ) k ON sr.cve = k.cve ORDER BY k.dueDate ASC") ]}EOF # Alert security team if KEV vulnerabilities existKEV_COUNT=$(jq '.affected_in_environment | length' /tmp/kev_report.json)if [ "$KEV_COUNT" -gt 0 ]; then mail -s "ALERT: $KEV_COUNT CISA KEV Vulnerabilities in Environment" security-team@example.com < /tmp/kev_report.jsonfiThe CISA Known Exploited Vulnerabilities catalog lists CVEs with confirmed active exploitation. Federal agencies are mandated to remediate these within specified timeframes (typically 2-3 weeks). All organizations should treat KEV entries as highest priority—they represent vulnerabilities that attackers are actively using right now.
A vulnerability's actual risk depends heavily on where it exists. The same CVE poses vastly different risks on an internet-facing production server versus an isolated development VM. Asset-based prioritization requires maintaining rich context about your environment.
Asset Classification Dimensions
Business Criticality
Data Sensitivity
Network Exposure
Compensating Controls
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
# Asset Classification Schema for Vulnerability Prioritization# This schema defines how assets should be tagged for risk calculations asset_classification: # Business Criticality Tiers criticality_tiers: tier1_critical: description: "Core infrastructure, customer-facing production" examples: - "Primary databases" - "Authentication systems" - "Payment processing" - "Customer web portals" remediation_sla_multiplier: 0.5 # Faster remediation required tier2_important: description: "Business-critical internal systems" examples: - "Internal applications" - "Secondary databases" - "Email servers" - "CI/CD infrastructure" remediation_sla_multiplier: 1.0 # Standard SLA tier3_standard: description: "Standard business systems" examples: - "Developer workstations" - "Printers and peripherals" - "Meeting room systems" remediation_sla_multiplier: 1.5 # Relaxed SLA tier4_low: description: "Non-critical, isolated systems" examples: - "Lab/sandbox environments" - "Test systems" - "Decommissioned systems pending removal" remediation_sla_multiplier: 3.0 # Best effort # Data Classification data_classifications: restricted: description: "Highly sensitive data with regulatory requirements" data_types: - "PII (Personally Identifiable Information)" - "PHI (Protected Health Information)" - "PCI (Payment Card Data)" - "Cryptographic keys" risk_multiplier: 2.0 confidential: description: "Internal sensitive data" data_types: - "Financial reports" - "Strategic plans" - "Employee records" - "Source code" risk_multiplier: 1.5 internal: description: "General internal data" data_types: - "Internal documentation" - "Non-sensitive configs" risk_multiplier: 1.0 public: description: "Data intended for public access" data_types: - "Marketing materials" - "Public documentation" risk_multiplier: 0.5 # Network Exposure exposure_zones: internet_facing: description: "Directly accessible from internet" network_segments: - "Public DMZ" - "CDN origin servers" exposure_multiplier: 2.0 dmz: description: "In DMZ with controlled internet access" network_segments: - "Application DMZ" - "Partner connectivity zone" exposure_multiplier: 1.5 internal_trusted: description: "Internal network, accessible to employees" network_segments: - "Corporate network" - "VPN-accessible" exposure_multiplier: 1.0 internal_restricted: description: "Restricted internal segments" network_segments: - "Management network" - "Backup network" exposure_multiplier: 0.7 isolated: description: "Air-gapped or highly restricted" network_segments: - "Isolated lab" - "Offline backup" exposure_multiplier: 0.3 # Example Asset Recordsample_asset: hostname: "prod-db-master-01" ip_addresses: - "10.0.1.50" classification: criticality: tier1_critical data_classification: restricted exposure_zone: internal_restricted attributes: os: "Red Hat Enterprise Linux 8" function: "Primary PostgreSQL database" owner: "database-team@example.com" environment: "production" compensating_controls: - "WAF in front of application tier" - "Database firewall active" - "Privileged access management enforced" - "Continuous backup with tested recovery"Not every vulnerability can or should be patched immediately. Effective vulnerability management employs multiple remediation strategies based on risk, feasibility, and resources.
Primary Remediation: Patching
Patching remains the gold standard for vulnerability remediation. Apply vendor patches to eliminate the vulnerability. However, patching isn't always immediately feasible due to:
Alternative Remediation Strategies
| Strategy | When to Use | Risk Reduction | Limitations |
|---|---|---|---|
| Patching | Patch available and tested | Complete (eliminates vuln) | Requires testing, may cause regression |
| Configuration Hardening | Vulnerability due to misconfiguration | Complete (if properly configured) | May break functionality |
| Virtual Patching (WAF/IPS) | Patch unavailable or delayed | High (blocks known exploits) | Zero-days may bypass, ongoing maintenance |
| Network Segmentation | Limit exposure of vulnerable systems | Medium (reduces access) | Doesn't fix underlying issue |
| Feature Disabling | Vulnerable feature not needed | Complete (for that feature) | May impact functionality |
| Upgrade/Replace | End-of-life systems, unsupported software | Complete (new version) | Expensive, time-consuming |
| Accept Risk | Low-risk scenarios, cost-prohibitive fixes | None | Documented, time-bounded, reviewed |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
#!/usr/bin/env python3"""Vulnerability Remediation Workflow AutomationIntegrates vulnerability data, determines remediation strategy,and creates actionable work items""" from dataclasses import dataclassfrom datetime import datetime, timedeltafrom enum import Enumfrom typing import List, Optionalimport json class RemediationStrategy(Enum): PATCH = "patch" VIRTUAL_PATCH = "virtual_patch" CONFIGURATION = "configuration" NETWORK_ISOLATION = "network_isolation" DISABLE_FEATURE = "disable_feature" UPGRADE = "upgrade" ACCEPT_RISK = "accept_risk" class TicketPriority(Enum): P1_CRITICAL = 1 P2_HIGH = 2 P3_MEDIUM = 3 P4_LOW = 4 @dataclassclass RemediationPlan: cve_id: str asset_hostname: str strategy: RemediationStrategy priority: TicketPriority due_date: datetime steps: List[str] owner: str fallback_strategy: Optional[RemediationStrategy] = None def determine_remediation_strategy( vuln: dict, asset: dict, patch_available: bool, patch_tested: bool) -> RemediationStrategy: """ Decision logic for selecting remediation strategy based on vulnerability and asset context. """ # Prefer patching if patch is available and tested if patch_available and patch_tested: return RemediationStrategy.PATCH # Virtual patching as bridge while testing if patch_available and not patch_tested: return RemediationStrategy.VIRTUAL_PATCH # For EOL systems, recommend upgrade if asset.get("end_of_support"): return RemediationStrategy.UPGRADE # Check if vulnerable feature can be disabled if vuln.get("affected_component") and not asset.get("requires_" + vuln["affected_component"]): return RemediationStrategy.DISABLE_FEATURE # Network isolation as fallback if asset.get("can_be_isolated"): return RemediationStrategy.NETWORK_ISOLATION # Configuration-based mitigation if vuln.get("config_workaround"): return RemediationStrategy.CONFIGURATION # If truly no options and low risk, consider acceptance if vuln.get("cvss_base", 10) < 4.0 and not vuln.get("actively_exploited"): return RemediationStrategy.ACCEPT_RISK # Default to virtual patching while awaiting options return RemediationStrategy.VIRTUAL_PATCH def calculate_due_date( priority: TicketPriority, asset_tier: str) -> datetime: """ Calculate remediation due date based on priority and asset tier. """ base_sla_days = { TicketPriority.P1_CRITICAL: 1, TicketPriority.P2_HIGH: 7, TicketPriority.P3_MEDIUM: 30, TicketPriority.P4_LOW: 90, } tier_multipliers = { "tier1_critical": 0.5, "tier2_important": 1.0, "tier3_standard": 1.5, "tier4_low": 2.0, } base_days = base_sla_days.get(priority, 30) multiplier = tier_multipliers.get(asset_tier, 1.0) return datetime.now() + timedelta(days=int(base_days * multiplier)) def generate_remediation_steps( strategy: RemediationStrategy, vuln: dict, asset: dict) -> List[str]: """ Generate specific remediation steps based on strategy. """ cve = vuln["cve_id"] hostname = asset["hostname"] steps_templates = { RemediationStrategy.PATCH: [ f"Download patch for {cve} from vendor", f"Test patch in staging environment", f"Schedule maintenance window for {hostname}", f"Apply patch: {vuln.get('patch_command', 'See vendor advisory')}", f"Verify patch applied: {vuln.get('verify_command', 'Check version')}", f"Monitor for issues for 24 hours", f"Re-scan to confirm vulnerability resolved", ], RemediationStrategy.VIRTUAL_PATCH: [ f"Create WAF/IPS rule to block {cve} exploit patterns", f"Deploy rule to production WAF/IPS", f"Verify blocking with test payload", f"Monitor for false positives", f"Schedule patching to replace virtual patch", ], RemediationStrategy.CONFIGURATION: [ f"Review configuration workaround for {cve}", f"Test configuration change in staging", f"Apply configuration change to {hostname}", f"Verify functionality after change", f"Document configuration modification", ], RemediationStrategy.NETWORK_ISOLATION: [ f"Identify minimum required network access for {hostname}", f"Create firewall rules to restrict access", f"Apply network segmentation", f"Test application functionality", f"Document isolation as temporary measure", ], RemediationStrategy.UPGRADE: [ f"Plan upgrade/replacement for {hostname}", f"Procure new system or licenses", f"Build replacement system", f"Migrate services and data", f"Decommission vulnerable system", ], } return steps_templates.get(strategy, [f"Develop custom remediation plan for {cve}"]) def create_remediation_ticket(plan: RemediationPlan) -> dict: """ Generate ticket content for ITSM integration (ServiceNow, Jira, etc.) """ return { "title": f"[{plan.priority.name}] Remediate {plan.cve_id} on {plan.asset_hostname}", "priority": plan.priority.value, "type": "Security Vulnerability", "assignee": plan.owner, "due_date": plan.due_date.isoformat(), "description": f"""## Vulnerability Details- **CVE**: {plan.cve_id}- **Affected Asset**: {plan.asset_hostname}- **Remediation Strategy**: {plan.strategy.value}- **Due Date**: {plan.due_date.strftime('%Y-%m-%d')} ## Remediation Steps{chr(10).join(f'{i+1}. {step}' for i, step in enumerate(plan.steps))} ## Fallback Strategy{plan.fallback_strategy.value if plan.fallback_strategy else 'N/A'} ## Acceptance Criteria- Vulnerability no longer detected in subsequent scan- No regression in system functionality- Documentation updated if configuration changed """, "labels": ["security", "vulnerability", plan.strategy.value], } # Example executionif __name__ == "__main__": # Sample vulnerability finding vuln = { "cve_id": "CVE-2024-1234", "cvss_base": 9.8, "affected_component": "smbv1", "patch_command": "yum update samba -y", "verify_command": "rpm -q samba", } # Sample asset asset = { "hostname": "fileserver-01", "tier": "tier2_important", "owner": "infra-team@example.com", "can_be_isolated": True, "requires_smbv1": False, } # Determine strategy strategy = determine_remediation_strategy( vuln, asset, patch_available=True, patch_tested=False ) # Generate plan plan = RemediationPlan( cve_id=vuln["cve_id"], asset_hostname=asset["hostname"], strategy=strategy, priority=TicketPriority.P1_CRITICAL, due_date=calculate_due_date(TicketPriority.P1_CRITICAL, asset["tier"]), steps=generate_remediation_steps(strategy, vuln, asset), owner=asset["owner"], fallback_strategy=RemediationStrategy.NETWORK_ISOLATION, ) # Create ticket ticket = create_remediation_ticket(plan) print(json.dumps(ticket, indent=2))A vulnerability management program needs metrics to demonstrate effectiveness, identify improvement areas, and communicate risk to leadership.
Key Performance Indicators (KPIs)
| Metric | Definition | Target Range | Why It Matters |
|---|---|---|---|
| Scan Coverage | % of assets scanned in last 30 days | 95% | Unscanned assets have unknown risk |
| Mean Time to Remediate (MTTR) | Average days from detection to fix | < 30 days (critical < 7) | Speed of reducing exposure |
| SLA Compliance | % of vulns remediated within SLA | 90% | Policy adherence |
| Vulnerability Age | Average age of open vulnerabilities | < 45 days | Prevents accumulation of risk debt |
| Recurrence Rate | % of vulns that reappear after fix | < 5% | Fix quality and root cause addressing |
| Critical/High Open Count | Number of severe vulns currently open | Trending down | Absolute risk exposure |
| Risk Score Trend | Aggregate risk score over time | Stable or decreasing | Overall program effectiveness |
Communicating to Leadership
Technical metrics must be translated into business risk for executive communication:
Instead of: "We have 5,000 open vulnerabilities"
Say: "Our internet-facing systems have 12 critical vulnerabilities with known exploits; remediation is 80% complete and on track for this week"
Instead of: "Our MTTR is 25 days"
Say: "We're fixing vulnerabilities faster than they're being discovered, reducing our exposure window by 40% over last quarter"
Program Maturity Evolution
Vulnerability management programs should evolve from reactive to proactive:
The absolute number of vulnerabilities in a large environment will always be high. What matters is the trend: Are we getting better or worse? Is the backlog growing or shrinking? Are critical vulnerabilities being addressed faster? Trending metrics over time tell a more meaningful story than point-in-time counts.
Vulnerability management transforms security from reactive firefighting to proactive risk reduction. It provides visibility, prioritization, and process for systematically reducing an organization's attack surface. Let us consolidate the essential principles.
Looking Ahead
Vulnerability management identifies weaknesses; Security Hardening proactively reduces them. The next and final page explores hardening practices—configurations and architectures that eliminate unnecessary attack surface before vulnerabilities even appear.
You now understand vulnerability management as a comprehensive program: the lifecycle of discovery through remediation, scanning technologies and their integration, CVSS interpretation and enrichment with threat intelligence, asset-based prioritization, remediation strategy selection, and program metrics. This capability enables proactive security rather than reactive incident response.