Problem
range42-catalog already hosts ~14 CVE-labelled exercises under 03_container_layer/docker/_ctf/cve/<category>/<product>/<CVE-ID>/ but there is no structured index. External vulnerability databases (e.g. vulnerability-lookup) cannot discover which CVEs we cover without parsing our taxonomy tree. The taxonomy is fine for authors, wrong for machines.
Goal
Emit a flat, auto-generated, validated manifest.json at a stable public URL so any consumer can answer "does range42 have a hands-on lab for CVE-XXXX-YYYY?" with a single HTTP GET.
Proposed design
1. Per-exercise source-of-truth: exercise.yml
Co-located with every CVE-*/ directory. Field names reuse the CTFd challenge.yml spec where semantically aligned, extended with CVE/CWE/CPE arrays:
schema_version: 1
id: cve-2021-42013-apache
cve: [CVE-2021-42013]
cwe: [CWE-22]
cpe: ["cpe:2.3:a:apache:http_server:2.4.49:*:*:*:*:*:*:*"]
product: apache
category: web
title: "Apache HTTPD Path Traversal + RCE"
description: "..."
exercise_type: docker-compose # docker-compose|dockerfile|lxc|vm|static
difficulty: intermediate # beginner|intermediate|advanced
stack: [apache, cgi, bash]
path: 03_container_layer/docker/_ctf/cve/web/apache/CVE-2021-42013
license: GPL-3.0-or-later
authors: ["..."]
tags: [path-traversal, rce]
has_solution: true
solution_path: poc/
estimated_time_minutes: 45
setup_cmd: "make up"
teardown_cmd: "make down"
safety: contained # contained|requires-isolation
status: active # active|deprecated
references:
- url: https://nvd.nist.gov/vuln/detail/CVE-2021-42013
tags: [technical-description]
2. Aggregated artefacts (CI-built, never hand-edited)
/manifest.json — flat array of all entries + top-level {schema_version, generated_at, source_commit}
/by-cve/CVE-YYYY-NNNNN.json — per-CVE entry for cheap point lookups
/schemas/exercise.schema.json — JSON Schema Draft 2020-12
3. Publication
- Commit built artefacts back to
main in the same PR as the exercise change that triggered them — stable raw URL: https://raw.githubusercontent.com/range42/range42-catalog/main/manifest.json
- Attach to GitHub Release assets on tagged versions (immutable snapshot)
- Optional future: enable GitHub Pages for a CORS-friendly
https://range42.github.io/range42-catalog/manifest.json if/when consumers request it
4. Automation (.github/workflows/manifest.yml)
- Walk
03_container_layer/docker/_ctf/cve/**/CVE-*/exercise.yml
- Validate each against the JSON Schema (
ajv-cli or check-jsonschema) — fail build on violation
- Aggregate → commit
manifest.json + per-CVE files back to the triggering branch
- On tag: attach assets to the Release
5. Optional feeder client
Ship tools/range42-sighting/ following the ExploitDBSighting pattern so operators can POST sightings to their own vulnerability-lookup instance without waiting for upstream feeder support.
Non-goals
- Restructuring the existing taxonomy tree (authors keep
category/product/CVE layout; the flat index is a sibling artefact, not a replacement)
- Defining a new standard — we align with CTFd + CVE 5.0 reference vocabulary
Prior art confirming the gap
Vulhub, trickest/cve, VulnerableApps, VWAD — none publishes a structured CVE manifest. This sets a small convention that external consumers can ingest today.
Acceptance criteria
Related
Companion feature request in vulnerability-lookup will consume this manifest — vulnerability-lookup/vulnerability-lookup#369
Problem
range42-catalogalready hosts ~14 CVE-labelled exercises under03_container_layer/docker/_ctf/cve/<category>/<product>/<CVE-ID>/but there is no structured index. External vulnerability databases (e.g. vulnerability-lookup) cannot discover which CVEs we cover without parsing our taxonomy tree. The taxonomy is fine for authors, wrong for machines.Goal
Emit a flat, auto-generated, validated
manifest.jsonat a stable public URL so any consumer can answer "does range42 have a hands-on lab for CVE-XXXX-YYYY?" with a single HTTP GET.Proposed design
1. Per-exercise source-of-truth:
exercise.ymlCo-located with every
CVE-*/directory. Field names reuse the CTFd challenge.yml spec where semantically aligned, extended with CVE/CWE/CPE arrays:2. Aggregated artefacts (CI-built, never hand-edited)
/manifest.json— flat array of all entries + top-level{schema_version, generated_at, source_commit}/by-cve/CVE-YYYY-NNNNN.json— per-CVE entry for cheap point lookups/schemas/exercise.schema.json— JSON Schema Draft 2020-123. Publication
mainin the same PR as the exercise change that triggered them — stable raw URL:https://raw.githubusercontent.com/range42/range42-catalog/main/manifest.jsonhttps://range42.github.io/range42-catalog/manifest.jsonif/when consumers request it4. Automation (
.github/workflows/manifest.yml)03_container_layer/docker/_ctf/cve/**/CVE-*/exercise.ymlajv-cliorcheck-jsonschema) — fail build on violationmanifest.json+ per-CVE files back to the triggering branch5. Optional feeder client
Ship
tools/range42-sighting/following the ExploitDBSighting pattern so operators can POST sightings to their own vulnerability-lookup instance without waiting for upstream feeder support.Non-goals
category/product/CVElayout; the flat index is a sibling artefact, not a replacement)Prior art confirming the gap
Vulhub, trickest/cve, VulnerableApps, VWAD — none publishes a structured CVE manifest. This sets a small convention that external consumers can ingest today.
Acceptance criteria
schemas/exercise.schema.jsoncommitted and documented in READMEexercise.ymltemplate added undercve/blank_template/exercise.ymlmanifest.jsonon every push tomainmanifest.jsonas an assettools/range42-sighting/client can POST to a configured vulnerability-lookup instanceRelated
Companion feature request in vulnerability-lookup will consume this manifest — vulnerability-lookup/vulnerability-lookup#369