Investigate a Linux System

Triage a live Linux host the way a security engineer does during incident response.

Introduction

30 Second Summary

Every program, every user, and every network connection on a Linux system tells a story. When a security engineer lands on a compromised machine, their first job is reading that story to figure out what is running, who put it there, and how it survives a reboot.

In this project, you will investigate your own Kali Linux machine using the same methodology professional incident responders use. You will produce a structured triage report covering processes, users, network connections, and persistence mechanisms.

What You'll Build

By the end of this project, you will open a text file on your Desktop containing a complete system investigation report that you wrote command by command, proving you can land on any Linux host and answer: what is running, who owns it, and how does it persist.

By the end of this project, you'll have:

  • A process snapshot showing every running program on your system, who owns it, and its full parent-child tree traced back to PID 1.
  • A network connection map linking every open port to the exact process and user responsible for it.
  • A persistence audit documenting every scheduled task, startup service, and login script that would bring a program back after a reboot.
  • Secret Mission: Hunt for SUID binaries on your system and explain why they create privilege escalation paths.

Are there any prerequisites?

You need a working Kali Linux installation with terminal access. This can be a dedicated machine, a dual-boot partition, or a virtual machine. As long as you can open a terminal and run commands, you are ready to go.

Before We Start

Before you touch any commands, take a moment to lock in what you are about to do and why it matters. Security engineers always start by understanding the scope of their investigation before collecting evidence.

Set Up Your Investigation Workspace

Before touching anything on a live system, a security engineer creates a workspace to capture findings. Without a dedicated place to store evidence, everything gets lost in terminal scroll-back.

In this step, you will create a structured investigation directory on your Kali Linux machine and record a system baseline. This gives you a timestamped starting point so you can prove what you found and when you found it.

In this step, get ready to:
  • Create a dedicated investigation directory and triage report file.
  • Record your system baseline (date, hostname, kernel, uptime).
  • Confirm your user identity and sudo access.
Create your investigation directory

Every investigation starts with a clean workspace. You need a folder to hold your findings and a report file to write them into.

  • Create the investigation directory, move into it, and create your report file by running these commands:
mkdir -p ~/investigation
cd ~/investigation
touch triage-report.txt

What do these commands do?

  • mkdir -p creates the directory (-p means no error if it already exists).
  • cd moves your terminal session into that directory.
  • touch creates an empty file called triage-report.txt.
  • Confirm the file was created by running:
ls

You should see triage-report.txt listed in the output.

Don't see the file?

  • Make sure you ran all three commands in order. If you skipped cd ~/investigation, run it now before running ls again.
  • If you see "No such file or directory", re-run mkdir -p ~/investigation first.

Why isn't my investigation directory showing up?

Record the system baseline

A triage report always starts with context: when the investigation began, which machine you are on, and what kernel is running. This header becomes your timestamp if findings are ever questioned.

  • Write the system baseline header into your report by running this command:
echo "=== SYSTEM TRIAGE REPORT ===" > triage-report.txt && echo "Date: $(date)" >> triage-report.txt && echo "Hostname: $(hostname)" >> triage-report.txt && echo "Kernel: $(uname -r)" >> triage-report.txt && echo "Uptime: $(uptime)" >> triage-report.txt

What does this command do?

  • The first echo uses > to overwrite the file with the report header.
  • Each following echo uses >> to append a new line without erasing what came before.
  • $(date), $(hostname), $(uname -r), and $(uptime) are command substitutions. The shell runs each one and inserts its output into the string.
  • Verify the baseline was written by running:
cat triage-report.txt

You should see five lines: the report header, your current date, your machine's hostname, your kernel version, and how long the system has been running.

Seeing an empty file?

  • Make sure you are still inside the ~/investigation directory. Run pwd to check your current location.
  • If cat shows nothing, re-run the full echo command above. Copy it exactly, including the && between each part.

Help me figure out why my triage-report.txt is empty.

Verify your user context and sudo access

Before you investigate a system, you need to know who you are on it. Your user identity determines what you can see and what commands you can run.

  • Check your user identity by running:
id

You should see your UID (user ID), GID (group ID), and a list of groups your account belongs to.

  • Confirm your username by running:
