Skip to content

Artifact Locations & The Digital Forensics Artifacts Repository

Dive deep into key forensic artifacts across Windows, macOS, and Linux. Learn how to leverage the collaborative, machine-readable Digital Forensics Artifacts Repository to automate triage, parse critical records, and build unified investigation timelines.

/ ARTICLE
[ FIG. 1 ]
Digital Forensics Artifacts Repository

The Anatomy of Digital Artifacts

Shimcache will tell you a binary existed on a system. It will not tell you the binary ran. Analysts conflate those two things constantly, and it is the difference between a defensible finding and one that collapses the first time opposing counsel asks a precise question.

That is the actual work of artefact analysis: not locating the records — locating them is a solved problem — but knowing exactly what each one proves and where its evidentiary value stops. Every file opened, process started, and connection made leaves some residue in registry hives, event logs, SQLite databases, and prefetch files. Knowing which residue answers which question is the skill.

The locating half has been automated by the Digital Forensics Artifacts Repository (ForensicArtifacts/artifacts), a community-maintained YAML knowledge base describing where these records live across operating systems and versions. Plaso, Velociraptor, Turbinia, and CyLR all consume those definitions, which is why a collection profile written against one tool tends to transfer to another.

graph TD A[Target System] -->|Evidence Collection| B(Triage / Disk Image) C[Artifacts Repository] -->|YAML Definitions| D[Forensic Parser
Plaso / Velociraptor] B --> D D -->|Parsing Rules Applied| E[Extracted System Events] E -->|Time-Slicing & Correlation| F[Unified Forensic Timeline] classDef warning fill:#f0ad4e,stroke:#e6890a,color:#000; classDef safe fill:#3a7d44,stroke:#2d6235,color:#fff; classDef danger fill:#c0392b,stroke:#96281b,color:#fff; class A,B warning; class C,D safe; class E,F danger;

Setting Up the Forensics Artifacts Library

You only need the library if you are writing code against the definitions — validating them, querying them, or generating collection profiles. If you just want the artefact knowledge, the YAML in the repository is readable on its own and costs you nothing to clone.

1. Using pip (Python Virtual Environment)

Use a virtual environment. On a forensics workstation this is not tidiness for its own sake: Plaso, Volatility, and half the DFIR Python ecosystem pin conflicting dependency versions, and a pip install into the system interpreter is how you break a tool you were relying on for an active case.

# Create and activate a clean virtual environment
python3 -m venv artifacts-env
source ./artifacts-env/bin/activate

# Upgrade pip and install the library
pip install --upgrade pip
pip install artifacts

# Verify the installation
python -c "import artifacts; print(artifacts.__version__)"

# Deactivate when finished
deactivate

Advertisement

2. On Ubuntu/Debian via the GIFT PPA

The GIFT PPA packages Plaso and its dependency tree, including the artefacts library, at versions that are known to work together. That last part is the reason to prefer it over pip on an analysis box — dependency resolution for the Plaso stack is genuinely painful to do by hand:

# Register the GIFT PPA
sudo add-apt-repository ppa:gift/stable -y
sudo apt-get update

# Install the Python 3 artifacts library
sudo apt-get install python3-artifacts -y

3. On Windows via pip

On a Windows analysis workstation, pip is the route. pywin32 supplies the Win32 API bindings some parsers need for live-system collection — it is irrelevant if you are only working from acquired images, which is most of the time:

# Install Windows-specific dependencies
pip install pywin32 wmi

# Install the artifacts library
pip install artifacts

Key OS Artifact Locations Every Analyst Must Know

Windows Artifacts

Windows records more about user and process activity than any other mainstream operating system, largely as a side effect of compatibility and performance features that were never intended as an audit trail. That is why they are useful — nobody clearing their tracks thinks about the application compatibility cache — and also why they are inconsistent between versions.

1. Persistence and Execution Keys

Persistence has to survive a reboot, which means it has to be written somewhere durable, which means it is findable. Start here:

  • Run / RunOnce Registry Keys:
    • System-wide: HKLM\Software\Microsoft\Windows\CurrentVersion\Run (and RunOnce)
    • User-specific: HKCU\Software\Microsoft\Windows\CurrentVersion\Run (and RunOnce)
  • Startup Folder: C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
  • Services Registry: HKLM\System\CurrentControlSet\Services — every system-level service, malware included. Note that CurrentControlSet is a runtime pointer; on a dead image you are reading ControlSet001 or ControlSet002, and Select\Current tells you which one was live

