Appendix D — Forensic Artifact Locations
Purpose. A keyboard-side cheat sheet of where the evidence lives — registry hives and keys, event logs, execution and USB artifacts, browser profiles, and the macOS/Linux equivalents — so you can go straight from "I need to prove X" to the exact path on the image. The chapters teach you what each artifact means; this appendix tells you where to find it.
This is a lookup table, not a tutorial. For how to interpret these artifacts, see Chapter 16 — Windows Forensics and Chapter 17 — macOS and Linux Forensics. For browser specifics, see Chapter 18 — Browser and Internet Forensics. For timestamps and timelines, see Chapter 21 — Timeline Analysis.
How to use this appendix (read first)
A few rules that apply to every path below. Internalize them once.
Work from the image, read-only. Every path here is written as it appears on a live system (with drive letters and
~). On an evidence image you reach the same file through your mounted/extracted copy — e.g.E:\evidence\C\Windows\System32\winevt\Logs\Security.evtx, or viafls/icatfrom a raw/E01. Never parse the live original when an image exists; the original is sacred (theme #2). Mount images read-only, or better, extract the artifact and hash it before you touch it.Deleted ≠ destroyed — even here. These artifacts have their own slack, free lists, and deleted remnants. Deleted registry keys often survive in the hive's free cells and in the
.LOG1/.LOG2transaction logs (recover withyarp/RegRipperagainst a replayed hive). SQLite stores (browser History, macOSknowledgeC.db, Quarantine) keep deleted rows in page free-blocks and the freelist untilVACUUM..evtxrecords can be carved from unallocated space after a1102clear. Always ask not just "what is here?" but "what was here?"The absence of a trace is a trace. Prefetch turned off, a
Security.evtxthat starts an hour ago, a$I` file with no matching `$R, awtmpthat disagrees withauth.log— gaps and inconsistencies are findings, not dead ends. See Chapter 30 — Anti-Forensics.Mind the epoch. Different artifacts count time from different zero points (1601, 1904, 1970, 2001…). A 31-year or 369-year timeline error is the kind of thing opposing counsel loves. Use the Timestamp Epoch Quick Reference at the end of this appendix and verify per-column.
Versions drift. Microsoft and Apple move and rename things between builds; SSD/server defaults differ from desktop defaults. Treat every path as "as of recent Windows 10/11, current macOS, mainstream Linux." Confirm the artifact exists before you rely on it, and note the OS build in your report.
Notation: <u> = a user account name · <SID> = a security identifier (e.g. S-1-5-21-…-1001) · <AppID> = a Jump List application ID · <UUID>/<machine-id>/<random> = host- or profile-specific identifiers. On an offline SYSTEM hive there is no CurrentControlSet — use ControlSet001 (or read SYSTEM\Select\Current to learn which ControlSet was active).
Windows
Windows is the most artifact-rich platform you will examine: it records what ran, when, by whom, from which device, and where files came from, across the registry, dedicated logs, and a sprawl of caches. The map below mirrors Chapter 16.
Registry hives — on-disk location → mount point
The registry is not one file. It is a set of hive files that the running OS stitches into the HKLM / HKU / HKCU tree. On an image you parse the files, not the live tree.
| Hive file (on disk) | Live mount point | What it holds |
|---|---|---|
C:\Windows\System32\config\SAM |
HKLM\SAM |
Local user accounts, RIDs, login counts, last-login, password-hash blobs |
C:\Windows\System32\config\SECURITY |
HKLM\SECURITY |
Local security policy, LSA secrets, cached domain creds |
C:\Windows\System32\config\SYSTEM |
HKLM\SYSTEM |
Hardware, services, USB history, mounted devices, time zone, control sets |
C:\Windows\System32\config\SOFTWARE |
HKLM\SOFTWARE |
Installed software, OS version, network list, autostarts, per-machine config |
C:\Windows\System32\config\DEFAULT |
HKU\.DEFAULT |
Default user profile template |
C:\Users\<u>\NTUSER.DAT |
HKU\<SID> (= HKCU when that user is logged on) |
Per-user activity: RecentDocs, UserAssist, RunMRU, TypedURLs, MountPoints2 |
C:\Users\<u>\AppData\Local\Microsoft\Windows\UsrClass.dat |
HKU\<SID>_Classes (the HKCR per-user portion) |
ShellBags (folder-browsing history), per-user file associations |
C:\Windows\AppCompat\Programs\Amcache.hve |
loaded on demand | Program presence + SHA-1 + driver inventory (see its own section) |
Tool Tip. Always grab each hive's transaction logs alongside it —
SAM.LOG1/.LOG2,SYSTEM.LOG1/.LOG2,NTUSER.DAT.LOG1/.LOG2, etc. A "dirty" hive must be replayed from its logs before parsing, and the logs themselves contain recently written (and recently deleted) keys.RegBack(C:\Windows\System32\config\RegBack\) historically held periodic hive backups, but it is empty by default since Windows 10 build 1803 — don't count on it.
Hive → tree mapping (offline)
SAM ─► HKLM\SAM
SECURITY ─► HKLM\SECURITY
SYSTEM ─► HKLM\SYSTEM (use ControlSet001; CurrentControlSet is runtime-only)
SOFTWARE ─► HKLM\SOFTWARE
NTUSER.DAT ─► HKU\<SID> (HKCU for the interactive user)
UsrClass.dat ─► HKU\<SID>_Classes
Notable registry keys
Paths use the hive's file as the root to keep them image-friendly. Where a key lives under CurrentControlSet, substitute ControlSet001 offline.
USB and removable-device history
| Artifact | Key / path | Tells you |
|---|---|---|
| USB mass-storage devices | SYSTEM\CurrentControlSet\Enum\USBSTOR\ |
Vendor, product, revision, and serial number (instance ID) of every USB storage device |
| All USB devices (VID/PID) | SYSTEM\CurrentControlSet\Enum\USB\ |
Broader USB enumeration incl. non-storage |
| First-install / connect times | device's Properties subkey FILETIMEs under USBSTOR (0064=first install, 0066=last connected, 0067=last removed) |
When a device was first/last seen |
| Drive-letter mapping | SYSTEM\MountedDevices |
Maps \DosDevices\E: and volume GUIDs to the device (binary contains the USBSTOR ID) |
| Volume label / friendly name | SOFTWARE\Microsoft\Windows Portable Devices\Devices\ |
Human-readable volume name tied to a device |
| Per-user mounts | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\ |
Volume GUIDs a specific user mounted (ties a device to a person) |
| Plain-text confirmation | C:\Windows\INF\setupapi.dev.log (not registry) |
First driver-install time per device, in readable text |
Limitation. Under
USBSTOR, the instance ID is the device serial only if its second character is not&. A&means Windows generated the ID because the device reported no unique serial — it is not globally unique, so do not claim cross-machine identity for it. (See Chapter 16.)
Program execution and persistence
| Artifact | Key / path | Tells you |
|---|---|---|
| UserAssist | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count |
GUI-launched programs, run count + last-run + focus time (value names are ROT13-encoded; {CEBFF5CD-…} = exe, {F4E57C4B-…} = LNK) |
| BAM / DAM | SYSTEM\CurrentControlSet\Services\bam\State\UserSettings\<SID>\ (and …\dam\…) |
Full path of executables run per user SID, with last-execution time (Win10/11) |
| ShimCache (AppCompatCache) | SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache (value AppCompatCache) |
Programs present (path + size + $STANDARD_INFO mtime); presence, not proof of execution |
| Run / RunOnce (machine) | SOFTWARE\Microsoft\Windows\CurrentVersion\Run and \RunOnce |
Autostart programs (a classic persistence spot) |
| Run / RunOnce (user) | NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run and \RunOnce |
Per-user autostart |
| Services | SYSTEM\CurrentControlSet\Services\ |
Installed services / drivers (start type, image path) |
| Scheduled tasks | SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\ |
Registered tasks (pairs with C:\Windows\System32\Tasks\ XML) |
| Winlogon / shell hijacks | SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon (Shell, Userinit) |
Logon persistence |
Why This Matters. Execution evidence is layered: Prefetch, UserAssist, and BAM indicate execution; Amcache and ShimCache indicate presence. No single key is proof — three that agree is a finding. State the distinction on the stand; do not call presence "execution."
Recent activity and shell usage (per-user — NTUSER.DAT / UsrClass.dat)
| Artifact | Key / path | Tells you |
|---|---|---|
| RecentDocs | NTUSER.DAT\…\Explorer\RecentDocs\ |
Recently opened files, grouped by extension; MRUListEx = order, subkey last-write = most-recent open |
| RunMRU | NTUSER.DAT\…\Explorer\RunMRU |
Commands typed into Win+R |
| TypedPaths | NTUSER.DAT\…\Explorer\TypedPaths |
Paths typed into the Explorer address bar |
| TypedURLs | NTUSER.DAT\Software\Microsoft\Internet Explorer\TypedURLs |
URLs typed into IE/legacy Edge |
| Open/Save MRU | NTUSER.DAT\…\Explorer\ComDlg32\OpenSavePidlMRU\ and LastVisitedPidlMRU\ |
Files/folders touched via common open/save dialogs |
| WordWheelQuery | NTUSER.DAT\…\Explorer\WordWheelQuery\ |
Terms typed into Explorer's search box |
| ShellBags | UsrClass.dat\Local Settings\Software\Microsoft\Windows\Shell\BagMRU and …\Shell\Bags (older entries also in NTUSER.DAT\Software\Microsoft\Windows\Shell\) |
Folders the user browsed — including now-deleted folders and removable/network paths |
System configuration and accounts
| Artifact | Key / path | Tells you |
|---|---|---|
| Computer name | SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName |
Hostname |
| Time zone | SYSTEM\CurrentControlSet\Control\TimeZoneInformation |
Local TZ + bias — essential for timeline normalization |
| OS version / install date | SOFTWARE\Microsoft\Windows NT\CurrentVersion |
Build, edition, InstallDate |
| Last shutdown | SYSTEM\CurrentControlSet\Control\Windows (value ShutdownTime, FILETIME) |
When the box last shut down |
| SID ↔ profile path | SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\ |
Maps each <SID> to its C:\Users\<u> path |
| Last logged-on user | SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI |
Last interactive user shown at the lock screen |
| Local accounts | SAM\SAM\Domains\Account\Users\ |
RIDs, usernames, login counts, last-login, hash blobs |
| Networks (SSID/first+last) | SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\ and …\NetworkList\Profiles\ |
Networks joined, with first/last-connected dates and network type |
| Network interfaces | SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ |
IPs/DHCP per adapter |
Event logs (.evtx)
Folder: C:\Windows\System32\winevt\Logs\ · Format: binary XML (.evtx), magic ElfFile\x00. Parse with EvtxECmd, wevtutil, Get-WinEvent -Path …, or Python python-evtx.
Core logs
| File | Records |
|---|---|
Security.evtx |
Logons/logoffs, privilege use, account & policy changes, audit-log clears (1102), (optionally) process creation |
System.evtx |
Service installs/state, driver loads, boots/shutdowns, time changes |
Application.evtx |
Application & installer events, crashes (Windows Error Reporting) |
Setup.evtx |
OS setup and servicing (update) events |
High-value specialized logs (same folder; %4 encodes the / in the channel name)
| File | Records |
|---|---|
Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx |
RDP session connect/disconnect at the target (IDs 21/22/24/25) |
Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx |
Inbound RDP auth (ID 1149) |
Microsoft-Windows-TaskScheduler%4Operational.evtx |
Scheduled-task registration and execution |
Microsoft-Windows-PowerShell%4Operational.evtx |
PowerShell module/script-block logging (4103/4104) |
Microsoft-Windows-WinRM%4Operational.evtx |
Remote management / lateral movement |
Microsoft-Windows-Windows Defender%4Operational.evtx |
Malware detections and actions |
Microsoft-Windows-DriverFrameworks-UserMode%4Operational.evtx |
USB device plug/unplug (2003/2100/2102) |
Microsoft-Windows-Partition%4Diagnostic.evtx |
Connected-disk details incl. removable media |
Microsoft-Windows-Bits-Client%4Operational.evtx |
Background file transfers (exfil/download) |
Microsoft-Windows-Sysmon%4Operational.evtx |
If Sysmon is deployed: process, network, file, registry telemetry |
Key Security event IDs
| ID | Meaning | ID | Meaning |
|---|---|---|---|
| 4624 | Successful logon (carries logon type) | 4672 | Special privileges assigned (admin session) |
| 4625 | Failed logon | 4688 | Process creation (cmdline if configured) |
| 4634 / 4647 | Logoff / user-initiated logoff | 4720 | User account created |
| 4648 | Logon with explicit credentials | 4724 / 4728 / 4732 / 4756 | Password reset / added to group |
| 4768 / 4769 / 4771 | Kerberos TGT / service ticket / pre-auth fail | 4697 | Service installed |
| 1102 | Security audit log cleared | 4698–4702 | Scheduled task created/changed/deleted |
Key System event IDs
| ID | Meaning |
|---|---|
| 7045 | New service installed |
| 7034 / 7036 / 7040 | Service crashed / state changed / start-type changed |
| 6005 / 6006 | Event Log service started / stopped (≈ boot / clean shutdown) |
| 6008 | Unexpected (dirty) shutdown |
| 1074 | Shutdown/restart initiated (by whom, why) |
| 104 | An event log was cleared |
Logon types (the LogonType field on 4624/4625)
| Type | Meaning | Type | Meaning |
|---|---|---|---|
| 2 | Interactive (at the keyboard) | 8 | NetworkCleartext (creds sent in clear) |
| 3 | Network (SMB share, etc.) | 9 | NewCredentials (runas /netonly) |
| 4 | Batch (scheduled task) | 10 | RemoteInteractive (RDP) |
| 5 | Service | 11 | CachedInteractive (cached domain creds) |
| 7 | Unlock (screen unlock) |
War Story. A burst of
4625(type 3 or 10) followed by a4624success is a brute force that worked. A lone1102is loud by itself: clearing the log is an action, the action is logged with who and when, and the silence afterward is the absence-of-a-trace trace.
Prefetch — "this program ran"
Folder: C:\Windows\Prefetch\ · Files: NAME-XXXXXXXX.pf (uppercased exe name + 8-hex path hash). On Win10/11 the body is MAM/Xpress-Huffman compressed — PECmd decompresses automatically.
- Holds run count, last 8 run times, and referenced files/directories (loaded DLLs, opened data files).
- Capacity: 128 entries (pre-Win8) → 1024 (Win8+).
- Often disabled on SSD-only systems and servers:
SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters(EnablePrefetcher= 0). Absence ≠ "nothing ran." - Boot tracing:
C:\Windows\Prefetch\ReadyBoot\.
Amcache.hve — presence + SHA-1
File: C:\Windows\AppCompat\Programs\Amcache.hve (registry-format hive; grab .LOG1/.LOG2). Parse with AmcacheParser.
| Subkey | Contents |
|---|---|
Root\InventoryApplicationFile\ |
Executable path, publisher, SHA-1 of the file, link (compile) date, first-seen |
Root\InventoryApplication\ |
Installed application inventory |
Root\InventoryDriverBinary\ |
Driver path + SHA-1 — gold for catching malicious/unsigned drivers |
Root\File\ |
Older (pre-Win10 1607) file-entry format |
Limitation. Amcache proves a binary was present on the system, not that it executed. Pair it with Prefetch/UserAssist/BAM before you say "ran."
Other Windows stores (ESE and SQLite)
| Artifact | Path | Tells you |
|---|---|---|
| SRUM (resource usage) | C:\Windows\System32\sru\SRUDB.dat (ESE) |
Per-app, per-user CPU/network use by hour — bytes sent = data-exfil evidence (SRUMECmd) |
| IE/legacy-Edge web cache | C:\Users\<u>\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat (ESE) |
History/cache/cookie containers (FILETIME) |
| Windows Search index | C:\ProgramData\Microsoft\Search\Data\Applications\Windows\Windows.edb (Win10 ESE; Windows.db SQLite on Win11) |
Indexed file content, email, deleted-file remnants |
| Windows Timeline / Activities | C:\Users\<u>\AppData\Local\ConnectedDevicesPlatform\<profile>\ActivitiesCache.db (SQLite) |
App/file usage timeline (mostly pre-Win11) |
| Notifications | C:\Users\<u>\AppData\Local\Microsoft\Windows\Notifications\wpndatabase.db (SQLite) |
Toast notification history |
| Thumbnail / icon cache | C:\Users\<u>\AppData\Local\Microsoft\Windows\Explorer\thumbcache_*.db, iconcache_*.db |
Thumbnails of images — incl. now-deleted files |
| WER crash dumps | C:\ProgramData\Microsoft\Windows\WER\ and …\<u>\AppData\Local\Microsoft\Windows\WER\ |
Crash reports (can reveal run programs/malware) |
$Recycle.Bin — deleted via the GUI
Folder: C:\$Recycle.Bin\<SID>\ (XP used C:\RECYCLER\<SID>\INFO2). Parse with RBCmd.
| File | Contents |
|---|---|
$I` (e.g. `$IA1B2C3.docx) |
Metadata: original full path, deletion timestamp (FILETIME), original size |
$R` (e.g. `$RA1B2C3.docx) |
The actual recoverable file content |
Match $I` and `$R by their shared 6-character token. A $I` with **no** matching `$R means the content was purged but the deletion record survives — itself a finding.
LNK files and Jump Lists — "this file was opened, and where it lived"
| Artifact | Path | Tells you |
|---|---|---|
| Recent LNK shortcuts | C:\Users\<u>\AppData\Roaming\Microsoft\Windows\Recent\*.lnk |
Target path, sizes, $STANDARD_INFO` + `$FILE_NAME MAC times of the target, volume serial, and (if removable/network) the original device/path |
| Office recent | C:\Users\<u>\AppData\Roaming\Microsoft\Office\Recent\ |
Recently opened Office docs |
| Automatic Jump Lists | C:\Users\<u>\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\<AppID>.automaticDestinations-ms |
OLE/CFB compound file; each stream is a LNK + a DestList ordering — per-app recent-file history |
| Custom Jump Lists | …\Recent\CustomDestinations\<AppID>.customDestinations-ms |
App-curated pinned/recent entries |
Tool Tip. The
<AppID>is a CRC of the application's path; use a published AppID list (orJLECmd) to map it back to the program. LNK targeting a drive letter with a volume serial that matches aUSBSTORdevice is how you prove a file lived on a USB stick that is no longer present.
Browser profiles (Windows)
Full schema and timestamp handling are in Chapter 18. Copy the -wal and -shm companions with any SQLite store — recent activity often lives only in the WAL.
| Browser | Profile root (Windows) | Key files |
|---|---|---|
| Chrome | C:\Users\<u>\AppData\Local\Google\Chrome\User Data\Default\ |
History, Network\Cookies, Login Data, Web Data, Bookmarks, Top Sites, Favicons, Shortcuts; Local State (one level up) holds the cookie-encryption key |
| Edge (Chromium) | C:\Users\<u>\AppData\Local\Microsoft\Edge\User Data\Default\ |
Same set as Chrome |
| Firefox | C:\Users\<u>\AppData\Roaming\Mozilla\Firefox\Profiles\<random>.default-release\ |
places.sqlite (history+bookmarks), cookies.sqlite, formhistory.sqlite, favicons.sqlite, logins.json + key4.db, sessionstore.jsonlz4 |
| IE / legacy Edge | C:\Users\<u>\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat |
ESE web cache (history/cache/cookies); older index.dat |
NTFS file-system metafiles (root of each NTFS volume)
These are owned by Chapter 4 — File Systems and detailed in Appendix G, but list them here because they are artifact goldmines:
$MFT` — every file's record (resident data, `$STANDARD_INFOand$FILE_NAMEMAC times — the latter resists timestomping).$LogFile— NTFS transaction log (recent metadata changes).$Extend\$UsnJrnl:$J— the USN change journal: a rolling log of file create/delete/rename/write. Deleting it is itself suspicious.$Recycle.Bin`, `$Extend\$ObjId`, `$Extend\$Quota.
Windows triage collection (illustrative)
# Read-only artifact pull from a mounted image (E:) into a case folder.
# Illustrative — never run against an original; hash everything you copy.
$src = "E:\C"; $out = "D:\case-2026-014\artifacts"
$paths = @(
"Windows\System32\config\SAM","Windows\System32\config\SYSTEM",
"Windows\System32\config\SOFTWARE","Windows\System32\config\SECURITY",
"Windows\System32\winevt\Logs", # all .evtx
"Windows\Prefetch", # *.pf
"Windows\AppCompat\Programs\Amcache.hve",
"Windows\System32\sru\SRUDB.dat",
"Windows\INF\setupapi.dev.log"
)
foreach ($p in $paths) { robocopy "$src\$p" "$out\$p" /E /COPY:DAT /R:0 /XJ | Out-Null }
# Per-user: NTUSER.DAT, UsrClass.dat, Recent\, browser profiles (loop C:\Users\*)
Get-ChildItem "$out" -Recurse -File | Get-FileHash -Algorithm SHA256 |
Export-Csv "$out\_hashes.csv" -NoTypeInformation
Tool Tip. In practice you do this with KAPE targets (see Chapter 15 — Live Response and Triage) and Eric Zimmerman's tools (
RECmd,PECmd,AmcacheParser,EvtxECmd,JLECmd,RBCmd,SRUMECmd) — see Appendix C — Tool Reference. The script shows what to grab; KAPE does it faster and with logging.
macOS
There is no registry on a Mac. The equivalents are property lists (plists), SQLite databases, and structured binary logs scattered mostly under ~/Library/ and /Library/. (/var is a symlink to /private/var; paths below use the short form.) See Chapter 17. The single biggest rookie error is treating macOS like Windows — learn its map on its own terms.
System and unified logs
| Artifact | Path | Tells you |
|---|---|---|
| Unified Log (data) | /var/db/diagnostics/*.tracev3 (+ Persist/, Special/, Signpost/, HighVolume/, timesync/) |
USB attach/detach, process launches, network/lock events — the firehose |
| Unified Log (strings) | /var/db/uuidtext/ |
Format strings needed to render .tracev3; collect both or use log collect for a .logarchive |
| Install history | /var/log/install.log |
Software/OS installs — plain text, long-retained |
| Legacy syslog (≤10.11) | /var/log/system.log, /var/log/asl/*.asl |
Pre-Unified-Logging system messages |
Live tools: log show / log collect (with --predicate). Offline: Mandiant UnifiedLogReader, mac_apt.
File-system and metadata activity
| Artifact | Path | Tells you |
|---|---|---|
| FSEvents | /.fseventsd/ (per volume; gzip logs + fseventsd-uuid) |
A change log of created/modified/deleted/renamed paths (no per-file timestamp, but ordered) |
| Spotlight metadata | /.Spotlight-V100/Store-V2/<UUID>/store.db (user: ~/Library/Metadata/CoreSpotlight/) |
Indexed metadata, incl. kMDItemWhereFroms (download URL) on key files |
| Quarantine DB | ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 (SQLite, table LSQuarantineEvent) |
Download provenance: URL, originating page, agent app, download time |
| Quarantine xattr | extended attribute com.apple.quarantine on downloaded files |
Per-file flag + UUID foreign-key into the Quarantine DB |
| Trash | ~/.Trash/ (per-user) and /Volumes/<vol>/.Trashes/<uid>/ |
User-trashed files |
| Folder view metadata | .DS_Store (in many folders) |
Records files that were in a folder — survives deletion of the files |
Activity timeline databases
| Artifact | Path | Tells you |
|---|---|---|
| KnowledgeC (user) | ~/Library/Application Support/Knowledge/knowledgeC.db |
App focus, device usage, notifications — Mac absolute time |
| KnowledgeC (system) | /private/var/db/CoreDuet/Knowledge/knowledgeC.db |
System-wide activity stream |
| Biome / segb (newer) | ~/Library/Biome/ and /private/var/db/biome/ |
Modern activity streams supplementing/superseding knowledgeC |
Limitation. macOS forgets fast. The Unified Log retains days to weeks, not months, and high-volume entries roll quickly. Acquire promptly and capture volatile state live where you can. (theme #5)
Key plists (configuration, persistence, identity)
| Artifact | Path | Tells you |
|---|---|---|
| LaunchAgents/Daemons (persistence) | ~/Library/LaunchAgents/, /Library/LaunchAgents/, /Library/LaunchDaemons/, /System/Library/Launch* |
Auto-run programs (a top malware-persistence spot) |
| Login items | ~/Library/Preferences/com.apple.loginitems.plist, …/backgrounditems.btm |
Per-user startup items |
| Last user / autologin | /Library/Preferences/com.apple.loginwindow.plist |
Last/auto login user |
| Computer & network name | /Library/Preferences/SystemConfiguration/preferences.plist |
Hostname, network services |
| Wi-Fi SSIDs | /Library/Preferences/com.apple.airport.preferences.plist (or …/SystemConfiguration/) |
Joined wireless networks |
| Bluetooth devices | /Library/Preferences/com.apple.Bluetooth.plist |
Paired devices |
| Local accounts | /var/db/dslocal/nodes/Default/users/<u>.plist |
Account records (UID, home, older password hash) |
| Install receipts | /Library/Receipts/InstallHistory.plist |
What was installed and when |
| OS version | /System/Library/CoreServices/SystemVersion.plist |
Product version/build |
Tool Tip. plists come in XML and binary form. Convert/inspect with
plutil -convert xml1 -o - file.plistorplutil -p file.plist. Parse the whole Mac at once withmac_apt(APFS, Spotlight, FSEvents, Unified Log, knowledgeC, Quarantine, plist, Safari plugins).
Time Machine and APFS snapshots
| Artifact | Where | Tells you |
|---|---|---|
| APFS local snapshots | tmutil listlocalsnapshots / · diskutil apfs listSnapshots <dev> |
Hourly point-in-time copies named com.apple.TimeMachine.<date>.local — often contain "deleted" files intact |
| Time Machine config | /Library/Preferences/com.apple.TimeMachine.plist |
Backup destinations and history |
| External TM backups | /Volumes/<backup>/Backups.backupdb/<Mac name>/<date>/ |
Full historical file copies |
Why This Matters. Enumerate snapshots before you carve. Why reconstruct from fragments what an hourly snapshot holds whole? Mount the snapshot read-only (APFS-Fuse /
mount_apfs -s) and diff against the live volume to prove deletion windows.
User-data SQLite stores
| Artifact | Path |
|---|---|
| Messages (iMessage/SMS) | ~/Library/Messages/chat.db (+ Attachments/) |
| Notes | ~/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite |
~/Library/Mail/ |
|
| Photos | ~/Pictures/Photos Library.photoslibrary/database/Photos.sqlite |
| Privacy permissions (TCC) | ~/Library/Application Support/com.apple.TCC/TCC.db and /Library/Application Support/com.apple.TCC/TCC.db |
| Keychain | ~/Library/Keychains/login.keychain-db, /Library/Keychains/System.keychain |
Browsers (macOS)
| Browser | Profile root |
|---|---|
| Safari | ~/Library/Safari/ (History.db, Bookmarks.plist, Downloads.plist, TopSites.plist); cookies at ~/Library/Cookies/Cookies.binarycookies (magic cook); cache ~/Library/Caches/com.apple.Safari/ |
| Chrome | ~/Library/Application Support/Google/Chrome/Default/ (same file set as Windows Chrome) |
| Firefox | ~/Library/Application Support/Firefox/Profiles/<random>.default-release/ (places.sqlite, cookies.sqlite, …) |
macOS collection one-liner (illustrative)
# From a mounted, read-only image volume at /Volumes/EVID — copy, then hash.
mac_apt.py -i /Volumes/EVID -o ~/case/mac_out ALL # broad plugin sweep
# Targeted grabs (paths relative to the mounted volume root):
# private/var/db/diagnostics + private/var/db/uuidtext (Unified Log: BOTH)
# .fseventsd (FSEvents)
# .Spotlight-V100/Store-V2 (Spotlight)
# Users/<u>/Library/Application Support/Knowledge/knowledgeC.db
# Users/<u>/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2
shasum -a 256 ~/case/mac_out/* > ~/case/mac_out/_hashes.txt
Linux
Linux gives you redundant records on purpose — the same SSH login lands in auth.log, in wtmp (via last), and in the systemd journal. When they agree, your finding is bulletproof; when one is edited and the others are not, the disagreement is the evidence. Paths follow mainstream distros; note the Debian/Ubuntu vs. RHEL/CentOS/Fedora split. See Chapter 17.
/var/log — text logs
| Artifact | Debian/Ubuntu | RHEL/CentOS/Fedora | Records |
|---|---|---|---|
| Authentication | /var/log/auth.log |
/var/log/secure |
Logins, sudo, ssh, PAM, account changes |
| General system | /var/log/syslog |
/var/log/messages |
Broad system/daemon messages |
| Kernel | /var/log/kern.log |
(in messages) |
Kernel + hardware (USB attach shows here) |
| Cron execution | /var/log/cron.log or in syslog |
/var/log/cron |
Scheduled-job runs |
| Package installs | /var/log/apt/history.log, /var/log/dpkg.log |
/var/log/yum.log, /var/log/dnf.log |
Software added/removed |
| Auditd (if installed) | /var/log/audit/audit.log |
/var/log/audit/audit.log |
Fine-grained syscall/file auditing |
| Boot | /var/log/boot.log, /var/log/dmesg |
same | Boot-time messages |
| Web servers | /var/log/apache2/{access,error}.log · /var/log/nginx/{access,error}.log |
/var/log/httpd/… |
HTTP requests/errors |
Binary login records (decode with the right tool)
| File | Tool | Records |
|---|---|---|
/var/log/wtmp |
last -f wtmp -F |
Historical logins, logouts, reboots, shutdowns |
/var/log/btmp |
lastb -f btmp -F |
Failed login attempts (a wall of these = brute force) |
/var/run/utmp (or /run/utmp) |
who, w |
Currently logged-in users (volatile) |
/var/log/lastlog |
lastlog |
Per-user last-login time |
Tool Tip. Each record is a fixed-size
utmpstruct (384 bytes on 64-bit glibc: type, PID, terminal, 32-byte user, 256-byte host, timestamp). Because they are binary, they are harder to edit cleanly than text logs — awtmpthat disagrees withauth.logis a tampering indicator. The full struct layout is in Appendix G.
systemd journal
Path: /var/log/journal/<machine-id>/*.journal (persistent) · /run/log/journal/ (volatile RAM-only — capture live). Files begin with magic LPKSHHRH.
# Read the journal straight from a MOUNTED IMAGE, offline, with structured filters.
journalctl --file ./var/log/journal/<machine-id>/system.journal \
-u ssh.service --since "2026-06-20 00:00" -o verbose
journalctl -D ./var/log/journal/<machine-id> --list-boots
Captures process executions, service starts/stops, authentication (ingests the same PAM events as auth.log), and kernel messages, with microsecond timestamps. Optional Forward Secure Sealing (FSS) makes it tamper-evident.
Shell history and per-user activity
| Artifact | Path | Notes |
|---|---|---|
| bash history | ~/.bash_history |
No timestamps unless HISTTIMEFORMAT set; written on shell exit |
| zsh history | ~/.zsh_history |
Default shell on modern macOS too |
| Tool histories | ~/.python_history, ~/.mysql_history, ~/.psql_history, ~/.lesshst, ~/.viminfo |
Often overlooked, frequently damning |
| Recent files (GUI) | ~/.local/share/recently-used.xbel |
GNOME recent-document list |
| SSH | ~/.ssh/authorized_keys, ~/.ssh/known_hosts, ~/.ssh/config |
Keys = persistence/lateral movement; known_hosts = where they went |
| Trash (freedesktop) | ~/.local/share/Trash/files/ + ~/.local/share/Trash/info/*.trashinfo |
Deleted files + original-path/time metadata |
| Thumbnails | ~/.cache/thumbnails/ |
Thumbnails of viewed images, incl. deleted |
Scheduled execution (cron, systemd timers)
| Artifact | Path |
|---|---|
| System crontab | /etc/crontab, /etc/cron.d/ |
| Periodic dirs | /etc/cron.{hourly,daily,weekly,monthly}/ |
| Per-user crontabs | /var/spool/cron/crontabs/<u> (Debian) · /var/spool/cron/<u> (RHEL) |
| Anacron | /etc/anacrontab |
| systemd timers | /etc/systemd/system/*.timer, /usr/lib/systemd/system/*.timer, ~/.config/systemd/user/ |
Persistence, accounts, and system identity
| Artifact | Path | Tells you |
|---|---|---|
| Startup units | /etc/systemd/system/, /lib/systemd/system/, /etc/init.d/, /etc/rc.local |
Boot-time program execution |
| Shell profiles | ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/profile, /etc/profile.d/ |
Per-shell persistence |
| Desktop autostart | ~/.config/autostart/*.desktop |
GUI-session persistence |
| Accounts | /etc/passwd, /etc/shadow, /etc/group |
Users, UIDs, home dirs, hashes |
| Sudo rights | /etc/sudoers, /etc/sudoers.d/ |
Who can escalate |
| Host / time / ID | /etc/hostname, /etc/timezone, /etc/machine-id, /etc/os-release |
Identity + TZ for timeline normalization |
| Network | /etc/hosts, /etc/resolv.conf, /etc/NetworkManager/system-connections/ |
Name resolution, saved Wi-Fi |
| Mounts | /etc/fstab, /proc/mounts (live) |
What was mounted where |
ext4 / file-system layer
The inode table, extents, and the ext4 journal (a "second chance" at the block map for recently deleted files) are owned by Chapter 4 and detailed in Appendix G. Recover deleted files with extundelete/ext4magic or carve (photorec, foremost — Appendix H).
Timestamp epoch quick reference (cross-OS)
The single most error-prone step in artifact analysis. Always confirm which epoch a column uses before you build a timeline (Chapter 21).
| Format | Zero point | Unit | Convert to Unix seconds | Seen in |
|---|---|---|---|---|
| Windows FILETIME | 1601-01-01 UTC | 100-ns ticks | ft / 10,000,000 − 11,644,473,600 |
Registry, NTFS, LNK, .evtx, $Recycle.Bin` `$I |
| WebKit / Chrome | 1601-01-01 UTC | microseconds | v / 1,000,000 − 11,644,473,600 |
Chrome/Edge History, Cookies, Login Data |
| Unix epoch | 1970-01-01 UTC | seconds | v (already) |
Linux logs, ext, Firefox cookies, many |
| Firefox PRTime | 1970-01-01 UTC | microseconds | v / 1,000,000 |
places.sqlite visit/added times |
| Mac Absolute (CFAbsoluteTime) | 2001-01-01 UTC | seconds | v + 978,307,200 |
knowledgeC.db, QuarantineEventsV2, Safari, many Apple SQLite |
| HFS+ time | 1904-01-01 UTC | seconds | v − 2,082,844,800 |
HFS+ volume timestamps |
| DOS date/time | 1980-01-01 (local) | 2-second resolution | bit-packed; decode fields | FAT/exFAT directory entries |
| APFS / ext4 (nsec) | 1970-01-01 UTC | nanoseconds | v / 1,000,000,000 |
APFS, ext4 inode times |
Why This Matters. Forget the
+978,307,200on a Mac column and your timeline is off by 31 years; treat a FILETIME as Unix and you are off by 369 years. These are the errors opposing counsel exhibits to the jury. Convert deliberately, label every timestamp with its source and time zone, and normalize everything to UTC in your master timeline.
Artifact-to-question matrix (start here)
Work backward from the question you must answer to the artifacts that answer it. Corroborate across at least two independent sources before you state a finding.
| You want to prove… | Windows | macOS | Linux |
|---|---|---|---|
| A program ran | Prefetch · UserAssist · BAM · 4688 | knowledgeC.db (app focus) · Unified Log · install.log |
auth.log/journal (sudo/exec) · ~/.bash_history |
| A program was present | Amcache (SHA-1) · ShimCache | App bundle + Spotlight · InstallHistory.plist |
package logs · binary on disk |
| A USB device was connected | USBSTOR · MountedDevices · MountPoints2 · setupapi.dev.log · DriverFrameworks log |
Unified Log (IOUSB) · FSEvents on the volume | kern.log/journal (USB) · /var/log/messages |
| A file was opened / existed | RecentDocs · LNK · Jump Lists · $MFT · thumbcache |
.DS_Store · Spotlight · recent-items plist |
~/.local/share/recently-used.xbel · ~/.viminfo |
| A file was deleted | $Recycle.Bin` (`$I/$R`) · `$UsnJrnl · MFT |
~/.Trash · APFS snapshots · FSEvents |
~/.local/share/Trash · ext4 journal |
| Where a file came from | browser History/Downloads · Zone.Identifier ADS |
com.apple.quarantine · QuarantineEventsV2 · kMDItemWhereFroms |
browser history · download dirs |
| Who logged in, when, how | Security.evtx 4624/4625 (+ logon type) · RDP logs |
Unified Log · /var/log/install.log |
auth.log/secure · wtmp/btmp · journal |
| Web activity | Chrome/Edge/Firefox/IE stores · WebCacheV01.dat |
Safari History.db + browsers |
browser profiles |
| Data exfiltration | SRUM (bytes sent) · BITS log · LNK/Jump Lists to USB | Unified Log · knowledgeC · network plists |
auth.log (scp/rsync) · web/access logs · ~/.bash_history |
| Anti-forensic activity | 1102/104 clears · Prefetch disabled · $I` without `$R · timestomp ($FN` vs `$SI) |
wiped Unified Log · disabled snapshots | edited text logs vs. intact wtmp/journal |
Caveats and cross-references
Legal Note. Knowing where an artifact lives is not authority to collect it. Scope your acquisition to the warrant or consent that authorizes it (Chapter 25 — The Legal Framework), and document every artifact's source path, acquisition method, and hash in your chain of custody.
Limitation. Encryption changes this map. On a BitLocker/FileVault/LUKS volume, none of these paths are reachable until the volume is unlocked — see Chapter 29 — Encrypted Device Forensics. Cloud-synced artifacts (browser history, files, mail) may live partly or wholly server-side — see Chapter 31 — Cloud Forensics. Mobile layouts differ entirely — see Chapter 24 — Mobile Device Forensics.
Related references in this book:
- Appendix A — File Signatures Reference: magic numbers for carving the files these artifacts point to.
- Appendix B — Python Forensics Toolkit: scripts to parse timestamps, registry, and SQLite stores.
- Appendix C — Tool Reference: the parsers named above (RECmd, PECmd, EvtxECmd, mac_apt, plaso…).
- Appendix G — File System Reference: NTFS MFT, ext4 inode, APFS, and the
utmpstruct. - Appendix H — Command-Line Reference:
fls/icat,xxd,exiftool,journalctl,last/lastb, and friends. - Glossary: every term used above, chapter-cross-referenced.
Recovery vs. Forensics. The same path serves both disciplines, with different priorities. A recovery tech reads
$Recycle.Bin, browser caches, and snapshots to restore what the user lost, fast. An examiner reads the identical artifacts to prove who did what, when — admissibly: image first, hash, work the copy, document the source path of every artifact, and normalize every timestamp to UTC. Know which job you are doing before you touch the keys.