◇ OpenCyber Academy
Engineering · Chapter 5 · English

Chapter 5 — Engineering communication

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 5 — Engineering communication

Lesson map

Lesson 05 published. Map, example, EX013.

flowchart TD
  N0["Learning outcomes"]
  N1["5.1 The reader decides"]
  N2["5.2 Write the claim at the right strength"]
  N3["5.3 Report structure"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4
  N4 --> EX["Worked example"]
  EX --> Q["Exercise EX013"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["5.1 The reader decides"]
  N2["5.2 Write the claim at the right strength"]
  N3["5.3 Report structure"]
  N4["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX013"]
[Learning outcomes]
    |
    v
[5.1 The reader decides]
    |
    v
[5.2 Write the claim at the right strength]
    |
    v
[5.3 Report structure]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX013]

Learning outcomes

You will (1) write a finding that a non-specialist can act on without exploit detail; (2) structure a short engineering report; (3) state uncertainty plainly.

5.1 The reader decides

A red-team report is read by an engineer who must fix something and a manager who must fund it. Neither needs a recipe. A finding needs: a title stating the weakness and asset; the affected scope; the evidence (what was observed, with time and ticket reference); the impact in business terms; the recommended fix; and how the fix will be verified. NIST SP 800-115 treats reporting as part of the assessment, not an afterthought.

Putting the fix and its verification next to the evidence means the engineer who must act has everything on one page. Business impact answers the manager's funding question without technical jargon: delayed trains, exposed rider data or a ticket forgery risk each land differently. Leaving out a working recipe is not vagueness; it is a deliberate choice so the report can be forwarded inside the client without becoming a how-to. NIST SP 800-115's place for reporting reminds teams that an unreported finding helps nobody.

5.2 Write the claim at the right strength

"We compromised the domain" is a headline. "Within the authorized window, a service account in the lab directory had domain-administrator rights; we confirmed the group membership read-only and did not use it" is a finding. The second states what was done, what was not done and on which scope, and the reader can verify it.

The weaker, careful claim is stronger as engineering because another team can re-check it. Stating what was not done closes the gap where a reader invents a worse scenario than occurred. Naming the scope, such as the lab directory rather than production, stops a finding being applied to the wrong system. Sam reads each draft aloud and asks whether every noun points to something in the evidence store.

5.3 Report structure

A short engineering report has: an executive summary (three sentences: what was tested, the most important result, the one decision needed); scope and method with ROE version; findings ordered by priority; limitations (what was out of scope or not reached); and an appendix with evidence hashes. Use tables for findings, prose for reasoning.

"""Score synthetic findings for report priority (no exploit details)."""
# impact 0-3, exploitability 0-3, exposure 0-3  -> priority
findings = [
    ("SYN-001", "default admin password on staging web UI", 3, 3, 2),
    ("SYN-002", "missing security headers on public site", 1, 1, 3),
    ("SYN-003", "outdated TLS on internal admin port", 2, 2, 1),
    ("SYN-004", "verbose error messages disclose paths", 1, 2, 2),
    ("SYN-005", "service account with domain admin in lab AD", 3, 2, 1),
]

def priority(impact, exploitability, exposure):
    score = impact*4 + exploitability*2 + exposure
    if score >= 16: return "critical", score
    if score >= 11: return "high", score
    if score >= 7: return "medium", score
    return "low", score

for fid, title, i, e, x in findings:
    p, s = priority(i, e, x)
    print(f"{fid} priority={p:8} score={s:2} impact={i} exploitability={e} exposure={x} :: {title}")

Expected output:

SYN-001 priority=critical score=20 impact=3 exploitability=3 exposure=2 :: default admin password on staging web UI
SYN-002 priority=medium   score= 9 impact=1 exploitability=1 exposure=3 :: missing security headers on public site
SYN-003 priority=high     score=13 impact=2 exploitability=2 exposure=1 :: outdated TLS on internal admin port
SYN-004 priority=medium   score=10 impact=1 exploitability=2 exposure=2 :: verbose error messages disclose paths
SYN-005 priority=critical score=17 impact=3 exploitability=2 exposure=1 :: service account with domain admin in lab AD

Synthetic case — Riverstone Transit. Sam's first draft of SYN-001 said "the staging UI is totally owned". The revised finding reads: "Staging admin UI (10.20.1.10:443) accepts the vendor default password; observed 10:45, ticket FD-118; an attacker on the corporate network could change fare tables in staging; fix: rotate and enforce unique credentials; verify by a re-test login failure."

5.4 Errors and limits

Avoid adjectives that cannot be checked ("trivial", "catastrophic"). Do not include working payloads, credentials or step-by-step instructions in reports; reference the evidence store instead.

Unchecked adjectives invite argument and hide the real evidence. Working payloads and credentials belong in a controlled store with access logs, not in a PDF that will be mailed around. When a reader needs more detail to verify a fix, Sam points them at the ticket and the evidence hash rather than pasting secrets into the report body.

Exercises

Synthesis

A good finding is specific, verifiable and safe to circulate. Writing it that way is part of the engineering, not decoration.

Continue studying — chapter 05 of 50

← Chapter 04 (draft) · Course chapter index · Chapter 06 (draft) →