skillZs
LIVE SKILL TAGS
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
REAL INSTALL DATA
← back to all skills
eip-public/security-skills2 installs

cve-research-analysis

Triage a CVE and emit the standard research intel block.

How do I install this agent skill?

npx skills add https://github.com/eip-public/security-skills --skill cve-research-analysis
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill is a specialized methodology for security researchers to triage CVEs. It incorporates strong host-safety policies, such as using Docker for builds and isolated virtual environments for Python tools, which mitigate the risk of host machine mutation. While it handles untrusted exploit code and external technical intelligence, it does so within a structured framework designed for analysis rather than direct execution on the host.

  • Socketwarn

    1 alert: gptSecurity

  • Snykfail

    Risk: HIGH · 2 issues

What does this agent skill do?

CVE Research and Analysis

Routing doctrine reference

Follow ../ROUTING-DOCTRINE.md as the house style for:

  • branch vs helper ownership
  • explicit load triggers
  • explicit When NOT to Use boundaries where ambiguity exists
  • normalized === SKILL HANDOFF === blocks
  • sequential phase loading instead of preloading downstream skills

When to Use

Load this immediately after cve-router-triage.

This is the first substantive analysis step in the CVE workflow. It gathers and normalizes the technical intel that the downstream branch needs, but it does not build the lab or package the PoC.

When NOT to Use

  • Do NOT use this skill to build a lab or write a PoC — those belong to branch skills and cve-poc-validation.
  • Do NOT load this skill again after the === CVE RESEARCH INTEL === block has been emitted and accepted by the branch.
  • Do NOT use this skill in place of a branch skill once ecosystem/class is confirmed.

Load Triggers

  • Loaded by cve-router-triage as the first skill in every CVE pipeline (step 1 of LOAD_ORDER).
  • Reload only if a branch skill discovers that the research intel block is incomplete or stale.

Required Environment

  • EIP MCP (eip-mcp) available for intelligence gathering (phases 1–2).
  • git and optionally gh for source code analysis (phase 3).
  • Active lab root must exist or be created before cloning. Default lab root: ~/exploit-intel/labs/CVE-YYYY-NNNNN/ unless the task or workspace provides another root.
  • Internet access for advisory and repository fetches.

Phase Ownership

This skill owns:

  • CVE intelligence gathering
  • exploit landscape review
  • patch / code / binary analysis
  • root-cause hypothesis
  • branch-ready research output

This skill does NOT own:

  • lab construction
  • branch-specific environment setup
  • exploit development
  • final PoC packaging or rerun evidence

Minimum Viable Path

The shortest correct use of this skill is:

  1. get vulnerability intelligence from EIP
  2. review existing exploit references
  3. identify the likely root cause
  4. determine the next branch
  5. emit === CVE RESEARCH INTEL ===
  6. emit === SKILL HANDOFF ===

If some fields remain unknown, mark them n/a with justification and hand off only when the branch can proceed honestly with the available evidence.

Procedure

Phase 0 — Check for prior pipeline output

Before fresh research, look for an existing run:

$ ls ~/win11-forge/lab/CVE-YYYY-NNNNN/ 2>/dev/null

If disclosure.md or poc_verification_report.md exists, read them first and confirm the verified trigger still fires against the current lab VM. Do not re-derive root cause, re-diff binaries, or re-write the trigger — hand off with what's there.

Phase 1 — Intelligence Gathering (only if Phase 0 found nothing)

Do only these phases, in order:

  1. check for prior pipeline output (Phase 0)
  2. intelligence gathering
  3. exploit landscape review
  4. code or binary analysis
  5. emit the === CVE RESEARCH INTEL === block
  6. hand off to the selected branch

Stop there. Do not build the lab, start exploitation, or package the final PoC inside this skill.

Handoff

Emit a normalized === SKILL HANDOFF === block targeting the branch skill identified in NEXT_BRANCH. All required fields in the intel block must be populated, or marked n/a with a concrete justification, before handoff proceeds. The goal is branch-ready intel, not perfect completeness.

Research completion is not CVE pipeline completion. If a downstream branch later validates real exploit impact, the expected next step is to continue into cve-poc-validation and produce the standardized PoC package and rerun evidence unless the user explicitly asked to stop before PoC authorship.

