courses

Navigation Basics

The ground floor of everything else

The course VM is Linux (Kali), and almost every later task — reading logs during incident response, hunting setuid binaries for privilege escalation, inspecting file permissions — starts with the ability to move around the filesystem and see what is there. Linux navigation is built around a small, stable set of commands; mastering them is the foundation the rest of the course assumes.

This page covers the core navigation and file-management commands (ls, cd, pwd, mv, cp, mkdir, rm) and the layout of the Linux filesystem itself. It pairs with Shell and Other Basics (how the shell finds and runs these commands) and Working with Files (permissions and ownership).

Basic Commands

The most frequently used commands for navigating a Linux system are ls, cd, and pwd.

ls — list directory contents

ls              # list current directory
ls -l           # long format: permissions, owner, size, date
ls -la          # long format including hidden files (dot-files)
ls -lh          # human-readable sizes (K, M, G)
ls -lt          # sort by modification time, newest first
ls -lS          # sort by file size, largest first
ls -R           # recursive listing of subdirectories
ls --color=auto # colorize output by file type

Key flags:

Flag Meaning
-a Include hidden files (names starting with .)
-l Long listing format
-h Human-readable sizes (use with -l)
-t Sort by modification time
-S Sort by size
-r Reverse sort order
-R Recursive
-F Append type indicator (/ dirs, * executables, @ symlinks)

Worked example — find recently modified files:

ls -lt /var/log | head -20

cd — change directory

cd /etc                 # absolute path
cd Documents            # relative path
cd ..                   # parent directory
cd ../..                # two levels up
cd ~                    # home directory
cd -                    # previous directory
cd                      # home directory (no argument)

pwd — print working directory

pwd                     # print current absolute path
pwd -P                  # print physical path (resolve symlinks)

Other essential navigation commands

file myfile             # determine file type
stat myfile             # detailed file metadata (size, inode, timestamps)
which bash              # show path to executable
type ls                 # show how shell resolves a command (alias, builtin, file)

Moving Files and Directories

The primary commands for moving and renaming files are mv and cp.

mv — move or rename

mv moves files or directories, and is also the way to rename them.

mv file.txt /tmp/             # move file.txt to /tmp/
mv old_name.txt new_name.txt  # rename a file
mv dir1/ /home/user/          # move a directory
mv -i file.txt /tmp/          # prompt before overwriting
mv -n file.txt /tmp/          # never overwrite existing files
mv -v file.txt /tmp/          # verbose: show what's being moved
Flag Meaning
-i Interactive — prompt before overwrite
-n No-clobber — never overwrite
-v Verbose output
-b Make a backup of files that would be overwritten

Worked example — move all .log files to an archive directory:

