Skip to main content

Overview

The Risk Analysis System provides automated security risk assessment based on audit findings. The RiskAnalyzer evaluates vulnerabilities, exposed services, and network configuration to calculate an overall risk score and classify targets into four severity levels.

RiskAnalyzer Class

The risk analyzer is implemented as a static utility class in services/risk_analyzer.py:
services/risk_analyzer.py
from models.host import Host
from models.vuln import RiskLevel

class RiskAnalyzer:
    @staticmethod
    def analyze(host: Host):
        score = 0
        
        # Vulnerabilities scoring
        critical = sum(1 for v in host.vulnerabilities if v.risk == RiskLevel.CRITICAL)
        score += critical * 30
        
        # Dangerous ports scoring
        dangerous = {21, 22, 23, 25, 53, 80, 110, 143, 443, 993, 995, 3306, 5432, 5900}
        exposed = sum(1 for p in host.ports_open if p in dangerous)
        score += exposed * 8
        
        # HTTP exposure scoring
        http = sum(1 for s in host.ports_open.values() if 'http' in s['service'].lower())
        score += http * 10
        
        # Risk level classification
        if score >= 60:
            host.risk_level = RiskLevel.CRITICAL
        elif score >= 30:
            host.risk_level = RiskLevel.HIGH
        elif score >= 10:
            host.risk_level = RiskLevel.MEDIUM
        else:
            host.risk_level = RiskLevel.LOW
        
        print(f"   🎯 RIESGO: {host.risk_level.value} (Score: {score}/100)")

Scoring Algorithm

The risk score is calculated using a weighted multi-factor algorithm that considers three primary dimensions:

1. Critical Vulnerabilities (Weight: 30 points each)

The most significant risk factor is the presence of critical vulnerabilities.
critical = sum(1 for v in host.vulnerabilities if v.risk == RiskLevel.CRITICAL)
score += critical * 30
Scoring examples:
  • 0 critical vulns: +0 points
  • 1 critical vuln: +30 points (immediately elevates to HIGH risk minimum)
  • 2 critical vulns: +60 points (immediately CRITICAL risk)
  • 3+ critical vulns: +90+ points (maximum CRITICAL risk)
A single CRITICAL vulnerability contributes 30 points, which alone classifies the system as HIGH risk. Two or more CRITICAL vulnerabilities guarantee CRITICAL risk classification.
What counts as CRITICAL?
  • SQL injection with database access
  • Remote code execution vulnerabilities
  • Authentication bypass
  • Exposed credentials in plaintext
  • Unpatched vulnerabilities with known exploits

2. Dangerous Port Exposure (Weight: 8 points each)

Exposed network services increase the attack surface.
dangerous = {21, 22, 23, 25, 53, 80, 110, 143, 443, 993, 995, 3306, 5432, 5900}
exposed = sum(1 for p in host.ports_open if p in dangerous)
score += exposed * 8
Dangerous port categories:
PortServiceRisk Reason
21FTPUnencrypted file transfer, often misconfigured
22SSHBrute-force target, lateral movement vector
23TelnetUnencrypted remote access (extreme risk)
25SMTPEmail relay abuse, spam vector
53DNSDNS amplification attacks, zone transfer leaks
80HTTPWeb vulnerabilities, unencrypted communication
110POP3Unencrypted email access
143IMAPUnencrypted email access
443HTTPSWeb application vulnerabilities
993IMAPSEncrypted email (lower risk but still attack surface)
995POP3SEncrypted email (lower risk but still attack surface)
3306MySQLDirect database access, data exfiltration
5432PostgreSQLDirect database access, data exfiltration
5900VNCRemote desktop access, often weak passwords
Scoring examples:
  • 1 dangerous port (e.g., only HTTPS): +8 points
  • 3 dangerous ports (SSH, HTTP, MySQL): +24 points
  • 6 dangerous ports (SSH, HTTP, HTTPS, MySQL, FTP, Telnet): +48 points
Even without vulnerabilities, exposing 8+ dangerous ports (64 points) results in CRITICAL risk classification due to excessive attack surface.

3. HTTP Service Exposure (Weight: 10 points each)

Web services represent high-value attack targets.
http = sum(1 for s in host.ports_open.values() if 'http' in s['service'].lower())
score += http * 10
Counted HTTP services:
  • http (port 80)
  • https (port 443)
  • http-proxy (ports 8080, 3128)
  • http-alt (port 8008)
  • Any service containing “http” in its name
