Skip to main content

Overview

The CVE Lookup module (modules/cve_lookup.py) queries public CVE databases to identify known vulnerabilities in discovered services. It provides CVSS scoring, exploit availability checking, and risk assessment.

CVELookup Class

Defined at cve_lookup.py:13, this class handles all CVE database interactions.

Initialization

cve_lookup.py:14-18
class CVELookup:
    def __init__(self):
        """Initialize CVE lookup module"""
        self.cve_data = []
        self.api_url = "https://cve.circl.lu/api"
        self.nvd_api = "https://services.nvd.nist.gov/rest/json/cves/2.0"
CVE Data Sources:
  1. CVE CIRCL API (primary): Fast, no authentication required
  2. NVD API (fallback): National Vulnerability Database with detailed metrics

Key Methods

search_cve_by_product()

Searches CVE databases for vulnerabilities affecting a specific product and version.
cve_lookup.py:20-64
def search_cve_by_product(self, product, version=""):
    """Search for CVEs by product name and version"""
    # Clean product name
    product_clean = product.lower().strip()
    product_clean = re.sub(r'[^\w\s-]', '', product_clean)
    
    # Query CVE CIRCL API
    search_url = f"{self.api_url}/search/{product_clean}"
    response = requests.get(search_url, timeout=10)
    
    if response.status_code == 200:
        data = response.json()
        
        # Limit to top 10 most relevant results
        for cve_entry in data[:10]:
            cve_info = self.parse_cve_entry(cve_entry)
            
            # Filter by version if specified
            if version and self.version_matches(cve_entry, version):
                cves.append(cve_info)
            else:
                cves.append(cve_info)
    
    return cves
product
string
required
Product name (e.g., “apache”, “openssh”, “mysql”)
version
string
Product version for filtering results (e.g., “2.4.41”)

parse_cve_entry()

Extracts and normalizes CVE information from API responses.
cve_lookup.py:66-111
def parse_cve_entry(self, cve_entry):
    """Parse CVE entry and extract relevant information"""
    cve_id = cve_entry.get('id', 'Unknown')
    summary = cve_entry.get('summary', 'No description available')
    
    # Get CVSS score
    cvss_score = 0.0
    if 'cvss' in cve_entry:
        cvss_score = float(cve_entry.get('cvss', 0.0))
    elif 'impact' in cve_entry:
        if 'baseMetricV3' in cve_entry['impact']:
            cvss_score = float(cve_entry['impact']['baseMetricV3']['cvssV3']['baseScore'])
        elif 'baseMetricV2' in cve_entry['impact']:
            cvss_score = float(cve_entry['impact']['baseMetricV2']['cvssV2']['baseScore'])
    
    # Determine risk level
    risk_level = self.calculate_risk_level(cvss_score)
    
    # Check exploit availability
    exploitable = self.check_exploit_availability(cve_id, cve_entry)
    
    return {
        'cve_id': cve_id,
        'description': summary[:500],
        'cvss_score': cvss_score,
        'risk_level': risk_level,
        'published_date': published,
        'exploitable': exploitable,
        'references': cve_entry.get('references', [])[:3]
    }

CVSS Score Interpretation

calculate_risk_level()

Maps CVSS scores to risk severity levels.
cve_lookup.py:113-124
def calculate_risk_level(self, cvss_score):
    """Calculate risk level based on CVSS score"""
    if cvss_score >= 9.0:
        return "CRITICAL"
    elif cvss_score >= 7.0:
        return "HIGH"
    elif cvss_score >= 4.0:
        return "MEDIUM"
    elif cvss_score > 0.0:
        return "LOW"
    else:
        return "UNKNOWN"
CVSS v3 Severity Ratings:
Score RangeSeverityColorPriority
9.0 - 10.0CRITICALRedImmediate action required
7.0 - 8.9HIGHOrangeFix within 30 days
4.0 - 6.9MEDIUMYellowFix within 90 days
0.1 - 3.9LOWBlueFix when convenient
0.0INFORMATIONALGrayNo action needed

Exploit Detection

check_exploit_availability()