Detailed Research Responsibilities

This skill owns the research phase only.

It should answer:

  • what the target is
  • what version(s) are vulnerable/fixed
  • what the root cause appears to be
  • what deployment/lab prerequisites exist
  • which branch skill should own the next phase

It should NOT absorb the whole workflow. After research is complete, hand off deliberately:

  • cve-wordpress-workflow for WordPress ecosystem targets
  • cve-browser for browsers (chromium, firefox, webkit)
  • cve-kernel-linux for Linux kernel targets
  • cve-kernel-windows for Windows kernel targets
  • cve-mobile-android for Android APK targets
  • cve-memory-linux for userland native binaries on Linux
  • cve-memory-windows for userland native binaries on Windows
  • cve-web-generic for OS-agnostic web apps, APIs, and hosted services
  • cve-logic-generic for OS-agnostic auth-bypass, business logic, path traversal

Helper Skill Triggers

Load helper skills only when their trigger is present:

  • code-differential-review -> patch commit(s) or multi-file fix exists and needs structured diff analysis
  • code-variant-analysis -> the root cause is a reusable pattern that may exist elsewhere
  • design-sharp-edges -> the bug seems driven by insecure defaults, misuse-prone APIs, auth/crypto/deserialization footguns, or a design-level failure rather than a one-off coding mistake
  • code-semgrep-hunting -> only after code-variant-analysis identifies a pattern that benefits from repeatable static detection

Standard Handoff Block

Before handing off to a branch skill, emit:

=== SKILL HANDOFF ===
FROM_SKILL:        cve-research-analysis
TO_SKILL:          cve-wordpress-workflow | cve-mobile-android | cve-browser | cve-kernel-linux | cve-kernel-windows | cve-memory-linux | cve-memory-windows | cve-web-generic | cve-logic-generic
REASON:            <why this branch owns the next phase>
PRIMARY_ARTIFACTS: <patch refs, repo/artifact refs, preserved tmp/ paths, auth material references, version info>
STATE_READY:       <root cause, prerequisites, lab assumptions>
OPEN_QUESTIONS:    <unknowns that the next skill must resolve>
NEXT_TRIGGER:      <what will cause helper skill or PoC loading>
====================

Minimum STATE_READY contents:

  • target/product identity
  • vulnerable and fixed version(s)
  • likely root cause
  • auth/config/runtime prerequisites
  • chosen next branch

Tool Priority (use in this order)

  1. mcp_eip_mcp_get_vulnerability - First call for any CVE. Returns CVSS, EPSS, description, exploits, references.
  2. mcp_eip_mcp_search_exploits - Find existing PoCs, Metasploit modules, GitHub exploits.
  3. mcp_eip_mcp_get_exploit_code - Fetch actual exploit source code for analysis.
  4. mcp_eip_mcp_get_nuclei_templates - Check for scanner templates and recon dorks.
  5. terminal + git commands - Clone repo, analyze patches, examine vulnerable code.
  6. browser tools - Only for gaps EIP can't fill (vendor advisories, blog posts).

Research Phases

Phase 1: Intelligence Gathering

mcp_eip_mcp_get_vulnerability(cve_id="CVE-YYYY-NNNNN")

Extract: severity, CVSS, EPSS, affected products, vulnerable version range, patched version, patch commits, references.

Phase 2: Exploit Landscape

mcp_eip_mcp_search_exploits(cve="CVE-YYYY-NNNNN")

Check for existing PoCs. If found, fetch and analyze code with mcp_eip_mcp_get_exploit_code. If a working PoC exists, use it as a reference - do not reinvent it.

PoC analysis checklist (determines KNOWN_POC value):

When mcp_eip_mcp_search_exploits / mcp_eip_mcp_get_exploit_code returns a PoC, evaluate:

  1. Triggering request shape — what HTTP method, path, body, or input format triggers the vulnerability? Document concretely.
  2. Assumed prerequisites — does the PoC assume auth, specific config, specific content, or a preceding action? List them.
  3. Weaponization level:
    • stub — demonstrates the crash/side-channel only; does not achieve exploitation
    • partial — exploitation achieved under specific preconditions (specific version, specific config); generalization needed
    • full — works against a freshly-installed vulnerable version with default config
  4. Version currency — does it still work against the LATEST vulnerable release (not just the release it was written for)?
  5. Dependencies — does it require specific Python/Ruby/Go versions, specific libraries (ysoserial + specific CC version), or custom tooling?