Scoring examples:
  • 1 HTTP service: +10 points
  • 2 HTTP services (HTTP + HTTPS): +20 points
  • 3+ HTTP services: +30+ points
HTTP services receive additional weight beyond the dangerous ports score because web applications are the most common attack vector in modern networks.

Risk Level Classification

The final risk level is determined by score thresholds:
if score >= 60:
    host.risk_level = RiskLevel.CRITICAL
elif score >= 30:
    host.risk_level = RiskLevel.HIGH
elif score >= 10:
    host.risk_level = RiskLevel.MEDIUM
else:
    host.risk_level = RiskLevel.LOW

Risk Level Definitions

🔴 CRITICAL

Score: 60-100+Immediate action required. System is highly vulnerable with multiple critical issues or excessive exposure.Typical conditions:
  • 2+ critical vulnerabilities
  • 1 critical vuln + 4+ dangerous ports
  • 8+ dangerous ports exposed
  • Database + web + SSH all exposed with vulns

🟠 HIGH

Score: 30-59Significant security concerns requiring prompt remediation. Single critical vulnerability or multiple high-severity issues.Typical conditions:
  • 1 critical vulnerability
  • 4-7 dangerous ports exposed
  • Multiple HIGH severity vulnerabilities
  • Database directly accessible from network

🟡 MEDIUM

Score: 10-29Moderate risk with some security gaps. Should be addressed in next security sprint.Typical conditions:
  • 2-3 dangerous ports exposed
  • Web services without critical vulnerabilities
  • MEDIUM severity vulnerabilities present
  • Standard web server configuration

🟢 LOW

Score: 0-9Minimal security concerns. System follows security best practices.Typical conditions:
  • 0-1 dangerous ports exposed
  • No exploitable vulnerabilities found
  • Services properly configured
  • Only encrypted protocols used

Real Scoring Examples

Example 1: Vulnerable Web Server

Configuration:
  • Ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 3306 (MySQL)
  • Vulnerabilities: SQL injection (CRITICAL)
Score calculation:
critical_vulns = 1  # SQL injection
score += 1 * 30     # = 30

dangerous_ports = 4  # SSH, HTTP, HTTPS, MySQL
score += 4 * 8       # = 32

http_services = 2    # HTTP, HTTPS
score += 2 * 10      # = 20

total_score = 30 + 32 + 20 = 82
risk_level = CRITICAL  # score >= 60
Output:
🎯 RIESGO: 🔴 CRÍTICO (Score: 82/100)

Example 2: Hardened Server

Configuration:
  • Ports: 443 (HTTPS) only
  • Vulnerabilities: None
Score calculation:
critical_vulns = 0
score += 0 * 30     # = 0

dangerous_ports = 1  # Only HTTPS
score += 1 * 8       # = 8

http_services = 1    # HTTPS
score += 1 * 10      # = 10

total_score = 0 + 8 + 10 = 18
risk_level = MEDIUM  # 10 <= score < 30
Output:
🎯 RIESGO: 🟡 MEDIO (Score: 18/100)

Example 3: DVWA Lab Environment

Configuration:
  • Ports: 22 (SSH), 80 (HTTP), 3306 (MySQL)
  • Vulnerabilities:
    • SQL injection (CRITICAL)
    • WordPress weak passwords (HIGH)
    • Outdated Apache (MEDIUM)
Score calculation:
critical_vulns = 1  # SQL injection (WordPress and Apache don't count as CRITICAL)
score += 1 * 30     # = 30

dangerous_ports = 3  # SSH, HTTP, MySQL
score += 3 * 8       # = 24

http_services = 1    # HTTP
score += 1 * 10      # = 10

total_score = 30 + 24 + 10 = 64
risk_level = CRITICAL  # score >= 60
Output:
🎯 RIESGO: 🔴 CRÍTICO (Score: 64/100)

Example 4: Minimal Exposure

Configuration:
  • Ports: None (firewall blocking all)
  • Vulnerabilities: None
Score calculation:
critical_vulns = 0
score += 0 * 30     # = 0

dangerous_ports = 0
score += 0 * 8      # = 0

http_services = 0
score += 0 * 10     # = 0

total_score = 0
risk_level = LOW  # score < 10
Output:
🎯 RIESGO: 🟢 BAJO (Score: 0/100)

Integration with Audit Engine

