Chapter 4 — Digital forensics and malware analysis: core methods
Lesson map
Lesson 04 published. Map, example, EX016.
flowchart TD
N0["Learning outcomes"]
N1["4.1 Questions first"]
N2["4.2 Baseline comparison"]
N3["Lab — new sign-in addresses"]
N4["4.3 Reading the result"]
N5["4.4 Competing explanations"]
N6["4.5 Confidence"]
N7["4.6 Repeatability"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX016"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["4.1 Questions first"]
N2["4.2 Baseline comparison"]
N3["Lab — new sign-in addresses"]
N4["4.3 Reading the result"]
N5["4.4 Competing explanations"]
N6["4.5 Confidence"]
N7["4.6 Repeatability"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX016"]
[Learning outcomes]
|
v
[4.1 Questions first]
|
v
[4.2 Baseline comparison]
|
v
[Lab — new sign-in addresses]
|
v
[4.3 Reading the result]
|
v
[4.4 Competing explanations]
|
v
[4.5 Confidence]
|
v
[4.6 Repeatability]
|
v
[Worked example] --> [Exercise EX016]
Learning outcomes
You will (1) form questions and hypotheses; (2) compare activity against a baseline; (3) analyse sign-in records; (4) state findings with confidence levels.
4.1 Questions first
Lena writes the questions: Was Joy's account used by someone else? When did it start? What did they do? Is anyone else affected? Each question names the records that could answer it. Writing the questions before opening any export keeps the work inside scope and stops it drifting into browsing. For example, 'when did it start?' points to the sign-in log for 1 to 3 March, while 'what did they do?' points to mailbox audit and message trace. The last question, about others affected, is the one that later needs Dev to widen scope.
4.2 Baseline comparison
Joy normally signs in from the office address 198.51.100.7. A successful sign-in from an address never seen for her account is a strong signal, though not proof: she might have worked from home. The baseline in the lab is two days of sign-ins: Joy from 198.51.100.7 on 2 and 3 March, and m.lee from 198.51.100.9. Including m.lee checks that the script does not flag ordinary users. The comparison only flags; Lena still has to ask Joy where she was and IT whether the new address belongs to Marlow before calling it unauthorised.
Lab — new sign-in addresses
"""Synthetic sign-in log: flag successful sign-ins from addresses new for each user."""
import csv, io
LOG = """time,user,ip,result
2026-03-02 08:01,j.okafor,198.51.100.7,success
2026-03-02 08:30,m.lee,198.51.100.9,success
2026-03-03 08:02,j.okafor,198.51.100.7,success
2026-03-03 09:12,j.okafor,203.0.113.50,failure
2026-03-03 09:14,j.okafor,203.0.113.50,success
2026-03-03 09:31,m.lee,198.51.100.9,success
"""
seen = {}
for r in csv.DictReader(io.StringIO(LOG)):
known = seen.setdefault(r["user"], set())
if r["result"] == "success":
if known and r["ip"] not in known:
print("NEW IP", r["time"], r["user"], r["ip"])
known.add(r["ip"])
print("users checked:", len(seen))
Run with python3 lab_signin.py. Verified output:
NEW IP 2026-03-03 09:14 j.okafor 203.0.113.50
users checked: 2
4.3 Reading the result
One successful sign-in from a new address: 203.0.113.50 at 09:14 on 3 March, two minutes after a failed attempt from the same address. Colleague m.lee shows nothing new. Joy confirms she was at her office desk all morning. The failed attempt matters: a failure followed two minutes later by a success from the same address is consistent with someone trying a captured password, though it could also be a mistyped entry. The script treats the 08:02 office sign-in as already known, because 198.51.100.7 was seen on 2 March. The line 'users checked: 2' confirms both accounts in the sample were read.
4.4 Competing explanations
Could 203.0.113.50 be a company VPN? IT checks: it is not a Marlow address. Could Joy have used her phone on mobile data? Her phone's mail app shows the office Wi-Fi. The explanation "someone else signed in" fits best. Each explanation is tested with a record, not dismissed by feeling: IT's list of Marlow address ranges answers the VPN question, and the phone's network settings answer the mobile-data question. Had either check failed, the finding would have dropped to a lower confidence. Lena writes both tests into her notes, because Dev will ask which alternatives were ruled out and how.
4.5 Confidence
Lena writes "high confidence" for unauthorised access (new address, Joy's statement, phishing click) and "unknown" for who was behind it. The three supports are independent: the sign-in record comes from the identity provider, the phishing visit from the proxy, and the denial from Joy herself. Agreement between three separate sources is what justifies writing 'high' here. For the person behind it, Lena has only an address, and 203.0.113.50 says where a connection came from, not who made it. Writing 'unknown' keeps the report from implying an identification that no record supports.
4.6 Repeatability
The lab script and its input are saved, so Dev can rerun the check. Lena saves lab_signin.py with the exact CSV it read, and records the expected output: one NEW IP line for j.okafor at 09:14 and 'users checked: 2'. When Dev reruns it at a checkpoint, a different output would mean the input or code had changed. Repeatability also helps later: when the sign-in export is redone with the full 1–3 March range, the same script can run on the new file and the two results can be compared.
Writing hypotheses
A hypothesis is a testable statement, such as 'the 09:14 sign-in was not Joy'. Lena lists what evidence would support it and what would refute it before looking, so she is not tempted to read only the confirming records.
Worked example
Lena's finding: "Unauthorised sign-in to j.okafor at 09:14 from 203.0.113.50 (not a Marlow address; never seen for this user). Supported by Joy's statement and the 09:10 visit to the look-alike page. Confidence: high."
Synthetic case. Records come from the lab script.
Errors and limits
A first-seen check misses attackers who use an address already seen, or a shared VPN.
Exercises
- EX016 — Investigation questions. Write three investigation questions for the case. Rubric: 3 = account misuse, start time, actions, others affected (three); 2 = two; 1 = one; 0 = none.
- EX017 — Lab output. What did the sign-in lab find? Rubric: 3 = j.okafor success 09:14 from 203.0.113.50 after failure; m.lee none; 2 = partial; 1 = wrong; 0 = none.
- EX018 — Alternatives tested. Which two innocent explanations were checked? Rubric: 3 = company VPN; phone on mobile data; 2 = one; 1 = vague; 0 = none.
- EX019 — Confidence wording. Why "unknown" for who was behind it? Rubric: 3 = address does not identify a person; 2 = partial; 1 = known; 0 = none.
- EX020 — Blind spot. Name one blind spot of a first-seen address check. Rubric: 3 = attacker using familiar/shared address or VPN; 2 = partial; 1 = vague; 0 = none.
Synthesis
Ask questions first, compare to baseline, test alternatives and state confidence plainly.
Continue studying — chapter 04 of 12
← Chapter 03 (draft) · Course chapter index · Chapter 05 (draft) →