mkdir -p /var/log/archive
mv /var/log/*.log /var/log/archive/

cp — copy files and directories

cp file.txt backup.txt          # copy a file
cp -r dir1/ dir2/               # recursively copy a directory
cp -p file.txt backup.txt       # preserve timestamps and permissions
cp -a dir1/ dir2/               # archive mode: preserve all attributes + recursive
cp -i file.txt /tmp/            # prompt before overwrite
cp -u file.txt /tmp/            # copy only if source is newer
Flag Meaning
-r Recursive (required for directories)
-p Preserve mode, ownership, timestamps
-a Archive: equivalent to -dR --preserve=all
-i Interactive prompt before overwrite
-u Update: only copy if source is newer
-v Verbose

Creating and Deleting Files and Directories

mkdir — make directories

mkdir mydir                     # create a single directory
mkdir -p path/to/new/dir        # create parent directories as needed
mkdir -m 755 mydir              # set permissions at creation time
mkdir dir1 dir2 dir3            # create multiple directories

The -p flag is essential for scripts — it does not fail if the directory already exists.

Worked example:

mkdir -p ~/projects/webapp/{src,tests,docs}

touch — create empty files / update timestamps

touch newfile.txt               # create empty file, or update timestamps
touch -t 202601010800 file.txt  # set specific timestamp (YYYYMMDDhhmm)
touch -r reference.txt file.txt # use reference file's timestamps

rm — remove files and directories

rm file.txt                     # remove a file
rm -i file.txt                  # prompt before each removal
rm -f file.txt                  # force remove without prompt
rm -r directory/                # recursively remove directory and contents
rm -rf directory/               # force recursive remove (use with extreme caution)
rm -v file.txt                  # verbose

⚠️ rm -rf is irreversible. There is no recycle bin — the bytes are gone. Always double-check the path before running it (a stray space, as in rm -rf / home/user, is catastrophic). Consider rm -ri for interactive removal when cleaning up directories.

rmdir — remove empty directories

rmdir emptydir/                 # only removes empty directories
rmdir -p a/b/c                  # remove directory and empty parents

Finding Files with find

find walks a directory tree and tests every entry against an expression, so it answers questions ls cannot: where is a file, which files changed recently, which are dangerously permissioned. The form is find <path...> <tests> <actions> — with no action, the default is to print each match.

find . -name "*.conf"           # by name (case-sensitive), under the current dir
find /etc -iname "ssh*"         # -iname is case-insensitive
find / -type f -name sshd_config 2>/dev/null   # files only; hide permission errors
find /var/log -maxdepth 1 -type f              # don't recurse below one level

Tests can match on type, size, time, owner, and permissions. With more than one test, find ANDs them together; use -o for OR and ! (or -not) to negate.

Test Matches
-name <glob> / -iname Name (case-sensitive / insensitive)
-type f / d / l Regular file / directory / symlink
-size +100M / -size -1k Larger than 100 MB / smaller than 1 KB
-mtime -7 / -mmin -60 Modified in the last 7 days / 60 minutes
-newer <ref> Modified more recently than the reference file
-user <name> / -group <name> Owned by a user / group
-perm -4000 Has the setuid bit set (also -2000 SGID, -0002 world-writable)
-maxdepth <n> / -mindepth <n> Limit how deep the recursion goes
-empty Empty files and directories

Acting on results

The default action prints matches, but find can run a command on each one. Prefer -exec ... {} + (batches matches into one invocation, like xargs) over -exec ... {} \; (one process per match):

find . -name "*.tmp" -delete                      # built-in delete (no rm needed)
find /var/log -name "*.log" -mtime +30 -exec gzip {} +   # compress logs older than 30 days
find . -type f -name "*.py" -exec grep -l "TODO" {} +    # files containing a pattern

# When piping to another tool, use -print0 / xargs -0 so spaces in names are safe
find . -type f -name "*.bak" -print0 | xargs -0 rm -v

⚠️ find ... -delete and -exec rm are as irreversible as rm itself. Run the command without the action first (so it just prints the matches), confirm the list, then add -delete.

Security-flavored examples

These are the queries you’ll reach for during host triage — see host security for how they fit a privilege-escalation hunt:

# setuid/setgid binaries — a classic privilege-escalation surface
find / -perm -4000 -type f 2>/dev/null

# world-writable files outside the usual temp dirs
find / -xdev -type f -perm -0002 ! -path "/proc/*" 2>/dev/null

# files modified in the last day (what changed during an incident?)
find /etc -type f -mtime -1 2>/dev/null

# files owned by a since-deleted user (orphaned UIDs)
find /home -nouser 2>/dev/null

locate answers name-only lookups much faster by querying a prebuilt index (updatedb), at the cost of being as fresh as the last index run:

sudo updatedb                   # refresh the index (often run nightly by cron)
locate sshd_config              # near-instant name search

Directory Hierarchy Overview

Linux follows the Filesystem Hierarchy Standard (FHS), which defines where system files live.

Directory Purpose
/ Root of the entire filesystem
/bin Essential user binaries (ls, cp, mv) — often symlink to /usr/bin
/sbin System binaries (fsck, ifconfig) — often symlink to /usr/sbin
/etc Host-specific system configuration files
/home User home directories
/root Home directory for the root user
/tmp Temporary files, cleared on reboot
/var Variable data: logs, spool files, databases
/usr Shareable read-only data: programs, libraries, documentation
/usr/local Locally installed software (not managed by package manager)
/opt Optional add-on application packages
/proc Virtual filesystem exposing kernel and process information
/sys Virtual filesystem exposing kernel device tree
/dev Device files (block devices, character devices)
/lib Shared libraries needed by /bin and /sbin
/boot Boot loader files, kernel images
/mnt Temporary mount points
/media Mount points for removable media
/srv Data for services (web, ftp)

Worked example — explore key config locations:

ls /etc/          # system config files
ls /var/log/      # system logs
ls /proc/cpuinfo  # CPU information from kernel
cat /etc/os-release  # OS identification
tree /etc -L 2                             # tree view, 2 levels deep
du -sh /var/log/*                          # disk usage per subdirectory
df -h                                      # filesystem usage summary

(For locating files by name, size, time, or permissions, see Finding Files with find above.)

Key takeaways

References


Related course pages: Shell and Other Basics · Working with Files · Editing Files · Process Management · Access Control and Authorization

🛠️ Maintenance note: these commands and the FHS are extremely stable. The main drift is the ongoing /bin/usr/bin merge (the “usrmerge”), now complete on Kali and most modern distros — verify the symlink notes in the FHS table against the course VM if it changes.