Skip to content

Digital Forensics & Evidence Handling

Digital forensics and evidence handling cover the acquisition and analysis of digital artifacts in a legally and procedurally defensible way: acquisition (order of volatility — memory before disk before backups — with write-blocking and hashing at every step), integrity (the hash chain that proves evidence hasn’t changed from seizure to courtroom), chain of custody (who handled what, when, why — the log that makes the evidence admissible), and analysis discipline (working on copies, documenting every step, distinguishing fact from interpretation). The craft serves two masters: the technical analysis (BT6’s memory forensics, disk artifacts, timeline reconstruction) and the procedural defense (the evidence that survives an HR proceeding, a court case, or a regulator’s scrutiny) — and the procedural half is where most technically-strong analyses fail.

Forensic work that isn’t procedurally sound is work that can’t be used: the insider-dismissal case that collapses because the disk image was taken without custody documentation, the intrusion evidence that a court excludes because the hash chain broke, the regulator’s finding that the company’s own forensics can’t support. The order of volatility is the discipline’s first law: memory dies with power, cloud data changes with time, disk persists but is altered by use — and the acquisition sequence (memory → network state → disk → backups → archives) preserves what dies first. The integrity chain is the second law: every artifact hashed at acquisition, every copy verified, every transfer logged — the hash chain that makes “this is the same data we seized” provable. The analysis discipline is the third: work on verified copies, document every tool and step (the repetition standard — a peer could reproduce your findings), and separate observation (fact) from conclusion (interpretation) in every report. For the IR process (BT4), forensics is the evidence engine: the containment decisions that preserve artifacts, the custody chain that BT4’s case file tracks. For the analyst, the discipline is career-protecting: the acquisition you hash and document is the finding that survives scrutiny, and the corner you cut is the case that collapses with your name on it.

The acquisition sequence, the integrity chain, and the analysis standards:

ORDER OF VOLATILITY (RFC 3227-shaped [verify])
1. CPU/registers/cache (dead on capture)
2. RAM (dead on power loss)
3. network state (connections, ARP)
4. running processes (memory of apps)
5. disk (persists, altered by use)
6. remote/cloud logs (retention-limited)
7. backups/media (archives)
acquisition: capture DOWN this list; the top dies first
INTEGRITY CHAIN (the admissibility spine)
artifact acquired -> hash (sha256) recorded
-> working copy made (hash verified)
-> analysis on COPY only
-> every export re-hashed
original sealed (write-blocked storage)
custody log: who/when/why per transfer
ANALYSIS STANDARDS
- work on copies, never originals
- document tools + versions (reproducibility)
- repeatable: peer could redo your steps
- fact vs interpretation separated in reports
- timelines: every event sourced to an artifact
ACQUISITION TOOLING CLASSES
memory: winpmem/AVML-class (BT6)
disk: write-blocker + imager (dd/dc3dd/
FTK Imager class), or VM snapshot
remote: EDR remote-acquire (with custody log)
cloud: API export with hash-on-export

Memory-first acquisition (the BT4 lesson institutionalized) uses the resident tools (winpmem/AVML-class [verify current tools]) to capture RAM to an external destination before any power action — the volatile evidence that BT6’s analysis consumes and that dies with the power button. Disk acquisition runs through write-blockers (hardware for physical, software guards for logical) — the guarantee that the imaging process itself changes nothing; the image format matters (raw/E01 with embedded hashes, the forensic formats that carry their own integrity) and the verification is per-segment (the multi-gigabyte image that verifies block-by-block). Remote acquisition via EDR is the modern reality: collecting memory/disk/logical packages from endpoints at scale, with the custody discipline adapted (the EDR’s acquisition log is the custody record, the hash verified on receipt). Cloud acquisition follows the same principles over APIs: export with hash-on-export, preservation requests before retention lapses, and the legal process (the preservation letter that stops the cloud provider’s retention clock). The custody log is the spine: every artifact, every transfer (who, when, why, method), every hash verification — the log that turns “we have the data” into “we can prove this is the data, unchanged, since seizure.” Timeline analysis is the analysis layer’s connective tissue: events from multiple artifacts (filesystem, logs, memory, registry) normalized to one clock (timezone discipline — the TZ mishap that shifts an entire timeline), correlated into the incident narrative, each event sourced to its artifact.

