Chapter 4 — Threat intelligence and OSINT: guided lab and applied synthesis
Lesson map
Lesson 04 published. Map, example, EX039.
flowchart TD
N0["Learning outcomes"]
N1["4.1 Lab rules"]
N2["Lab — validate, match and filter"]
N3["4.2 Reading and acting on the result"]
N4["4.3 The summary and the weekly routine"]
N5["4.4 Synthesis of the month"]
N6["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6
N6 --> EX["Worked example"]
EX --> Q["Exercise EX039"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["4.1 Lab rules"]
N2["Lab — validate, match and filter"]
N3["4.2 Reading and acting on the result"]
N4["4.3 The summary and the weekly routine"]
N5["4.4 Synthesis of the month"]
N6["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> Q["EX039"]
[Learning outcomes]
|
v
[4.1 Lab rules]
|
v
[Lab — validate, match and filter]
|
v
[4.2 Reading and acting on the result]
|
v
[4.3 The summary and the weekly routine]
|
v
[4.4 Synthesis of the month]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX039]
Learning outcomes
You will (1) validate shared indicators before use; (2) match them against a synthetic mail log; (3) build a summary that respects TLP; (4) combine the month's learning into a repeatable weekly routine.
4.1 Lab rules
The lab runs offline on synthetic data with Python's standard library. No real mail logs, no network connections, no visiting domains, no live DNS lookups. The indicators, labels and mail lines are invented for the lab.
Stdlib-only and offline are kickoff checklist lines, and offline is proven rather than assumed: the kickoff makes a deliberate DNS lookup in the runner, and if the runner can reach the network the lab fails before it starts. Only after that check passes does lab_rapid start.
Lab — validate, match and filter
"""Lab (ch 04): validate shared indicators, match a synthetic mail log, and build a TLP-safe summary."""
import ipaddress
shared = [("donate-elmfield.example", "TLP:GREEN"), ("198.51.100.400", "TLP:GREEN"),
("elmfield-giftaid.example", "TLP:AMBER"), ("203.0.113.9", "TLP:CLEAR")]
mail = [("vol-07", "donate-elmfield.example"), ("vol-12", "news.example"), ("office", "elmfield-giftaid.example")]
valid = []
for v, lab in shared:
try:
ipaddress.ip_address(v); valid.append((v, lab))
except ValueError:
if v.replace(".", "").isdigit():
print("invalid:", v); continue
valid.append((v, lab))
print("valid:", len(valid))
hits = [(who, d) for who, d in mail if d in {v for v, _ in valid}]
print("hits:", hits)
public = [v for v, lab in valid if lab in ("TLP:CLEAR", "TLP:GREEN")]
print("shareable with community:", public)
Run with python3 lab_rapid.py. Verified output:
invalid: 198.51.100.400
valid: 3
hits: [('vol-07', 'donate-elmfield.example'), ('office', 'elmfield-giftaid.example')]
shareable with community: ['donate-elmfield.example', '203.0.113.9']
4.2 Reading and acting on the result
Of four shared indicators, 198.51.100.400 is invalid — an octet above 255 — so three remain. Two log entries match: volunteer vol-07 received mail involving donate-elmfield.example, and the office received mail involving elmfield-giftaid.example. Only donate-elmfield.example and 203.0.113.9 may be shared with the community; elmfield-giftaid.example is TLP:AMBER and stays inside EFBN.
Sam quotes the verified output lines in his notebook rather than retyping them.
vol-07 is contacted kindly: did you click or enter details? If yes, change the password and turn on two-step login. The contact script avoids blame language. The office match goes to the chair by phone the same day. Both domains are blocked in the email provider's settings.
4.3 The summary and the weekly routine
The CCC feedback says: "Two indicators from this week's alert reached our mailboxes; both blocked." It lists only the GREEN domain. The AMBER item is not mentioned.
The omission is deliberate and checked: a second reader confirms that nothing AMBER appears in the outbound paragraph before it is sent, and their initials on the GREEN-only paragraph are filed beside the send timestamp.
Monday: read CCC and advisories, log items. Tuesday: check mail and sign-in logs for indicators. Wednesday: warn volunteers if needed. Friday: send feedback to CCC and update the log.
The rhythm is written on the trustee scope page so deputies can run it. Before Sam takes leave, the deputies run the Monday-to-Friday routine once under his watch, and those observed runs are logged with dates so coverage is evidence, not hope.
4.4 Synthesis of the month
Week 1 gave vocabulary and decisions; week 2 permission and safety; week 3 systems and dependencies; week 4 a working routine — four weeks, no malware lab heroics.
The month-end synthesis for the trustees shows those four themes and claims nothing outside the deliverable list: CCC membership, weekly reading, volunteer warnings, MFA on key accounts and the log. It repeats the two non-goals from week one, attribution and malware analysis, so no one reads advanced CTI skills into a month EFBN never funded for them.
Worked example
Sam's first full week: three CCC items logged, one match found, one volunteer password changed, one GREEN feedback note sent. The chair asks for a monthly one-paragraph summary; Sam adds it to the routine.
Synthetic case. The lab and week are invented teaching material.
Errors and limits
The lab uses exact matching only; lookalikes need separate watching.
Exercises
- EX039 — Invalid value. Which lab indicator was invalid and why? Rubric: 3 = 198.51.100.400; octet over 255; 2 = value; 1 = wrong; 0 = none.
- EX040 — Lab matches. Which two log entries matched? Rubric: 3 = vol-07 donate-elmfield; office elmfield-giftaid; 2 = one; 1 = wrong; 0 = none.
- EX041 — Community list. Which indicators may be shared with the community? Rubric: 3 = donate-elmfield.example and 203.0.113.9; 2 = one; 1 = includes AMBER; 0 = none.
- EX042 — AMBER mention. Why does the feedback not mention the AMBER item? Rubric: 3 = AMBER stays in EFBN; even mention reveals; 2 = partial; 1 = should list; 0 = none.
- EX043 — Volunteer contact. How should vol-07 be approached? Rubric: 3 = kindly; ask if clicked/entered; reset + two-step if so; 2 = partial; 1 = blame; 0 = none.
- EX044 — Blocking place. Where were the domains blocked? Rubric: 3 = email provider settings; 2 = partial; 1 = nowhere; 0 = none.
- EX045 — Routine days. Give the four-day weekly routine. Rubric: 3 = Mon read/log, Tue check logs, Wed warn, Fri feedback; 2 = three; 1 = one; 0 = none.
- EX046 — Exact matching limit. What does exact matching miss? Rubric: 3 = lookalikes/variants; 2 = partial; 1 = vague; 0 = none.
- EX047 — Month in review. Summarise what each week contributed. Rubric: 3 = vocabulary/decisions, permission/safety, systems/dependencies, routine; 2 = three; 1 = one; 0 = none.
- EX048 — First-week outputs. List the outputs of Sam's first full week. Rubric: 3 = 3 logged, 1 match, 1 password changed, 1 feedback; 2 = three; 1 = one; 0 = none.
- EX049 — Chair request. What did the chair add to the routine? Rubric: 3 = monthly one-paragraph summary; 2 = partial; 1 = vague; 0 = none.
- EX050 — Lab safety. State two lab safety rules. Rubric: 3 = offline/synthetic, no visiting domains/no real logs; 2 = one; 1 = vague; 0 = none.
Synthesis
Validate before use, match carefully, act kindly on hits, share only what labels allow and keep a weekly routine.
Continue studying — chapter 04 of 04
← Chapter 03 (draft) · Course chapter index · Worked results ↓ · Next course via chapter index →