whoami

This outputs your current username in plain text.

  • Append your identity information to the triage report by running:
echo -e "\n=== INVESTIGATOR CONTEXT ===" >> triage-report.txt && id >> triage-report.txt

Why record your investigator context?

If someone reviews your findings later, they need to know what level of access you had during the investigation. Recording your UID and groups proves whether you could see everything or were limited by permissions.

  • Now confirm you have root-level access through sudo by running:
sudo whoami

What is sudo?

sudo lets you run a single command with root (administrator) privileges. Many investigation commands need root access to see all processes and network connections.

Kali Linux will prompt you for your user password when you run sudo for the first time in a session. Type your password and press Enter. You will not see any characters appear as you type.

You should see root printed in your terminal. This confirms you have the access needed for the full investigation.

Seeing 'user is not in the sudoers file'?

  • This means your account does not have sudo privileges. If you set up Kali with the default installer, your user should already have sudo access.
  • If you are running an older Kali image that uses a root account directly, run whoami. If it shows root, you already have full access and can proceed without sudo.

Why can't I run sudo on my Kali machine?

Before you move on, what do you expect to see if you run ls ~/investigation/ right now?

  • Verify your workspace is ready by running:
ls ~/investigation/

You should see triage-report.txt listed. Your investigation workspace is set up and your report file is ready to receive findings.

Your workspace is locked in and your identity is documented. Next up, you will investigate every running process on the system and trace what launched it.

Investigate Running Processes

Your investigation workspace is ready, with a report file primed to capture findings. Now it is time to see what is actually alive on this machine.

Every program executing on a Linux system is a process. An attacker who compromises a system also runs processes to maintain access.

If you cannot see what is running and who owns it, you cannot spot the intruder. This step produces a complete snapshot of everything alive on the system right now.

In this step, get ready to:
  • Capture a full process listing showing every running program, its owner, and resource usage.
  • Explore the /proc filesystem to read process details directly from the kernel.
  • Map parent-child relationships in the process tree.
Capture a full process listing with hierarchy

The ps command reads the kernel's process table and presents it in a human-readable format. With the right flags, it shows every process on the system, who owns it, and how much CPU and memory it consumes.

  • In your terminal, view all running processes in tree format by running this command:
ps auxf

What do these flags mean?

  • a shows processes from all users, not just your own.
  • u adds the user-oriented format with columns for USER, PID, %CPU, %MEM, and more.
  • x includes processes without a terminal (background daemons and services).
  • f displays the full forest/tree format showing parent-child hierarchy via indentation.

You should see a table filling your terminal with columns including USER, PID, %CPU, %MEM, STAT, and COMMAND. The tree indentation shows which processes spawned which others.

  • Scan the output for anything unexpected: processes owned by root that you did not start, unfamiliar names, or anything consuming high CPU or memory.
  • Save this snapshot to your triage report by running:
ps auxf >> ~/investigation/triage-report.txt
  • Confirm it saved by running:
tail -5 ~/investigation/triage-report.txt

You should see the last few lines of your process listing appended to the report file.

Seeing very few processes?

If you only see 2-3 lines, make sure you included all four flags: auxf (no dashes before them). The a and x flags are what expand the listing beyond just your shell session.

Help me understand my ps output

Trace a specific process deeper using /proc

The ps command gives you a summary, but the kernel stores far more detail about each process. The /proc filesystem is a virtual filesystem the kernel creates in memory to expose live information about every running process.

Tools like ps are just reading /proc for you. Learning to read it directly gives you access to details that no wrapper tool shows.

  • Read the status of PID 1 (the systemd init process that starts everything else) by running:
cat /proc/1/status

What does this output show?

The /proc/1/status file provides a human-readable view of the process including its Name, State, PID, parent PID (PPid), UID, GID, virtual and physical memory sizes, threads, and capabilities.

For PID 1, you should see the Name as systemd and the PPid as 0 (it has no parent because the kernel started it).

  • See the exact command line that launched this process by running:
cat /proc/1/cmdline | tr '\0' ' '

Why pipe through tr?