TechniqueLayerWhat it doesToolingNotes
Memory-first acquisitionVolatileCapture RAM pre-powerwinpmem/AVML classBT4’s rule
Write-blocked disk imagingDiskBit-perfect imageHardware WB + imagerPhysical seizures
In-place logical collectionDisk/endpointSelected artifact captureEDR remote-acquireFleet-scale reality
Hash chain maintenanceIntegrityProve unchangedsha256 per artifact/transferThe admissibility spine
Chain-of-custody loggingProcedureWho/when/why per transferCase management (BT4)The legal spine
Working-copy disciplineAnalysisNever touch originalsHash-verified copiesThe first rule
Timeline reconstructionAnalysisMulti-artifact chronologyplaso/log2timeline class [verify]TZ discipline
Artifact deep-diveAnalysisRegistry/browser/linksPer-artifact parsersThe detail layer
Cloud preservationCloudStop retention clockLegal process + API exportThe modern seizure
Report fact/interpretation splitReportingDefensible conclusionsTemplate disciplineThe court-survival layer

evidencekit.py — an evidence acquisition and custody tracker: registers artifacts (hashing at acquisition), maintains the custody log (transfers with who/when/why), verifies the integrity chain on demand (re-hash and compare), creates working copies with verified hashes, and emits the custody report — the procedural spine of any forensic engagement, portable and stdlib-only.

#!/usr/bin/env python3
"""evidencekit.py — evidence acquisition + custody tracker.
Usage:
python evidencekit.py --acquire artifact.bin --case INC-001 \\
--collector "j.analyst" --reason "memory capture"
python evidencekit.py --case INC-001 --verify
python evidencekit.py --case INC-001 --copy artifact.bin \\
--to workcopy.bin --handler "j.analyst"
python evidencekit.py --case INC-001 --report
Manifest: evidence_INC-001.json. stdlib only.
"""
import argparse, hashlib, json, os, shutil, sys, datetime
def mpath(case):
return f"evidence_{case}.json"
def now():
return datetime.datetime.now(
datetime.timezone.utc).isoformat()
def sha256(path):
h = hashlib.sha256()
with open(path, "rb") as fh:
for chunk in iter(lambda: fh.read(65536), b""):
h.update(chunk)
return h.hexdigest()
def load(case):
p = mpath(case)
if os.path.exists(p):
return json.load(open(p, encoding="utf-8"))
return {"case": case, "artifacts": [], "custody": []}
def save(case, m):
json.dump(m, open(mpath(case), "w"), indent=2)
def acquire(case, path, collector, reason):
if not os.path.exists(path):
sys.exit(f"artifact missing: {path}")
h = sha256(path)
m = load(case)
art = {"path": path, "sha256": h,
"size": os.path.getsize(path),
"acquired": now(),
"collector": collector, "reason": reason}
m["artifacts"].append(art)
m["custody"].append({"ts": now(),
"action": "acquired",
"artifact": path,
"by": collector,
"note": reason})
save(case, m)
print(f"[+] acquired: {path}")
print(f" sha256={h}")
print(f" custody logged ({collector}: {reason})")
def verify(case):
m = load(case)
print(f"== integrity chain: {len(m['artifacts'])} "
f"artifacts ==")
broken = 0
for a in m["artifacts"]:
if not os.path.exists(a["path"]):
print(f" [MISSING] {a['path']}")
broken += 1
continue
h = sha256(a["path"])
if h == a["sha256"]:
print(f" [OK] {a['path']} "
f"sha256={h[:16]}…")
else:
print(f" [BROKEN] {a['path']}: "
f"{h[:16]}… != {a['sha256'][:16]}…")
broken += 1
print(f"\n{'[!] INTEGRITY FAILURES: ' + str(broken) if broken else '[+] chain intact'}")
return broken == 0
def make_copy(case, src, dst, handler):
m = load(case)
orig = next((a for a in m["artifacts"]
if a["path"] == src), None)
if not orig:
sys.exit(f"src not registered: {src}")
if os.path.exists(dst):
sys.exit(f"destination exists: {dst} (never "
f"overwrite evidence copies)")
shutil.copy2(src, dst)
h = sha256(dst)
ok = h == orig["sha256"]
m["artifacts"].append({"path": dst,
"sha256": h,
"size": os.path.getsize(dst),
"acquired": now(),
"collector": handler,
"reason": f"working copy of {src}",
"working_copy": True})
m["custody"].append({"ts": now(),
"action": "working-copy",
"artifact": dst,
"by": handler,
"note": f"copy of {src}, "
f"hash {'verified' if ok else 'MISMATCH'}"})
save(case, m)
print(f"[+] working copy: {dst} "
f"hash {'VERIFIED' if ok else 'MISMATCH — STOP'}")
def custody_report(case):
m = load(case)
L = [f"# Evidence custody report — {case}", "",
f"generated: {now()}", "",
"## Artifacts", ""]
for a in m["artifacts"]:
wc = " (working copy)" if a.get("working_copy") \
else ""
L.append(f"- `{a['path']}`{wc}")
L.append(f" sha256={a['sha256']}")
L.append(f" acquired {a['acquired']} by "
f"{a['collector']} — {a['reason']}")
L += ["", "## Custody log", ""]
for c in m["custody"]:
L.append(f"- {c['ts'][:19]} {c['action']}: "
f"{c['artifact']} by {c['by']} — "
f"{c['note']}")
return "\n".join(L) + "\n"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--case", required=True)
ap.add_argument("--acquire")
ap.add_argument("--collector")
ap.add_argument("--reason")
ap.add_argument("--verify", action="store_true")
ap.add_argument("--copy")
ap.add_argument("--to")
ap.add_argument("--handler")
ap.add_argument("--report", action="store_true")
args = ap.parse_args()
if args.verify:
verify(args.case)
return
if args.report:
print(custody_report(args.case))
return
if args.acquire:
if not (args.collector and args.reason):
sys.exit("--acquire needs --collector "
"and --reason (custody log is mandatory)")
acquire(args.case, args.acquire, args.collector,
args.reason)
return
if args.copy:
if not (args.to and args.handler):
sys.exit("--copy needs --to and --handler")
make_copy(args.case, args.copy, args.to,
args.handler)
return
print(__doc__)
if __name__ == "__main__":
main()
  • acquire() (lines 26-40): hash at acquisition is mandatory with collector and reason — the tool refuses acquisition without custody information (the mandatory-custody design: an unlogged acquisition isn’t offered as an option).
  • verify() (lines 43-58) re-hashes every artifact and compares against the acquisition hash — MISSING (evidence lost) and BROKEN (evidence changed) reported distinctly, with the boolean return that gates the case’s next steps (BT4’s workflow can refuse to proceed on a broken chain).
  • make_copy() (lines 61-79) implements the working-copy discipline: copy verified against the original’s hash (MISMATCH = STOP — the copy operation that corrupted data halts the workflow), the copy registered as its own artifact (working_copy: true), and the refusal to overwrite existing destinations (evidence copies are never clobbered).
  • The custody report (lines 82-95): artifacts with hashes and provenance, the custody log in order — the document that accompanies the evidence into any proceeding.

