Lesson map
Lesson 14 published. Map, example, EX040.
flowchart TD
N0["Learning outcomes"]
N1["14.1 The method"]
N2["14.2 Choosing the window"]
N3["Lab — failures by source"]
N4["14.3 Reading the result"]
N5["14.4 Internal sources"]
N6["14.5 Setting the threshold"]
N7["14.6 Documentation"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX040"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["14.1 The method"]
N2["14.2 Choosing the window"]
N3["Lab — failures by source"]
N4["14.3 Reading the result"]
N5["14.4 Internal sources"]
N6["14.5 Setting the threshold"]
N7["14.6 Documentation"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX040"]
[Learning outcomes]
|
v
[14.1 The method]
|
v
[14.2 Choosing the window]
|
v
[Lab — failures by source]
|
v
[14.3 Reading the result]
|
v
[14.4 Internal sources]
|
v
[14.5 Setting the threshold]
|
v
[14.6 Documentation]
|
v
[Worked example] --> [Exercise EX040]
Learning outcomes
You will (1) design threshold detections for remote logon failures; (2) distinguish internal from external sources; (3) set thresholds from data; (4) document rules for analysts.
14.1 The method
A threshold rule counts events in a time window and alerts when the count passes a limit. For remote desktop guessing: failed logons from one source in 15 minutes.
The rule has three parts that each need a decision: what is counted, over how long, and at what number the alert fires. In the lab the count is failed remote desktop logons, grouped by source address, and the limit is 20 for external sources. Every later choice in this chapter adjusts one of those three parts against real history.
14.2 Choosing the window
Fifteen minutes catches fast automated guessing; slower attackers need a longer window or a daily count rule.
The trade-off in choosing a window is noise against how much it can reach. A long window catches a patient attacker who tries one password every few minutes, but it also gathers more ordinary mistakes from the contractor and staff. Mei keeps the 15-minute rule for fast guessing and would cover slow attempts with a separate daily count, rather than stretching one rule to cover both. Whichever window is chosen is written on the rule page, so an analyst knows which kind of guessing the rule can and cannot see.
Lab — failures by source
"""Failed remote-desktop logons by source in 15-minute windows (synthetic)."""
from collections import Counter
fails = [("203.0.113.45", 1) for _ in range(46)] + [("198.51.100.9", 1) for _ in range(3)] + [("10.2.0.15", 2) for _ in range(4)]
by_src = Counter(src for src, _ in fails)
for src, n in by_src.most_common():
internal = src.startswith("10.")
print(f"{src:14} failures={n:3} {'internal' if internal else 'external'} {'ALERT' if n >= 20 and not internal else ''}")
Run with python3 lab_rdp.py. Verified output:
203.0.113.45 failures= 46 external ALERT
10.2.0.15 failures= 4 internal
198.51.100.9 failures= 3 external
14.3 Reading the result
In one 15-minute window, 203.0.113.45 produced 46 failures and triggers the alert. An internal address, 10.2.0.15, had four failures — a receptionist mistyping — and is excluded from this rule. An external address with three failures is below the threshold of 20.
Mei checks the lab input against the printout: the list holds 46 entries for 203.0.113.45, three for 198.51.100.9 and four for 10.2.0.15, and the output shows the same three counts. Only the first source both comes from outside and reaches 20, so exactly one ALERT is printed, which is what the rule was written to do.
14.4 Internal sources
Internal failures are handled by a separate, higher threshold, because staff mistakes are common and attackers inside the network show other signs.
Inside a clinic, several failures in a row usually mean a receptionist on a cold morning or a forgotten password after a change. An attacker already inside would more often show up through other rules, such as a new administrator or an unusual process, so a high threshold for internal failures loses little while removing most daily noise.
14.5 Setting the threshold
Mei looks at a month of history: legitimate external failures (the contractor mistyping) never exceeded six in 15 minutes. A threshold of 20 leaves margin.
Six legitimate failures against a limit of 20 means an honest user would need to make more than three times their worst recorded month of mistakes to trigger the rule. The 46 failures from 203.0.113.45 are more than double the limit, so the gap between normal and attack in this data is wide enough to set the limit without fine adjustment.
14.6 Documentation
The rule page states purpose, logic, threshold reasoning, known benign triggers and response steps.
For this rule, the benign triggers include the monitoring tool found during testing, and the response steps are the ones in the worked example. An analyst meeting the alert at night reads the page, not Mei's memory, so anything Mei learned while building the rule must be written there before the rule goes live. The page also records the testing replay and the exception list for the misconfigured monitoring tool, with the reason each exception was granted.
Testing the rule
Before enabling the rule for all clients, Mei replays a week of historical firewall and logon data. It would have fired five times: three real guessing campaigns and two from a client's misconfigured monitoring tool repeatedly trying an old password. She adds that tool's address to a documented exception list.
Worked example
Mei's rule page response steps: "Check whether any logon from the same source succeeded. If yes, treat as high: disable the account and call the client. If no, advise the client to restrict remote access; block the source at the firewall if the agreement allows."
Synthetic case. Sources come from the lab script.
Errors and limits
Attackers spread attempts across many addresses to stay below per-source thresholds.
Exercises
- EX040 — Lab result. Which source alerts and why are the others excluded?
Show marking criteria
Rubric: 3 = 203.0.113.45 (46); internal 10.2.0.15 excluded; 198.51.100.9 below 20; 2 = partial; 1 = wrong; 0 = none. - EX041 — Threshold reasoning. How was the threshold of 20 chosen?
Show marking criteria
Rubric: 3 = legitimate external failures never above 6 in history; margin; 2 = partial; 1 = guess; 0 = none. - EX042 — Response step. What should the analyst check first after the alert?
Show marking criteria
Rubric: 3 = whether any logon from same source succeeded; 2 = partial; 1 = block; 0 = none.
Synthesis
Threshold rules work when windows, scopes and limits are chosen from data and documented for analysts.
Continue studying — chapter 14 of 30
← Chapter 13 (draft) · Course chapter index · Chapter 15 (draft) →