Lesson 14 / 14
Common Network Attacks
When the six controls built in this course are switched on together, the number of flows on which each of four attack classes closes is counted; with the narrow selector none of them closes across all forty flows, with full tunnel only one closes, and denial of service stays open on twenty-two flows.
Contents
Six controls were built across the course, and each measured its own boundary in both directions at once: generation and coverage on the wireless side; segmentation, the rule chain, detection, the tunnel, and the criterion moving from location to identity on the security side. One question is left: when these six controls are switched on together, which class of network attacks actually closes, how many classes remain open, and what is there in hand for the ones that stay open? What is measured is not attack; it is the scope of defense.
What This Lesson Does Not Do
How eavesdropping, spoofing, on-path attack, and denial of service are carried out is not this course’s subject. All four were covered by procedure across eight lessons in the Network Attacks topic of the Cybersecurity curriculum; procedure, tooling, payload, and evasion stay there. Here the four names appear only as class names, and what stands in for them is not a procedure but a condition — a sentence, read only from the defending side, that says for which flow the class stays accessible.
| Class | Read from the defending side |
|---|---|
| Eavesdropping | Is the flow’s content readable in transit |
| Spoofing | Can the flow’s source claim be verified |
| On-path attack | Is content readable and the source unverifiable |
| Denial of service | Does the service sit somewhere the flow can reach |
A class is closed for a flow if its condition does not hold; it is open if the condition holds.
A Control Being On Is Not the Same as a Class Closing
The real distinction this measurement carries is this: a control being set up is not the same as a class being closed for that flow. The tunnel is set up, but it does not touch a flow left outside its selector. The identity criterion is set up, but it produces no decision for a flow with no credential. The generation requirement is in force, but it has nothing to do with a flow that has no wireless leg. This is why the measurement is done at the flow level: forty flows and four classes, 160 flow-class pairs.
The measurement’s assumptions:
- NS64 — The forty flows are produced from the course’s shared fixture; the oracle is
the
policyfunction and is not changed in this lesson. Two fields are added to each flow:wireless, saying whether the first leg is on the wireless segment;credential, saying whether the source claim can be verified. Both come from the fixture and preserve the same flow set as the previous lesson’s draws. - NS65 — Eavesdropping closes if the flow is inside the tunnel selector and, if it has a wireless leg, the generation requirement is in force; it does not close if either leg is uncovered.
- NS66 — Spoofing closes if the zero-trust criterion is on and the flow has a credential. On-path attack requires both to close at once.
- NS67 — Denial of service closes only when the service is unreachable: segmentation and the rule chain are both on, and intent already blocks that flow. On a flow that stays reachable, this class is open by definition.
- NS68 — The detection system closes no class; this is not a gap in the setup but the mechanism’s definition, and contributing zero to the measurement is the expected result.
- NS69 — Two tunnel selectors are compared: narrow selector and full tunnel. In the coverage-report measurement, the oracle is closure computed at the flow level.
- NS70 — The set is 160 pairs; the smallest measurable difference is
1/160. In rows read at the flow level, the resolution is1/40 = 0.025.
Measurement
"""The scope of defense: which control closes which class, what stays open. Part 1 - closure at the flow level, across two tunnel selectors. Part 2 - the flow-class pairs lost when a control is switched off. Part 3 - the coverage report's two-way error. """ SEED = 20260811 ZONES = ("ext", "dmz", "int", "mgmt") CLASSES = ("eavesdropping", "spoofing", "on-path attack", "denial of service") CONTROLS = ("segmentation", "rule chain", "tunnel", "detection", "zero trust", "wireless generation") def generator(seed): d = seed % 2147483646 + 1 def r(n): nonlocal d d = (d * 48271) % 2147483647 return d % n return r def flows(count=40, seed=SEED): r, out = generator(seed), [] for i in range(count): out.append({"no": i + 1, "source": ZONES[r(4)], "dest": ZONES[r(4)], "port": (80, 443, 22, 3306, 8080)[r(5)]}) return out def add_surfaces(flows_list, seed=SEED + 6, env=SEED + 11): """Whether the flow has a wireless leg, whether its source claim has a credential.""" r, o, out = generator(seed), generator(env), [] for a in flows_list: r(9), r(4) # identity draws; keeps the same flow set out.append({**a, "credential": r(8) != 0, "wireless": o(3) == 0}) return out def policy(a): if a["source"] == "ext": return a["dest"] == "dmz" and a["port"] in (80, 443) if a["source"] == "dmz": return a["dest"] == "int" and a["port"] == 3306 if a["source"] == "mgmt": return True return a["dest"] != "mgmt" def diff(events, intent, device): d = {"correct_pass": 0, "correct_block": 0, "false_admit": 0, "false_deny": 0} for o in events: n, g = intent(o), device(o) if n and g: d["correct_pass"] += 1 elif not n and not g: d["correct_block"] += 1 elif g: d["false_admit"] += 1 else: d["false_deny"] += 1 return d def closure(a, enabled, selector): """Which class is closed per flow. Only the defending side is read.""" eavesdropping = ("tunnel" in enabled and selector(a) and (not a["wireless"] or "wireless generation" in enabled)) spoofing = "zero trust" in enabled and a["credential"] unreachable = ("segmentation" in enabled and "rule chain" in enabled and not policy(a)) return {"eavesdropping": eavesdropping, "spoofing": spoofing, "on-path attack": eavesdropping and spoofing, "denial of service": unreachable} SELECTORS = {"narrow selector": lambda a: a["dest"] in ("int", "dmz"), "full tunnel": lambda a: True} NARROW = SELECTORS["narrow selector"] ALL = set(CONTROLS) ak = add_surfaces(flows()) pairs = [(a, s) for a in ak for s in CLASSES] print(f"flow {len(ak)} | class {len(CLASSES)} | flow-class pair {len(pairs)}" f" | with a wireless leg {sum(a['wireless'] for a in ak)} | credentialed " f"{sum(a['credential'] for a in ak)} | crossing a zone boundary " f"{sum(a['source'] != a['dest'] for a in ak)}") print() print(f"{'class':<18s} {'narrow selector':>18s} {'full tunnel':>18s}") print(f"{'':18s} {'closed':>9s} {'open':>8s} {'closed':>9s} {'open':>8s}") for s in CLASSES: h = [] for sec in SELECTORS.values(): k = sum(closure(a, ALL, sec)[s] for a in ak) h += [k, len(ak) - k] print(f"{s:<18s} {h[0]:9d} {h[1]:8d} {h[2]:9d} {h[3]:8d}") print() whole = sum(closure(a, ALL, NARROW)[s] for a, s in pairs) print(f"{'control switched off':<22s} {'closed pairs':>12s} {'lost':>6s}") print(f"{'(none)':<22s} {whole:12d} {0:6d}") for c in CONTROLS: n = sum(closure(a, ALL - {c}, NARROW)[s] for a, s in pairs) print(f"{c:<22s} {n:12d} {whole - n:6d}") print() REPORTS = {"control checklist": lambda a, s: s != "denial of service", "boundary only": lambda a, s: closure(a, ALL - {"wireless generation", "zero trust"}, NARROW)[s]} print(f"{'coverage report':<18s} {'correct':>7s} {'false admit':>12s} " f"{'false deny':>12s}") for name, report in REPORTS.items(): d = diff(pairs, lambda c: closure(c[0], ALL, NARROW)[c[1]], lambda c: report(c[0], c[1])) print(f"{name:<18s} {d['correct_pass'] + d['correct_block']:7d} " f"{d['false_admit']:12d} {d['false_deny']:12d}")
flow 40 | class 4 | flow-class pair 160 | with a wireless leg 9 | credentialed 35 | crossing a zone boundary 27
class narrow selector full tunnel
closed open closed open
eavesdropping 18 22 40 0
spoofing 35 5 35 5
on-path attack 16 24 35 5
denial of service 18 22 18 22
control switched off closed pairs lost
(none) 87 0
segmentation 69 18
rule chain 69 18
tunnel 53 34
detection 87 0
zero trust 36 51
wireless generation 79 8
coverage report correct false admit false deny
control checklist 91 51 18
boundary only 105 0 55
What Closes and What Does Not
The upper table places the four classes side by side in two tunnel configurations, and with the narrow selector, no class closes on all forty of the forty flows. The best row is spoofing: 35 closed, 5 open. Eavesdropping is 18/22, on-path attack 16/24, denial of service 18/22.
When the tunnel selector covers every destination, eavesdropping becomes 40 closed, 0 open — one class closes entirely. Its cost was measured in the tunnel lesson: closing a class entirely requires the control to be applied without exception, and the price of that exceptionlessness is paid on the rule side. On-path attack, being an intersection, is always narrower (16 and 35); the two controls need to cover the same set of flows.
Denial of service stays at 18/22 in both columns, and this fixedness is structural: this class closes only when the service is unreachable, and intent itself passes 22 of the forty flows. Reachability is the reason this class cannot be closed, not a gap in configuration.
The middle table shows what each control carries. With all six controls on, 87 flow-class pairs are closed. Switching off zero trust opens 51 pairs; the tunnel, 34; segmentation or the rule chain, 18; wireless generation, 8. Switching off detection opens 0 pairs: detection closes no class; it gives visibility along with its two-way error, and the set it sees is the 27 flows crossing a zone boundary.
The Two Directions of the Coverage Report
The lower table carries the lesson’s central warning. A coverage report that looks at the control checklist — one that says “the tunnel is set up, zero trust is set up, generation is in force, so three classes are closed” — gives 91 correct, 51 false admit, 18 false deny. On fifty-one pairs it calls something closed that is not; on eighteen pairs it fails to see something that is closed, because it does not account for denial of service narrowing through the rule chain.
A report counting only the controls at the boundary — one that treats generation and zero trust as another team’s job and leaves them out — gives 105 correct, 0 false admit, 55 false deny. It has no false admits at all; its entire error comes from undercounting.
Both reports are wrong, and their wrongness runs in opposite directions: one shows coverage as wider than it is, the other as narrower. A coverage report that counts only one direction hides the other.
Classes Left Open, and Narrowings
In the narrow-selector configuration, all four classes leave open flows. What is left in hand must be written next to each of them.
Eavesdropping — 22 flows open. What stays open are the flows outside the tunnel selector. Narrowing: widen the selector; at full tunnel, open drops to 0, and its cost was measured in the tunnel lesson. On the 9 flows with a wireless leg, coverage depends on both conditions at once.
Spoofing — 5 flows open. What stays open are flows with no credential. Narrowing: widen credential coverage. Dropping an uncredentialed flow to implicit deny grew false deny; widening coverage is the one move that improves both numbers together.
On-path attack — 24 flows open. Being an intersection, the widest opening is here. Narrowing: align the two controls’ coverage sets; matching the tunnel selector to credential coverage gains more than widening a single control does.
Denial of service — 22 flows open, and no configuration closes it. Narrowing: the surface, with segmentation and the rule chain together, drops from 40 to 22; the remaining twenty-two are flows intent passes and that stay reachable because that is the service’s job. What remains of this class’s surface narrows on the capacity side, not the rule side, and that side is not this course’s subject.
Summary
- The four classes appear in this lesson only as class names; their procedures stay in the Network Attacks topic of the Cybersecurity curriculum. Here each class is reduced to a condition read from the defending side, and the measurement is done on 160 flow-class pairs.
- A control being set up and a class closing are separate things: with the narrow selector, spoofing is 35/5, eavesdropping 18/22, on-path attack 16/24, denial of service 18/22, and no class closes on all forty flows at once.
- At full tunnel, only eavesdropping rises to 40/0; a class closing entirely requires the control to be applied without exception, and its cost was measured in the tunnel lesson.
- With all six controls on, 87 pairs are closed; zero trust carries 51, the tunnel 34, segmentation and the rule chain 18, generation 8. Detection closes 0 pairs, and this is by definition.
- The coverage report’s two directions err separately: the report reading the control checklist produces 51 false admits, the report counting only the boundary produces 55 false denies. Denial of service closes under no configuration; the remaining 22 flows narrow on the capacity side.
Course Wrap-Up
The course asked a single question fourteen times: what is the difference between the boundary the design intended and what actually crosses it? Every lesson built one mechanism, changed one thing, and counted the difference in both directions at once. The table below collects the boundary each lesson measured and both of its directions; the numbers come from each lesson’s own run.
| Lesson | Boundary Measured | False Admit | False Deny |
|---|---|---|---|
| Physics of Wireless Transmission | cell intent of thirty meters at power 52 | 0 | 4 |
| Access Points and Controllers | location of the decision: standalone → controller | 2 → 0 | 4 → 4 |
| Channel Planning and Coverage | power budget 58 → 40 | 5 → 0 | 1 → 14 |
| Roaming and Band Steering | handover threshold 30 → 14 | 8 → 0 | 0 → 8 |
| Wireless Security Protocols | generation condition 1 → 3 | 5 → 2 | 1 → 20 |
| Short-Range and Wide-Area Wireless | short / local / wide range | 3 / 0 / 1 | 0 / 4 / 2 |
| Mobile Networks | inter-site distance 90 → 30 | 5 → 0 | 1 → 0 |
| Firewall Types | unmirrored / mirrored / stateful / application-aware | 6 / 6 / 0 / 0 | 7 / 4 / 0 / 8 |
| Access Control Lists | narrow 7 / wide 6 / misordered 8 / tightened 7 rules | 0 / 2 / 2 / 0 | 0 / 0 / 0 / 2 |
| Network Segmentation and DMZ | zone graph 2 → 4, narrow / wide derivation | 0 / 6 → 0 / 0 | 22 / 0 → 0 / 0 |
| Intrusion Detection and Prevention | network-based threshold 7 → 9; 19 flows the host-based system never sees | 0 → 5 | 7 → 0 |
| VPN Technologies | tunnel selector: full tunnel → split | 0 → 6 | 0 → 10 |
| Zero Trust Network Model | location criterion stripped → identity criterion | 18 → 1 | 0 → 1 |
| Common Network Attacks | coverage report: control checklist / boundary only | 51 / 0 | 18 / 55 |
The table has a single reading, and it shows up in all fourteen rows: the two columns do not move together. Every adjustment that zeroes one column grows the other. Lower the power budget and the leak stops while the miss count rises to fourteen; tighten the generation condition and the leak drops from five to two while the miss count rises to twenty; narrow the tunnel selector and the unreachable count becomes ten. A control that counted only one direction would have shown a flawless table in all fourteen of the fourteen lessons.
The second reading concerns rule count. Seven rules gave 40/40 correct, seven rules gave 38; six rules leaked, eight rules both leaked and shadowed. Counting rules does not measure policy — and stripping a criterion can turn a rule into an implicit allow without changing the rule count at all. The reason two rows are left blank sits in the same place: in this course, the source of a number is not a shared definition, it is the lesson that ran it.
This is also where the course leaves off. Fourteen lessons measured how the boundary gets written: which power, which threshold, which rule chain, which criterion, which selector. None of them asked what happens to the boundary after it is written. A written boundary sits inside a living system: its load changes, its rules get edited by hand, its deviation is invisible to anyone, and its two-way error is known only once it is measured. Writing the boundary and operating what was written are separate jobs.
The next course, Network Operations and Automation, takes on the second job: how traffic gets distributed, which measurements the network uses to report its own state, and which failure modes close when configuration is managed as code. The two columns counted in this course become, there, a measurement problem: how is a boundary’s two-way error seen while it is running?
To keep your progress and take notes, Log in
My notes
Log in to take notes.