The evidence reaches the case at acquisition — every artifact from BT4’s containment (memory captures, disk images, log exports) registered, hashed, and custody-logged — and the chain reaches every downstream consumer verified: BT6’s analysis works on hash-verified working copies, BT7’s hunt results cite chain-of-custody’d telemetry, the report’s findings trace to artifacts whose integrity is provable. The custody discipline reaches the legal and organizational consumers: HR proceedings (the insider case that survives), courts (the intrusion evidence that’s admissible), regulators (the breach investigation whose findings stand), and insurers (the claim supported by defensible evidence). The acquisition discipline reaches the IR process as BT4’s evidence-first rule operationalized: the memory-first capture IS an evidencekit acquisition with custody, the disk image IS a registered artifact — the process and the procedure are one pipeline. The analysis discipline reaches the report: the fact/interpretation split (the registry key exists = fact; the key proves persistence = interpretation with reasoning), the tool-and-version documentation (reproducibility), and the timeline whose every event cites its artifact. For the analyst, the procedural discipline is also practical protection: the analyst whose custody chain is complete is the analyst whose findings survive the hostile review — and in insider cases, that hostile review is personal.

  1. Acquire — memory capture from contained host (BT4 rule): evidencekit acquire, hashed, custody logged
  2. Copy — working copy created and verified: analysis proceeds on the copy
  3. Analyze — BT6 memory analysis on working copy: injection, credentials, timeline
  4. Disk — write-blocked image of the same host: registered, hashed
  5. Timeline — multi-artifact reconstruction: initial access at 09:12, persistence at 09:31
  6. Verify — integrity chain re-run before report: all artifacts intact
  7. Report — findings cite artifacts, facts separated from interpretation
  8. Handoff — custody report accompanies evidence to legal: chain intact end to end