The /proc/1/cmdline file stores command line arguments separated by null bytes (invisible characters). The tr '\0' ' ' converts those null bytes into spaces so the output is readable.

You should see the path to the systemd binary and any arguments it was launched with.

  • Check what binary the process is actually running by running:
ls -la /proc/1/exe

Why does this matter for security?

The /proc/1/exe is a symlink to the actual binary being executed. If an attacker renames their malware to look like a legitimate process, the exe symlink reveals the true path of the binary on disk.

If the symlink shows (deleted) next to it, that means the binary was removed from disk while still running. That is a strong indicator of malicious activity.

You should see a symlink pointing to something like /usr/lib/systemd/systemd. That confirms PID 1 is running a legitimate binary from the expected system path.

Getting permission denied?

Some /proc entries require elevated privileges to read. Prefix the command with sudo if you see a permission error. For example: sudo cat /proc/1/status.

Help me read /proc entries

Identify process parent-child relationships

Every process on a Linux system has a parent that spawned it. All processes trace back to PID 1 (systemd). Any process with a broken chain or an unexpected parent is worth investigating further.

  • View the full process tree with PIDs by running:
pstree -p

What does this show?

The pstree -p command displays the process tree with PIDs shown in parentheses next to each process name. You can trace any process back up the tree to see exactly what chain of programs launched it.

You should see systemd(1) at the top with branches spreading out to every other process on the system. Find your own terminal session in the tree to confirm you can trace your shell's ancestry.

  • Save the process tree to your triage report by running:
echo -e "\n=== PROCESS TREE ===" >> ~/investigation/triage-report.txt && pstree -p >> ~/investigation/triage-report.txt

What does this command do?

This appends a section header (=== PROCESS TREE ===) followed by the full process tree to your triage report. The && means the second command only runs if the first one succeeds.

Before you verify, predict what you expect to see when you look at the first 20 lines of a process listing. Which columns will appear, and what process do you think will be first?

  • Confirm your investigation captured everything by running:
ps auxf | head -20

You should see a process tree showing at least your terminal session and the ps command itself, with columns for USER, PID, %CPU, %MEM, and COMMAND.

  • Also verify your report file has both sections by running:
grep "===" ~/investigation/triage-report.txt

You should see at least three section headers: SYSTEM TRIAGE REPORT, INVESTIGATOR CONTEXT, and PROCESS TREE.

Missing the PROCESS TREE section?

Make sure you ran the combined echo and pstree command with >> (double arrow, which appends) and not > (single arrow, which overwrites the entire file).

Help me fix my triage report

You now have a complete process snapshot in your report. You know who is running what, how much resource each process takes, and where every process sits in the hierarchy. Next, you will figure out which of these users actually has the power to do damage.

Map Users, Groups, and Privileges

Your process investigation revealed everything running on the system. But knowing what is running tells you nothing about who is allowed to do what.

A single user account with UID 0 that is not named root is a classic backdoor. In this step, you will examine every identity on the system, map out sudo access, and review login history to spot unauthorized privilege.

In this step, get ready to:
  • Enumerate every user account and identify anomalies like unauthorized root-equivalent users.
  • Determine which accounts have sudo access and can escalate to root.
  • Review login history for evidence of unauthorized access.
Enumerate all user accounts and find anomalies

Every account on a Linux system is defined in /etc/passwd. Each line follows the format: username:password:UID:GID:comment:home:shell.

  • List every user account on the system by running:
cat /etc/passwd

You will see a long list of accounts. Most are system service accounts (like daemon, nobody, www-data) that exist to run services with limited permissions.

What do the fields mean?

Each line has seven colon-separated fields. The third field is the UID (User ID). UID 0 means root-level access. The last field is the login shell.

Accounts with /nologin or /false as their shell cannot log in interactively. They exist only to own service processes.

Not every account in that list can actually log in. Filter down to only accounts with real interactive shells.

  • List accounts that have interactive shells by running:
grep -v '/nologin\|/false' /etc/passwd

This much shorter list shows the accounts that can actually log in. These are the accounts an attacker would target or create.

  • Save the full user account listing to your report by running:
echo -e "\n=== USER ACCOUNTS ===" >> ~/investigation/triage-report.txt && cat /etc/passwd >> ~/investigation/triage-report.txt

What does this command do?

The echo -e writes a section header with a leading blank line. The && chains a second command that appends the full /etc/passwd contents to your report. The >> operator appends without overwriting existing content.

  • Confirm the section was added by running:
grep "USER ACCOUNTS" ~/investigation/triage-report.txt

You should see === USER ACCOUNTS === printed back, confirming your report now contains the user enumeration.

Examine who has sudo access

Any user in the sudo group or listed in the sudoers file can escalate to root. An attacker who gains access to one of these accounts effectively owns the entire system.

  • View the main sudoers configuration by running:
sudo cat /etc/sudoers

This file defines which users and groups can run commands as root. Look for lines starting with a username or %groupname followed by privilege definitions.

  • Check for additional sudoers drop-in files by running:
ls -la /etc/sudoers.d/

Why check sudoers.d?

Attackers often add files to /etc/sudoers.d/ instead of editing the main sudoers file. Drop-in files are less likely to be noticed during a quick review and they persist across system updates.

  • See which users belong to the sudo group by running:
cat /etc/group | grep sudo

The output shows the sudo group and its members after the final colon. Any username listed here can run sudo commands and escalate to root.

Check login history and currently logged-in users

Login records reveal who has accessed the system recently. Unfamiliar usernames or IP addresses in the login history are strong indicators of compromise.

  • See who is logged in right now by running:
who

You should see your own session listed. On a freshly booted Kali machine, this is typically just your terminal session.

  • View the last 20 login entries by running:
last -a | head -20

This shows recent logins with timestamps and source addresses. On a personal Kali machine you should see only your own user. Any unfamiliar usernames or external IPs would be a red flag.

  • Check for failed login attempts (brute force evidence) by running:
lastb 2>/dev/null | head -10

What if lastb shows nothing?

An empty result is good news. It means no failed login attempts have been recorded. The 2>/dev/null suppresses an error message if the log file does not exist yet.

  • Save the login history to your report by running:
echo -e "\n=== LOGIN HISTORY ===" >> ~/investigation/triage-report.txt && last -a | head -20 >> ~/investigation/triage-report.txt
  • Confirm the section was added by running:
grep "LOGIN HISTORY" ~/investigation/triage-report.txt

You should see === LOGIN HISTORY === printed back.

Now run the critical security check for this step. Before you execute the next command, ask yourself: do you expect any account other than root to have UID 0?

  • Check for accounts with UID 0 (root-equivalent privileges) by running:
awk -F: '($3==0)' /etc/passwd

You should see only root listed. If you see any other account with UID 0, you have found a backdoor-style persistence mechanism.

Why is UID 0 special?

The Linux kernel treats UID 0 as the superuser. Any account with UID 0 bypasses all permission checks, regardless of its name. Attackers sometimes create accounts like sysadmin or backup with UID 0 to maintain hidden root access.

Seeing more than just root?

If another account appears with UID 0, investigate it immediately. Check when it was created, what shell it uses, and whether anyone on your team recognizes it. On a standard Kali install, only root should appear.

Need help interpreting your results?

You now have a complete picture of who can do what on this system. Next up, you will connect the dots between processes, users, and the network to find out which ones are talking to the outside world.

Expose Network Connections

You have a full map of processes and users on your system. But one critical question remains unanswered: which of those processes are talking to the outside world?

An attacker's reverse shell is just a process with an outbound TCP connection. In this step, you will use ss, lsof, and the /proc filesystem to connect the dots between processes, users, and network sockets.

In this step, get ready to:
  • Map every listening port to its owning process.
  • Identify active outbound connections and the processes behind them.
  • Read the kernel's raw network table directly from /proc.
List all listening ports and map them to processes

Every open port on your system is a door. To assess risk, you need to know which process opened each door and which user owns it.

Before you run this command, think about what you expect to find. How many services do you think are listening on your Kali machine right now?

  • View all listening TCP and UDP ports with their owning processes by running:
sudo ss -tulnp

