Linux
Objectives: By the end of this topic, you will be able to…
- Navigate the Linux filesystem with confidence
- Manipulate files, permissions, and processes from the terminal
- Install tools needed for other classes
- Begin writing simple scripts to automate tasks
- Explain how Linux decides who may read a file or signal a process, and why
/etc/shadowis protected the way it is
Why use Linux in cybersecurity
Linux is the working environment for most security tooling, and Kali Linux packages that tooling into a single Debian-based distribution. You met Kali in class 01, so this section does not re-introduce it. What matters here is narrower: from this class onward, nearly everything you do in this course happens through the shell rather than a graphical interface, so the rest of the course assumes you are comfortable at the command line.
The reason a security course spends a session on an operating system you have already used is that two questions come back in every later class: which user is allowed to read this file, and which user is this process running as. Both are answered by mechanisms this class establishes, and both are what an attacker manipulates when they escalate privileges on a host.
Filesystem structure
Linux presents most system resources through a single directory hierarchy, and a large share of them, including block devices and running processes, are reachable as ordinary file paths. Treat “everything is a file” as a useful approximation rather than a literal rule: network sockets, for example, are reached through file descriptors but have no path in the hierarchy. Where the approximation does hold it buys you something concrete, because a resource with a path is covered by the ordinary permission model described in the next section.
You already recognize most of the hierarchy. The directories that matter for security work, and that you will use in the lab, are these:
| Directory | Why it matters here |
|---|---|
/etc | System-wide configuration, including the account and credential files covered below. Configuration you can read is reconnaissance material, which is why so much of /etc is root-only |
/var | Variable data, including /var/log, where the system keeps its logs. Among them are a record of every package installed or removed and a record of authentication and privilege-elevation attempts |
/proc | A kernel-generated pseudo-filesystem with one directory per running process. /proc/<pid>/cmdline gives the full command line of a process and /proc/<pid>/exe links to its binary, while /proc/<pid>/environ holds its environment and is readable only by the process owner and root. This is how you inspect a process you did not start |
/root | The root account’s home directory, which is distinct from / and is mode 700 on Debian-based systems, so an unprivileged user cannot enter it |
/tmp | World-writable scratch space with the sticky bit set, which is why it is the default drop location for downloaded payloads and the first place to look for them |
The remaining top-level directories behave as you would expect from any Unix system. One detail worth knowing before you run ls -l / on Kali: current Debian-based releases use a merged /usr layout, so /bin, /sbin, and /lib are symbolic links into /usr rather than separate directories.
Reading /var/log is among the first things a responder does on a suspect host. Classes 13 and 15 return to these same files, the first with forensic technique and the second with automated analysis; here the point is simply that the system keeps a written record of who did what, and that the record is a file with an owner and permissions like any other.
Essential commands
The commands below are reference material rather than something to memorize in class. Read the table once, and use man <command> for anything you need in detail.
| Command | What it does |
|---|---|
pwd, ls, cd | Where am I, what is here, go there. ls -l is the form you will use constantly, and the next section explains its output field by field |
cp, mv, rm | Copy, move or rename, delete |
mkdir, touch | Create a directory, create an empty file |
cat, less | Print a file, page through a file |
file <path> | Identify what a file actually is from its contents rather than its name. Class 05 and class 07 both start their analysis with this command |
find <path> -name '<pattern>' | Search a subtree by name or extension. Sweeping a filesystem for scripts and binaries is a standard enumeration step once you have access to a machine, and it is what Part 5 of the lab asks you to automate |
File permissions and privilege
Reading ls -l
$ ls -l file.sh
-rwxr-xr-- 1 daniel daniel 1234 Jul 18 10:23 file.sh
The first character is the entry type: - for a regular file, d for a directory, l for a symbolic link. The nine characters after it are three permission triads of three bits each, which apply in order to the file’s owning user, its owning group, and everyone else. In the line above the owner may read, write, and execute; members of the group may read and execute; everyone else may only read. The two names after the link count are the owning user and the owning group, in that order, and they are resolved from numeric IDs through a file you will read in the next section.
On a regular file, x means the kernel will execute it. On a directory, x means you may traverse into it to reach the entries inside, so a directory with r but no x lets you list names and do nothing else with them.
Octal notation
Because each triad is a three-bit field, permissions are usually written as three digits, one per triad. Read is worth 4, write 2, and execute 1, and each digit is the sum of the bits set in its own triad. chmod 755 file.sh sets rwx (4+2+1) for the owner and r-x (4+1) for both the group and everyone else. chmod 644 copy.txt, which you will run in the lab, sets rw- for the owner and r-- for the other two. Work the notation in the other direction on mode 640 and you get rw- for the owner, r-- for the group, and no access at all for everyone else, which is exactly the mode you will find on /etc/shadow.
Which triad applies to you
Permissions do not accumulate. When a process opens a file the kernel selects exactly one triad and ignores the other two: if the process’s effective user ID matches the file’s owning user ID it uses the user triad; otherwise, if one of the process’s groups matches the file’s owning group it uses the group triad; otherwise it uses the others triad. First match wins. A file you own with mode 077 is a file you cannot read even though everyone else on the system can, which is counter-intuitive until you see that ownership is what selects the triad applying to you, so a permissive others triad cannot rescue an owner denied by the user triad. (POSIX ACLs, shown by a trailing + in ls -l, extend this model. You will not meet them in this course.)
Root, and what sudo actually does
The root account is user ID 0, and it is exempt from the check above rather than being granted generous permissions inside it. That distinction is worth holding onto, because it is why privilege escalation is the objective it is: reaching UID 0 removes the permission check instead of satisfying it.
Some operations are restricted to root regardless of file permissions, and changing a file’s owner to another user is one of them. chown root:root copy.txt run as an unprivileged user fails with chown: changing ownership of 'copy.txt': Operation not permitted, and the ownership does not change. Commands of this kind have to be run through sudo.
sudo runs a single command as another user, root by default, after checking the invoking account against the policy in /etc/sudoers and recording the attempt in the system’s authentication log. Its purpose is to let you work in an unprivileged account and elevate only for the specific commands that require it, which is the principle of least privilege that class 12 develops formally at the level of network and system architecture. In practice, for the rest of this course, the difference between a command that works and one that returns Operation not permitted is most often a missing sudo.
Accounts and credential storage
Every account on the system has one line in /etc/passwd. The seven colon-separated fields are the username, a password placeholder, the numeric user ID, the primary group ID, a free-text description, the home directory, and the login shell:
daniel:x:1000:1000:Daniel,,,:/home/daniel:/bin/bash
/etc/passwd is world-readable, and it has to be. Any process that displays a username instead of a number consults it, including the ls -l output from the previous section, which turns user ID 1000 into daniel by looking it up here.
The x in the second field is the part with a history. On early Unix systems that field held the account’s password hash directly, and since the file has to stay readable by everyone, so did every password hash on the machine. Any local user could copy the file and attack the hashes offline, at their own pace and on their own hardware, without needing any further access to the system. Shadow files were introduced to end that: the hash moved into /etc/shadow, and x was left behind as a marker meaning that the credential lives in the shadow file.
$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1284 Jul 18 09:12 /etc/shadow
Owner root, group shadow, mode 640. Decode that with the rules from the previous section and you have the reason an unprivileged user cannot read the file: that is the ordinary permission model doing its job on a file that happens to matter more than most. This is also the first point in the course where the confidentiality property from class 01’s CIA triad is something you can verify for yourself with one command.
What /etc/shadow stores for each account, in its second field, is a one-way hash rather than the password. The leading $id$ names the algorithm: $6$ is SHA-512 crypt, and $y$ is yescrypt, the default on recent Debian-based releases. Class 06 covers what makes a hash function suitable for this purpose and how stored hashes are attacked in practice. The point to carry into the lab is the one that explains why the file is protected the way it is: reading /etc/shadow does not give an attacker the passwords; it gives them a computation to run, and how expensive that computation is decides whether the compromise stops there.
Processes and services
Processes have owners
ps aux # every process on the system
ps aux | grep bash # filtered to one program
kill <PID> # ask a process to terminateThe first column of ps aux is USER, the account each process runs as, and it decides what you are allowed to do to that process. In general you may only signal processes running as your own user, unless you are root, so kill against a root-owned process returns Operation not permitted rather than reporting that no such process exists. The error tells you the process is there and that you are not entitled to touch it, and the remedy is the same as in the previous section.
That column is also the first thing to read on a host you suspect is compromised. A web server running as root instead of www-data, or an interactive shell owned by a service account that should never have one, is a finding by itself. Class 13 develops this style of reasoning against forensic evidence.
For a live view rather than a snapshot, use top, or htop if it is installed.
Services and scheduled work
systemctl status <name> # is it loaded, enabled, running?
systemctl start <name> # also stop, restartA service is a long-running process managed by systemd, the init system on Kali and on current Debian releases, which starts it, supervises it, and can restart it on failure. The older service <name> status form still works and is redirected to systemd, which is why you will see both spellings in the lab and in the wild.
The set of services running on a machine is its attack surface stated concretely. ssh is remote access, apache2 is a web application reachable by anyone who can route to the host, and cron, the daemon that runs commands on a schedule from per-user crontabs, is where persistence tends to be planted, because a scheduled job survives reboots and attracts less routine attention than a running process. Enumerating services is one of the first things you do after gaining access to a machine in class 09, and one of the first things you check when investigating one in class 13.
Package installation and using man
sudo apt update # refresh the package index
sudo apt install <name> # install
sudo apt remove <name> # remove
apt search <term> # search the index; no privileges requiredKali ships with most of the tooling this course uses already installed, so apt matters here mainly for the tools it does not carry and for reading what is present on a machine you did not build. Note which of these commands need sudo and which do not, and why: installing a package writes outside your home directory, and searching the index does not.
For anything you have not seen before, man <command> gives the full manual and <command> --help gives the summary.
Basic Bash scripting concepts
Scripts automate the commands above. The minimal structure is a shebang line naming the interpreter, followed by the commands you would otherwise type:
#!/bin/bash
echo "Hello, World"You already know loops, conditionals, and command substitution as programming constructs, so what follows is about Bash’s spelling of them rather than the ideas. This script takes a directory as an argument, defaults to the current one, and reports which entries are executable:
#!/bin/bash
target="${1:-.}"
for f in "$target"/*; do
if [ -f "$f" ] && [ -x "$f" ]; then
echo "executable: $f"
fi
doneThree details carry most of the Bash-specific weight. ${1:-.} is the first positional argument with a default, "$f" is quoted so that filenames containing spaces stay a single word, and $(command) (not used above, but used constantly elsewhere) captures a command’s output as a value. The [ -x "$f" ] test asks whether the current user may execute the file, which resolves through exactly the triad-selection rule from earlier, so the same script can print different results when you run it under sudo.
Make a script executable and run it:
chmod +x script.sh
./script.shHands-on lab
Requirements: Kali Linux
Part 1: System exploration
- Navigate from
/to/etc,/var, and/home. Identify the purpose of each - Read the contents of
/etc/passwdand answer:- What type of information does it contain?
- What is the difference between this file and
/etc/shadow?
- Verify the permissions of
/etc/shadowwithls -land explain why it cannot be read as a normal user - Review logs:
less /var/log/boot.log
less /var/log/dpkg.logPart 2: Files and permissions
- Create a working folder at
~/linux_practice - Create three files with dummy content
- Execute and document the effects of:
cp file1.txt copy.txt
mv file2.txt renamed.txt
rm file3.txt
chmod 644 copy.txt
chmod +x renamed.txt
sudo chown root:root copy.txtQuestion
After running
chown root:root copy.txt, try to modify the file as a regular user. What error do you get? How does ownership interact with permissions to control access to a file?
Part 3: Processes and services
- Run
topand observe the most active processes. Filter withps aux | grep bash - Start a program in the background and terminate it with
kill
Question
What PID was assigned to the process you killed? What happens if you try to kill a process owned by root without using
sudo?
- Check the status of
ssh,cron, andapache2:
systemctl status ssh
service cron statusPart 4: Package management
- Search for a package such as
nmap,htop, ornet-tools:
apt search nmap- Install, verify, and uninstall a package
Part 5: Bash automation
- Create a script that:
- Finds all
.txtfiles in the home directory - Counts the lines in each file
- Prints the result sorted by number of lines
- Finds all
- Add improvements: save results to a file, accept a directory as an argument
Question
How does your script handle directories that contain no
.txtfiles, or files that are empty? What change would you make to also detect files with potentially executable extensions like.shor.py?
Submission
Compressed file (.zip or .tar.gz) with:
- Key screenshots
- The Bash script with comments
- Document with answers to questions and reflections
Key concepts
| Term | Definition |
|---|---|
| CLI | Command Line Interface. Text-based interface for interacting with the operating system |
| Permissions | File access control system based on read, write, and execute for user, group, and others |
| systemd | Init system and service manager used in modern Linux distributions |
| Bash | Bourne Again Shell. Default command interpreter and scripting language on most Linux distributions |
apt | Advanced Package Tool. Package manager for Debian and its derivatives like Kali |
/etc/shadow | Root-readable file holding one-way password hashes, separated from the world-readable /etc/passwd so that hashes are not exposed to every local user |
sudo | Runs one command as another user, root by default, subject to the policy in /etc/sudoers and recorded in the system’s authentication log |
UID 0 / root | The superuser identity, exempt from file permission checks rather than granted permissions within them. Reaching it is the usual objective of privilege escalation |
| SUID | Set-user-ID: a permission bit that makes an executable run with its owner’s privileges rather than its caller’s, shown as s in the owner triad of ls -l. A standard privilege-escalation vector, not covered in this class’s theory |