Chapter 23 — Security operations and blue team: methods I
Lesson map
Lesson 23 published. Map, example, EX067.
flowchart TD
N0["Learning outcomes"]
N1["23.1 Two guessing patterns"]
N2["23.2 Grouping matters"]
N3["Lab — spray versus brute force"]
N4["23.3 Reading the result"]
N5["23.4 Responses differ"]
N6["23.5 Thresholds"]
N7["23.6 Shared addresses"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX067"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["23.1 Two guessing patterns"]
N2["23.2 Grouping matters"]
N3["Lab — spray versus brute force"]
N4["23.3 Reading the result"]
N5["23.4 Responses differ"]
N6["23.5 Thresholds"]
N7["23.6 Shared addresses"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX067"]
[Learning outcomes]
|
v
[23.1 Two guessing patterns]
|
v
[23.2 Grouping matters]
|
v
[Lab — spray versus brute force]
|
v
[23.3 Reading the result]
|
v
[23.4 Responses differ]
|
v
[23.5 Thresholds]
|
v
[23.6 Shared addresses]
|
v
[Worked example] --> [Exercise EX067]
Learning outcomes
You will (1) design detections for password guessing patterns; (2) distinguish spraying from single-account brute force; (3) evaluate thresholds on synthetic data; (4) decide alert routing by pattern.
23.1 Two guessing patterns
Brute force tries many passwords against one account. Password spraying tries one or two common passwords against many accounts, staying under per-account lockout limits. Both appear in identity logs as failures, but they look different when grouped.
Lockout limits explain the difference. Riverton locks an account after several failures in a short period, so brute force against one account soon stops working, while a spray that tries each account only once or twice never triggers a lock. Spraying succeeds when some users choose common passwords, which is why it targets many accounts.
23.2 Grouping matters
Grouping failures by source and counting distinct users and attempts per user separates the patterns: spraying shows many users and few attempts each; brute force shows one user and many attempts.
Without grouping, both patterns are just failures in a long list, and the spray's forty failures look much like the day's background of mistyped passwords. Grouping by source address turns them into two clear profiles. The lab below applies exactly this grouping to synthetic records. The grouping is cheap to compute, even on a busy day.
Lab — spray versus brute force
"""Password-spray pattern: one source, many users, few attempts each, within 30 minutes (synthetic)."""
from collections import defaultdict
fails = [("198.51.100.77", f"s{n}", t) for n, t in zip(range(3000, 3040), range(0, 40))] + \
[("192.0.2.5", "s1001", t) for t in (1, 2, 3, 4, 5, 6)]
by_src = defaultdict(lambda: defaultdict(int))
for src, user, minute in fails:
if minute < 30: by_src[src][user] += 1
for src, users in by_src.items():
per_user = max(users.values())
kind = "SPRAY" if len(users) >= 20 and per_user <= 2 else ("BRUTE-FORCE ONE USER" if len(users) == 1 and per_user >= 5 else "-")
print(f"{src:14} users={len(users):3} max attempts/user={per_user} {kind}")
Run with python3 lab_spray.py. Verified output:
198.51.100.77 users= 30 max attempts/user=1 SPRAY
192.0.2.5 users= 1 max attempts/user=6 BRUTE-FORCE ONE USER
23.3 Reading the result
In 30 minutes, 198.51.100.77 failed against 30 accounts with at most one attempt each — a spray. 192.0.2.5 failed six times against s1001 only — a brute-force pattern on one account.
Only the first thirty of the spray's forty attempts fall inside the thirty-minute window, which is why the lab reports thirty users rather than forty. The window choice matters: a slower spray spread over hours would show fewer users per window and could fall below the threshold. Lucas notes this limit in the rule's description, so analysts know that a quiet result does not rule out a slow spray.
23.4 Responses differ
Spraying threatens many weak passwords; the response is to check whether any targeted account later signed in successfully and to block the source. Brute force against one account may be a user who forgot a password, or a targeted attack; the response is to contact the account holder.
In the lab, the different responses produced different outcomes, as the worked example below shows: the spray was checked for later successful sign-ins and its source blocked, while the brute-force pattern turned out to be a forgotten saved password. Treating both the same way would either alarm s1001's owner needlessly or under-react to the spray.
23.5 Thresholds
The lab uses 20 users and 2 attempts per user. Lower thresholds catch slower sprays but raise false alerts from shared campus addresses, such as library computers.
Lucas tested lower values on a week of real failure records. At ten users and two attempts, the rule flagged three library and lab addresses each day, all benign. At twenty, it flagged none of them. He kept twenty for general addresses and documented the trade-off, so slower sprays are a known limit rather than a surprise.
23.6 Shared addresses
Campus NAT means many students share one public address; a real spray must be distinguished from a busy lab. The rule excludes known campus egress addresses and handles them with separate thresholds.
For campus egress addresses, the rule uses higher thresholds and also looks at the share of failures, since a busy computer lab produces many successes alongside its failures. A spray from a shared address would show unusually many failures across many users with few successes, a pattern a lab full of students seldom produces.
Worked example
Lucas checks whether any of the 30 sprayed accounts signed in successfully afterwards: none did. For 192.0.2.5, s1001's owner says he had changed his password and his old laptop kept retrying. The SOC closes it as benign and suggests he update the saved password.
Synthetic case. Sources and accounts come from the lab script.
Errors and limits
Attackers can spread sprays across many addresses and long periods; per-source grouping then misses them.
Exercises
- EX067 — Pattern difference. How do spraying and brute force differ in grouped logs? Rubric: 3 = spray: many users, few attempts; brute: one user, many attempts; 2 = partial; 1 = same; 0 = none.
- EX068 — Lab classification. Classify the two sources in the lab. Rubric: 3 = 198.51.100.77 spray (30 users, 1 each); 192.0.2.5 brute force on s1001 (6); 2 = one; 1 = wrong; 0 = none.
- EX069 — Shared addresses. Why are campus egress addresses handled separately? Rubric: 3 = many users share them; would trigger false sprays; 2 = partial; 1 = no reason; 0 = none.
Synthesis
Group identity failures to reveal patterns, choose responses by pattern, and adapt thresholds to shared campus addresses.
Continue studying — chapter 23 of 40
← Chapter 22 (draft) · Course chapter index · Chapter 24 (draft) →