You should see a table with columns: Netid, State, Recv-Q, Send-Q, Local Address:Port, Peer Address:Port, and Process. Each row represents a socket that is actively waiting for incoming connections.

What do the flags mean?

  • -t: show TCP sockets.
  • -u: show UDP sockets.
  • -l: show only listening sockets (not established connections).
  • -n: display numeric ports instead of resolving service names.
  • -p: show the process name and PID that owns each socket.

Why ss instead of netstat?

The netstat command is deprecated. Its own man page states it is "mostly obsolete" and recommends ss as the replacement. ss reads directly from kernel socket tables, making it faster and more accurate.

  • Save your listening ports to the triage report by running:
echo -e "\n=== LISTENING PORTS ===" >> ~/investigation/triage-report.txt && sudo ss -tulnp >> ~/investigation/triage-report.txt
  • Confirm the section was added by running:
grep "LISTENING PORTS" ~/investigation/triage-report.txt

You should see === LISTENING PORTS === printed back, confirming your network findings are now part of the report.

Not seeing any output from ss?

Make sure you included sudo before ss. Without root privileges, the Process column will be empty because your user cannot see other users' socket ownership.

If the entire table is empty, you may have no services running. Try starting SSH with sudo systemctl start ssh and re-run the command.

Help me troubleshoot why ss -tulnp shows no output on my Kali machine.

Check for active outbound connections

Listening ports show what is waiting for traffic. Outbound connections show what is actively talking to another machine right now. A reverse shell, a data exfiltration channel, or a command-and-control beacon all appear as established outbound connections.

  • View all currently established TCP connections by running:
sudo ss -tnp state established

This filters to show only TCP sockets in the ESTABLISHED state with process info. Any connection to an external IP you do not recognize is a red flag worth investigating.

What if the table is empty?

An empty result means your system has no active outbound TCP connections right now. This is normal for a freshly booted Kali system that is not running background services or browsing the web. On a compromised system, this is where you would spot suspicious connections.

  • Cross-reference sockets with their owning processes using a different tool by running:
sudo lsof -i -n -P | grep ESTABLISHED

Why use lsof as well?

In Linux, network sockets are files. The lsof command lists open files, which includes network sockets.

The flags work like this: -i selects network files, -n skips hostname resolution, and -P shows numeric ports. Using both ss and lsof gives you two independent views of the same data. If they disagree, something is hiding from one of them.

Seeing 'command not found' for lsof?

The lsof command is pre-installed on Kali Linux. If you see an error, install it by running sudo apt install lsof.

Help me get lsof working on my Kali system.

Read the raw kernel network table

Tools like ss and lsof read from the kernel's /proc filesystem and present the data in a human-readable format. But a rootkit can hook these tools and hide connections from their output. Reading /proc/net/tcp directly lets you see what the kernel actually knows.

  • Read the raw TCP socket table from the kernel by running:
cat /proc/net/tcp | head -10

You should see rows of hex-encoded data with columns like local_address, rem_address, and st (state).

How do I read the hex addresses?

The local_address column uses the format hex_IP:hex_port. For example, 0100007F:0016 means 127.0.0.1:22.

The IP is stored in little-endian byte order (reversed). The port is a straightforward hex-to-decimal conversion: 0016 in hex equals 22 in decimal, which is the SSH port.

This is what ss reads behind the scenes. Unless the kernel itself is compromised, this data cannot be hidden from you.

Take a moment to compare a row from /proc/net/tcp with your ss output. If they match, your tools are reporting honestly. If they ever disagree on a real investigation, you may be dealing with a rootkit.

  • Verify your triage report now contains the network findings by running:
cat ~/investigation/triage-report.txt | grep "==="

You should see all your section headers listed, including === LISTENING PORTS ===. This confirms your network investigation is captured alongside your process and user findings.

Missing the LISTENING PORTS section?

If the section header does not appear, the save command from the first substep may not have run correctly. Re-run the save command:

echo -e "\n=== LISTENING PORTS ===" >> ~/investigation/triage-report.txt && sudo ss -tulnp >> ~/investigation/triage-report.txt

Then run the grep check again to confirm.

Help me fix my triage report so it includes network data.

