Click any topic to see why it matters — several also expand with the actual commands, paths, or workflow you'd use.
A few habits that make every module below faster to apply once you're in a real scenario.
Whether it's a phishing verdict or a full IR write-up, structuring your answer the same way every time makes it faster to write — and easier for a grader to follow. A reliable skeleton:
Example opening line: "On [date/time], user [X] received a phishing email impersonating [brand] that led to execution of [file/technique] on host [Y]. The activity is assessed as malicious with [confidence] confidence based on [key evidence]." Leading with a sentence like this signals you understood the scenario before the grader reads another word.
A time-box, not a rulebook — the point is to stop yourself either freezing on question 1 or burning 10 hours on a single Hard while three Easy ones sit unanswered. Adapt the hours to whatever window your exam actually gives you; the order is what matters.
| Phase | Roughly | What you're doing |
|---|---|---|
| Kickoff | First ~5% | Read the whole scenario doc once. Read every question twice. Mark each Easy/Medium/Hard and note which tool it's clearly pointing at. Open your timeline notes file before touching any tool. |
| Easy sweep | Next ~20% | Answer everything Easy first. Every finding — even ones you don't need yet — goes into the timeline as one line: time, host, user, event. This is what makes the Medium pass fast. |
| Medium pass | Next ~35% | Work the Mediums using the timeline as your anchor. A common pattern: question 1 identifies the compromised user/host, questions 2 onward just reuse that anchor. |
| Hard pass | Next ~25% | Now the Hards have context — the Easy/Medium answers and the timeline usually hand you most of the pivot already. |
| Verify | Next ~10% | Re-read every answer against the exact format the question asked for. Copy-paste values instead of retyping — a mistyped hash or MITRE ID is a wrong answer even when the finding was right. |
| Rest | As needed | A tired brain both misreads questions and mistypes answers — a short break usually nets positive time back. |
| Final check | Last stretch | One last pass, then submit. See "Final 60 minutes — verify ritual" in the Quick Reference for the exact checklist. |
The habit underneath the schedule: keep a running timeline from minute one, in one consistent format (TIME | HOST | USER | EVENT), and don't skip logging an Easy-question finding just because it feels too obvious to write down — it's very often the exact anchor a later Hard question needs.
attack.mitre.org / ATT&CK Navigator for mapping and visualizing what you've found.Hands-on with the platforms you'll actually use to pivot on indicators day to day. Click through to any of these:
Teaches following streams and exporting objects — this is how you actually pull evidence out of a capture.
Applies Wireshark to real attack traffic — the applied skill, not just the tool interface.
| Operator | Meaning |
|---|---|
eq / ==, ne / != | Equal / not equal |
gt / >, lt / <, ge / >=, le / <= | Greater/less than (or equal) |
and / &&, or / ||, not / ! | Logical AND / OR / NOT |
xor / ^^ | Exactly one side true, not both — rarely needed but occasionally the cleanest way to isolate an either/or condition |
[ ] substring | Match part of a field, e.g. eth.src[0:3] == 00:70:f4 for a MAC OUI prefix |
{ } membership | Match against a set of values, e.g. tcp.port in {80 443 8080} |
eth.addr == 00:70:f4:23:18:c4 eth.dst == ff:ff:ff:ff:ff:ff # broadcast traffic
ip.addr == 10.0.0.5 ip.src == 10.0.0.5 ip.dst == 185.x.x.x !(ip.addr == 10.0.0.0/8)
tcp.port == 4444 tcp.dstport == 8080 || tcp.dstport == 443 udp.port == 53
dns.qry.name contains "evil" dns.qry.name.len > 50 dns.qry.type == 16 dns.flags.response == 0
http.request.method == "POST" http.request.uri contains "gate" || http.request.uri contains "panel" http.user_agent contains "python" || http.user_agent contains "curl" http.response.code >= 400 http && frame.len > 10000
smb || smb2 smb2.filename contains ".exe" || smb2.filename contains ".ps1" smb2.filename contains "ADMIN$" || smb2.filename contains "C$"
tcp.flags.syn == 1 && tcp.flags.ack == 0 ip.dst == <suspected_c2> frame.len > 1400 && tcp
tls.handshake.type == 1 # Client Hello — check the SNI for the real destination domain tls.handshake.extensions_server_name contains "evil" tls.handshake.type == 11 # Server certificate — check issuer/validity ssl.record.version == 0x0301 # unusually old TLS version, sometimes a red flag
Even without decrypting, the JA3/JA3S fingerprint of the TLS handshake can identify known malware families — worth checking against a JA3 blacklist if you suspect C2 over HTTPS.
kerberos && tcp.port == 88 kerberos.CNameString kerberos.msg_type == 10 # AS-REQ — relevant when hunting AS-REP roasting / Kerberoasting attempts
arp.duplicate-address-detected # possible ARP spoofing icmp.type == 8 && data.len > 64 # oversized ICMP payloads can indicate ICMP tunneling
ftp.request.command == "USER" || ftp.request.command == "PASS"
tcp.analysis.retransmission tcp.analysis.zero_window
Useful when you don't have the GUI, or want to script extraction against a large capture:
tshark -r capture.pcap -Y "http.request" -T fields -e ip.src -e http.host -e http.request.uri tshark -r capture.pcap -Y "dns" -T fields -e dns.qry.name | sort -u tshark -r capture.pcap --export-objects http,./extracted/
The filters above are grouped by protocol; this set is grouped by intent, which is often faster when a question tells you the goal but not the protocol ("was there brute forcing," "was data exfiltrated") — a useful companion to the question-pattern table in the playbook card below.
Weak protocols & misconfigurations
ssl.handshake.version <= 0x0301 # outdated TLS in use (SSLv3 / TLS 1.0 / 1.1) — downgrade attack or just a misconfigured server telnet || http.authbasic || ftp.request.command == "PASS" || pop || imap # any cleartext-credential-carrying protocol present at all smb.negotiate_protocol.index == 0 # SMBv1 negotiated — the version EternalBlue/WannaCry actually target
Data exfiltration & tunneling
icmp.type == 8 && data.len > 100 # oversized ICMP echo payloads — possible ICMP tunneling dns.count.labels > 10 # unusually deep subdomains — classic DNS-tunneling shape, catches what a TXT-record filter alone would miss http.request.method == "POST" && http.content_length > 500000 # large outbound POST body leaving the network
Lateral movement & exploitation
ntlmssp.auth.status == 0xc000006d # NTLM auth failure — brute force / password-spraying signal, especially in volume against one host smb2.filename contains "svcctl" || smb2.filename contains "RemCom" # PsExec-style remote service control over SMB http.request.uri contains ".." || http.request.uri contains "/etc/passwd" # directory traversal attempt in a URI
Reconnaissance & scanning
tcp.flags.syn == 1 && tcp.flags.ack == 0 && tcp.window_size <= 1024 # TCP stealth (SYN) scan tcp.flags == 0x000 # TCP Null scan — no flags set at all tcp.flags == 0x029 # TCP Xmas scan — FIN, PSH, and URG set together
System health & anomalies
_ws.malformed # malformed packets — fuzzing attempt, or just a bad NIC/capture _ws.expert.severity >= 2 # Expert Info, errors and warnings only — the concrete filter for a final anomaly sweep
That last filter is the literal command behind "Expert Information as a last sweep" in the investigation playbook below — run it once you've exhausted the specific leads and want Wireshark to flag anything it independently considers anomalous.
The filter cheat sheet above answers "how do I write this filter." This is the layer above it — why you'd look in that order, and what a question's exact phrasing is telling you to do. Where the filters live is in the Exam Tracker's Quick Reference; this is the reasoning that gets you there faster.
Writing a specific display filter before you've looked at the capture as a whole is how you miss things — you can only filter for what you already suspect exists. The point of opening with Statistics is to let the capture tell you what's actually in it, instead of guessing:
The underlying principle is the same one that shows up everywhere else in this pack: cast wide first, narrow once you have a real reason to. A too-specific filter written too early doesn't just slow you down — it can hide the answer entirely, because you never see the traffic that would have told you the filter was wrong.
BTL1-style questions tend to encode which Wireshark feature you need directly in their wording — recognizing the pattern saves the trial-and-error:
| Question is asking about… | Points you toward |
|---|---|
| What was downloaded | HTTP GET requests → Export Objects → HTTP |
| What domain was contacted | DNS queries (dns.flags.response == 0) → dns.qry.name, or the TLS SNI field if it's HTTPS |
| Whether there was C2 | Conversations → an external IP with sustained or evenly-spaced traffic, not a one-off connection |
| What tool/script made the request | The http.user_agent field — scripted tools rarely bother spoofing a browser string |
| Whether there was brute forcing | Filter to the target service/port, then count failure responses grouped by source |
| What's inside HTTPS traffic | Content is unreadable without the key, but the SNI in the Client Hello still gives you the destination domain |
| Whether data was exfiltrated | Conversations sorted by bytes descending — look for outbound-heavy flows to unfamiliar destinations |
| Whether credentials were sent in the clear | http contains "password", or ftp.request.command == "PASS" for FTP |
This mapping is exactly why "what is the question actually asking me to go find" is worth thirty seconds of thought before you touch the filter bar — the phrasing is doing half the work of telling you which Statistics menu or filter family to reach for.
Mirrors the mostly-Windows BTL1 content with Linux-specific artifacts — fills a real gap most students miss.
/etc/passwd /etc/shadow /etc/group /etc/sudoers /etc/crontab /etc/cron.* /var/spool/cron/ /var/log/auth.log # Debian/Ubuntu /var/log/secure # RHEL/CentOS /var/log/syslog /var/log/messages /home/<user>/.bash_history /home/<user>/.ssh/ /tmp /dev/shm /var/tmp
# Users / privileged accounts
awk -F: '($3==0){print}' /etc/passwd
grep -E 'sudo|wheel' /etc/group
sudo -l
# Auth / logon
grep -iE 'accepted|failed|invalid|sudo' /var/log/auth.log
last | lastb | w
# History / persistence
cat ~/.bash_history
systemctl list-unit-files --type=service
crontab -l -u <user>
# Network / processes (live)
ss -tulnp | ps aux | lsof -i | netstat -antp
# Hashing / integrity
sha256sum <file>
# File carving — recover deleted/fragmented files from an image or unallocated space
scalpel -b -o <output_dir> <disk_image>
# Embedded metadata (EXIF, GPS, author, editing app — device/author linkage)
exiftool <file>
What to note: new UID 0 accounts, unexpected sudoers, SSH authorized_keys, cron/systemd persistence, failed-then-success logons, unusual shells or home dirs.
The foundation for the entire Phishing Analysis section — headers, artifacts, verdicts. Full workflow:
Convert http → hxxp and . → [.] before any lookup or paste, so you never trigger a live link.
Received: chain bottom to top → true originating IP.From:, Return-Path:, Reply-To:, Sender: for mismatches.| Type | Value | Source | Notes |
|---|---|---|---|
| Sender IP | x.x.x.x | Received header | … |
| Domain | evil[.]com | From / URL | … |
| File hash | abc123… | Attachment | SHA256 preferred |
Recommend blocking domains/IPs/hashes, map to MITRE ATT&CK (Initial Access – Phishing T1566), then write a short structured report: summary, IOCs, analysis steps, verdict, recommended actions, lessons learned.
You'll be identifying protocols and ports constantly in packet captures and logs — know the common ones cold.
| Port | Service |
|---|---|
| 20/21 | FTP |
| 22 | SSH |
| 23 | Telnet |
| 25 | SMTP |
| 53 | DNS |
| 67 / 68 | DHCP |
| 80 / 443 | HTTP / HTTPS |
| 88 | Kerberos |
| 110 / 143 | POP3 / IMAP |
| 135 / 139 / 445 | RPC / NetBIOS / SMB |
| 389 / 636 | LDAP / LDAPS |
| 514 | Syslog |
| 3389 | RDP |
| 5985 / 5986 | WinRM |
Also watch for non-standard C2 ports in Wireshark — 4444, 8080, 8443, and other high random ports.
This entire section is core — one of the most heavily used skillsets in day-to-day Blue Team work.
Before you spend an hour on full IR, the very first decision is which of these three buckets you're actually looking at — and that decision alone determines whether the rest of your time is even justified. Categorization is the bottleneck skill here, more than any single technical check: it's easy to tunnel-vision into treating everything as spam (and miss a real phish) or treating everything as a full incident (and burn hours on a newsletter).
| Category | Typical examples | Response |
|---|---|---|
| Spam | Marketing floods, newsletter spam | Block the sender. No incident response needed. |
| Scam | 419/advance-fee scams, romance scams, fake invoices | User awareness note, possibly a law-enforcement referral. No IR. |
| Phishing — credential harvester | Fake login pages impersonating a real service | Full IR: block the domain/IP, hash and share the IOCs, notify anyone who clicked. |
| Phishing — malicious attachment | Double-extension files (.pdf.exe), macro-enabled Office docs, ISO/IMG droppers | Full IR: sandbox the file, hash it, pivot the hash/IOCs through threat intel. |
| Phishing — recon | Probing for out-of-office/auto-reply responses to map who's real and who's away | Block, then watch for a follow-up campaign — this is usually a precursor, not the main event. |
Practical read order: confirm it's not just spam/scam first (cheap, fast — usually obvious from sender + content alone), then, once you're confident it's phishing, use the sub-category to decide your next move — a credential harvester sends you straight to URL analysis and clicker notification, while a malicious attachment sends you straight to sandboxing and hashing.
Speeds up the same analysis once you already understand the manual process. CyberChef is your go-to for decoding/defanging along the way.
PowerShell's -enc / -EncodedCommand flag takes Base64 of UTF-16LE text, not plain UTF-8 — so a single "From Base64" step gives you garbage with null bytes between characters. Two-step recipe:
Recipe: From Base64 → Decode text (UTF-16LE (1200)) Input: JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAA... Output: readable PowerShell source
Other recipes worth keeping bookmarked: URL Decode → Remove whitespace for messy phishing links, and the Defang URL / Fang URL operations for safely pasting IOCs into a report without them being clickable.
Understanding NTFS/EXT basics is what makes artifact locations later make sense. Key Windows paths you'll navigate constantly inside Autopsy:
C:\Windows\System32\config\ → SYSTEM, SOFTWARE, SAM, SECURITY, DEFAULT hives C:\Windows\Prefetch\ → Prefetch files C:\Windows\System32\winevt\Logs\ → Event Logs (.evtx) C:\Windows\AppCompat\Programs\Amcache.hve C:\Users\<username>\ → NTUSER.DAT ...\AppData\Local\Microsoft\Windows\UsrClass.dat ...\AppData\Roaming\Microsoft\Windows\Recent\ → LNK files, Jump Lists
$MFT, USN Journal ($J), and Alternate Data Streams.sha256sum <file> / md5sum <file>.The fast-triage tool you'll use repeatedly to pull artifacts without imaging an entire disk.
kape.exe --tsource C: --tdest E:\Evidence --tflush --target !SANS_Triage
Then parse the output with the Eric Zimmerman tools (PECmd, AmcacheParser, AppCompatCacheParser, LECmd, JLECmd).
Prefetch, shimcache, and similar — the go-to evidence for "was this program executed."
C:\Windows\Prefetch\*.pf — run count + last 8 timestamps (often disabled on servers)C:\Windows\AppCompat\Programs\Amcache.hve — includes SHA1, great for VirusTotal pivotsThese are Eric Zimmerman's tools — free, and the standard way to turn raw artifacts into a clean CSV you can pivot in Excel, Timeline Explorer, or re-ingest into Splunk:
# Prefetch — PECmd PECmd.exe -d "C:\Windows\Prefetch" --csv "C:\output" --csvf prefetch.csv # Amcache — AmcacheParser AmcacheParser.exe -f "C:\Windows\AppCompat\Programs\Amcache.hve" --csv "C:\output" # ShimCache / AppCompatCache — AppCompatCacheParser AppCompatCacheParser.exe -f "C:\Windows\System32\config\SYSTEM" --csv "C:\output"
Parsing tools: PECmd, AmcacheParser, AppCompatCacheParser, ProcDump for live process memory. Triage priority: Prefetch + Amcache + key Event Logs + UserAssist for a quick picture of what executed and when.
Browser history/downloads are frequently the pivot point in phishing-to-compromise chains.
%AppData%\Microsoft\Windows\Recent\...\Recent\AutomaticDestinations\ and CustomDestinations\# LNK files — LECmd LECmd.exe -d "C:\Users\<user>\AppData\Roaming\Microsoft\Windows\Recent" --csv "C:\output" # Jump Lists — JLECmd JLECmd.exe -d "...\Recent\AutomaticDestinations" --csv "C:\output"
Tools: Browser History Capturer / Viewer, JumpList Explorer, Windows File Analyzer for LNK shortcuts.
$I (metadata) and $R (actual file) entries. Small topic, commonly tested.awk -F: '($3==0){print}' /etc/passwd for UID 0 accounts, grep -E 'sudo|wheel' /etc/group for privileged users. Full Linux forensics cheat sheet is under "Linux Forensics" above./var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/CentOS) for logon activity, /var/lib/ for package and service state.~/.bash_history, ~/.ssh/, cron/systemd persistence.Memory analysis catches things disk forensics never will — a genuinely different, essential skill. Labs may use Volatility 2 (needs --profile=) or Volatility 3 (no profile) — keep both syntaxes ready.
volatility -f memory.dmp imageinfo volatility -f memory.dmp --profile=PROFILE pslist volatility -f memory.dmp --profile=PROFILE pstree volatility -f memory.dmp --profile=PROFILE netscan volatility -f memory.dmp --profile=PROFILE malfind volatility -f memory.dmp --profile=PROFILE cmdline volatility -f memory.dmp --profile=PROFILE filescan
vol -f memory.dmp windows.info vol -f memory.dmp windows.pslist vol -f memory.dmp windows.pstree vol -f memory.dmp windows.netscan vol -f memory.dmp windows.malfind vol -f memory.dmp windows.cmdline vol -f memory.dmp windows.filescan
pslist/pstree — odd parents, short-lived processes, suspicious namesnetscan — external connections and unusual portsmalfind — injected code regionscmdline/dlllist on interesting PIDs, then dump for further analysisThe GUI disk-forensics tool you'll rely on for full disk-image investigations. The full loop: new case → add data source → wait for ingest → keyword search → filter with File Views → tag relevant items → generate a report from the tagged items → cite that report in your own write-up. The Autopsy HTML report is supporting evidence, not your final report — your narrative is what cites it, e.g. "Nmap was downloaded from nmap.org at 17:14 UTC — see report.html → Web Downloads."
| Field | What to set |
|---|---|
| Case type | Single User for solo analysis (Multi-User needs a server and lets a team work the same case concurrently — not the BTL1/exam scenario) |
| Base directory | A dedicated non-system drive/folder — never mix case data with your own workstation's C:\ |
| Time zone (on the data source) | UTC if unknown — don't guess a locale, it silently shifts every timestamp you read afterward |
| MD5 / SHA256 (on the data source) | Paste from your imaging tool's verification output — Autopsy does not auto-validate these; run the Data Source Integrity ingest module to actually verify them |
.dd/.raw/.001, EWF .E01, VMDK — the default choice; always work off a copy of a copyEnable more than you think you'll need — you can't go back and reprocess evidence for a module you skipped. Keep on by default: Recent Activity, Hash Lookup (✅ tick "Calculate MD5 even if no hash set" — the single most-forgotten checkbox), File Type Identification, Extension Mismatch Detector, Embedded File Extractor, Picture Analyzer, Keyword Search, Email Parser, Interesting Files Finder, Central Repository, PhotoRec Carver, Data Source Integrity. Turn on situationally: Encryption Detection (slow), YARA Analyzer (malware cases), Android/iOS Analyzer (mobile cases). Usually leave off: Plaso — duplicates other modules' output and is very slow for what it adds.
Ingest time scales hard with image size: a thumb drive finishes in seconds to minutes; a single 1TB workstation drive can take several hours to 24+ hours, more with Encryption Detection/Plaso/OCR enabled. Start ingest at the end of a working session, not when you need answers in the next ten minutes.
Exact enforces word boundaries — fewer, cleaner hits (searching cat won't also match catalog). Substring is the opposite trade: more hits, more noise. Regex is the most powerful and the easiest to get subtly wrong — write it carefully. Always tick Save the search, or the results live only in a one-shot tab instead of persisting under Analysis Results → Keyword Hits.
| Tag | Use for |
|---|---|
| Bookmark | Likely relevant, want to revisit |
| Notable | Confirmed relevant — this is what shows up in your final report scope |
| Follow Up | Worth a second look, not yet confirmed either way |
Tag aggressively while you're still exploring — under time pressure, an untagged lead is a lead you'll forget you found. Tagged items collect under Tree → Tags for one-click review, and Tools → Generate Report → Specific Tagged Results builds your evidence pack straight from them (pick HTML, then just Bookmark + Notable, skipping unresolved Follow Ups).
After ingest finishes, two tree sections hold almost everything you need: Data Artifacts (whatever the ingest modules extracted, sorted by category) and Analysis Results (module-driven findings — entropy hits, mismatches, keyword hits). The actual skill is triangulating across categories — one artifact rarely tells the whole story, three that agree usually do.
| Category | What it tells you |
|---|---|
| Installed Programs | Profiles user skill/intent in seconds — an FTP client implies a remote server somewhere, a scanner implies a target range, privacy tools imply evasion intent |
| Metadata (embedded, not filesystem) | Survives filesystem MAC-time tampering — matching Author/Organization fields across differently-named files can link them to one common source |
| Operating System Information | Pulled from the SOFTWARE hive — confirms the actual system drive letter and the likely primary user; don't assume C:\ until you've checked |
| Recent Documents (LNK files) | ⚠️ The single biggest "go back and seize more evidence" signal — an LNK pointing at E:\ or any drive letter not present in your image means an external drive existed and was never seized |
| Recycle Bin | Paired $I (metadata) / $R (content) files — but Shift+Delete bypasses this entirely, so an empty Recycle Bin is not proof nothing was deleted |
| Run Programs (Prefetch-derived) | Your primary execution-timeline table — last-run time + run count per binary; sort by name and read straight off it |
| Shell Bags | Every drive letter and folder ever browsed via Explorer, even ones with no files left behind — proves a drive existed even without a surviving LNK |
| USB Device Attached | Make/model + connect time + device serial — the serial can physically link two suspects' machines, or disprove a denial that a device ever existed |
| Web Downloads | Often the single most valuable column on a case: filename + source URL + save path + timestamp — pair with Run Programs for a download→install→run chain |
| Web Form Autofill | Cached usernames typed into login forms — use one as a keyword-search seed to pivot into emails/forum handles/chat accounts elsewhere on the image |
| Web Search vs. Web History | Search terms show intent — investigate these first. History shows behavior/what actually got opened — investigate second. |
| Web Accounts / Cache / Cookies | Accounts logged into, domains + first-access time, per-cookie domain/set-time/value — mostly timeline anchors and visited-site proof |
| Category | Sanity-check before trusting it |
|---|---|
| Encryption Suspected | High entropy ≠ encrypted — Prefetch .db files are densely encoded and a very common false positive; weigh location + filename + size before flagging it as real |
| EXIF Metadata | Capture date, device, GPS, editing program — always cross-check the hex view too, the parser can miss non-standard EXIF tags |
| Extension Mismatch Detected | Install NSRL if you can — it filters out known-good system files, leaving only genuinely anomalous header/extension mismatches to review |
| Interesting Files | Default rule categories: cloud storage, crypto wallets, encryption programs, privacy programs — extend with your own custom mime-type signatures per case type |
| Keyword Hits — email addresses | Huge false-positive rate (the regex matches email-shaped strings inside binaries/libraries too) — double-click the hit-count column to sort descending; the top address is almost always the primary user's own identity |
| Previously Unseen | Central-repository correlation — nearly everything is "unseen" on your very first case; the signal only gets sharp once you've built up case history |
| User Content Suspected | Autopsy's guess at user-generated vs. system files — a useful filter to cut noise, not a guarantee |
This is the pattern the exam rewards: don't stop at one artifact, cross-reference until the story is airtight.
Installed Programs → Nmap 7.91 present Run Programs → nmap setup.exe run 17:15; nmap.exe run 17:37 (count 3) PowerShell history → ConsoleHost_history.txt: 3 nmap commands vs 10.0.2.15 + /24 Web Downloads → nmap-7.91-setup.exe from nmap.org, 17:14, saved to Downloads\ Reconstructed timeline: 17:14 Downloaded nmap-7.91-setup.exe from nmap.org 17:15 Installed (setup.exe prefetched) 17:15-37 Ran nmap 3x via PowerShell, scanning 10.0.2.15 and the /24 range
| You need | Go to |
|---|---|
| Did the user run a specific program? | Data Artifacts → Run Programs (Prefetch) — last-run time + run count |
| Does another device (USB/external drive) exist that wasn't seized? | Recent Documents (LNK to a foreign drive letter) + Shell Bags + USB Device Attached |
| What did they search for / browse to? | Web Search (intent) before Web History (behavior) |
| Who is the primary user, identity-wise? | Analysis Results → Keyword Hits → email regex, sorted by hit count descending |
| Is a file hiding its real type? | Analysis Results → Extension Mismatch Detected (NSRL-filtered) |
| Is something encrypted? | Analysis Results → Encryption Suspected — verify context before trusting it |
| Is this genuinely new to this case/org? | Analysis Results → Previously Unseen (Central Repository) |
Habits that pay off under time pressure: sort columns aggressively — most "find the suspect" answers fall out of a single sort; bookmark before you fully understand, prune later, since untagged context evaporates fast; cross-check across categories rather than trusting one in isolation (Installed Programs alone is weak, Installed + Run + Web Downloads together is strong); and cite the full source path in your notes — Users\john\NTUSER.DAT, not just "registry".
Windows\System32\config\ (SYSTEM, SOFTWARE, SAM, SECURITY, DEFAULT)NTUSER.DAT and UsrClass.datAlways note the exact path and timestamp of anything you extract, and cross-reference with Event Logs and Splunk results.
The single most common data source you'll be searching through in any Windows-based incident. Core Event IDs to know:
Dramatically richer logging than default Windows Event Logs — the tool that makes real detection possible.
The exact SPL skills every Splunk investigation lab assumes you already have. Always start by identifying the correct index= and sourcetype=.
| Field | What it holds | Why you'd look at it |
|---|---|---|
_time | Event timestamp | Builds your timeline and lets you narrow to the incident window. Watch for odd-hour activity or gaps that hint at log tampering. |
index | Which data repository the event lives in (e.g. wineventlog, main, firewall) | Confirms you're actually searching the right data source — the wrong index means you silently miss evidence, not that there's none. |
sourcetype | Format Splunk assigned to the data (e.g. WinEventLog:Security, sysmon) | Tells you which other field names to expect — Windows Security fields look different from Sysmon or firewall fields. |
host / ComputerName | The machine that generated the event | Scopes your search to the affected host(s), and helps spot lateral movement — same account showing up on hosts it normally doesn't touch. |
EventCode / EventID | The specific Windows event type (4624, 4688, 4625…) | Your primary filter for "what kind of activity happened" — logon, process creation, account change, log clear, etc. |
Account_Name / user | Username involved in the event | Flags accounts that shouldn't be doing this — a service account logging in interactively, an unexpected admin, or a terminated employee's account. |
src_ip / Source_Network_Address | Where the connection or logon came from | Look for external IPs on internal-only accounts, geographically odd source IPs, or one IP hitting many accounts (password spraying). |
dest_ip / DestinationIp | Where traffic or a connection went to | Check against threat intel for known-bad IPs, or watch for rare/unseen internal-to-internal destinations — a sign of lateral movement. |
src_port / dest_port | Source / destination port | Unusual high ports or common C2 ports (4444, 8080, 8443) are worth a second look, especially paired with an odd destination. |
Logon_Type | How the logon happened — 2 = interactive, 3 = network, 10 = RDP | Type 10/3 from somewhere unexpected is far more suspicious than a Type 2 at the physical console. |
Image / New_Process_Name | Full file path of the process that ran | Legit software runs from Program Files/System32 — a process launching from Temp, AppData, or Downloads is a red flag. |
ParentImage / Creator_Process_Name | The parent process that spawned it | Mismatched parent-child pairs are one of the strongest signals you'll find — e.g. Word or Excel spawning PowerShell. |
CommandLine / Process_Command_Line | The exact command that was run | Where you actually find encoded PowerShell, download cradles, and LOLBins — read closely for -enc, IEX, DownloadString, certutil, bitsadmin. |
process_name | Just the executable name, pulled from the command line | Faster to stats/top by than the full path — good for spotting a rare process name across many hosts. |
signature | Name of the alert/rule that fired (AV, IDS, correlation search) | Tells you what a security tool already flagged — usually your fastest starting point/pivot into deeper manual analysis. |
A lot of Windows Security events split "who did it" from "who/what was acted on" into two separate fields. Knowing which is which saves you from misreading an event.
| Field | What it holds | Why you'd look at it |
|---|---|---|
SubjectUserName / Subject_User_Name | The account that performed the action | The "who did it" — critical when an attacker is using a compromised account to act on a different target account (privilege escalation, account creation on someone else's behalf). |
TargetUserName / Target_User_Name | The account being logged into, created, or modified | In 4624/4625 this is who's logging on; in 4720/4732 it's the account being created or added to a privileged group — flags unexpected new accounts or privilege changes. |
TargetFileName | Full path of a file being created, deleted, or modified (Sysmon Event 11 FileCreate / 23 FileDelete) | Where you catch a dropped payload or evidence being deleted — e.g. an executable written to Temp or AppData right before execution. |
TargetObject | The registry key/value being modified (Sysmon Event 12/13/14) | Where you catch persistence being set up — e.g. a new Run key, service entry, or Winlogon shell modification. |
TargetImage | The process being accessed or injected into (Sysmon Event 8 CreateRemoteThread / 10 ProcessAccess) | Flags process injection or credential dumping — e.g. an unfamiliar process opening a handle to lsass.exe. |
Field names shift depending on the sourcetype/Technology Add-on (Windows TA fields look different from raw Sysmon XML, for example) — if a field you expect isn't showing up, check the Fields sidebar on the left of your search results, or run | fieldsummary / | top <field> to see what's actually available in that index.
# Failed logons index=* EventCode=4625 | stats count by Account_Name, src_ip, ComputerName | sort -count # Suspicious process creation index=* (EventCode=4688 OR EventCode=1) | search CommandLine="*powershell*" OR CommandLine="*-enc*" OR CommandLine="*IEX*" OR CommandLine="*DownloadString*" | table _time, ComputerName, User, ParentImage, Image, CommandLine | sort -_time # Aggregation helpers | stats count by src_ip, dest_ip, dest_port | top limit=20 Account_Name | timechart span=1h count by src_ip # Decode a base64 command line | rex field=CommandLine "-enc\s+(?<encoded>[A-Za-z0-9+/=]+)" | eval decoded=base64decode(encoded)
Investigation flow: start broad with a relevant time window → filter by EventCode or host → pivot with stats/table → tighten the time range once a lead appears.
Think of it as a standalone SIEM in a script — Eric Conrad's PowerShell tool applies dozens of detection rules to raw .evtx files in one pass. Its real value shows up specifically when Splunk isn't an option: an offline EVTX handed to you with no SIEM ingesting it, or a pivot target when a Splunk search comes back empty and you want a second, independently-built detection pass over the same logs. Full commands (single file, bulk-run + grep, the logging-enabled pre-check, and the Mimikatz string list) are in the Exam Tracker's Quick Reference — this card is the "why" behind them.
| Category | Event IDs it scans | What it catches |
|---|---|---|
| Long / unusual command lines | 4688, 4103, 4104 | Encoded PowerShell, oversized or obfuscated payloads |
| Base64-encoded PowerShell | 4103, 4104 | The -EncodedCommand pattern specifically |
| Password spraying | 4625 | Many different usernames, each with only a few attempts — distinct from a classic single-account brute force |
| Mimikatz-style keywords | 4103, 4104, 4688 | sekurlsa, lsadump, kerberos:: and similar strings |
| Suspicious service creation | 7045, 4697 | Service-based persistence |
| Account creation | 4720, 4732, 4756 | Backdoor accounts, especially ones added straight into a privileged group |
| PowerShell download cradles | 4103, 4104 | Net.WebClient, IEX, DownloadString |
| WMI execution | 4688 | A common lateral-movement technique |
| Log clearing | 1102 | Anti-forensics — the tool flags its own blind spot when someone's tried to cover tracks |
This is exactly why the "was logging even enabled" pre-check (in the Quick Reference) matters so much: DeepBlueCLI is only as good as the events actually present in the EVTX. A clean result against a log where 4104 was never being generated in the first place isn't evidence of nothing happening — it's evidence you were looking in a log with a hole in it.
The tool you'll use to actually document and track the incident as you work it.
You don't need a deep admin write-up — know how to create a case, attach IOCs, and find them again.
The eradication step — directly follows from everything you found during detection and analysis. Common persistence to check and remove:
HKLM\SYSTEM\CurrentControlSet\Services (Event 4697 / 7045)All of it is core — the closest hands-on practice to real Blue Team work. Make sure to complete every one of these.
Not a BTL1-assigned lab — Splunk's own tool (splunk/attack_range on GitHub) for spinning up a lab environment pre-loaded with realistic attack data, similar in spirit to the Boss of the SOC datasets. Useful if you want extra Splunk-hunting reps beyond the assigned labs, on your own schedule. Requires some setup (cloud or local VM) — treat as a bonus, not a requirement before sitting the exam.
Goal: maintain a clear, running timeline that becomes the backbone of your investigation and your final write-up. Update it every time you find something significant in Splunk, Autopsy, Wireshark, Event Logs, or DeepBlueCLI.
| Timestamp | Host / Source | Artifact / Tool | Finding | ATT&CK / Notes |
|---|---|---|---|---|
| 14:22:11 | WORKSTATION01 | Splunk 4624 | RDP logon from 10.x.x.x as user X | Initial Access |
| 14:25:03 | WORKSTATION01 | Prefetch / Autopsy | malicious.exe executed | Execution |
Include both the raw timestamp and the source so you can re-verify quickly, and clean it up into a short narrative for any written report-style answers.