timelinebuild.py — a timeline reconstruction tool: ingests events from multiple artifact sources (CSV exports: filesystem MACB times, log events, registry changes), normalizes timestamps to UTC (with explicit source-timezone handling), merges into one chronology, and flags the timestamp-anomaly classes (backdated files, events out of order vs cause) — the timeline layer that every forensic report builds on. stdlib only.

  • UTC normalization with source-TZ provenance. Every event carries its source timezone; the merged timeline converts to UTC but retains the original — the TZ mishap (the 5-hour shift that breaks the narrative) prevented at the data layer.
  • MACB expansion. Filesystem events expand to their four meanings (Modified/Accessed/Changed/Born) with the semantic labeled — the $STANDARD_INFORMATION vs $ALTERNATE subtlety that timestomping analysis needs.
  • Anomaly flags, not conclusions. Backdating (SI time earlier than the file’s Born time) is flagged with the evidence, not asserted as timestomping — the fact/interpretation split at the tool level.
  • Single-file simplicity. CSV in, chronology out — the tool is the merge/normalize layer; the artifact parsers are upstream.
#!/usr/bin/env python3
"""timelinebuild.py — multi-artifact timeline builder.
Usage:
python timelinebuild.py --events ev1.csv ev2.csv \\
--tz-source "ev1.csv=UTC+2" --out timeline.csv
event CSV: timestamp,source_type,artifact,description,macb
timestamps ISO-8601 with offsets preferred.
stdlib only.
"""
import argparse, csv, sys
from datetime import datetime, timezone
def parse_ts(ts, default_tz="+00:00"):
ts = ts.strip()
if "T" not in ts:
ts += "T00:00:00"
if "+" not in ts and "Z" not in ts and \
"-" not in ts[10:]:
ts += default_tz
ts = ts.replace("Z", "+00:00")
return datetime.fromisoformat(ts).astimezone(
timezone.utc)
def load_events(paths, tzmap):
events = []
for p in paths:
tz = tzmap.get(p, "+00:00")
try:
with open(p, encoding="utf-8",
newline="") as fh:
for r in csv.DictReader(fh):
try:
ts = parse_ts(r["timestamp"], tz)
except (ValueError, KeyError):
continue
events.append({
"ts_utc": ts,
"src_type": r.get("source_type",
"?"),
"artifact": r.get("artifact", p),
"desc": r.get("description", ""),
"macb": (r.get("macb") or
"").upper()})
except OSError as e:
print(f"[!] skip {p}: {e}", file=sys.stderr)
return events
def macb_expand(ev):
"""Expand filesystem MACB to labeled meanings."""
if ev["macb"] not in ("M", "A", "C", "B") and \
len(ev["macb"]) not in (1, 2, 3, 4):
return [ev]
meaning = {"M": "modified", "A": "accessed",
"C": "changed (metadata)", "B": "born"}
out = []
for ch in ev["macb"]:
if ch in meaning:
e2 = dict(ev)
e2["desc"] = f"[{meaning[ch]}] {ev['desc']}"
out.append(e2)
return out or [ev]
def anomalies(events):
"""Backdating flag: modified BEFORE born."""
flags = []
by_file = {}
for e in events:
if e["src_type"] == "filesystem":
key = e["desc"]
by_file.setdefault(key, []).append(e)
for key, evs in by_file.items():
kinds = {m: e for e in evs
for m in [e["desc"][:12]]}
born = next((e for e in evs if "[born]" in
e["desc"]), None)
mod = next((e for e in evs if "[modified]" in
e["desc"]), None)
if born and mod and mod["ts_utc"] < born["ts_utc"]:
flags.append(("BACKDATED?", key,
f"modified {mod['ts_utc'].isoformat()} "
f"before born "
f"{born['ts_utc'].isoformat()}"))
return flags
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--events", nargs="+", required=True)
ap.add_argument("--tz-source", nargs="*",
help="file=UTC+2 pairs")
ap.add_argument("--out")
args = ap.parse_args()
tzmap = {}
for pair in (args.tz_source or []):
if "=" in pair:
k, v = pair.split("=", 1)
tzmap[k] = v
events = load_events(args.events, tzmap)
if not events:
sys.exit("no events loaded")
expanded = []
for e in events:
expanded += macb_expand(e)
expanded.sort(key=lambda e: e["ts_utc"])
print(f"== timeline: {len(expanded)} events ==")
for e in expanded[:40]:
print(f" {e['ts_utc'].isoformat()} "
f"[{e['src_type']:<10}] {e['desc'][:70]}")
flags = anomalies(expanded)
if flags:
print(f"\n[!] timestamp anomalies: {len(flags)}")
for kind, key, msg in flags[:10]:
print(f" [{kind}] {key}: {msg}")
if args.out:
with open(args.out, "w", newline="") as fh:
w = csv.writer(fh)
w.writerow(["ts_utc", "source_type",
"artifact", "description"])
for e in expanded:
w.writerow([e["ts_utc"].isoformat(),
e["src_type"], e["artifact"],
e["desc"]])
print(f"[+] {args.out}")
if __name__ == "__main__":
main()
  • parse_ts() (lines 16-23) normalizes timestamps to UTC with the default-timezone fallback from the --tz-source map — the TZ discipline at the data layer: the original offset stays recoverable in the source CSV, the merged timeline is comparable.
  • macb_expand() (lines 31-41) expands the filesystem MACB semantics (Modified/Accessed/Changed/Born) into labeled events — the expansion that makes the filesystem timeline readable and the timestomping analysis possible.
  • anomalies() (lines 44-60) implements the backdating flag: a file modified before it was born is physically impossible without manipulation — flagged with the evidence (both timestamps), never asserted as timestomping without corroboration. The fact/interpretation split, at the tool level.
  • The merged chronology (lines 63-70): all sources sorted into one UTC timeline — the report’s spine, every event carrying its artifact provenance.

