Skip to content

Lab 17 — Penetration Test Reporting

Hands-on lab · ← Back to the module concept

Setup

git clone https://github.com/plaintext-security/plaintext-labs.git
cd plaintext-labs/offensive/17-reporting
make demo   # prints writing guide, validates template, checks reference URLs

No Docker required. The validator and report template run with Python 3 only.

Scenario

You have completed a simulated penetration test against the target's internal web application. Your raw notes include findings from throughout the offensive track (SSRF, IDOR, privilege escalation, LOLBins). Turn those raw notes into a professional deliverable the CISO can share with the board and the engineering team can act on within 30 days.

No target is attacked in this lab — you're writing up findings, not running exploits. The authorization rule still governs the work it documents: a real engagement report covers only systems you owned or were explicitly authorised in writing to test. Treat the findings here as coming from such an authorised assessment.

Do

  1. [ ] Run make demo. Observe:
  2. Which 11 structural sections the validator checks for.
  3. The five common writing mistakes and their fixes.
  4. The public report references (confirm they resolve with ✓).

  5. [ ] Copy the template and start filling it in:

    cp data/report-template.md engagement-report.md
    
    Use findings from this track (modules 07–14). Include at least three findings across Critical, High, and Medium severity.

  6. [ ] For each finding, complete all fields:

  7. Severity + CVSS 3.1 vector (use the calculator at first.org/cvss)
  8. CWE (look up at cwe.mitre.org)
  9. Reproduction steps (specific commands from your lab notes)
  10. Impact in business terms (what could an attacker do with this?)
  11. Remediation specific enough to assign to a developer

  12. [ ] Write the Executive Summary. Rules:

  13. No acronyms without expansion on first use.
  14. State total findings by severity.
  15. State the business risk in one sentence.
  16. Name no specific vulnerabilities (that belongs in section 4).

  17. [ ] Validate your report:

    make validate FILE=engagement-report.md
    
    Fix any ✗ marks until 11/11 pass.

  18. [ ] Read two public reports from the references printed by make demo. For each:

  19. How does their executive summary differ from yours?
  20. What evidence do they include per finding?
  21. How specific are their remediation recommendations?

Success criteria — you're done when

  • [ ] make validate FILE=engagement-report.md passes 11/11 checks.
  • [ ] Executive Summary reads cleanly to a non-technical reader.
  • [ ] Every finding has CVSS, CWE, reproduction steps, impact, and remediation.
  • [ ] Remediation roadmap orders findings by real-world exploitability, not raw CVSS.

Deliverables

Commit engagement-report.md. This is a portfolio piece — it demonstrates not just technical skill but the written communication that clients pay for.

Artifact hygiene: Do not commit screenshots, pcap files, or evidence dumps — reference them as "[Figure 1 — see appendix]" and keep the originals local.

Automate & own it

Required. Write gen_finding.py that: - Takes --title, --severity, --cvss, --cwe, --desc, --repro, --impact, --remediation as arguments - Outputs a correctly-formatted finding block (Markdown) matching the report template - Can be called in a loop over a findings JSON file

AI drafts it; you verify the field ordering matches the template exactly, then run it against your three findings. Commit gen_finding.py.

AI acceleration

Paste your raw lab notes (terminal output, vulnerability description) into a model and ask it to draft the finding block. Then review every sentence: - Does the CVSS vector match the actual attack path? - Is the impact overstated or vague? - Is the remediation actionable, or is it "sanitize inputs"?

The skill is in the review, not the generation.

Connects forward

This is the capstone of Track 01 — every specialization track ends in a deliverable, and the report format (clear, evidence-backed, actionable) carries into all of them. The defensive tracks also consume this format: a SOC analyst reviewing a pentest report reads CVSS, reproduction steps, and indicators of compromise to build detection logic.

Marketable proof

"I write professional pentest reports: executive summary, CVSS-scored technical findings, risk-based prioritisation, and actionable remediation — modeled on real industry reports. I can validate report completeness programmatically."

Stretch

  • Validate one of the public Cure53 reports with python3 validate.py <file>. Does it pass 11/11? What structural differences do you see?
  • Add a severity-distribution bar chart (ASCII) to validate.py that counts Critical/High/Medium/Low findings in the report under test.
  • Stand up Ghostwriter and produce the same report through it, to see how consultancies manage findings at scale.

Comments

Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).