Skip to content

Greenbone Management Protocol: Import (Asset/Service/Software/Vulns) + Export+Scan - #57

Closed
hdm wants to merge 2 commits into
mainfrom
feat-greenbone
Closed

Greenbone Management Protocol: Import (Asset/Service/Software/Vulns) + Export+Scan#57
hdm wants to merge 2 commits into
mainfrom
feat-greenbone

Conversation

@hdm

@hdm hdm commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Note: This depends on runZero 5.1.260815.0 or newer for the TLS socket and SSH unix stream socket forwarding support.

Greenbone Management Protocol (GMP) integrations

Two integrations that talk to a Greenbone / OpenVAS scanner over the Greenbone
Management Protocol. Both support SSH and TLS transports with
username/password GMP auth, the standard runZero TLS trust options (CA, SHA-256
thumbprint pinning, client certs), and SSH host-key/key pinning.

Script Dir Type Purpose
greenbone-import.star greenbone/ inbound Import assets, services, software, and vulnerabilities from Greenbone reports
runzero-greenbone-scan.star greenbone-scan/ internal Export matching runZero addresses and launch a Greenbone scan against them

Together they form a loop: runZero addresses can be scanned in Greenbone, and
Greenbone results can be imported back into runZero.

Requirement: both declare minVersion 5.1.260815.0. They rely on Explorer
runtime support for the GMP transport primitives: forwarding to the gvmd UNIX
socket over SSH (direct-streamlocal, i.e. ssh -L localport:/run/gvmd/gvmd.sock, so no socat/netcat helper is needed on the
appliance) and passing TLS options into a raw TLS socket.

greenbone-import.star

For each task's most recent report (within a configurable age window), it
streams one runZero asset per scanned host:

  • Asset: OS name/CPE, hostnames, MAC/IP interfaces. Keyed by the Greenbone
    host asset id but with matchBehavior="no-id-match no-id-break", so results
    merge into existing runZero assets by IP/MAC/hostname, not by the foreign id.
  • Services: open TCP/UDP ports with service name, banner, and per-port
    severity.
  • Software: application CPEs (cpe:/a:…) parsed into vendor/product/version.
  • Vulnerabilities: one per CVE (or per NVT when there is no CVE) with name,
    description, solution, CVSS base score, severity rank, QoD, and NVT OID.

Reports are fetched page by page (get_reports … first/rows sort=host) and each
host is emitted with report_assets as it completes. Only one page and the
current host are ever held in memory, so a multi-megabyte report imports without
buffering the whole thing.

Parameters

  • transport: ssh (default) or tls.
  • SSH: ssh_host, ssh_username, ssh_password or ssh_private_key
    (+ passphrase), ssh_host_key (authorized_keys format), gmp_socket_path
    (default /run/gvmd/gvmd.sock).
  • TLS: gmp_host, gmp_port (default 9390), plus tls_*
    (tls_disable_validation, tls_ca_cert, tls_peer_hash, tls_client_cert,
    tls_client_key).
  • GMP auth: gmp_username, gmp_password.
  • Scope: max_age_days (default 30), task_filter, report_filter,
    severity_levels (default hmlg; include g to import hosts with no findings
    as assets), min_qod (default 70), page_size (default 100).

Running it

SSH transport:

runzero script --filename greenbone/greenbone-import.star \
  --kwargs transport=ssh \
  --kwargs ssh_host=192.0.2.10 \
  --kwargs ssh_username=gvm-admin \
  --kwargs "ssh_host_key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..." \
  --kwargs ssh_password='<ssh-password>' \
  --kwargs gmp_username=admin \
  --kwargs gmp_password='<gmp-password>' \
  --kwargs severity_levels=hmlg --kwargs min_qod=70

TLS transport with thumbprint pinning:

runzero script --filename greenbone/greenbone-import.star \
  --kwargs transport=tls \
  --kwargs gmp_host=192.0.2.10 --kwargs gmp_port=9390 \
  --kwargs tls_peer_hash=AB:CD:EF:... \
  --kwargs gmp_username=admin \
  --kwargs gmp_password='<gmp-password>'

Output:

greenbone: 1 task(s) found
greenbone: importing task 'Lab All' report 743b3975 (scan_end 2026-08-14T13:53:46Z)
greenbone: report 743b3975 imported 87 assets so far
greenbone: imported 141 assets from 1 report(s)

Imported asset

The logical ImportAsset built for one host (Ubuntu box from a lab report):