Set KNOWN_POC:

  • yes if the PoC is weaponization-level full AND version-current AND runs without custom dependencies the branch skill won't have
  • partial if any of the above are lacking but the PoC demonstrates the primitive
  • no only if no PoC was found OR the found PoC is purely theoretical/speculative with no running code

Phase 3: Code / Binary Analysis

Fork on SOURCE_AVAILABLE and acquisition shape. All paths produce the same INTEL.md fields: VULNERABLE_FILE, VULNERABLE_FUNC, PATCH_FILES, PATCH_COMMITS (when available), ROOT_CAUSE, EXPLOITATION_PREREQS.

Phase 3A: SOURCE_AVAILABLE = yes (public git repo)

  • Clone affected repo INTO the active lab root under tmp/repo/ (Default: ~/exploit-intel/labs/CVE-YYYY-NNNNN/tmp/repo/ unless the task/workspace provides another root; NEVER clone directly into ~/.)
  • Use the vulnerable version tag
  • Examine patch diff to understand the fix
  • Trace the vulnerable code path from attacker input to sink
  • Identify all prerequisites: auth required? specific config? specific endpoint?

Massive-repo fallback: for repos with 50k+ files (GitLab, Linux kernel, Chromium), a full git fetch --unshallow can time out or exhaust disk space. When the shallow clone is already available, try these in order:

  1. Search the shallow clone directly with search_files using the vulnerability class keywords, affected filenames from the advisory, and CWE-specific patterns. The vulnerability code is often discoverable without history.
  2. Use the forge's web API to find the fix: GitLab MR search (/api/v4/projects/:id/merge_requests?search=<issue number>), GitHub issue cross-references, or the advisory's own patch links.
  3. Use git blame on key files via the forge web UI (not local clone) to identify the fix commit from line annotations.
  4. If all else fails, mark PATCH_COMMITS: n/a and PATCH_FILES: n/a (fix location not identified; <reason>). The research phase can complete with architectural analysis from the advisory alone - the branch's lab step will confirm reachability regardless.

Phase 3C preflight: SSH credential verification

Before any SSH/scp to the lab VM, verify credentials from the source of truth — NOT from memory or README:

$ grep -E 'VM_USER|VM_PASS' ~/win11-forge/vm-setup/lib/defaults.sh

The gold image uses forge/forge123. README references to winforge are stale. Do NOT cycle through alternative usernames — if forge/forge123 fails, the VM may still be booting. Wait and retry, but never try multiple usernames.

SSH auth retry rule: If the correct credentials (from defaults.sh) fail twice in a row, do NOT retry a third time with minor variations. Pivot: check virsh domstate, ping, or virsh domifaddr to diagnose whether the VM is actually running and network-ready. Looping on auth looks like you're stuck and burns user patience.

Phase 3B: SOURCE_AVAILABLE = partial

Use this path when there is no complete public source repository, but source-like material exists:

  • debug symbols, PDBs, DWARF, map files
  • decompiled source from Ghidra/IDA/jadx/dnSpy
  • patch fragments, vendor diff snippets, generated source packages
  • partial source archives, SDK examples, vendored module snapshots
  • public headers/interfaces sufficient to identify the vulnerable surface

Rules:

  • Store source-like material under tmp/partial-source/ or tmp/decompiled/ under the active lab root.
  • Mark SOURCE_URL as the best available source-like artifact URL, or n/a with a justification in BLOCKERS.
  • Populate PATCH_FILES with the best available file/module/function names, even if inferred from symbols or decompiler paths.
  • Populate VULNERABLE_FILE / VULNERABLE_FUNC with confidence labels: [FROM SYMBOLS], [FROM DECOMPILER], [FROM PATCH FRAGMENT], or [FROM ADVISORY].
  • Populate PATCH_COMMITS: n/a unless a real public commit exists.
  • Keep ROOT_CAUSE honest about evidence level, e.g. [FROM DECOMPILER, UNCONFIRMED UNTIL LAB].