2. Evidence of Execution

These four are the standard set, and the distinctions between them are exactly what gets misstated in reports:

  • Prefetch Files (.pf): C:\Windows\Prefetch. Records the first ten seconds of a program’s startup — run count, referenced modules, and up to eight execution timestamps on Windows 8 and later. This is genuine evidence of execution. It is also disabled by default on servers and on systems with SSDs in some configurations, so absence proves nothing at all.
  • Shimcache (AppCompatCache): HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache. Records path, size, and last-modified time for binaries the compatibility layer evaluated. Read the previous sentence carefully: evaluated, not executed. Shimcache proves the file was present on the filesystem, which survives deletion and is valuable — but it is not an execution artefact, and treating it as one is the most common error in this area. It also only flushes to the registry at shutdown, so a live system’s cache is incomplete.
  • Amcache: C:\Windows\AppCompat\Programs\Amcache.hve. Execution metadata, installation source, and SHA-1 hashes of binaries — the hash being the reason to reach for it, since it lets you pivot to threat intelligence on a file that has since been deleted. Windows 8 and later.
  • UserAssist: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist. Run counts and last-execution timestamps for GUI applications launched through Explorer, ROT13-encoded for no defensible reason. Scoped to interactive launches: anything started from a command line, a service, or a scheduled task will not appear here.

3. Windows Event Logs (EVTX)

Event logs live at %SystemRoot%\System32\Winevt\Logs\. Three carry most of the weight:

  • Security.evtx: 4624 (successful logon) and 4625 (failed logon). Read the Logon Type field rather than the event ID alone — Type 3 is network, Type 10 is RDP, and Type 2 is someone physically at the keyboard. Conflating them produces confident wrong conclusions about how an account was used
  • System.evtx: 7045 (new service installed) is the classic lateral movement indicator, because remote execution tooling in the PsExec lineage installs a service to run its payload
  • Microsoft-Windows-TerminalServices-LocalSessionManager/Operational.evtx: reconstructs RDP sessions, including reconnections that never generate a fresh logon event and are therefore invisible in the Security log

The general constraint on all of them: default retention is size-capped, not time-capped. On a busy domain controller the Security log can roll in hours. If you are engaging on a compromise that started three weeks ago and nobody was forwarding events, the window you care about may simply be gone — check retention before building an investigation plan around it.

4. Browser History Databases

Both store history as SQLite, which means standard SQLite recovery applies: deleted rows frequently persist in freelist pages and in the write-ahead log, so History-journal and History-wal are worth collecting alongside the database. Copy the file rather than opening it in place — an open handle from a running browser will otherwise block you, and analysing the live file modifies it:

  • Google Chrome: C:\Users\<username>\AppData\Local\Google\Chrome\User Data\Default\History
  • Microsoft Edge: C:\Users\<username>\AppData\Local\Microsoft\Edge\User Data\Default\History

macOS Artifacts

The fastest way to spot someone who has never done Mac work: they open a terminal and reach for /var/log/system.log. It has been effectively empty since Sierra, when unified logging replaced the traditional syslog files with a compressed binary tracev3 format that no text tool will read.

Beyond that, macOS keeps configuration in property lists — sometimes XML, often binary, occasionally both in the same directory — and its most useful activity records live in SQLite databases that Apple has never documented.

1. System and User Activity Logs

  • Unified Logging System: Use the native log tool; the on-disk format is not practically parseable otherwise. Default retention is short, frequently only a few days on a busy system, so collect early:
    log show --predicate 'process == "sudo"' --style syslog
    
  • Legacy Log Paths: Application-specific logs may still appear in /private/var/log/ and ~/Library/Logs/.

2. Persistence Mechanisms

  • LaunchDaemons (System-Level): /Library/LaunchDaemons/ and /System/Library/LaunchDaemons/
  • LaunchAgents (User/Session-Level): /Library/LaunchAgents/ and ~/Library/LaunchAgents/
  • Preference Plists: ~/Library/Preferences/com.apple.*.plist holds user and application configuration, and modified settings are frequently how persistence announces itself. Most are binary plists — run them through plutil -convert xml1 before trying to read anything