{
  "id": "80b81a84-183e-4807-ad9c-696ceeb1b50f",
  "matchBehavior": "no-id-match no-id-break mac-match mac-break ip-match ip-break name-match name-break",
  "os": "Ubuntu 24.04",
  "networkInterfaces": [{ "ipv4Addresses": ["10.114.122.3"] }],
  "customAttributes": {
    "greenbone.report_id": "743b3975-8d80-4ebc-a1f7-6957898b5d03",
    "greenbone.task": "Lab All",
    "greenbone.scan_end": "2026-08-14T13:53:46Z",
    "greenbone.asset_id": "80b81a84-183e-4807-ad9c-696ceeb1b50f",
    "greenbone.os_cpe": "cpe:/o:canonical:ubuntu_linux:24.04"
  },
  "services": [
    {
      "address": "10.114.122.3", "port": 22, "transport": "tcp",
      "protocolData": [{
        "name": "ssh",
        "attributes": {
          "banner": "Remote SSH server banner: SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.18\n...",
          "severity": "2.6"
        }
      }]
    }
  ],
  "software": [
    { "cpe23": "cpe:/a:ietf:transport_layer_security:1.2", "vendor": "ietf",
      "product": "transport_layer_security", "version": "1.2",
      "serviceAddress": "10.114.122.3", "serviceTransport": "tcp", "servicePort": 3780 }
  ],
  "vulnerabilities": [
    {
      "id": "1.3.6.1.4.1.25623.1.0.90022:22/tcp",
      "name": "Weak MAC Algorithm(s) Supported (SSH)",
      "category": "SSH", "serviceAddress": "10.114.122.3",
      "serviceTransport": "tcp", "servicePort": 22,
      "cvss2BaseScore": 2.6, "severityRank": 1,
      "customAttributes": { "greenbone.nvt_oid": "1.3.6.1.4.1.25623.1.0.90022",
                            "greenbone.threat": "Low", "greenbone.qod": "80" }
    },
    {
      "id": "1.3.6.1.4.1.25623.1.0.103190:CVE-1999-0524",
      "name": "ICMP Timestamp Reply Information Disclosure",
      "category": "General", "cve": "CVE-1999-0524",
      "serviceAddress": "10.114.122.3", "serviceTransport": "icmp",
      "cvss2BaseScore": 2.1, "severityRank": 1
    }
  ]
}

One lab report (141 responsive hosts) imported 141 assets, 521 services, 628
software, and 816 vulnerabilities at default settings, with an OS on every asset
and no duplicate ids.

runzero-greenbone-scan.star

  1. Calls the runZero export CSV endpoint
    (/api/v1.0/export/org/assets.csv) with your search filter and collects each
    matching asset's primary address (de-duplicated and IP-validated).
  2. Connects to Greenbone and authenticates.
  3. Creates a target with those addresses, creates a task (scan config +
    scanner), and starts the scan unless disabled, logging the report id. If task
    creation fails, the new target is rolled back.

Parameters

  • runZero export: runzero_url, runzero_export_token (Export API key),
    export_filter (e.g. os:Windows, last_seen:<30d, first_seen:<3d),
    max_hosts (default 1,000,000). Uses rz_http_* / rz_tls_*.
  • Transport: same ssh / tls options as the importer.
  • Scan definition: target_name prefix (a timestamp is appended),
    scan_config_id (default Full and fast), scanner_id (default OpenVAS
    Default), port_list_id (default All IANA assigned TCP), start_scan.

Running it

runzero script --filename greenbone-scan/runzero-greenbone-scan.star \
  --kwargs runzero_url=https://console.runzero.com \
  --kwargs runzero_export_token='<export-api-key>' \
  --kwargs export_filter='os:Windows last_seen:<30d' \
  --kwargs transport=ssh \
  --kwargs ssh_host=192.0.2.10 --kwargs ssh_username=gvm-admin \
  --kwargs "ssh_host_key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..." \
  --kwargs ssh_password='<ssh-password>' \
  --kwargs gmp_username=admin --kwargs gmp_password='<gmp-password>'

Output:

greenbone-scan: 240 target address(es) selected
greenbone-scan: created target d277c8b0-9a54-435a-9795-053e492a71c7 (240 hosts)
greenbone-scan: created task 1fb203b0-2e93-46c3-a4dd-2a04d24a3bb9
greenbone-scan: started task 1fb203b0-... (target d277c8b0-..., report 18ea8ebc-...)

If the export matches nothing, it stops before connecting to Greenbone and no
target or task is created:

greenbone-scan: 0 assets matched export filter 'os:DoesNotExist'; nothing to scan, no Greenbone target created

Testing

Validated against Greenbone Community Edition (GVM 25.2.1 / gvmd 22.6): full
paged import (141 assets) and target/task/start with cleanup. Response framing
tokenizes on > (gvmd escapes </> in text), tracks tag depth, and is bounded
by per-tag and per-response byte caps; a forward-progress guard stops paging if a
server ignores pagination. Every read carries a deadline and every connection and
goroutine is torn down on task completion.

Credentials above are placeholders. This PR covers the seven integration-repo
files; the supporting Explorer runtime changes are in the platform repo.

@hdm

hdm commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

rolled into #58

@hdm hdm closed this Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant