vulnerability management

Implementing Vulnerability Management with Greenbone

Deploy and operate Greenbone/OpenVAS vulnerability management using the python-gvm library to create scan targets, execute vulnerability scans, and parse scan reports via GMP protocol.

compliancegmpgreenboneopenvaspython-gvmvulnerability-managementvulnerability-scanning
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Greenbone Vulnerability Management (GVM) is the open-source framework behind OpenVAS, providing comprehensive vulnerability scanning with over 100,000 Network Vulnerability Tests (NVTs). The python-gvm library provides a Python API to interact with GVM through the Greenbone Management Protocol (GMP), enabling programmatic creation of scan targets, task management, scan execution, and report retrieval. This skill covers connecting to GVM via Unix socket or TLS, authenticating, creating scan configs and targets, launching scans, and parsing XML-based vulnerability reports to produce actionable findings.

When to Use

  • When deploying or configuring implementing vulnerability management with greenbone capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Greenbone Community Edition or Greenbone Enterprise Appliance installed
  • Python 3.9+ with python-gvm (pip install python-gvm)
  • GMP access credentials (username/password)
  • Network connectivity to GVM daemon (Unix socket or TCP/TLS)
  • Understanding of CVSS scoring and vulnerability classification

Steps

  1. Install python-gvm: pip install python-gvm
  2. Establish a GMP connection via UnixSocketConnection or TLSConnection
  3. Authenticate with gmp.authenticate(username, password)
  4. Create a target with gmp.create_target(name, hosts=[...], port_list_id=...)
  5. Create a scan task with gmp.create_task(name, config_id, target_id, scanner_id)
  6. Start the scan with gmp.start_task(task_id)
  7. Monitor scan progress with gmp.get_task(task_id)
  8. Retrieve results with gmp.get_report(report_id, report_format_id=...)
  9. Parse the XML report for vulnerabilities, CVSS scores, and affected hosts
  10. Generate a JSON summary report with severity distribution and remediation priorities

Expected Output

A JSON report containing total vulnerabilities found, severity breakdown (critical/high/medium/low), per-host findings with CVE references and CVSS scores, and scan metadata including duration and NVT feed version.

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

api-reference.md2.5 KB

Greenbone/OpenVAS python-gvm API Reference

Installation

pip install python-gvm

Connection Setup

from gvm.connections import UnixSocketConnection, TLSConnection
from gvm.protocols.gmp import Gmp
from gvm.transforms import EtreeTransform
 
# Unix socket (local)
conn = UnixSocketConnection(path="/run/gvmd/gvmd.sock")
# TLS (remote)
conn = TLSConnection(hostname="gvm-host", port=9390)
 
transform = EtreeTransform()
with Gmp(connection=conn, transform=transform) as gmp:
    gmp.authenticate("admin", "password")
    version = gmp.get_version()

Core GMP API Methods

Method Description
gmp.authenticate(username, password) Authenticate to GVM
gmp.get_version() Get GMP protocol version
gmp.create_target(name, hosts, port_list_id) Create scan target
gmp.create_task(name, config_id, target_id, scanner_id) Create scan task
gmp.start_task(task_id) Start a scan task
gmp.get_task(task_id) Get task status/progress
gmp.get_tasks() List all scan tasks
gmp.get_report(report_id, report_format_id) Retrieve scan report
gmp.get_reports() List all reports
gmp.get_results(filter_string) Get vulnerability results

Default Resource IDs

Resource ID Description
Port List (All IANA TCP) 33d0cd82-57c6-11e1-8ed1-406186ea4fc5 All IANA assigned TCP ports
Scan Config (Full and fast) daba56c8-73ec-11df-a475-002264764cea Full and fast scan
Scanner (OpenVAS Default) 08b69003-5fc2-4037-a479-93b440211c73 Default OpenVAS scanner
Report Format (XML) a994b278-1f62-11e1-96ac-406186ea4fc5 XML report format

Report XML Structure

<report>
  <results>
    <result>
      <host>192.168.1.10</host>
      <name>SSL/TLS Certificate Expired</name>
      <threat>High</threat>
      <severity>7.5</severity>
      <nvt oid="1.3.6.1.4.1.25623.1.0.103955">
        <cve>CVE-2024-12345</cve>
      </nvt>
      <description>The SSL certificate has expired...</description>
    </result>
  </results>
</report>

CLI Usage

python agent.py --input scan_results.json --output report.json
python agent.py --input scan_results.json --host gvm-server --username admin --password secret

References

Scripts 1