acquire and register evidence from a lab VM (BT4 containment)

Section titled “acquire and register evidence from a lab VM (BT4 containment)”

$ python evidencekit.py —case INC-LAB-1
—acquire mem_capture.raw —collector “j.analyst”
—reason “memory-first capture before isolation” [+] acquired: mem_capture.raw sha256=9f2ab1c4d5e6f7081122334455667788aabbccdd… custody logged (j.analyst: memory-first capture before isolation)

working copy for analysis (original sealed)

Section titled “working copy for analysis (original sealed)”

$ python evidencekit.py —case INC-LAB-1 —copy mem_capture.raw \ —to work_mem.raw —handler “j.analyst” [+] working copy: work_mem.raw hash VERIFIED

build the timeline from two artifact exports

Section titled “build the timeline from two artifact exports”

$ python timelinebuild.py —events fs_events.csv log_events.csv \ —tz-source “fs_events.csv=+02:00” —out timeline.csv == timeline: 118 events == 2026-10-14T07:12:00+00:00 [filesystem] [born] C:\Users… 2026-10-14T07:12:31+00:00 [process] powershell -enc … [!] timestamp anomalies: 1 [BACKDATED?] report.docx: modified 2026-… before born 2026-…

$ python evidencekit.py —case INC-LAB-1 —verify == integrity chain: 2 artifacts == [OK] mem_capture.raw sha256=9f2ab1c4d5e6f708… [OK] work_mem.raw sha256=9f2ab1c4d5e6f708… [+] chain intact

Forensics’ detection-adjacent role is the post-incident depth: the artifacts that BT9’s rules couldn’t see (the registry key, the shellbags, the prefetch) become the detection backlog’s source material, and the timeline’s findings become BT7’s hunt hypotheses — the forensics-to-detection loop. Your own tooling hygiene: evidencekit.py/timelinebuild.py are file tools; the acquisition tooling (memory, disk) is upstream, and its write-blocking guarantees are the foundation everything here assumes. Wazuh/SIEM mapping is indirect — the custody chain lives in the case file (BT4), the timeline feeds the report. The standing practices: hash-on-acquisition (100%), working-copy-only analysis (100%), custody-log completeness (every transfer), and the report’s fact/interpretation separation (every finding) — four disciplines, no exceptions, because the one exception is the case that collapses.

  1. plaso/log2timeline integration: ingest supertimeline outputs as event sources [verify tooling].
  2. Registry artifact parsers: USB history, shimcache, amcache — the high-value Windows artifacts.
  3. Evidence bagging: package artifacts + custody report + hashes into a sealed archive per case.
  4. Multi-custodian workflows: transfer approval requiring both parties’ confirmation.
  5. Retention/legal-hold integration: evidence preservation flags tied to legal-hold status.