The risk analyzer runs as Phase 6 of the audit workflow:
audit_engine.py
# After all attack phases complete
rprint(f"\n[bold cyan]FASE 6: 🎯 ANÁLISIS DE RIESGO[/bold cyan]")
RiskAnalyzer.analyze(self.host)

# Risk level is now set and used in reporting
rprint(f"Risk Level: {self.host.risk_level.value}")
Timeline:
  1. Phases 1-4 populate host.vulnerabilities and host.ports_open
  2. Phase 6 analyzes accumulated data
  3. host.risk_level is set
  4. PDF report uses risk level for color coding and recommendations

Usage in Risk-Based Decision Making

The risk level drives automated decision-making throughout the framework:

Report Color Coding

reporter/pdf_generator.py
# Risk level determines report styling
if host.risk_level == RiskLevel.CRITICAL:
    color = HexColor('#e74c3c')  # Red
elif host.risk_level == RiskLevel.HIGH:
    color = HexColor('#e67e22')  # Orange
elif host.risk_level == RiskLevel.MEDIUM:
    color = HexColor('#f39c12')  # Yellow
else:
    color = HexColor('#27ae60')  # Green

Prioritized Recommendations

CRITICAL and HIGH risk systems receive more urgent recommendations in the PDF report.

Automated Alerting

Extend the analyzer for automated notifications:
if host.risk_level in [RiskLevel.CRITICAL, RiskLevel.HIGH]:
    send_alert(f"High-risk system detected: {host.ip}")
    escalate_to_security_team(host)

Customizing the Risk Algorithm

Modify services/risk_analyzer.py to adjust weights and thresholds:

Adjusting Weights

# Increase weight of critical vulnerabilities
score += critical * 50  # Changed from 30

# Add weight for credentials found
if len(host.credentials) > 0:
    score += len(host.credentials) * 15

Custom Dangerous Ports

# Add custom services to dangerous list
dangerous = {
    21, 22, 23, 25, 53, 80, 110, 143, 443, 993, 995,
    3306, 5432, 5900,
    6379,  # Redis
    27017,  # MongoDB
    9200,   # Elasticsearch
}

Modified Thresholds

# More conservative risk classification
if score >= 50:      # Changed from 60
    host.risk_level = RiskLevel.CRITICAL
elif score >= 25:    # Changed from 30
    host.risk_level = RiskLevel.HIGH
elif score >= 8:     # Changed from 10
    host.risk_level = RiskLevel.MEDIUM
else:
    host.risk_level = RiskLevel.LOW

Vulnerability Risk Classification

Vulnerabilities are classified during discovery:
services/sqlmap_inject.py
# SQL injection is always CRITICAL
vuln = Vulnerability(
    name="SQL Injection - DVWA",
    description="Parameter 'id' is vulnerable to SQL injection",
    port=80,
    risk=RiskLevel.CRITICAL,  # Affects overall risk score
    recommendations="Use prepared statements"
)
Common vulnerability classifications:
Vulnerability TypeTypical Risk Level
SQL InjectionCRITICAL
Remote Code ExecutionCRITICAL
Authentication BypassCRITICAL
Weak Credentials (brute-forced)HIGH
Outdated Software with Known ExploitsHIGH
Information DisclosureMEDIUM
Missing Security HeadersLOW

Limitations and Considerations

The risk analysis system has important limitations:
  • No business context: Doesn’t consider asset value or business criticality
  • Point-in-time: Risk score reflects findings at audit time, not ongoing risk
  • Limited scope: Only analyzes tested attack vectors, not all possible threats
  • No false positive filtering: Assumes all reported vulnerabilities are valid
  • Network-centric: Doesn’t account for application logic flaws or social engineering

Best Practices

  1. Combine with manual review: Use automated risk scores as input, not final decision
  2. Context matters: CRITICAL risk on a test server differs from production database
  3. Trend analysis: Track risk scores over time to measure security posture improvement
  4. Validate findings: Confirm vulnerabilities before taking drastic action
  5. Customize weights: Adjust algorithm to match your organization’s risk tolerance

Future Enhancements

Potential improvements to the risk analysis system:
  • CVSS integration: Use standard CVSS scores for vulnerability weighting
  • Asset tagging: Multiply risk scores based on asset criticality
  • Exploitability assessment: Weight by availability of public exploits
  • Compensating controls: Reduce score if WAF, IDS, or other defenses detected
  • Compliance mapping: Flag specific compliance violations (PCI-DSS, HIPAA)
  • Machine learning: Train models on historical audit data for improved accuracy

Build docs developers (and LLMs) love