If partial source is enough to identify a branch and likely vulnerable surface, hand off. The branch owns live reachability and impact confirmation.

Phase 3C: SOURCE_AVAILABLE = no (binary-only)

No source to read. Everything must come from the binaries and the advisory.

Acquire both versions:

For Microsoft Windows PE binaries (the most common case), use Winbindex FIRST — it provides individual PE files by KB/build/version from Microsoft's symbol servers. Do NOT download full MSU/CAB patch packages (often 5GB+) when you only need a few DLLs:

# Winbindex CLI (host tool)
$ winbindex spoolsv.exe --windows 11 --release 11-24H2 --arch x64 --kb KB5083769 --download --output tmp/binaries/patched/
# Web UI fallback when CLI crashes on certain modules:
#   https://winbindex.m417z.com/?file=<module.dll> → search KB → click Download → copy msdl URL

See cve-windows-binary-diff §"Winbindex helper" for CLI quirks and web fallback patterns.

For non-Microsoft binaries or when Winbindex doesn't have the file:

  • Vendor download page (look for older-version links, patch archives)
  • FileHippo / OldVersion.com / archive.org Wayback for historical builds
  • Docker Hub (for services with official images; check tags)
  • Package archives: Debian snapshot.debian.org, Ubuntu Launchpad, CentOS/RHEL vault
  • Trial / free-tier signup (document what was used)
  • Patch archives linked from vendor advisory (often 3-part patches for commercial software)

Save both vulnerable and patched binaries into tmp/binaries/ under the active lab root (default: ~/exploit-intel/labs/CVE-YYYY-NNNNN/tmp/binaries/). Preserve branch-needed binaries until the branch -> cve-poc-validation handoff and list them in PRIMARY_ARTIFACTS.

Extract / unpack:

  • MSI: lessmsi x installer.msi extracted/ (cross-platform) or 7z x installer.msi
  • DEB: dpkg-deb -R package.deb extracted/
  • RPM: rpm2cpio package.rpm | cpio -idmv
  • NSIS installers: 7z x usually works
  • Docker image: docker save <image> | tar xf - && find . -name '*.tar' -exec tar xf {} \;
  • Extract JARs / WARs / EARs: unzip app.war -d unpacked/

String diff for fast triage:

strings tmp/binaries/vuln-binary | sort -u > tmp/binaries/vuln.strings
strings tmp/binaries/patched-binary | sort -u > tmp/binaries/patched.strings
diff tmp/binaries/vuln.strings tmp/binaries/patched.strings | head -100

Look for: new validation strings, new allowlist/blocklist content, new class names, new filter names, renamed error messages.

Symbol / section diff:

  • For ELF: nm -D vuln.so vs nm -D patched.so to spot new symbols; objdump -d per changed function.
  • For PE: dumpbin /exports vuln.dll vs dumpbin /exports patched.dll; dumpbin /disasm for changed functions.
  • For Java: jadx -d vuln-src vuln.jar, jadx -d patched-src patched.jar, then diff -rq vuln-src patched-src | grep -v .class to identify changed files.

Function-level diff (when string diff is inconclusive):

  • radiff2 -C vuln-binary patched-binary | head -50 — matches functions by structural similarity and shows distance
  • BinDiff or Diaphora for IDA users
  • Ghidra with BinExport / BinDiff plugin for cross-tool analysis

Populate INTEL.md fields from binary analysis:

  • VULNERABLE_FILE: path within the installer / archive (e.g., WEB-INF/lib/core.jar or Program Files/Vendor/Product/core.dll)
  • VULNERABLE_FUNC: function name from the decompilation. If stripped and no symbols, document as <stripped: address 0x401500 in core.dll>.
  • PATCH_FILES: list of files that differ between versions, scoped to non-resource changes (ignore icon/PE version info diffs).
  • PATCH_COMMITS: usually n/a for binary-only. Mark as such.
  • ROOT_CAUSE: inferred from the diff (e.g., "added class allowlist in SerializationFilter.resolveClass before readObject"). Label as [FROM BINARY DIFF].