3. Execution History — KnowledgeC

  • KnowledgeC Database: ~/Library/Application Support/Knowledge/knowledgeC.db. Undocumented, and the single richest activity source on the platform — application focus intervals, screen lock and unlock, device connections, all with start and end timestamps rather than single points. It answers “was someone at this machine at 03:00” better than anything else available. Two practical notes: timestamps are Mac absolute time, seconds since 2001-01-01, not Unix epoch, and reading the file requires Full Disk Access.
  • Safari Browser History: ~/Library/Safari/History.db — URL visits and redirect chains, SQLite, same collection caveats as Chrome above.

Linux Artifacts

Linux is the easiest of the three to read and the hardest to trust. Everything is plain text, which means everything is trivially editable by anyone who reached root — and unlike the Windows compatibility caches, there is no obscure secondary record quietly contradicting the log a competent attacker cleaned.

The path differences between distributions are also a genuine trap when you are working at speed on an unfamiliar host.

1. Authentication and System Logs

  • Debian/Ubuntu: /var/log/auth.log — records SSH logins, sudo commands, PAM events, and authentication failures
  • RHEL/CentOS/Fedora: /var/log/secure serves the same purpose
  • General System Events: /var/log/syslog (Debian) or /var/log/messages (Red Hat) for kernel and daemon output. On systemd hosts, check journalctl as well — if the journal is persistent, it may retain events that the text logs have already rotated away

2. Shell History Files

~/.bash_history or ~/.zsh_history, depending on the user’s shell. Check the root user’s, service account home directories, and any account the attacker created — the last one is often the most productive and the most often skipped.

[!WARNING] Shell history is the least trustworthy artefact on this page. It can be cleared, disabled for a session with unset HISTFILE, bypassed entirely by prefixing commands with a space where HISTCONTROL=ignorespace is set, or fabricated outright with a text editor.