Determines if public exploits are available for a CVE.
cve_lookup.py:126-142
def check_exploit_availability(self, cve_id, cve_entry):
    """Check if exploit is publicly available"""
    # Check in CVE data
    if 'exploit-db' in str(cve_entry).lower():
        return True
    
    if 'metasploit' in str(cve_entry).lower():
        return True
    
    # Check references
    if 'references' in cve_entry:
        for ref in cve_entry['references']:
            ref_str = str(ref).lower()
            if any(keyword in ref_str for keyword in 
                ['exploit', 'poc', 'metasploit', 'exploit-db']):
                return True
    
    return False
Exploit Sources Checked:
  • Exploit-DB
  • Metasploit Framework
  • Proof-of-Concept (PoC) repositories
  • Security advisories with exploit code

Service CVE Lookup

lookup_services()

Looks up CVEs for all discovered services from port scan.
cve_lookup.py:160-185
def lookup_services(self, services):
    """Look up CVEs for list of services"""
    all_cves = []
    
    for service in services:
        port = service.get('port')
        service_name = service.get('service', '')
        version = service.get('version', '')
        
        # Skip generic services
        if not service_name or service_name in ['unknown', 'tcpwrapped']:
            continue
        
        # Search for CVEs
        cves = self.search_cve_by_product(service_name, version)
        
        # Attach port information
        for cve in cves:
            cve['port'] = port
            cve['service'] = service_name
            cve['version'] = version
            all_cves.append(cve)
    
    return all_cves
The module automatically skips generic services like “unknown” or “tcpwrapped” to reduce false positives.

Usage Example

from modules.cve_lookup import CVELookup
from modules.scanner import Scanner

# Get services from scan
scanner = Scanner("192.168.1.100")
scan_results = scanner.run_full_scan()

# Look up CVEs
cve_lookup = CVELookup()
cves = cve_lookup.lookup_services(scan_results['services'])

# Display results
for cve in cves:
    print(f"Port {cve['port']}: {cve['cve_id']}")
    print(f"  Service: {cve['service']} {cve['version']}")
    print(f"  CVSS: {cve['cvss_score']} ({cve['risk_level']})")
    print(f"  Exploitable: {cve['exploitable']}")
    print(f"  Description: {cve['description']}")

Output Format

[
  {
    "port": 22,
    "service": "ssh",
    "version": "OpenSSH 7.4",
    "cve_id": "CVE-2018-15473",
    "description": "OpenSSH through 7.7 allows remote attackers to enumerate users...",
    "cvss_score": 5.3,
    "risk_level": "MEDIUM",
    "published_date": "2018-08-17",
    "exploitable": true,
    "references": [
      "https://github.com/Rhynorater/CVE-2018-15473-Exploit",
      "https://nvd.nist.gov/vuln/detail/CVE-2018-15473"
    ]
  }
]

Rate Limiting

The module implements rate limiting to respect API usage policies:
cve_lookup.py:56-57
# Rate limiting between requests
time.sleep(1)  # 1 second delay per request
Excessive API requests may result in temporary IP blocking. The built-in rate limiting prevents this.

Configuration

CVE lookup settings in config.json:
config.json
{
  "cve_lookup": {
    "enabled": true,
    "api_url": "https://cve.circl.lu/api",
    "nvd_api_url": "https://services.nvd.nist.gov/rest/json/cves/2.0",
    "max_results_per_service": 10,
    "cache_results": true
  }
}
enabled
boolean
default:true
Enable/disable CVE lookup during scans
max_results_per_service
number
default:10
Maximum CVEs to return per service (prevents overwhelming results)
cache_results
boolean
default:true
Cache CVE data to reduce API calls

Error Handling

Requests timeout after 10 seconds. Returns empty results and continues scanning.
response = requests.get(search_url, timeout=10)
Returns empty list if no CVEs match the service/version.Common causes:
  • Service version too new (no CVEs yet)
  • Product name not in CVE database
  • Version string parsing failed
Catches connection errors and continues scan.
except requests.exceptions.RequestException as e:
    print(f"[!] CVE lookup failed: {e}")
    return []

Risk Engine

How CVE data is used in risk scoring

Exploit Engine

Matching CVEs to available exploits

PDF Reports

CVE information in generated reports

Configuration

CVE lookup settings

Build docs developers (and LLMs) love