Introduction
Linux powers the majority of the world's servers, cloud workloads, containers, IoT devices, and network appliances. Yet when a security incident occurs, many incident response teams find themselves underprepared for Linux forensics. Most IR training and tooling has historically focused on Windows, and responders who are comfortable navigating the Windows registry, event logs, and prefetch files often struggle to locate equivalent evidence sources on Linux systems.
This guide is a practical reference for incident responders investigating Linux systems. It covers the essential forensic artifacts — where they live, what they contain, how to collect them, and what they tell you about adversary activity. It is designed as a companion to our Windows Forensic Artifacts Cheatsheet, providing equivalent coverage for Linux environments.
A critical caveat before we begin: Linux is not a single operating system. It is a family of distributions with meaningful differences in default logging configurations, file locations, and available tools. This guide focuses on the most common distributions — Debian/Ubuntu and RHEL/CentOS/Fedora — but always verify the specifics of the system you are investigating. Check the distribution version, the init system (systemd vs SysV init), the logging daemon (rsyslog, syslog-ng, journald), and the filesystem type (ext4, xfs, btrfs) before making assumptions about artifact locations.
Authentication & Access Logs
Authentication logs are typically the first artifact examined during an incident because they answer the most fundamental question: who accessed this system, when, and how?
/var/log/auth.log and /var/log/secure
On Debian-based systems (Ubuntu, Debian), authentication events are logged to /var/log/auth.log. On Red Hat-based systems (RHEL, CentOS, Fedora), the equivalent file is /var/log/secure. Both files record the same categories of events through the PAM (Pluggable Authentication Modules) subsystem:
- SSH authentication: Successful and failed login attempts, including the source IP address, username, and authentication method (password, public key, keyboard-interactive). Look for entries containing
sshd. Failed attempts showFailed password fororFailed publickey for. Successful logins showAccepted password fororAccepted publickey for. - sudo usage: Every
sudocommand execution, including the user who ran it, the command executed, and the working directory. Entries begin with the username followed by: TTY=and; COMMAND=. Look forsudo: authentication failureentries indicating failed privilege escalation attempts. - su commands: User switching via
su, showing the source user, target user, and whether authentication succeeded. Entries containsu: pam_unix(su:session). - Account changes: User creation (
useradd), password changes (passwd), group membership modifications (usermod). These entries indicate potential persistence mechanisms — an attacker adding a new user account or adding an existing compromised account to privileged groups.
Check rotated log files as well: /var/log/auth.log.1, /var/log/auth.log.2.gz, etc. Log rotation configuration in /etc/logrotate.conf and /etc/logrotate.d/ determines retention periods. Attackers frequently clear or truncate these logs, so a suspiciously small file size or a gap in timestamps is itself an indicator of compromise.
wtmp, btmp, and utmp
These binary login record files predate modern syslog-based logging and provide a structured record of user sessions:
/var/log/wtmp— Records all logins and logouts. Read with thelastcommand. Each entry includes the username, terminal, source IP (for remote logins), login time, and session duration. Thelast -f /var/log/wtmpcommand displays the full history./var/log/btmp— Records failed login attempts. Read withlastb(requires root). A high volume of entries for a single username or from a single IP indicates brute-force activity. Entries for non-existent usernames may indicate credential stuffing./var/run/utmp— Records currently logged-in users. Read withwhoorw. This is a volatile artifact that only shows active sessions and is reset on reboot./var/log/lastlog— Records the most recent login for each user account. Read with thelastlogcommand. Useful for identifying accounts that have been dormant and are suddenly active, or service accounts that should never have interactive logins.
SSH Artifacts
SSH is the primary remote access protocol for Linux systems, and it leaves artifacts in multiple locations:
~/.ssh/authorized_keys— Public keys authorized for passwordless login. Examine this file for every user account, especially root. Attackers frequently add their own public key to maintain persistent access. Compare against known legitimate keys.~/.ssh/known_hosts— Hosts the user has connected to via SSH. This reveals lateral movement — which other systems were accessed from this host. Entries may be hashed (ifHashKnownHostsis enabled in SSH config), making direct hostname identification harder, but the IP address or hash can still be correlated with other evidence./etc/ssh/sshd_config— SSH server configuration. Check for modifications that weaken security:PermitRootLogin yes,PasswordAuthentication yes, non-standard ports, or allowed users/groups. Also check forAuthorizedKeysFiledirectives pointing to unusual locations.
Shell History & User Activity
Shell history is one of the most valuable forensic artifacts on a Linux system because it records the exact commands an attacker executed. It is also one of the most fragile — easily deleted, truncated, or disabled.
Command History Files
By default, Bash records command history to ~/.bash_history and Zsh to ~/.zsh_history. Check the history file for every user account, including root, service accounts, and any account with a valid shell. The following commands identify all accounts with valid login shells:
grep -v '/nologin\|/false' /etc/passwd | cut -d: -f1,6
Critical considerations for shell history forensics:
- Timestamps: By default, Bash does not record timestamps in the history file. If
HISTTIMEFORMATis set (e.g., in~/.bashrc), timestamps appear as comment lines (#1709654400) before each command entry in epoch format. Without timestamps, you know what was executed but not when — significantly reducing the evidentiary value. - History size limits: The
HISTSIZEandHISTFILESIZEvariables control how many entries are kept. Default values vary by distribution. An attacker who runs hundreds of commands may push their activity out of the history buffer. Check these variables in the user's shell configuration files. - History evasion: Attackers commonly evade history logging by: prefixing commands with a space (if
HISTCONTROL=ignorespaceis set), unsettingHISTFILE, settingHISTSIZE=0, linking.bash_historyto/dev/null, or simply deleting the file. A missing or suspiciously empty history file for an active account is itself an indicator of compromise. - History writes on logout: Bash writes history to the file when the session terminates. If an attacker's session is killed abruptly (or if the system crashes), the history from that session may not be written. Conversely, if
shopt -s histappendandPROMPT_COMMAND="history -a"are set, history is written after every command — making it more resilient to session interruption.
Shell Configuration and Profile Files
Shell configuration files are a common persistence vector. Examine the following files for modifications, especially recently modified entries or appended commands:
~/.bashrc— Executed for every interactive non-login shell. Attackers may append a reverse shell command, a cron job installation command, or a command to download and execute a payload. Since this file runs on every new terminal session, it provides reliable persistence.~/.bash_profile/~/.profile— Executed for login shells. Similar persistence vector but triggers only on initial login rather than every terminal session./etc/profile//etc/profile.d/*.sh— System-wide profile scripts executed for all users. Modifications here affect every user on the system, providing broad persistence.~/.viminfo— Records files opened in vim, search patterns, command history, and register contents. This artifact can reveal which files an attacker viewed or edited, what they searched for, and text they copied.
System Logs
systemd Journal
On modern Linux distributions using systemd (which is the vast majority of systems deployed in the last decade), the systemd journal is the primary logging mechanism. The journal stores log data in a binary format in /var/log/journal/ (persistent) or /run/log/journal/ (volatile, lost on reboot). Query it with journalctl:
journalctl --since "2026-03-10" --until "2026-03-12"— Filter by time rangejournalctl -u sshd— Filter by service unitjournalctl _UID=1001— Filter by user IDjournalctl -p err— Filter by priority (emerg, alert, crit, err, warning, notice, info, debug)journalctl -k— Kernel messages onlyjournalctl --output=json-pretty— Structured output with full metadata
The journal's structured format includes rich metadata — process ID, user ID, executable path, systemd unit — that traditional syslog does not capture. The json-pretty output mode exposes all available fields. Check whether the journal is configured for persistent storage: if /var/log/journal/ does not exist, journal data is stored only in the volatile /run/log/journal/ directory and is lost on reboot.
Traditional Syslog Files
/var/log/syslog(Debian) //var/log/messages(RHEL) — General system messages from all services. A broad artifact that captures events from services that do not have dedicated log files./var/log/kern.log— Kernel messages, including kernel module loading events. An attacker loading a rootkit kernel module will generate a log entry here (unless the log is tampered with). Look for entries containingmodule,insmod, or unusual device messages./var/log/dmesg— Boot-time kernel messages. Useful for establishing the system boot timeline and identifying hardware changes or unusual kernel events at startup./var/log/daemon.log— Messages from system daemons. May contain output from attacker-installed services or modified legitimate daemons.
Scheduled Tasks & Persistence
Persistence is the attacker's mechanism for surviving reboots, service restarts, and credential rotations. Linux offers multiple persistence vectors, each of which must be examined during an investigation.
Cron Jobs
/etc/crontab— System-wide crontab file with user field. Rarely modified by administrators in modern systems, so any entries here warrant scrutiny./etc/cron.d/— Directory for system cron jobs, typically installed by packages. Check for files with unusual names or recent modification times./etc/cron.hourly/,/etc/cron.daily/,/etc/cron.weekly/,/etc/cron.monthly/— Periodic cron job directories. Attackers may drop a script here knowing it will execute on a regular schedule./var/spool/cron/crontabs/(Debian) //var/spool/cron/(RHEL) — Per-user crontab files. List them withcrontab -l -u <username>for each user. These files are frequently used for persistence because they survive package updates and are not typically monitored.
Also check /var/log/cron (RHEL) or grep syslog for CRON entries (Debian) to see cron execution history — this shows when scheduled tasks actually ran, which is critical for establishing a timeline.
Systemd Services and Timers
Systemd provides a more modern persistence mechanism through service units and timer units:
/etc/systemd/system/— System-wide service units. Attackers may create a new malicious service here that starts on boot. Look for units with unusual names, recently created files, orExecStartdirectives pointing to unexpected binaries or scripts.~/.config/systemd/user/— Per-user service units. These run in the user's context without requiring root privileges and are often overlooked during investigations.systemctl list-unit-files --type=service— List all installed services and their enable/disable status. Compare against a known-good baseline to identify unauthorized services.systemctl list-timers --all— List all timer units (systemd's cron equivalent). Timer units trigger associated service units on a schedule and are increasingly used for both legitimate and malicious scheduled task persistence.
Other Persistence Vectors
/etc/rc.local— Executed at the end of the boot process on systems that support it. While deprecated in modern systemd distributions, many systems still honor this file if it exists and is executable./etc/init.d/— SysV init scripts. On systemd systems, these are often wrapped by systemd compatibility layers but may still be used for persistence.- Kernel modules:
/etc/modules,/etc/modules-load.d/,/lib/modules/— Malicious kernel modules (rootkits) can be configured to load at boot. Verify loaded modules withlsmodand compare against a baseline. - LD_PRELOAD:
/etc/ld.so.preload— Forces a shared library to be loaded into every process. A powerful persistence and hijacking mechanism. This file should typically be empty or nonexistent.
File System Artifacts
MAC Timestamps
Linux file systems track multiple timestamps for each file. On ext4 (the most common Linux file system), each file has four timestamps:
- Modify (mtime): Last time file contents were changed. Updated by write operations.
- Access (atime): Last time the file was read. Note: many modern systems mount filesystems with
noatimeorrelatimeoptions for performance, which means atime may not accurately reflect the last access. Check mount options withmount | grep atime. - Change (ctime): Last time file metadata was changed (permissions, ownership, link count). Critically, ctime cannot be set to an arbitrary value using standard tools —
touchcan modify mtime and atime but not ctime. This makes ctime valuable for detecting timestamp manipulation. - Birth (crtime/btime): File creation time. Supported on ext4 but not easily accessible through standard tools until recently. Use
staton newer systems ordebugfsto extract it:debugfs -R 'stat <inode>' /dev/sdX.
Use stat <filename> to display all available timestamps for a file. For investigations, use find to locate files modified within a timeframe of interest: find / -mtime -7 -type f (modified in the last 7 days). Combine with -not -path to exclude noisy directories like /proc, /sys, and /run.
Staging Directories and Suspicious Locations
Attackers commonly stage tools, payloads, and exfiltrated data in directories that are world-writable, infrequently monitored, or designed to be temporary:
/tmpand/var/tmp— World-writable temporary directories./tmpis typically cleared on reboot;/var/tmppersists across reboots. Look for executable files, scripts, hidden files (dotfiles), and recently created directories./dev/shm— A tmpfs (RAM-based filesystem) that is world-writable and commonly used by malware to stage fileless payloads. Contents exist only in memory and are lost on reboot, so capture these artifacts before rebooting.- Hidden directories in
/tmp,/var,/opt— Directories starting with.(e.g.,/tmp/.ICE-unix/../.hidden/) are commonly used by attackers to hide tools. - Unusual locations:
/usr/share,/usr/lib,/opt— Legitimate-looking directories that blend in with system files. Check for recently modified files in these locations.
Search for SUID/SGID binaries, which can be used for privilege escalation: find / -perm -4000 -type f 2>/dev/null. Compare results against a known-good baseline — any unexpected SUID binary is a serious finding.
Package Management Logs
/var/log/apt/history.log— APT package operations on Debian-based systems (install, upgrade, remove). Reveals whether the attacker installed additional tools./var/log/dpkg.log— Lower-level dpkg operations on Debian-based systems./var/log/yum.log//var/log/dnf.log— Package operations on RHEL-based systems.
Network Artifacts
Network configuration and connection artifacts reveal how the attacker communicated with the compromised system and what network modifications they made.
/etc/hosts— Static DNS overrides. Attackers may add entries to redirect domain resolution — for example, redirecting a security update server to prevent patching, or redirecting internal services to an attacker-controlled server./etc/resolv.conf— DNS resolver configuration. Modified DNS servers may route queries to attacker infrastructure for interception or redirection.iptables -L -n -v/nft list ruleset— Current firewall rules. Check for rules that open unexpected ports, allow traffic from specific IPs, or redirect traffic. Also check persistent firewall configurations in/etc/iptables/or/etc/nftables.conf.ss -tulnp— Currently listening TCP and UDP ports with associated processes. Identifies backdoor listeners and unexpected services. Compare against expected services.ss -tnp— Current established TCP connections with process information. Shows active command-and-control connections./proc/net/tcpand/proc/net/tcp6— Established connections from procfs, readable even ifss/netstatbinaries have been tampered with. Fields are in hexadecimal and require decoding, but they provide a tamper-resistant view of network state.
Process & Memory Artifacts
The /proc filesystem is a virtual filesystem that provides a window into every running process. For live system forensics, /proc is an invaluable source of information about active adversary processes.
/proc/[pid]/cmdline— The full command line used to launch the process. Null-byte separated. Reveals what arguments were passed to the process, which may include file paths, IP addresses, or credentials./proc/[pid]/exe— A symbolic link to the executable file. If the file has been deleted from disk (a common technique for fileless attacks), this link will show(deleted)but can still be copied:cp /proc/[pid]/exe /evidence/recovered_binary. This allows you to recover malware that the attacker tried to hide./proc/[pid]/environ— The process environment variables. May contain credentials, API keys, paths, or configuration values that reveal the attacker's infrastructure or tools./proc/[pid]/fd/— Open file descriptors. Shows what files, sockets, and pipes the process has open. Socket entries (prefixed withsocket:) can be correlated with/proc/net/tcpto identify network connections./proc/[pid]/maps— Memory mappings for the process. Lists all memory regions and the files mapped into them. Look for unusual shared libraries that are not part of the standard system — this can reveal injected libraries (LD_PRELOAD attacks) or memory-resident malware./proc/[pid]/status— Process status including UID, GID, parent PID, and capabilities. The parent PID (PPid) is useful for building process trees to understand how a malicious process was spawned.
For full memory acquisition, use LiME (Linux Memory Extractor), a loadable kernel module that acquires a raw memory dump. The dump can then be analyzed with Volatility or Rekall for deeper analysis — process listings, network connections, loaded kernel modules, and injected code that may not be visible through /proc alone. Memory acquisition should be performed as early as possible in the investigation, before any remediation actions that might terminate attacker processes.
Container-Specific Artifacts
Containers add layers of complexity to Linux forensics. The containerized process runs on the host kernel but operates in isolated namespaces, and its filesystem is a layered overlay.
Docker
/var/lib/docker/— Docker's root directory containing images, containers, volumes, and network configuration. Thecontainers/subdirectory holds per-container configuration and logs.docker logs <container_id>— Container stdout/stderr output. May contain application logs, error messages, or output from attacker commands.docker inspect <container_id>— Full container configuration including environment variables, mounted volumes, network configuration, and the command used to start the container. Mounted volumes may provide access to host filesystems.docker diff <container_id>— Shows filesystem changes in the container layer relative to the base image. Lists added, modified, and deleted files — useful for identifying what an attacker changed.- Overlay filesystem: Docker uses overlay2 by default. Container-specific changes live in
/var/lib/docker/overlay2/<layer_id>/diff/. You can examine these layers directly on the host filesystem without entering the container.
Kubernetes
- Pod logs:
kubectl logs <pod> -n <namespace> --previous— Retrieve logs from the current and previous container instance. - Kubernetes audit logs: Record API server requests including who requested what, when, and the response. Essential for investigating unauthorized pod deployments, privilege escalation via RBAC manipulation, or secret access. Typically found in
/var/log/kubernetes/audit/or forwarded to a centralized logging system. - etcd: Kubernetes stores all cluster state in etcd. A compromised etcd instance exposes secrets, configurations, and the complete cluster state.
Quick Reference Table
The following summary maps common investigation questions to the artifacts and tools that answer them:
- Who logged in? →
/var/log/auth.log,wtmp(last),btmp(lastb) - What commands were run? →
~/.bash_history,~/.zsh_history,/var/log/auth.log(sudo) - What services are running? →
systemctl list-units,ss -tulnp,/proc/[pid]/ - How does the attacker persist? →
crontab,systemdunits,~/.ssh/authorized_keys,~/.bashrc,/etc/ld.so.preload - What files changed? →
findwith-mtime/-ctime, package manager logs,docker diff - What network connections exist? →
ss,/proc/net/tcp,iptables,/etc/hosts - What is in memory? →
/proc/[pid]/, LiME + Volatility - Were logs tampered with? → Timestamp gaps, truncated files, missing rotated logs,
journalctl --verify
"In Linux forensics, the absence of an artifact is often as informative as its presence. An empty history file, a missing log, or a suspiciously recent ctime on a file that should not have changed — these negative indicators are signals that should drive your investigation, not dead ends."