What to look for in the diff, by vuln class:

  • Deserialization: new class allowlist/blocklist, new ObjectInputFilter, new resolveClass override, new SerialKiller/NotSoSerial dependency
  • Auth bypass: new permission check before a handler, removed "skip auth" branch, new session validation
  • Injection: new input sanitization, new parameterized query, new encoding step
  • Path traversal: new realpath / basename / extension check, new allowlist-based path validation
  • LFI: new extension filter, new base-path enforcement

When no patch is available (only vulnerable version obtainable):

  • Focus decompilation on the function / class named in the advisory (often a researcher's writeup names specific classes)
  • Use IDA/Ghidra/jadx to map the vulnerable call chain from exposed entrypoint → dangerous sink
  • Mark ROOT_CAUSE as [FROM CODE REVIEW, UNPATCHED REFERENCE]

Binary-only reachability check:

  • Identify the entrypoint that reaches the vulnerable sink. For a service, this is typically a network endpoint; for a CLI, a flag / argument.
  • Use strings + objdump to map string constants to functions (URL paths, argument names)
  • Run the binary in the lab with strace / ltrace / dtrace to confirm the entrypoint actually reaches the sink for your test input

Common binary-only pitfalls:

  • Confusing "patch adds X" with "vulnerability is lack of X" — the diff tells you what was added; the advisory confirms whether that's the fix
  • Working from the wrong version: vendor re-issues installers; verify the build number / SHA256 matches the advisory
  • Treating debug symbols as authoritative: stripped release builds may behave differently — always confirm crash-reproduction against the distributed binary
  • ASLR/DEP randomized between runs: for crash triage, disable ASLR at the binary level (setarch <arch> -R) or use debugger-controlled startup

Phase 3D: hosted / SaaS / black-box access only

Use this path when no source, binary, installer, or image is obtainable, but authorized hosted access exists.

Research output should make the downstream web/logic branch usable without pretending code evidence exists:

  • SOURCE_AVAILABLE: no
  • SOURCE_URL: n/a (hosted-only target; no source or installer available)
  • PATCH_COMMITS: n/a
  • PATCH_FILES: n/a
  • VULNERABLE_FILE: n/a
  • VULNERABLE_FUNC: n/a
  • ROOT_CAUSE: [FROM ADVISORY / BLACK-BOX HYPOTHESIS] <one-sentence summary>
  • REFERENCES: advisory, vendor bulletin, docs, API references, changelog, hosted URL if safe to record
  • EXPLOITATION_PREREQS: account tier, role, feature flags, tenant setup, rate limits, API tokens
  • AUTH_REQUIRED and MIN_ROLE: state the current hypothesis and evidence source
  • BLOCKERS: include any missing access, legal/authorization boundary, unavailable paid tier, or rate limit

Do not invent patch files or source paths for hosted-only targets. Hand off to cve-web-generic or cve-logic-generic with exact endpoint candidates, auth model, and evidence gaps.

Pitfalls

Advisory language can obscure simple structural bugs

Advisory descriptions often use implementation-specific vocabulary that misdirects code search. A vulnerability described in terms of a specific feature path may, structurally, be a missing-allowlist, missing-bounds-check, or missing-permission-check on a much simpler surface. Before tracing the advisory's exact words through source:

  1. Confirm what the affected endpoint or function actually returns (or accepts) on the running build. Hit it. Read the response. Read the source of the response serializer.
  2. Then, and only then, decide whether the advisory's described feature path is the real exploit vector or just one of several that the same structural bug exposes.

The advisory's vocabulary is a hint, not a contract.

Patch commit discovery on massive repos

See Phase 3A massive-repo fallback above. Do not block research on git fetch --unshallow timing out.

Key Patterns

Version Range Determination

  • Cross-reference git tags with patch commit dates
  • Check when the vulnerable feature was first introduced
  • Use: git log --oneline --follow <vulnerable_file>
  • Shallow clones (--depth=1) lack tags and history needed for patch analysis; if tags or log ranges are needed, run git fetch --unshallow first
  • Advisory version numbers may not match git tag names; verify the tag exists with git tag -l before checking out

Authentication Bypass CVEs

  • The lab MUST have auth enabled - if the CVE bypasses auth, there must be auth to bypass
  • Default Docker configs often disable auth - always check

Advisory-vs-Code Reachability Check

  • Do not trust advisory metadata like PR:N or "unauthenticated" at face value
  • Trace the real entrypoint from the route/controller/page class into the vulnerable sink
  • Verify whether request parsing constrains the attacker-controlled value before it reaches the sink (for example, route regexes that only accept \d+)
  • Check page/module permission gates and README/permission SQL to confirm whether the vulnerable path is actually authenticated
  • If advisory reachability conflicts with code, document the discrepancy explicitly and treat the stricter, code-backed prerequisite as the current hypothesis until lab validation proves otherwise

Patch Analysis

  • Focus on what was ADDED (auth checks, validation, sanitization, class allowlists)
  • The absence of those checks IS the vulnerability
  • Compare vulnerable endpoint with patched equivalent in same codebase
  • For multi-file or complex patches, load the code-differential-review skill for a structured methodology (risk classification, blast radius, bypass detection)

Advanced Verification Patterns

Partial vs Full Fix

  • Do not trust advisory version ranges alone - verify the fix exists in the code
  • Steps:
    1. Identify the executing sink (the function that does the dangerous thing)
    2. Trace call chain from external input to that sink
    3. Check for explicit guards: blocked key sets, auth checks, input validation
    4. git log --oneline <prev_tag>..<patched_tag>
    5. git show <patched_tag>:path/to/critical_file

Route-Level Normalization Can Kill a Real Sink Bug

A source-level sink can still be non-reachable in the stock route you test. Before assuming exploitability, inspect the HTTP entrypoint that populates the vulnerable object/function arguments.

Checklist:

  1. Find the exact route/controller/page that reaches the sink
  2. Inspect how route params are parsed (preg_match, intval, casts, allowlists)
  3. Compare attacker input at the HTTP layer with the final value passed into the sink
  4. If the route only captures a numeric prefix or otherwise normalizes input, test baseline vs injected requests and compare full response bodies / hashes
  5. If injected requests are byte-identical to baseline, document that the stock reachable path did not carry attacker-controlled syntax to the sink

Example pattern: a vulnerable SQL builder may use raw FileID='$this->fileID', but if the route extracts it with preg_match('#fileID=(\\d+)#', $path, ...), trailing SQL metacharacters never reach the sink on that path.

Large Changelog Handling

  • Use search_files with regex to jump to version headers
  • Use read_file with offset/limit rather than loading entire files

Auth-Bypass and Gated Routes

  • Many fixes gate vulnerable routes behind feature flags
  • Ensure labs enable those flags, otherwise the vulnerable endpoint won't register
  • Confirm reachability: health check endpoints, bind to 0.0.0.0

YAML/JSON-to-Exec Pattern

  • Config files with callable args is a common RCE pattern
  • Search for functions that import/resolve symbols and execute them
  • Verify patches block the args path or remove invocation entirely

Constrained LFI Escalation Analysis

For constrained LFI analysis (appended-extension LFI), see cve-logic-generic §1.4 — logic-layer path traversal methodology owns this.

Host machine policy

The host is shared workspace, not a sandbox. Two rules, both with a clear boundary:

  1. No package installation that mutates host state. Never apt-get install, pip install (system-wide or user-wide), gem install, npm install -g, cargo install, or any package manager that adds packages to the host. All build dependencies live inside Docker. If a Docker build fails on a missing dependency, add it to the Dockerfile and rebuild - do not fall back to the host. If you genuinely need a host-side Python helper (rare), the escape hatch is a self-contained venv under the active lab root: python3 -m venv tmp/venv && tmp/venv/bin/pip install <pkg>. Run the helper as tmp/venv/bin/<tool>; the venv dies with the lab.
  2. Sudo is allowed for inspection and cleanup, not environment setup. Operational one-shots that do not change security posture are fine (sudo lsof, sudo kill for a lab-owned process, sudo dmesg where permitted). Do not write host kernel/runtime knobs (/proc/sys, sysctl), load host kernel modules, enable services, add firewall rules, create users/groups, or change ownership outside the lab root without explicit approval. Runtime tuning belongs inside the guest VM, container, emulator, or other lab target.

The boundary is host-state mutation or host security posture change, not the literal command name.

Work Hygiene

  • All work lives under the active CVE lab root. Default lab root: ~/exploit-intel/labs/CVE-YYYY-NNNNN/ unless the task or workspace provides another root.
  • Never clone repos into ~/ or any other ad-hoc location.
  • Keep the standard structure inside the active lab root: tmp/, artifacts/, lab/, poc/ as applicable.
  • Clone source repos into tmp/repo/ under the active lab root.
  • Preserve branch-needed source checkouts, binaries, extracted archives, and decompiler output under tmp/ until the branch -> cve-poc-validation handoff.
  • Delete only unneeded scratch during research; list any preserved tmp/ paths in PRIMARY_ARTIFACTS.
  • Persist the === CVE RESEARCH INTEL === block to INTEL.md at the active lab root before handoff.

Output Required Before Handoff

Emit the standardized CVE Research Intel block before handoff. Persist it to INTEL.md at the active lab root (default: ~/exploit-intel/labs/CVE-YYYY-NNNNN/INTEL.md).

=== CVE RESEARCH INTEL ===
CVE:                 CVE-YYYY-NNNNN
VENDOR:              <string>
PRODUCT:             <string>
ECOSYSTEM:           wordpress | browser | kernel-linux | kernel-windows | mobile-android | none
OS:                  linux | windows | macos | cross-platform
VULN_CLASS:          memory | web | logic | deserialization | injection | xss | auth_bypass | lfi | ssrf | idor | xxe | race | type_confusion | privilege_escalation | information_disclosure
CWE:                 CWE-NNN[, CWE-NNN]
VULNERABLE_VERSIONS:    <min>..<max> exact, NOT a vague product line. e.g. 10.0.26100.1742..10.0.26100.8115 (Windows), 7.85.0..8.1.0 (Linux pkg). Pull exact bounds from the vendor's advisory (MSRC/GHSA), not NVD's summary.
BUG_INTRODUCED_VERSION: <version where the regression landed> | n/a-RTM (only when the bug is in the product's initial release, not a regression)
FIXED_VERSION:          <first build/version containing the fix>
EXPECTED_TARGET_BINARIES:
  # one line per binary the trigger reaches, consumed by the branch / lab pre-flight gate
  <full path or package identifier>: <min>..<max>
SOURCE_AVAILABLE:    yes | partial | no
SOURCE_URL:          <repo url, source-like artifact url, or n/a with justification>
VULNERABLE_COMMITS:  <sha or range or n/a>
PATCH_COMMITS:       <sha or url or n/a>
PATCH_FILES:         <paths or n/a>
VULNERABLE_FILE:     <path or n/a>
VULNERABLE_FUNC:     <function/method or n/a>
ROOT_CAUSE:          <one-sentence summary>
AUTH_REQUIRED:       yes | no
MIN_ROLE:            <role name or n/a>
EXPLOITATION_PREREQS: <list or none>
BLOCKERS:            <list or none>
KNOWN_POC:           yes | partial | no
REFERENCES:          <advisory url, vendor bulletin, EIP id>
NEXT_BRANCH:         <skill-slug>
==========================

Fields that are not yet known must be marked n/a with a concrete justification. Do not proceed to a branch until the intel is honest and branch-usable.

When to Continue with Variant Analysis

Required when VULN_CLASS is memory / race / type-confusion / privilege-escalation / information-disclosure AND the upstream PoC reaches [SUCCESS]: the same bug pattern is the single highest-yield place to find the next CVE. Load code-variant-analysis and search sibling functions in the same module, sibling modules with the same code lineage (e.g. all RPC dispatchers in spoolsv), and the patched function's callers/callees.

Optional for unique logic bugs, configuration-specific issues, or one-off parsing errors — those rarely have variants.

cve-poc-validation will refuse to close a memory-class verdict without a populated ## Variant analysis section.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/eip-public/security-skills/cve-research-analysis">View cve-research-analysis on skillZs</a>