You can now trace any network connection on a Linux system back to the process and user that owns it. Next up, you will hunt for persistence mechanisms that let attackers survive a reboot.

Find Persistence Mechanisms

In the previous step, you connected processes to network sockets and identified which programs are talking to the outside world. You can now see what is running, who owns it, and where it is communicating.

Everything you have found so far is volatile. If the system reboots, processes die and connections close. An attacker who wants to maintain access needs persistence: scheduled tasks, startup services, or modified login scripts that re-establish their foothold after every reboot. This is where you catch the real threat.

In this step, get ready to:
  • Enumerate all scheduled tasks (cron jobs) on the system.
  • Identify services that start automatically on boot.
  • Check user startup scripts for injected commands.
Enumerate all cron jobs

Cron is the Linux task scheduler. It runs commands at specified times or intervals. Attackers use cron to re-download malware, re-open reverse shells, or re-establish persistence every few minutes.

  • Check your user's crontab and root's crontab by running these commands one at a time:
crontab -l
sudo crontab -l

You will likely see "no crontab for <username>" on a fresh Kali system. That is normal and means no user-level scheduled tasks exist.

  • Check the system-wide cron directories and main crontab by running:
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/
cat /etc/crontab

What are these cron directories?

Linux organizes scheduled tasks in multiple locations. User crontabs live in /var/spool/cron/crontabs/. System-wide jobs live in /etc/crontab and the drop-in directories (/etc/cron.d/, /etc/cron.daily/, etc.).

Attackers often add files to /etc/cron.d/ because administrators rarely check it manually. Anything that downloads from the internet, runs scripts from /tmp, or connects to external IPs is highly suspicious.

  • Save your crontab findings to the triage report by running:
echo -e "\n=== SCHEDULED TASKS ===" >> ~/investigation/triage-report.txt && crontab -l >> ~/investigation/triage-report.txt 2>&1 && echo "--- root crontab ---" >> ~/investigation/triage-report.txt && sudo crontab -l >> ~/investigation/triage-report.txt 2>&1
  • Confirm the section was written by running:
tail -5 ~/investigation/triage-report.txt

You should see the === SCHEDULED TASKS === header and the crontab output (or "no crontab" messages) in the last few lines.

Not seeing the SCHEDULED TASKS section?

Make sure you are still in the ~/investigation/ directory and that you typed the path ~/investigation/triage-report.txt correctly. Run cat ~/investigation/triage-report.txt to see the full file and verify all prior sections are intact.

help me debug why my echo append command did not write to triage-report.txt

List enabled systemd services

Systemd manages which programs start at boot time. Any service set to "enabled" will automatically launch when the system powers on. Attackers create custom service unit files to ensure their tools restart after every reboot.

  • List all services configured to start on boot by running:
systemctl list-unit-files --type=service --state=enabled

You will see a table of service names with the state "enabled" next to each one. Common entries on Kali include ssh.service, networking.service, and systemd-timesyncd.service.

Investigate unfamiliar services

If you see a service you do not recognize, run systemctl status <service-name> (replacing <service-name> with the name from the list). This shows its description, PID, and recent log entries.

  • Check for custom unit files that an attacker might have placed by running:
ls /etc/systemd/system/

This directory is where custom service definitions live. Attacker persistence often appears here as a new .service file with a generic-sounding name.

  • Save your enabled services findings to the triage report by running:
echo -e "\n=== ENABLED SERVICES ===" >> ~/investigation/triage-report.txt && systemctl list-unit-files --type=service --state=enabled >> ~/investigation/triage-report.txt
  • Confirm the section was written by running:
grep "ENABLED SERVICES" ~/investigation/triage-report.txt

You should see === ENABLED SERVICES === printed back, confirming the section header is in your report.

Check user startup scripts for backdoors

Every time a user logs in, Linux runs their .bashrc and .profile scripts automatically. Attackers inject commands into these files so their payload executes with every new terminal session.

  • Check your own startup files by running these commands one at a time:
cat ~/.bashrc
cat ~/.profile

Look for anything that does not belong: commands that download files, connect to remote IPs, or execute encoded strings. On a clean Kali system, these files contain standard environment setup only.

  • Check startup scripts for every user account that has an interactive shell by running:
for user in $(grep -v '/nologin\|/false' /etc/passwd | cut -d: -f6); do echo "--- $user ---"; cat "$user/.bashrc" 2>/dev/null | grep -v "^#\|^$"; done

What does this command do?

This loop extracts the home directory of every user who has a real login shell (filtering out service accounts with /nologin or /false). For each user, it prints the non-comment, non-empty lines from their .bashrc.

This shows you the active commands that execute on login for every real user on the system. Any unexpected entry could be an attacker's backdoor.

  • Save the filtered startup script output to your triage report by running:
echo -e "\n=== STARTUP SCRIPTS ===" >> ~/investigation/triage-report.txt && cat ~/.bashrc | grep -v "^#\|^$" >> ~/investigation/triage-report.txt
  • Confirm the final section was written by running:
grep "STARTUP SCRIPTS" ~/investigation/triage-report.txt

You should see === STARTUP SCRIPTS === confirming the section header is in your report.

Seeing permission denied errors?

Some user home directories may not be readable by your current account. This is expected for locked-down accounts. The 2>/dev/null in the for loop suppresses these errors. If you want to force access, prefix the entire command with sudo.

help me troubleshoot permission errors when reading other users' startup scripts

Verify your persistence investigation

Before you check the final result, predict: what types of persistence mechanisms do you think your Kali system has? Do you expect many cron jobs, or mostly systemd services?

  • Confirm your scheduled tasks are captured by running:
crontab -l
  • Confirm your enabled services are captured by running:
systemctl list-unit-files --type=service --state=enabled

You should see the scheduled tasks (or "no crontab" messages) and the list of enabled services that will start automatically on boot. Your triage report now contains a complete record of everything that would survive a reboot on this system.

  • Verify your full triage report has all sections by running:
grep "===" ~/investigation/triage-report.txt

You should see all the section headers you have built across the investigation: SYSTEM TRIAGE REPORT, INVESTIGATOR CONTEXT, PROCESS TREE, USER ACCOUNTS, LOGIN HISTORY, LISTENING PORTS, SCHEDULED TASKS, ENABLED SERVICES, and STARTUP SCRIPTS.

Secret mission

Hunt for SUID Binaries

You have mapped processes, users, ports, and persistence. But there is one more class of risk hiding in plain sight: binaries that grant root privileges to anyone who runs them. Can you find them and explain why they are dangerous?

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally on your Kali Linux machine, so there are no ongoing costs. Decide whether to keep your investigation files for future reference or delete them entirely.

Resources you used:

  • ~/investigation/ directory containing your triage-report.txt file.

Keep everything running

No action needed. Choose this if you want to keep your triage report for future reference or plan to continue adding to it.

  • Your ~/investigation/triage-report.txt stays on disk and you can revisit it any time.
  • All commands you learned (ps auxf, ss -tulnp, find / -perm -4000) are built into Kali and require no maintenance.

Pause - I'll come back to this later

Since this is a local project with no running processes or services, there is nothing to pause. Your files remain on disk until you delete them.

  • Close your terminal session when you are done.
  • Your ~/investigation/ directory will still be there next time you open a terminal.

Delete - I don't want to use this again

Remove all project files to start fresh. This permanently deletes your triage report.

  • Delete the investigation directory and everything in it by running:
rm -rf ~/investigation
  • Confirm deletion by running:
ls ~/investigation
  • You should see an error message indicating the directory does not exist.

Nice Work!

Nice Work!

You just investigated a live Linux system using the same structured methodology that professional security engineers use during incident response. Your triage-report.txt is a complete record of everything running, connected, and persisting on your machine.

You've learned how to:

  • Enumerate every running process on a Linux system, trace parent-child relationships with pstree, and read live process details directly from the /proc filesystem.
  • Identify every user account on the system, determine who has root-equivalent privileges, and map network connections to the exact process and user that owns each socket.
  • Find persistence mechanisms that survive a reboot, including cron jobs, systemd services, and user startup scripts.
  • Secret Mission: Hunted for SUID binaries across the filesystem and documented how they enable privilege escalation.

Ready to quiz yourself?