agent.py5.9 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Greenbone/OpenVAS Vulnerability Management agent - creates scan targets, executes scans, and parses reports via python-gvm GMP protocol"""

import argparse
import json
from collections import Counter, defaultdict
from datetime import datetime
from pathlib import Path

try:
    from gvm.connections import UnixSocketConnection, TLSConnection
    from gvm.protocols.gmp import Gmp
    from gvm.transforms import EtreeTransform
    HAS_GVM = True
except ImportError:
    HAS_GVM = False


def load_data(path):
    return json.loads(Path(path).read_text(encoding="utf-8"))


def connect_gvm(host, port=9390, socket_path="/run/gvmd/gvmd.sock", use_tls=False, username="admin", password="admin"):
    """Connect to GVM daemon and authenticate via GMP."""
    if not HAS_GVM:
        return None, "python-gvm not installed"
    transform = EtreeTransform()
    if use_tls:
        conn = TLSConnection(hostname=host, port=port)
    else:
        conn = UnixSocketConnection(path=socket_path)
    gmp = Gmp(connection=conn, transform=transform)
    gmp.authenticate(username, password)
    version_resp = gmp.get_version()
    version = version_resp.xpath("version/text()")[0] if version_resp.xpath("version/text()") else "unknown"
    return gmp, version


def create_target(gmp, name, hosts, port_list_id="33d0cd82-57c6-11e1-8ed1-406186ea4fc5"):
    """Create a scan target. Default port list is 'All IANA assigned TCP'."""
    resp = gmp.create_target(name=name, hosts=hosts, port_list_id=port_list_id)
    target_id = resp.get("id", "")
    return target_id


def create_and_start_task(gmp, task_name, target_id, config_id="daba56c8-73ec-11df-a475-002264764cea", scanner_id="08b69003-5fc2-4037-a479-93b440211c73"):
    """Create scan task and start it. Default config is 'Full and fast', default scanner is 'OpenVAS Default'."""
    resp = gmp.create_task(name=task_name, config_id=config_id, target_id=target_id, scanner_id=scanner_id)
    task_id = resp.get("id", "")
    gmp.start_task(task_id)
    return task_id


def parse_report_xml(report_xml):
    """Parse GMP report XML into structured findings."""
    findings = []
    results = report_xml.findall(".//result") if report_xml is not None else []
    for result in results:
        host_el = result.find("host")
        host = host_el.text if host_el is not None else ""
        name_el = result.find("name")
        name = name_el.text if name_el is not None else ""
        threat_el = result.find("threat")
        threat = threat_el.text if threat_el is not None else "Log"
        severity_el = result.find("severity")
        cvss = float(severity_el.text) if severity_el is not None and severity_el.text else 0.0
        nvt = result.find("nvt")
        oid = nvt.get("oid", "") if nvt is not None else ""
        cve_el = nvt.find("cve") if nvt is not None else None
        cve = cve_el.text if cve_el is not None and cve_el.text != "NOCVE" else ""
        desc_el = result.find("description")
        desc = (desc_el.text or "")[:200] if desc_el is not None else ""
        sev_label = "critical" if cvss >= 9.0 else "high" if cvss >= 7.0 else "medium" if cvss >= 4.0 else "low"
        findings.append({
            "host": host,
            "vulnerability": name,
            "severity": sev_label,
            "cvss": cvss,
            "cve": cve,
            "nvt_oid": oid,
            "description": desc,
        })
    return findings


def analyze_offline_report(data):
    """Analyze pre-exported GVM report data (JSON format)."""
    findings = []
    results = data.get("results", data.get("vulnerabilities", []))
    if isinstance(data, list):
        results = data
    for r in results:
        cvss = r.get("cvss", r.get("severity_score", 0.0))
        if isinstance(cvss, str):
            try:
                cvss = float(cvss)
            except ValueError:
                cvss = 0.0
        sev_label = "critical" if cvss >= 9.0 else "high" if cvss >= 7.0 else "medium" if cvss >= 4.0 else "low"
        findings.append({
            "host": r.get("host", r.get("ip", "")),
            "vulnerability": r.get("name", r.get("vulnerability", "")),
            "severity": sev_label,
            "cvss": cvss,
            "cve": r.get("cve", r.get("cves", "")),
            "nvt_oid": r.get("nvt_oid", r.get("oid", "")),
            "description": (r.get("description", r.get("summary", "")) or "")[:200],
        })
    return findings


def generate_report(input_path):
    data = load_data(input_path)
    findings = analyze_offline_report(data)
    sev = Counter(f["severity"] for f in findings)
    host_vulns = defaultdict(int)
    for f in findings:
        host_vulns[f["host"]] += 1
    cve_list = [f["cve"] for f in findings if f["cve"]]
    findings.sort(key=lambda x: x["cvss"], reverse=True)
    return {
        "report": "greenbone_vulnerability_management",
        "generated_at": datetime.utcnow().isoformat() + "Z",
        "total_vulnerabilities": len(findings),
        "severity_summary": dict(sev),
        "hosts_scanned": len(host_vulns),
        "host_vulnerability_counts": dict(host_vulns),
        "unique_cves": len(set(cve_list)),
        "top_10_findings": findings[:10],
        "findings": findings,
    }


def main():
    ap = argparse.ArgumentParser(description="Greenbone Vulnerability Management Agent")
    ap.add_argument("--input", required=True, help="Input JSON with GVM scan results")
    ap.add_argument("--output", help="Output JSON report path")
    ap.add_argument("--host", help="GVM host for live scan (requires python-gvm)")
    ap.add_argument("--username", default="admin", help="GMP username")
    ap.add_argument("--password", default="admin", help="GMP password")
    args = ap.parse_args()
    report = generate_report(args.input)
    out = json.dumps(report, indent=2)
    if args.output:
        Path(args.output).write_text(out, encoding="utf-8")
        print(f"Report written to {args.output}")
    else:
        print(out)


if __name__ == "__main__":
    main()
Keep exploring