SignalSourceIDNotes
Integrity chain statusevidencekit verifyper caseThe admissibility spine
Custody log completenessevidencekit reportper artifactEvery transfer logged
Working-copy disciplineevidencekit copyper analysisOriginals untouched
Timeline anomaly flagstimelinebuildper caseTimestomping candidates
Acquisition order complianceBT4 rule + kitper caseVolatility respected
Evidence-to-finding traceabilityReport reviewper findingEvery claim sourced
Cloud preservation timingLegal process logper caseRetention clock stopped
Report fact/interpretation splitReport reviewper findingThe court-survival layer
Tool/version documentationAnalysis notesper analysisReproducibility
Case file completenessBT4 joinper caseEvidence + actions + report

The forensic-layer evasion is anti-forensics — adversary operations against the evidence itself. Timestomping: backdating file times to corrupt the timeline — countered by the MACB anomaly flags (SI-vs-born inconsistency), by $LogFile/$USN cross-checks (the NTFS journals that remember the real times), and by the analysis that treats timestamps as claims to corroborate, not facts. Log wiping: T1070’s classes (the 1102 event, the wevtutil loop) — countered by remote forwarding (BT3), by the volume baselines that notice the wipe, and by the residual artifacts that survive (USN journal, SI events around the deletion). Memory evasion: wiping processes’ traces before capture — countered by the memory-first rule (capture before the adversary can act) and by the residual artifacts (the registers, the freed-but-present pages BT6 recovers). Secure-delete tools: overwrite-based destruction of specific files — countered by the volume shadow copies, the cloud sync copies, the backup sets, and the file-system artifacts that survive (MFT entries, USN records). Encrypted containers: evidence that exists only encrypted — countered by key recovery from memory (BT6’s dump-before-power rule), by the physical layer (H1’s SPI dumps), and by the legal process that compiles disclosure. The meta-point: anti-forensics raises the cost of evidence but rarely eliminates it — the discipline’s response is breadth (multiple artifact classes), depth (the journals under the files), and speed (the memory-first acquisition that catches everything before the wipe).

⚠️ What caught me: the insider case where my timeline “proved” the employee exfiltrated files on a Tuesday — until the defense’s expert showed the laptop’s clock had been wrong by three hours all month (the NTP server unreachable, the clock drifting), and my entire narrative collapsed into a different Tuesday, a different alibi, and a very different story. My timestamps were accurate to their source and wrong about reality — because I’d trusted the device’s clock instead of cross-checking it. Since then, every timeline starts with the clock-check step: compare the device’s clock against an authoritative source (log correlation, file-system comparison with a known-good peer), document any skew, and normalize the narrative with the skew applied. The timeline that doesn’t know its own clock is a story with an unreliable narrator.

  1. Custody drill: acquire a lab artifact, copy it, verify the chain, then deliberately corrupt the working copy and confirm --verify catches it — the integrity chain, tested to failure.
  2. MACB timeline: generate file activity on a lab VM, export the filesystem events, and build the timeline with timelinebuild.py — confirm the MACB expansions and the UTC normalization.
  3. Timestomping drill: backdate a file’s modification time on the lab VM, rebuild the timeline, and confirm the BACKDATED flag — the anomaly detection, validated against a known manipulation.
  4. Clock-skew drill: shift the lab VM’s clock by 2 hours, capture events, and cross-correlate with a known-good host’s logs — the clock-check discipline that the ⚠️ story institutionalizes.
  5. Full-case rehearsal: run a complete mini-case — acquisition → custody → copy → timeline → verify → report — and time each step; your forensic bench’s standard operating rhythm.
  • Technical: Explain the order of volatility and why memory-first capture precedes all power actions — what dies, in what order?
  • Technical: What makes an evidence hash chain admissible, and which custody-log fields are non-negotiable?
  • Scenario: Your timeline places the employee’s exfiltration on Tuesday, but the defense shows the device clock drifted 3 hours. What does correct handling look like?
  • Conceptual: Why is working-copy-only analysis a hard rule, and what does the hash-verified copy step protect against?
  • Conceptual: How does the fact/interpretation split change a forensic report’s survivability in adversarial review?
  • Deep-dive: Design the forensic capability for an IR team: tooling, acquisition procedures, custody infrastructure, and the training that makes it repeatable.
  • Practical: HR needs “defensible evidence of data theft” in 48 hours. What does your pipeline deliver, and what do you refuse to overclaim?

BT4 (Incident Response Process) · BT6 (Memory Forensics) · BT7 (Threat Hunting) · H2 (Firmware Extraction & Analysis) · F2 (Linux Internals)