It also carries no timestamps by default — entries appear only in the order they were written, and only if HISTTIMEFORMAT was explicitly configured (export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "). Worse, history is normally flushed at session exit, so a session that was still open when you acquired the image may have left nothing behind.

Use it to generate leads and to corroborate. Never build a finding on it alone.

3. Scheduled Tasks and Persistence

  • Cron Jobs: /etc/crontab, /var/spool/cron/crontabs/, and the drop-in directories /etc/cron.d/, /etc/cron.hourly/, /etc/cron.daily/. Per-user crontabs under /var/spool are the ones most often missed, because they do not appear when you read /etc/crontab and stop there.
  • Systemd Services: /etc/systemd/system/ (site-local) and /lib/systemd/system/ (package-installed). Also check ~/.config/systemd/user/ — user units run without root and are absent from every system-level review. Systemd timers are a cron equivalent that a cron-focused check will not find at all.

4. SSH Configuration and Trust Records

  • Authorised Keys: ~/.ssh/authorized_keys — public keys permitted to log in without a password. Appending a key here is one of the cheapest persistence mechanisms available and survives every password reset your containment plan calls for. Check the file’s mtime against your incident timeline, and check every account, not just root.
  • Known Hosts: ~/.ssh/known_hosts — fingerprints of hosts this account has connected out to, which makes it a map of lateral movement from this system. Note that most distributions now hash the hostnames by default, so you cannot read them directly; you can still test a candidate host against the file with ssh-keygen -F.

Parsing YAML-Based Forensic Artifacts

One schema across every definition is what makes the repository useful as a data source rather than just documentation. You can ask it questions — which artefacts touch the registry, which apply only to a given Windows version, which your collection profile is currently missing — and get answers in a few lines.

Both examples below pull from main at runtime. For casework, clone the repository at a specific commit and read locally instead: your collection scope should be reproducible, and a definition file that silently changed between two engagements is not something you want to explain later.

PowerShell YAML Parsing

# Install and import the YAML parsing module
Install-Module -Name powershell-yaml -Scope CurrentUser -Force
Import-Module powershell-yaml

# Fetch live definitions from the main branch
$WindowsArtifacts = (Invoke-RestMethod -Uri "https://raw.githubusercontent.com/ForensicArtifacts/artifacts/main/data/windows.yaml")

# Convert YAML to a PowerShell object
$obj = ConvertFrom-Yaml $WindowsArtifacts -AllDocuments

# Extract registry key paths from the definitions
$obj.sources.attributes.keys | Select-String "HKEY"

Python YAML Parsing (Cross-Platform)

import yaml
import requests

url = "https://raw.githubusercontent.com/ForensicArtifacts/artifacts/main/data/windows.yaml"

try:
    response = requests.get(url)
    response.raise_for_status()

    definitions = list(yaml.safe_load_all(response.text))

    for artifact in definitions:
        name = artifact.get('name', 'Unknown')
        sources = artifact.get('sources', [])
        print(f"Artifact: {name}")
        for source in sources:
            attributes = source.get('attributes', {})
            paths = attributes.get('paths', [])
            keys = attributes.get('keys', [])
            if paths:
                print(f"  [Paths] -> {paths}")
            if keys:
                print(f"  [Keys]  -> {keys}")

except Exception as e:
    print(f"Error fetching or parsing artifacts: {e}")

Practical Analysis and Auditing Commands

Live response on a host you cannot take down. Everything below runs against a running system, which means everything below is subject to the same caveat: on a compromised host with a rootkit, these tools query kernel interfaces the attacker may have hooked. A clean result is not proof of a clean system.

1. Monitor Active Network Connections

ss reads netlink directly rather than walking /proc, which is why it returns in a fraction of the time netstat takes on a busy host:

# List all active TCP/UDP connections with associated process IDs
ss -tupn

2. Hunt for Authentication Anomalies

Grep gets you started; it does not get you finished. What you are looking for is rarely a single suspicious line — it is a successful login from a source address that never appears elsewhere, at an hour that account never works, or a burst of failures ending in one success. Pull the matches, then sort by source and by time:

# Find successful logins in auth.log
grep -i "Accepted" /var/log/auth.log

# Audit sudo usage
grep -i "COMMAND=" /var/log/auth.log

3. Recover Deleted Files from ext4 Filesystems

First rule, and it is not optional: never run recovery against a mounted filesystem, and never against the original media. Every write to that partition can overwrite the blocks you are trying to recover. Work from an image, read-only.

extundelete is worth trying and worth low expectations:

# Attempt recovery of all deleted files on an ext4 partition
sudo extundelete /dev/sda1 --restore-all

The limitation is structural rather than a bug: ext4 zeroes the block pointers in the inode on delete, so the metadata linking a filename to its data is gone even when the data blocks themselves are intact. extundelete reconstructs what it can from the journal, which on a busy filesystem is not much and gets worse with every minute the system stays up.

PhotoRec takes the other approach — ignore the filesystem entirely and carve by file signature. It recovers content that extundelete cannot, and it returns those files with no original names, no paths, and no timestamps, which limits what you can say about them. Autopsy with The Sleuth Kit combines both and keeps the case documentation you will need afterwards. For anything that might end up in front of a court, use Autopsy.


Best Practices for Forensic Artifact Handling

Correct findings from mishandled evidence are worth nothing. These four are what makes the difference, and each one fails in a specific, recoverable-if-caught-early way.

  1. Maintain the Chain of Custody: Who collected it, when, from what, and every transfer since. Write it as you go — a custody record reconstructed from memory three months later is exactly the thing a competent cross-examination is looking for.
  2. Never Analyse the Original: Work from a forensic duplicate, acquired through a write-blocker. Note that a software write-blocker depends on the acquiring OS behaving; Windows in particular has been known to touch a newly attached volume before you have done anything. Hardware blockers do not have this failure mode, which is why they still exist.
  3. Cryptographic Validation: SHA-256 the acquisition immediately, verify before analysis and again after. This is what lets you demonstrate the image is unchanged. It only works if the first hash was taken at acquisition — hashing later proves the file has not changed since you hashed it, which is a much weaker claim and a common mistake.
  4. Respect the Order of Volatility: Memory, network state, and the process table are gone the instant power drops, and every minute a compromised host stays running is another minute of overwrite pressure on deleted disk content. Capture volatile first. The corollary people skip: pulling the plug destroys memory, and a graceful shutdown lets malware run its cleanup routine — decide which you are doing, deliberately, and record why.

Additional Resources


The repository automates the part that was never the hard part. Collection is a solved problem; what it cannot do is tell you that Shimcache proves presence rather than execution, that a missing prefetch file means nothing on a server, or that the shell history reading as a clean confession is the artefact most easily forged. Knowing where to look is the entry fee. Knowing what each record actually proves — and saying so precisely, including where it stops — is the job.


Share article

Subscribe to my newsletter

Receive my case study and the latest articles on my WhatsApp Channel.

Warning

Ask CyberROX AI